* [PATCH 7.2 001/733] iommu/arm-smmu-v3: Disable implementations during devm teardown
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 002/733] wifi: mt76: mt7921: validate CLC firmware records Greg Kroah-Hartman
` (743 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Guan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Guan <guanwentao@uniontech.com>
The Tegra241 CMDQV teardown fix moved VINTF hardware deinitialization
into the implementation device_disable() callback. However, its stable
backport preceded the conversion to devm teardown and could only invoke
the callback from the shutdown path.
Now that arm_smmu_disable_action() manages normal teardown, invoke the
implementation callback there while the command queue is still alive.
This prevents the subsequent implementation remove action from releasing
resources while the CMDQV hardware remains active.
After ("iommu/arm-smmu-v3: Manage teardown with devm") merged in stable,
now keep the shutdown path consistent with mainline, where disabling
the base SMMU is sufficient.
It is a fix for stable tree commit to aligned with mainline, so no
upstream commit id here.
Fixes: 5994617e09ee ("iommu/tegra241-cmdqv: Fix CMD_SYNC use-after-free on teardown")
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
index 35b7b2fd4a122..b52dae11fbbef 100644
--- a/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
+++ b/drivers/iommu/arm/arm-smmu-v3/arm-smmu-v3.c
@@ -4741,6 +4741,8 @@ static void arm_smmu_disable_action(void *data)
{
struct arm_smmu_device *smmu = data;
+ if (smmu->impl_ops && smmu->impl_ops->device_disable)
+ smmu->impl_ops->device_disable(smmu);
arm_smmu_device_disable(smmu);
}
@@ -5555,8 +5557,6 @@ static void arm_smmu_device_shutdown(struct platform_device *pdev)
{
struct arm_smmu_device *smmu = platform_get_drvdata(pdev);
- if (smmu->impl_ops && smmu->impl_ops->device_disable)
- smmu->impl_ops->device_disable(smmu);
arm_smmu_device_disable(smmu);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 002/733] wifi: mt76: mt7921: validate CLC firmware records
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 001/733] iommu/arm-smmu-v3: Disable implementations during devm teardown Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 003/733] wifi: mt76: mt7921: skip unknown " Greg Kroah-Hartman
` (742 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Laxman Acharya Padhya, Felix Fietkau,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
[ Upstream commit 9417c5818a0146980c2608fda94c908e604eb033 ]
The CLC region is supplied by firmware, but the loader trusts the
region count and each record length. A malformed image can make the
region table pointer precede the firmware buffer, make the record loop
fail to advance, or index phy->clc past its end. Validate the table and
record bounds before dereferencing or copying.
Fixes: 23bdc5d8cadf ("wifi: mt76: mt7921: introduce Country Location Control support")
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Link: https://patch.msgid.link/CAMyXUJmh=WfwC4_KHupNxYR5e2Gy5QhBDL5TSG6XEW-XLa+X4Q@mail.gmail.com
Signed-off-by: Felix Fietkau <nbd@nbd.name>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/wireless/mediatek/mt76/mt7921/mcu.c | 28 ++++++++++++++++---
1 file changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 25b9437250f7b..564dd836e0b38 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -415,7 +415,8 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)
struct mt76_dev *mdev = &dev->mt76;
struct mt792x_phy *phy = &dev->phy;
const struct firmware *fw;
- int ret, i, len, offset = 0;
+ size_t clc_len, fw_data_len, len, offset = 0;
+ int ret, i;
u8 *clc_base = NULL, hw_encap = 0;
dev->phy.clc_chan_conf = 0xff;
@@ -441,13 +442,21 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)
}
hdr = (const void *)(fw->data + fw->size - sizeof(*hdr));
+ if (hdr->n_region > (fw->size - sizeof(*hdr)) / sizeof(*region)) {
+ dev_err(mdev->dev, "Invalid firmware region table\n");
+ ret = -EINVAL;
+ goto out;
+ }
+ fw_data_len = fw->size - sizeof(*hdr) -
+ hdr->n_region * sizeof(*region);
+
for (i = 0; i < hdr->n_region; i++) {
region = (const void *)((const u8 *)hdr -
(hdr->n_region - i) * sizeof(*region));
len = le32_to_cpu(region->len);
/* check if we have valid buffer size */
- if (offset + len > fw->size) {
+ if (len > fw_data_len - offset) {
dev_err(mdev->dev, "Invalid firmware region\n");
ret = -EINVAL;
goto out;
@@ -464,8 +473,19 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)
if (!clc_base)
goto out;
- for (offset = 0; offset < len; offset += le32_to_cpu(clc->len)) {
+ for (offset = 0; offset < len; offset += clc_len) {
+ if (len - offset < sizeof(*clc)) {
+ ret = -EINVAL;
+ goto out;
+ }
+
clc = (const struct mt7921_clc *)(clc_base + offset);
+ clc_len = le32_to_cpu(clc->len);
+ if (clc_len < sizeof(*clc) || clc_len > len - offset ||
+ clc->idx >= ARRAY_SIZE(phy->clc)) {
+ ret = -EINVAL;
+ goto out;
+ }
/* do not init buf again if chip reset triggered */
if (phy->clc[clc->idx])
@@ -477,7 +497,7 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)
continue;
phy->clc[clc->idx] = devm_kmemdup(mdev->dev, clc,
- le32_to_cpu(clc->len),
+ clc_len,
GFP_KERNEL);
if (!phy->clc[clc->idx]) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 003/733] wifi: mt76: mt7921: skip unknown CLC firmware records
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 001/733] iommu/arm-smmu-v3: Disable implementations during devm teardown Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 002/733] wifi: mt76: mt7921: validate CLC firmware records Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 004/733] leds: st1202: Validate pattern input before stopping the sequence Greg Kroah-Hartman
` (741 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Gavrilov,
Laxman Acharya Padhya, Junjie Cao, Linus Torvalds, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
[ Upstream commit 1a296bfd3e775e515233f746218824fc7dd5ff16 ]
Treat an out-of-range CLC index as newer firmware rather than a
malformed image. linux-firmware 20260810 ships MT7922 records with
idx 3, and rejecting them made mt7921e fail to probe.
Keep the record-length checks, and report those as errors so a
truncated table is visible instead of a silent retry loop.
Fixes: 9417c5818a01 ("wifi: mt76: mt7921: validate CLC firmware records")
Reported-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Reviewed-by: Junjie Cao <junjie.cao@intel.com>
Tested-by: Mikhail Gavrilov <mikhail.v.gavrilov@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/mediatek/mt76/mt7921/mcu.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
index 564dd836e0b38..45439652c847b 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7921/mcu.c
@@ -475,18 +475,23 @@ static int mt7921_load_clc(struct mt792x_dev *dev, const char *fw_name)
for (offset = 0; offset < len; offset += clc_len) {
if (len - offset < sizeof(*clc)) {
+ dev_err(mdev->dev, "Invalid CLC record\n");
ret = -EINVAL;
goto out;
}
clc = (const struct mt7921_clc *)(clc_base + offset);
clc_len = le32_to_cpu(clc->len);
- if (clc_len < sizeof(*clc) || clc_len > len - offset ||
- clc->idx >= ARRAY_SIZE(phy->clc)) {
+ if (clc_len < sizeof(*clc) || clc_len > len - offset) {
+ dev_err(mdev->dev, "Invalid CLC record\n");
ret = -EINVAL;
goto out;
}
+ /* Newer firmware may add records this driver does not use yet */
+ if (clc->idx >= ARRAY_SIZE(phy->clc))
+ continue;
+
/* do not init buf again if chip reset triggered */
if (phy->clc[clc->idx])
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 004/733] leds: st1202: Validate pattern input before stopping the sequence
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (2 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 003/733] wifi: mt76: mt7921: skip unknown " Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 005/733] ppp_async: drop the errored frame instead of resetting its headroom Greg Kroah-Hartman
` (740 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Manuel Fombuena, Lee Jones,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Manuel Fombuena <fombuena@outlook.com>
[ Upstream commit fd2529ba8fb44cd4b56f1069363b949644b42cec ]
Input validation for pattern duration is performed inside the write
loop, after the pattern sequence has already been stopped. If
validation fails mid-loop the chip is left with the sequence stopped
and partially written pattern data, with no recovery.
Move all input validation before the mutex and before any hardware
interaction, so an invalid input leaves the chip state unchanged.
Signed-off-by: Manuel Fombuena <fombuena@outlook.com>
Assisted-by: Claude:claude-sonnet-4-6
Link: https://patch.msgid.link/GV1PR08MB84975929B6ED7CDFBCEB7D76C5F52@GV1PR08MB8497.eurprd08.prod.outlook.com
Signed-off-by: Lee Jones <lee@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/leds/leds-st1202.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/drivers/leds/leds-st1202.c b/drivers/leds/leds-st1202.c
index 2593ff39f22a6..168df5ecf27b7 100644
--- a/drivers/leds/leds-st1202.c
+++ b/drivers/leds/leds-st1202.c
@@ -237,6 +237,12 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
if (len > ST1202_MAX_PATTERNS)
return -EINVAL;
+ for (int patt = 0; patt < len; patt++) {
+ if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
+ pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
+ return -EINVAL;
+ }
+
guard(mutex)(&chip->lock);
ret = st1202_write_reg(chip, ST1202_CONFIG_REG, ST1202_CONFIG_REG_SHFT);
@@ -244,10 +250,6 @@ static int st1202_led_pattern_set(struct led_classdev *ldev,
return ret;
for (int patt = 0; patt < len; patt++) {
- if (pattern[patt].delta_t < ST1202_MILLIS_PATTERN_DUR_MIN ||
- pattern[patt].delta_t > ST1202_MILLIS_PATTERN_DUR_MAX)
- return -EINVAL;
-
ret = st1202_pwm_pattern_write(chip, led->led_num, patt, pattern[patt].brightness);
if (ret != 0)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 005/733] ppp_async: drop the errored frame instead of resetting its headroom
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (3 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 004/733] leds: st1202: Validate pattern input before stopping the sequence Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 006/733] RAS/AMD/ATL, EDAC/amd64: Only load ATL when needed Greg Kroah-Hartman
` (739 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Vlatko Kosturjak,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlatko Kosturjak <kost@linux.hr>
[ Upstream commit 8dc5d98a16fa23c00999aecf10018c9f69fa5bf4 ]
ppp_receive_nonmp_frame() prepends a two-byte direction tag before running
the pass/active BPF filters:
*(__be16 *)skb_push(skb, 2) = htons(PPP_FILTER_INBOUND_TAG);
Nothing on the receive path guarantees those two bytes of headroom. The
frame-error path in ppp_async's process_input_packet() resets a reused skb's
headroom to zero while claiming to restore it to a freshly allocated state -
but a fresh skb from dev_alloc_skb() carries NET_SKB_PAD:
err:
if (skb) {
/* make skb appear as freshly allocated */
skb_trim(skb, 0);
skb_reserve(skb, - skb_headroom(skb));
}
ap->rpkt still points at that skb, so the next frame is reassembled into it
with no headroom at all. A peer that sends a bad-FCS frame followed by one
beginning ff 03 then leaves a single byte of headroom by the time the filter
tag is pushed, which lands one byte below skb->head:
skbuff: skb_under_panic: len:49 put:2 head:ffff888003c10000
data:ffff888003c0ffff tail:0x30 end:0x640 dev:<NULL>
kernel BUG at net/core/skbuff.c:214!
RIP: 0010:skb_panic+0x13e/0x230
Call Trace:
skb_push+0xbd/0x100
ppp_receive_nonmp_frame+0x48a/0x1d10
ppp_input+0x4e9/0x2f80
ppp_async_process+0x2a/0xe0
tasklet_action_common+0x20f/0x8a0
handle_softirqs+0x18e/0x590
Kernel panic - not syncing: Fatal exception in interrupt
Zeroing the headroom violates the NET_SKB_PAD guarantee that dev_alloc_skb()
gives the rest of the receive path. Besides the filter panic above, when CCP
compression is enabled ppp_decompress_frame() hands skb->data - 2 to
->decompress()/->incomp(), which then reads out of bounds before skb->head
for the same reason.
Rather than restore the headroom, drop the errored frame - as ppp_synctty
already does on its error path - and clear ap->rpkt so the next frame is
reassembled into a fresh skb with proper headroom. This is simpler and fixes
both the filter under-panic and the CCP out-of-bounds read.
The original V1 of this patch made room in ppp_receive_nonmp_frame() with
skb_cow_head(); Eric pointed out that fixing the root cause in the transport
is the right approach.
Found by fuzzing the PPP receive path with a mutating peer on a pty; it is an
interesting (remote) DoS: root configures PPP, the peer supplies two crashing
frames. The reproducer (repro-ppp-skb.c, unchanged from v1) panics in about a
second, and returns cleanly with this applied.
Fixes: 6722e78c9005 ("[PPP]: handle misaligned accesses")
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Vlatko Kosturjak <kost@linux.hr>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/apkR6ZU+tqP2C3Fl@griffin.linux.hr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ppp/ppp_async.c | 7 ++-----
1 file changed, 2 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c
index 93a7b0f6c4e7e..a5db4f78b5fc8 100644
--- a/drivers/net/ppp/ppp_async.c
+++ b/drivers/net/ppp/ppp_async.c
@@ -812,11 +812,8 @@ process_input_packet(struct asyncppp *ap)
err:
/* frame had an error, remember that, reset SC_TOSS & SC_ESCAPE */
ap->state = SC_PREV_ERROR;
- if (skb) {
- /* make skb appear as freshly allocated */
- skb_trim(skb, 0);
- skb_reserve(skb, - skb_headroom(skb));
- }
+ kfree_skb(skb);
+ ap->rpkt = NULL;
}
/* Called when the tty driver has data for us. Runs parallel with the
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 006/733] RAS/AMD/ATL, EDAC/amd64: Only load ATL when needed
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (4 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 005/733] ppp_async: drop the errored frame instead of resetting its headroom Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 007/733] EDAC/igen6: Fix interleave boundary condition Greg Kroah-Hartman
` (738 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello, Yazen Ghannam,
Borislav Petkov (AMD), Deskhmukh Shrirang, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <yazen.ghannam@amd.com>
[ Upstream commit 4c3da04827dc01dc1cfc3d03654b7de656c42d80 ]
The AMD Address Translation Library (ATL) will attempt to load on all AMD
Zen/SMCA systems.
However, only systems with DRAM ECC enabled will use the library. Other
systems will fail to load the library and produce an unnecessary message to
the user. More importantly, that thing is dead code loaded and unused.
Remove the ATL module dependency table to prevent autoloading. Request
ATL to load from EDAC once all system checks are complete.
[ bp: Massage commit message. ]
Fixes: 3f3174996be6 ("RAS: Introduce AMD Address Translation Library")
Closes: https://lore.kernel.org/20260305154528.1171999-1-mario.limonciello@amd.com
Reported-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Tested-by: Deskhmukh Shrirang <Shrirang.Deskhmukh@amd.com>
Link: https://lore.kernel.org/all/20260307144910.GA113343@yaz-khff2.amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/amd64_edac.c | 2 ++
drivers/ras/amd/atl/core.c | 1 -
2 files changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/edac/amd64_edac.c b/drivers/edac/amd64_edac.c
index c6aa69dbd9fb1..475235c402e88 100644
--- a/drivers/edac/amd64_edac.c
+++ b/drivers/edac/amd64_edac.c
@@ -4173,6 +4173,8 @@ static int __init amd64_edac_init(void)
goto err_pci;
}
+ request_module_nowait("amd_atl");
+
/* register stuff with EDAC MCE */
if (boot_cpu_data.x86 >= 0x17) {
amd_register_ecc_decoder(decode_umc_error);
diff --git a/drivers/ras/amd/atl/core.c b/drivers/ras/amd/atl/core.c
index 0f7cd6dab0b0e..d77dacdd4f569 100644
--- a/drivers/ras/amd/atl/core.c
+++ b/drivers/ras/amd/atl/core.c
@@ -190,7 +190,6 @@ static const struct x86_cpu_id amd_atl_cpuids[] = {
X86_MATCH_FEATURE(X86_FEATURE_ZEN, NULL),
{ }
};
-MODULE_DEVICE_TABLE(x86cpu, amd_atl_cpuids);
static int __init amd_atl_init(void)
{
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 007/733] EDAC/igen6: Fix interleave boundary condition
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (5 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 006/733] RAS/AMD/ATL, EDAC/amd64: Only load ATL when needed Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 008/733] EDAC/igen6: Fix channel selection hash Greg Kroah-Hartman
` (737 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qiuxu Zhuo, Tony Luck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
[ Upstream commit f4008169bd320eedb9ddf2b39eeb21370ddac278 ]
The address translation logic splits the memory space into interleaved
and non-interleaved regions using a boundary at 2 * s_size.
The current check uses '>' and incorrectly classifies the boundary
address (2 * s_size) as part of the interleaved region. This leads to
incorrect channel/sub-channel selection at the region boundary.
Fix the classification by using '>=' so that the boundary address is
handled in the non-interleaved region, matching the hardware layout.
Fixes: 10590a9d4f23 ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC")
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260730024238.4096623-3-qiuxu.zhuo@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/igen6_edac.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
index f1fc20d4ebf61..43b56a2eb5479 100644
--- a/drivers/edac/igen6_edac.c
+++ b/drivers/edac/igen6_edac.c
@@ -1035,7 +1035,7 @@ static void decode_addr(u64 addr, u32 hash, u64 s_size, int l_map,
{
int intlv_bit = CHANNEL_HASH_LSB_MASK_BIT(hash) + 6;
- if (addr > 2 * s_size) {
+ if (addr >= 2 * s_size) {
*sub_addr = addr - s_size;
*idx = l_map;
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 008/733] EDAC/igen6: Fix channel selection hash
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (6 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 007/733] EDAC/igen6: Fix interleave boundary condition Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 009/733] EDAC/igen6: Fix channel address decode for non-hash mode Greg Kroah-Hartman
` (736 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qiuxu Zhuo, Tony Luck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
[ Upstream commit 540b79536f3a89a66c5b6c490110298d43025618 ]
In channel selection hash mode, the hardware decoding logic always
includes the channel interleave bit in XOR operations. However, the
hash mask may or may not include this channel interleave bit. When
the mask does include this bit, the current igen6_edac code performs
XOR on the interleave bit twice, effectively ignoring it - which is
incorrect.
Fix this issue by ensuring the hash mask always includes the interleave
bit, so XOR is performed on the interleave bit exactly once.
Fixes: 10590a9d4f23 ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC")
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260730024238.4096623-4-qiuxu.zhuo@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/igen6_edac.c | 14 +++++++++++---
1 file changed, 11 insertions(+), 3 deletions(-)
diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
index 43b56a2eb5479..f1fb644154ae3 100644
--- a/drivers/edac/igen6_edac.c
+++ b/drivers/edac/igen6_edac.c
@@ -1009,14 +1009,22 @@ static void set_dimm_params(struct igen6_imc *imc, int chan)
static int decode_chan_idx(u64 addr, u64 mask, int intlv_bit)
{
- u64 hash_addr = addr & mask, hash = 0;
- u64 intlv = (addr >> intlv_bit) & 1;
+ u64 hash_addr, hash = 0;
int i;
+ /*
+ * In hash mode, the @intlv_bit is the lowest selected bit of @addr
+ * to be XORed. While @mask may or may not include this @intlv_bit,
+ * we enforce that @mask includes @intlv_bit to ensure @intlv_bit is
+ * XORed exactly once.
+ */
+ mask |= 1 << intlv_bit;
+ hash_addr = addr & mask;
+
for (i = 6; i < 20; i++)
hash ^= (hash_addr >> i) & 1;
- return (int)hash ^ intlv;
+ return (int)hash;
}
static u64 decode_channel_addr(u64 addr, int intlv_bit)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 009/733] EDAC/igen6: Fix channel address decode for non-hash mode
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (7 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 008/733] EDAC/igen6: Fix channel selection hash Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 010/733] EDAC/igen6: Fix Raptor Lake-P logged error address Greg Kroah-Hartman
` (735 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qiuxu Zhuo, Tony Luck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
[ Upstream commit 7b348d0d401d478f1923ba20a34a61681d1f7971 ]
In non-hash mode, decode_channel_addr() and channel index extraction
used a hardcoded interleave bit position 6 instead of the actual
intlv_bit parameter, causing incorrect channel address decoding.
Fix this by using intlv_bit consistently in both hash and non-hash modes.
Fixes: 10590a9d4f23 ("EDAC/igen6: Add EDAC driver for Intel client SoCs using IBECC")
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260730024238.4096623-5-qiuxu.zhuo@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/igen6_edac.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
index f1fb644154ae3..ea5628d780eba 100644
--- a/drivers/edac/igen6_edac.c
+++ b/drivers/edac/igen6_edac.c
@@ -1049,13 +1049,12 @@ static void decode_addr(u64 addr, u32 hash, u64 s_size, int l_map,
return;
}
- if (CHANNEL_HASH_MODE(hash)) {
- *sub_addr = decode_channel_addr(addr, intlv_bit);
+ *sub_addr = decode_channel_addr(addr, intlv_bit);
+
+ if (CHANNEL_HASH_MODE(hash))
*idx = decode_chan_idx(addr, CHANNEL_HASH_MASK(hash), intlv_bit);
- } else {
- *sub_addr = decode_channel_addr(addr, 6);
- *idx = GET_BITFIELD(addr, 6, 6);
- }
+ else
+ *idx = GET_BITFIELD(addr, intlv_bit, intlv_bit);
}
static int igen6_decode(struct decoded_addr *res)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 010/733] EDAC/igen6: Fix Raptor Lake-P logged error address
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (8 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 009/733] EDAC/igen6: Fix channel address decode for non-hash mode Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 011/733] EDAC/device_sysfs: Use kstrtouint() for poll_msec to prevent truncation Greg Kroah-Hartman
` (734 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qiuxu Zhuo, Tony Luck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
[ Upstream commit 0361f576ec0dffca13edc94580c8666146a91e02 ]
Raptor Lake-P was treated as using a different IBECC (In-Band ECC) error
address format and therefore had a dedicated extraction path that shifted
the logged address.
However, Raptor Lake-P uses the same cache-line-granularity error address
format as other IBECC platforms. The special handling causes the logged
address to be decoded incorrectly.
Fix the issue by removing Raptor Lake-P specific extraction logic and using
the common path instead. This also allows reusing Alder Lake resource
configuration data.
Fixes: d23627a7688f ("EDAC/igen6: Add Intel Raptor Lake-P SoCs support")
Signed-off-by: Qiuxu Zhuo <qiuxu.zhuo@intel.com>
Signed-off-by: Tony Luck <tony.luck@intel.com>
Link: https://patch.msgid.link/20260730024238.4096623-6-qiuxu.zhuo@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/igen6_edac.c | 39 ++++++---------------------------------
1 file changed, 6 insertions(+), 33 deletions(-)
diff --git a/drivers/edac/igen6_edac.c b/drivers/edac/igen6_edac.c
index ea5628d780eba..12d718a50e1c9 100644
--- a/drivers/edac/igen6_edac.c
+++ b/drivers/edac/igen6_edac.c
@@ -175,8 +175,6 @@ static struct res_config {
/* Set imc->dimm_{l_size,s_size,l_map}[chan]. */
void (*set_dimm_params)(struct igen6_imc *imc, int chan);
bool (*ibecc_available)(struct pci_dev *pdev);
- /* Extract error address logged in IBECC */
- u64 (*err_addr)(u64 ecclog);
/* Convert error address logged in IBECC to system physical address */
u64 (*err_addr_to_sys_addr)(u64 eaddr, int mc);
/* Convert error address logged in IBECC to integrated memory controller address */
@@ -522,11 +520,6 @@ static u64 adl_err_addr_to_imc_addr(u64 eaddr, int mc)
return imc_addr;
}
-static u64 rpl_p_err_addr(u64 ecclog)
-{
- return field_get(res_cfg->reg_eccerrlog_addr_mask, ecclog);
-}
-
static enum mem_type ptl_h_get_mem_type(struct igen6_imc *imc)
{
u32 mtype, val;
@@ -716,22 +709,6 @@ static struct res_config adl_n_cfg = {
.err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
};
-static struct res_config rpl_p_cfg = {
- .machine_check = true,
- .num_imc = 2,
- .reg_mchbar_mask = GENMASK_ULL(41, 17),
- .reg_tom_mask = GENMASK_ULL(41, 20),
- .reg_touud_mask = GENMASK_ULL(41, 20),
- .reg_eccerrlog_addr_mask = GENMASK_ULL(45, 5),
- .imc_base = 0xd800,
- .ibecc_base = 0xd400,
- .ibecc_error_log_offset = 0x68,
- .ibecc_available = tgl_ibecc_available,
- .err_addr = rpl_p_err_addr,
- .err_addr_to_sys_addr = adl_err_addr_to_sys_addr,
- .err_addr_to_imc_addr = adl_err_addr_to_imc_addr,
-};
-
static struct res_config mtl_ps_cfg = {
.machine_check = true,
.num_imc = 2,
@@ -877,11 +854,11 @@ static struct pci_device_id igen6_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, DID_ASL_SKU1), .driver_data = (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ASL_SKU2), .driver_data = (kernel_ulong_t)&adl_n_cfg },
{ PCI_VDEVICE(INTEL, DID_ASL_SKU3), .driver_data = (kernel_ulong_t)&adl_n_cfg },
- { PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), .driver_data = (kernel_ulong_t)&rpl_p_cfg },
- { PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), .driver_data = (kernel_ulong_t)&rpl_p_cfg },
- { PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), .driver_data = (kernel_ulong_t)&rpl_p_cfg },
- { PCI_VDEVICE(INTEL, DID_RPL_P_SKU4), .driver_data = (kernel_ulong_t)&rpl_p_cfg },
- { PCI_VDEVICE(INTEL, DID_RPL_P_SKU5), .driver_data = (kernel_ulong_t)&rpl_p_cfg },
+ { PCI_VDEVICE(INTEL, DID_RPL_P_SKU1), .driver_data = (kernel_ulong_t)&adl_cfg },
+ { PCI_VDEVICE(INTEL, DID_RPL_P_SKU2), .driver_data = (kernel_ulong_t)&adl_cfg },
+ { PCI_VDEVICE(INTEL, DID_RPL_P_SKU3), .driver_data = (kernel_ulong_t)&adl_cfg },
+ { PCI_VDEVICE(INTEL, DID_RPL_P_SKU4), .driver_data = (kernel_ulong_t)&adl_cfg },
+ { PCI_VDEVICE(INTEL, DID_RPL_P_SKU5), .driver_data = (kernel_ulong_t)&adl_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU1), .driver_data = (kernel_ulong_t)&mtl_ps_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU2), .driver_data = (kernel_ulong_t)&mtl_ps_cfg },
{ PCI_VDEVICE(INTEL, DID_MTL_PS_SKU3), .driver_data = (kernel_ulong_t)&mtl_ps_cfg },
@@ -1237,11 +1214,7 @@ static void ecclog_work_cb(struct work_struct *work)
llist_for_each_entry_safe(node, tmp, head, llnode) {
memset(&res, 0, sizeof(res));
- if (res_cfg->err_addr)
- eaddr = res_cfg->err_addr(node->ecclog);
- else
- eaddr = node->ecclog & res_cfg->reg_eccerrlog_addr_mask;
-
+ eaddr = node->ecclog & res_cfg->reg_eccerrlog_addr_mask;
res.mc = node->mc;
res.sys_addr = res_cfg->err_addr_to_sys_addr(eaddr, res.mc);
res.imc_addr = res_cfg->err_addr_to_imc_addr(eaddr, res.mc);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 011/733] EDAC/device_sysfs: Use kstrtouint() for poll_msec to prevent truncation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (9 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 010/733] EDAC/igen6: Fix Raptor Lake-P logged error address Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 012/733] drm/virtio: Fix a NULL vs ERR_PTR() bug in virtio_gpu_user_framebuffer_create() Greg Kroah-Hartman
` (733 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jad Keskes, Borislav Petkov (AMD),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jad Keskes <inasj268@gmail.com>
[ Upstream commit 66cc9dec919dd63d8e4b3d386f7aed3ae684e645 ]
The poll_msec sysfs store file uses simple_strtoul() which accepts an unsigned
long, but the target field (poll_msec) is unsigned int. On 64-bit systems,
a value > UINT_MAX is silently truncated when stored.
Fix the mismatch by using kstrtouint() instead. This rejects values larger
than UINT_MAX at parse time, making truncation impossible. Also add a check
for value < 1 to reject the 0-delay case, which would cause the poll work to
spin without delay and consume 100% CPU.
Fixes: e27e3dac6517 ("drivers/edac: add edac_device class")
Signed-off-by: Jad Keskes <inasj268@gmail.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Link: https://patch.msgid.link/20260730145549.148229-1-inasj268@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/edac/edac_device_sysfs.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/edac/edac_device_sysfs.c b/drivers/edac/edac_device_sysfs.c
index b1c2717cd0237..6995ce039db97 100644
--- a/drivers/edac/edac_device_sysfs.c
+++ b/drivers/edac/edac_device_sysfs.c
@@ -88,14 +88,21 @@ static ssize_t edac_device_ctl_poll_msec_store(struct edac_device_ctl_info
*ctl_info, const char *data,
size_t count)
{
- unsigned long value;
+ unsigned int value;
+ int ret;
/* get the value and enforce that it is non-zero, must be at least
* one millisecond for the delay period, between scans
* Then cancel last outstanding delay for the work request
* and set a new one.
*/
- value = simple_strtoul(data, NULL, 0);
+ ret = kstrtouint(data, 0, &value);
+ if (ret < 0)
+ return ret;
+
+ if (value < 1)
+ return -EINVAL;
+
edac_device_reset_delay_period(ctl_info, value);
return count;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 012/733] drm/virtio: Fix a NULL vs ERR_PTR() bug in virtio_gpu_user_framebuffer_create()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (10 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 011/733] EDAC/device_sysfs: Use kstrtouint() for poll_msec to prevent truncation Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 013/733] drm/virtio: use the DMA API for resource backing on Xen Greg Kroah-Hartman
` (732 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dan Carpenter, Dmitry Osipenko,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <error27@gmail.com>
[ Upstream commit 94579f24e2b526a04eb41050af0ba018c6f528e7 ]
Smatch complains that returning a NULL here will lead to a NULL pointer
dereference in drm_mode_addfb2(). Return an error pointer instead.
Fixes: dc5698e80cf7 ("Add virtio gpu driver.")
Signed-off-by: Dan Carpenter <error27@gmail.com>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/an1tWfHIHwtXd9SO@stanley.mountain
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/virtio/virtgpu_display.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_display.c b/drivers/gpu/drm/virtio/virtgpu_display.c
index 44ffffec550fd..85ea252c658e3 100644
--- a/drivers/gpu/drm/virtio/virtgpu_display.c
+++ b/drivers/gpu/drm/virtio/virtgpu_display.c
@@ -344,7 +344,7 @@ virtio_gpu_user_framebuffer_create(struct drm_device *dev,
if (ret) {
kfree(virtio_gpu_fb);
drm_gem_object_put(obj);
- return NULL;
+ return ERR_PTR(ret);
}
return &virtio_gpu_fb->base;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 013/733] drm/virtio: use the DMA API for resource backing on Xen
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (11 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 012/733] drm/virtio: Fix a NULL vs ERR_PTR() bug in virtio_gpu_user_framebuffer_create() Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 014/733] accel/qaic: Address potential out-of-bounds read in resp_worker() Greg Kroah-Hartman
` (731 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ben Leggett, Dmitry Osipenko,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Benjamin Leggett <benjamin@edera.io>
[ Upstream commit 6a736d2f9d0c6e6217fe7532bc4c50ceca71db78 ]
On a Xen PV domain page addresses bear no relation to the real machine
addresses the host would have to use to reach it.
virtio_ring.c handles this correctly, vring_use_map_api() returns true
for any xen_domain() regardless of VIRTIO_F_ACCESS_PLATFORM.
virtio-gpu makes the same decision independently, but its copy
looks only at the feature bit:
bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
QEMU does not set iommu_platform on virtio-vga by default, so
VIRTIO_F_ACCESS_PLATFORM is not negotiated, use_dma_api is false, and
virtio_gpu_object_shmem_init() describes the framebuffer's backing pages
to the host with sg_phys(). Those are guest-physical addresses. In a PV
domain they resolve, on the host side, to pages belonging to some other
domain, so the host scans out unrelated memory.
Move the decision into virtio_gpu_use_dma_api() and give it the
xen_domain() check, like vring_use_map_api() has. This
additionally enables the dma_sync_sgtable_for_device() calls in
virtgpu_vq.c, which are required for correctness whenever swiotlb
is in play.
Reproduced with a Xen 4.21 PV dom0 nested inside QEMU 8.2 with
virtio-vga, on both a distro 6.8 kernel and 6.18 LTS. A PVH dom0
works fine and doesn't need this fix because it is identity-mapped,
only PV dom0s are affected.
Fixes: a3b815f09bb8 ("drm/virtio: add iommu support.")
Signed-off-by: Ben Leggett <benjamin@edera.io>
Signed-off-by: Dmitry Osipenko <dmitry.osipenko@collabora.com>
Link: https://patch.msgid.link/20260806-virtgpu-xen-dma-v1-1-e499b345bbad@edera.io
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/virtio/virtgpu_drv.h | 20 ++++++++++++++++++++
drivers/gpu/drm/virtio/virtgpu_object.c | 2 +-
drivers/gpu/drm/virtio/virtgpu_vq.c | 6 +++---
3 files changed, 24 insertions(+), 4 deletions(-)
diff --git a/drivers/gpu/drm/virtio/virtgpu_drv.h b/drivers/gpu/drm/virtio/virtgpu_drv.h
index 7449907754a43..88fb4be92cf3e 100644
--- a/drivers/gpu/drm/virtio/virtgpu_drv.h
+++ b/drivers/gpu/drm/virtio/virtgpu_drv.h
@@ -43,6 +43,8 @@
#include <drm/drm_probe_helper.h>
#include <drm/virtgpu_drm.h>
+#include <xen/xen.h>
+
#define DRIVER_NAME "virtio_gpu"
#define DRIVER_DESC "virtio GPU"
@@ -60,6 +62,24 @@
/* See virtio_gpu_ctx_create. One additional character for NULL terminator. */
#define DEBUG_NAME_MAX_LEN 65
+/*
+ * Whether the host must be told about resource backing pages by DMA address
+ * rather than guest-physical address.
+ *
+ * This mirrors vring_use_map_api() in drivers/virtio/virtio_ring.c, including
+ * its xen_domain() case.
+ */
+static inline bool virtio_gpu_use_dma_api(const struct virtio_device *vdev)
+{
+ if (!virtio_has_dma_quirk(vdev))
+ return true;
+
+ if (xen_domain())
+ return true;
+
+ return false;
+}
+
struct virtio_gpu_object_params {
unsigned long size;
bool dumb;
diff --git a/drivers/gpu/drm/virtio/virtgpu_object.c b/drivers/gpu/drm/virtio/virtgpu_object.c
index ec9efacc69195..1527c62be88ba 100644
--- a/drivers/gpu/drm/virtio/virtgpu_object.c
+++ b/drivers/gpu/drm/virtio/virtgpu_object.c
@@ -163,7 +163,7 @@ static int virtio_gpu_object_shmem_init(struct virtio_gpu_device *vgdev,
struct virtio_gpu_mem_entry **ents,
unsigned int *nents)
{
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
struct scatterlist *sg;
struct sg_table *pages;
int si;
diff --git a/drivers/gpu/drm/virtio/virtgpu_vq.c b/drivers/gpu/drm/virtio/virtgpu_vq.c
index e5e1af8b8e8a0..2b7af8e4e9e61 100644
--- a/drivers/gpu/drm/virtio/virtgpu_vq.c
+++ b/drivers/gpu/drm/virtio/virtgpu_vq.c
@@ -724,7 +724,7 @@ int virtio_gpu_panic_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
struct virtio_gpu_transfer_to_host_2d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
@@ -755,7 +755,7 @@ void virtio_gpu_cmd_transfer_to_host_2d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
struct virtio_gpu_transfer_to_host_2d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
@@ -1188,7 +1188,7 @@ void virtio_gpu_cmd_transfer_to_host_3d(struct virtio_gpu_device *vgdev,
struct virtio_gpu_object *bo = gem_to_virtio_gpu_obj(objs->objs[0]);
struct virtio_gpu_transfer_host_3d *cmd_p;
struct virtio_gpu_vbuffer *vbuf;
- bool use_dma_api = !virtio_has_dma_quirk(vgdev->vdev);
+ bool use_dma_api = virtio_gpu_use_dma_api(vgdev->vdev);
if (virtio_gpu_is_shmem(bo) && use_dma_api)
dma_sync_sgtable_for_device(vgdev->vdev->dev.parent,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 014/733] accel/qaic: Address potential out-of-bounds read in resp_worker()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (12 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 013/733] drm/virtio: use the DMA API for resource backing on Xen Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 015/733] nvme-rdma: fix -EIO cleanup order in queue_rq Greg Kroah-Hartman
` (730 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ruikai Peng, Jeff Hugo, Lizhi Hou,
Youssef Samir, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
[ Upstream commit ab243f74ab4084ca5c8dec608cb5b0deb27db067 ]
Although 'commit 2feec5ae5df7 ("accel/qaic: Handle DBC deactivation if the
owner went away")' fixes the scenario it was intended for by walking the
message and only decoding QAIC_TRANS_DEACTIVATE_FROM_DEV, if present, it
skipped over the bounds checking code that is included in decode_message().
This could lead to issues such as reading past the slab allocation's end,
infinite loops or kernel panics. For those issues to happen, a malformed
wire message is needed to be sent from the device.
Instead of duplicating the bounds checking code already present in
decode_message(), use the function inside resp_worker().
Reported-by: Ruikai Peng <ruikai@pwno.io>
Fixes: 2feec5ae5df7 ("accel/qaic: Handle DBC deactivation if the owner went away")
Reviewed-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Reviewed-by: Lizhi Hou <lizhi.hou@amd.com>
Signed-off-by: Youssef Samir <youssef.abdulrahman@oss.qualcomm.com>
Signed-off-by: Jeff Hugo <jeff.hugo@oss.qualcomm.com>
Link: https://patch.msgid.link/20260731152344.1905882-1-youssef.abdulrahman@oss.qualcomm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/qaic/qaic_control.c | 46 ++++++++++++++++---------------
1 file changed, 24 insertions(+), 22 deletions(-)
diff --git a/drivers/accel/qaic/qaic_control.c b/drivers/accel/qaic/qaic_control.c
index 50bf3340e49ce..2ccc55486aac0 100644
--- a/drivers/accel/qaic/qaic_control.c
+++ b/drivers/accel/qaic/qaic_control.c
@@ -963,11 +963,13 @@ static int decode_status(struct qaic_device *qdev, void *trans, struct manage_ms
static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
struct wire_msg *msg, struct ioctl_resources *resources,
- struct qaic_user *usr)
+ struct qaic_user *usr, bool orphaned_deactivate)
{
+ u32 msg_hdr_count = le32_to_cpu(msg->hdr.count);
u32 msg_hdr_len = le32_to_cpu(msg->hdr.len);
struct wire_trans_hdr *trans_hdr;
u32 msg_len = 0;
+ int trans_type;
int ret;
int i;
@@ -975,10 +977,12 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
msg_hdr_len > QAIC_MANAGE_MAX_MSG_LENGTH)
return -EINVAL;
- user_msg->len = 0;
- user_msg->count = le32_to_cpu(msg->hdr.count);
+ if (user_msg) {
+ user_msg->len = 0;
+ user_msg->count = msg_hdr_count;
+ }
- for (i = 0; i < user_msg->count; ++i) {
+ for (i = 0; i < msg_hdr_count; ++i) {
u32 hdr_len;
if (msg_len > msg_hdr_len - sizeof(*trans_hdr))
@@ -990,7 +994,20 @@ static int decode_message(struct qaic_device *qdev, struct manage_msg *user_msg,
size_add(msg_len, hdr_len) > msg_hdr_len)
return -EINVAL;
- switch (le32_to_cpu(trans_hdr->type)) {
+ trans_type = le32_to_cpu(trans_hdr->type);
+ /*
+ * orphaned_deactivate is the case where a deactivate response
+ * is received from the device after the user owning the DBC,
+ * and the message requesting deactivation, has gone away.
+ * In this case, only process QAIC_TRANS_DEACTIVATE_FROM_DEV
+ * transaction and skip the others.
+ */
+ if (orphaned_deactivate && trans_type != QAIC_TRANS_DEACTIVATE_FROM_DEV) {
+ msg_len += hdr_len;
+ continue;
+ }
+
+ switch (trans_type) {
case QAIC_TRANS_PASSTHROUGH_FROM_DEV:
ret = decode_passthrough(qdev, trans_hdr, user_msg, &msg_len);
break;
@@ -1281,7 +1298,7 @@ static int qaic_manage(struct qaic_device *qdev, struct qaic_user *usr, struct m
goto dma_cont_failed;
}
- ret = decode_message(qdev, user_msg, rsp, &resources, usr);
+ ret = decode_message(qdev, user_msg, rsp, &resources, usr, false);
dma_cont_failed:
free_dbc_buf(qdev, &resources);
@@ -1446,22 +1463,7 @@ static void resp_worker(struct work_struct *work)
* response to the QAIC_TRANS_TERMINATE_TO_DEV transaction,
* otherwise, the user can issue an soc_reset to the device.
*/
- u32 msg_count = le32_to_cpu(msg->hdr.count);
- u32 msg_len = le32_to_cpu(msg->hdr.len);
- u32 len = 0;
- int j;
-
- for (j = 0; j < msg_count && len < msg_len; ++j) {
- struct wire_trans_hdr *trans_hdr;
-
- trans_hdr = (struct wire_trans_hdr *)(msg->data + len);
- if (le32_to_cpu(trans_hdr->type) == QAIC_TRANS_DEACTIVATE_FROM_DEV) {
- if (decode_deactivate(qdev, trans_hdr, &len, NULL))
- len += le32_to_cpu(trans_hdr->len);
- } else {
- len += le32_to_cpu(trans_hdr->len);
- }
- }
+ decode_message(qdev, NULL, msg, NULL, NULL, true);
/* request must have timed out, drop packet */
kfree(msg);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 015/733] nvme-rdma: fix -EIO cleanup order in queue_rq
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (13 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 014/733] accel/qaic: Address potential out-of-bounds read in resp_worker() Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 016/733] nvme: add context annotations for nvme_subsystem::lock Greg Kroah-Hartman
` (729 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Xixin Liu,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
[ Upstream commit d61828199c6cb4b76d48403c77023cd4bb9d09fc ]
On -EIO, the RDMA queue_rq path reports a host path error and then
still cleans up the command and unmaps the SQE DMA. The path error
helper completes the request, so that is double cleanup and DMA unmap
after the request is already complete.
Unmap the SQE first, then report the host path error. Skip the outer
command cleanup on that path.
Fixes: 62eca39722fd ("nvme-rdma: handle nvme_rdma_post_send failures better")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/rdma.c | 18 ++++++++++--------
1 file changed, 10 insertions(+), 8 deletions(-)
diff --git a/drivers/nvme/host/rdma.c b/drivers/nvme/host/rdma.c
index 6909e35427942..618ee95444263 100644
--- a/drivers/nvme/host/rdma.c
+++ b/drivers/nvme/host/rdma.c
@@ -2003,7 +2003,7 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
struct ib_device *dev;
bool queue_ready = test_bit(NVME_RDMA_Q_LIVE, &queue->flags);
blk_status_t ret;
- int err;
+ int err = 0;
WARN_ON_ONCE(rq->tag < 0);
@@ -2059,16 +2059,18 @@ static blk_status_t nvme_rdma_queue_rq(struct blk_mq_hw_ctx *hctx,
err_unmap:
nvme_rdma_unmap_data(queue, rq);
err:
- if (err == -EIO)
- ret = nvme_host_path_error(rq);
- else if (err == -ENOMEM || err == -EAGAIN)
- ret = BLK_STS_RESOURCE;
- else
- ret = BLK_STS_IOERR;
- nvme_cleanup_cmd(rq);
+ if (err != -EIO) {
+ nvme_cleanup_cmd(rq);
+ if (err == -ENOMEM || err == -EAGAIN)
+ ret = BLK_STS_RESOURCE;
+ else
+ ret = BLK_STS_IOERR;
+ }
unmap_qe:
ib_dma_unmap_single(dev, req->sqe.dma, sizeof(struct nvme_command),
DMA_TO_DEVICE);
+ if (err == -EIO)
+ return nvme_host_path_error(rq);
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 016/733] nvme: add context annotations for nvme_subsystem::lock
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (14 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 015/733] nvme-rdma: fix -EIO cleanup order in queue_rq Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 017/733] nvme: set ns->head in nvme_alloc_ns_head Greg Kroah-Hartman
` (728 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Nilay Shroff,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <nilay@linux.ibm.com>
[ Upstream commit d1fdf49b5f7fce5f65ae0d11d484bd7e31cedbb1 ]
Several helpers access or traverse data structures protected by
nvme_subsystem::lock and therefore require callers to hold the lock.
Annotate nvme_mpath_unfreeze(), nvme_mpath_wait_freeze(),
nvme_mpath_start_freeze(), nvme_find_ns_head(), nvme_alloc_ns_head()
and nvme_subsys_check_duplicate_ids() with __must_hold(&subsys->lock)
so that Clang's lock context analysis can validate the locking
requirements at compile time.
Also annotate nvme_subsystem::nsheads and
nvme_ns_head::delayed_removal_secs with __guarded_by(&subsys->lock),
as both are protected by the subsystem lock.
Annotate nvme_init_subsystem() with __context_unsafe(), as it
initializes these lock-protected members before the object is published,
suppressing a false positive from Clang's context analysis.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Nilay Shroff <nilay@linux.ibm.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Stable-dep-of: 56e1c6bbe4bb ("nvme: fix racy access to FDP placement id array")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 4 ++++
drivers/nvme/host/nvme.h | 15 ++++++++++-----
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 0b80db7a0599f..0224b99317cdd 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3292,6 +3292,7 @@ static bool nvme_validate_cntlid(struct nvme_subsystem *subsys,
}
static int nvme_init_subsystem(struct nvme_ctrl *ctrl, struct nvme_id_ctrl *id)
+ __context_unsafe(/* initialize unpublished/lock-guarded variables */)
{
struct nvme_subsystem *subsys, *found;
int ret;
@@ -3863,6 +3864,7 @@ static const struct file_operations nvme_dev_fops = {
static struct nvme_ns_head *nvme_find_ns_head(struct nvme_ctrl *ctrl,
unsigned nsid)
+ __must_hold(&ctrl->subsys->lock)
{
struct nvme_ns_head *h;
@@ -3885,6 +3887,7 @@ static struct nvme_ns_head *nvme_find_ns_head(struct nvme_ctrl *ctrl,
static int nvme_subsys_check_duplicate_ids(struct nvme_subsystem *subsys,
struct nvme_ns_ids *ids)
+ __must_hold(&subsys->lock)
{
bool has_uuid = !uuid_is_null(&ids->uuid);
bool has_nguid = memchr_inv(ids->nguid, 0, sizeof(ids->nguid));
@@ -3986,6 +3989,7 @@ static void nvme_add_ns_cdev(struct nvme_ns *ns)
static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
struct nvme_ns_info *info)
+ __must_hold(&ctrl->subsys->lock)
{
struct nvme_ns_head *head;
size_t size = sizeof(*head);
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 957ded0c6f53b..5e2e45ef7dadf 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -503,7 +503,8 @@ struct nvme_subsystem {
struct list_head entry;
struct mutex lock;
struct list_head ctrls;
- struct list_head nsheads;
+ struct list_head nsheads
+ __guarded_by(&lock);
char subnqn[NVMF_NQN_SIZE];
char serial[20];
char model[40];
@@ -575,7 +576,8 @@ struct nvme_ns_head {
struct mutex lock;
unsigned long flags;
struct delayed_work remove_work;
- unsigned int delayed_removal_secs;
+ unsigned int delayed_removal_secs
+ __guarded_by(&subsys->lock);
atomic_long_t io_requeue_no_usable_path_count;
atomic_long_t io_fail_no_available_path_count;
#define NVME_NSHEAD_DISK_LIVE 0
@@ -1046,9 +1048,12 @@ static inline bool nvme_ctrl_use_ana(struct nvme_ctrl *ctrl)
return ctrl->ana_log_buf != NULL;
}
-void nvme_mpath_unfreeze(struct nvme_subsystem *subsys);
-void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys);
-void nvme_mpath_start_freeze(struct nvme_subsystem *subsys);
+void nvme_mpath_unfreeze(struct nvme_subsystem *subsys)
+ __must_hold(&subsys->lock);
+void nvme_mpath_wait_freeze(struct nvme_subsystem *subsys)
+ __must_hold(&subsys->lock);
+void nvme_mpath_start_freeze(struct nvme_subsystem *subsys)
+ __must_hold(&subsys->lock);
void nvme_mpath_default_iopolicy(struct nvme_subsystem *subsys);
void nvme_failover_req(struct request *req);
void nvme_kick_requeue_lists(struct nvme_ctrl *ctrl);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 017/733] nvme: set ns->head in nvme_alloc_ns_head
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (15 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 016/733] nvme: add context annotations for nvme_subsystem::lock Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 018/733] nvme: fix racy access to FDP placement id array Greg Kroah-Hartman
` (727 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Kanchan Joshi,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kanchan Joshi <joshi.k@samsung.com>
[ Upstream commit c1888444dc28310222dcc6e5c301d60d0943787f ]
so that it becomes possible to submit non-admin commands.
This is a prep patch with no functional changes.
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Stable-dep-of: 56e1c6bbe4bb ("nvme: fix racy access to FDP placement id array")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 0224b99317cdd..e5051a6b33578 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -3987,10 +3987,11 @@ static void nvme_add_ns_cdev(struct nvme_ns *ns)
set_bit(NVME_NS_CDEV_LIVE, &ns->flags);
}
-static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
+static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ns *ns,
struct nvme_ns_info *info)
- __must_hold(&ctrl->subsys->lock)
+ __must_hold(&ns->ctrl->subsys->lock)
{
+ struct nvme_ctrl *ctrl = ns->ctrl;
struct nvme_ns_head *head;
size_t size = sizeof(*head);
int ret = -ENOMEM;
@@ -4018,6 +4019,7 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
ratelimit_state_init(&head->rs_nuse, 5 * HZ, 1);
ratelimit_set_flags(&head->rs_nuse, RATELIMIT_MSG_ON_RELEASE);
kref_init(&head->ref);
+ ns->head = head;
if (head->ids.csi) {
ret = nvme_get_effects_log(ctrl, head->ids.csi, &head->effects);
@@ -4041,6 +4043,7 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ctrl *ctrl,
ida_free(&ctrl->subsys->ns_ida, head->instance);
out_free_head:
kfree(head);
+ ns->head = NULL;
out:
if (ret > 0)
ret = blk_status_to_errno(nvme_error_status(ret));
@@ -4127,7 +4130,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
info->nsid);
goto out_unlock;
}
- head = nvme_alloc_ns_head(ctrl, info);
+ head = nvme_alloc_ns_head(ns, info);
if (IS_ERR(head)) {
ret = PTR_ERR(head);
goto out_unlock;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 018/733] nvme: fix racy access to FDP placement id array
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (16 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 017/733] nvme: set ns->head in nvme_alloc_ns_head Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 019/733] nvmet-rdma: fix queue leak when connect backlog is exceeded Greg Kroah-Hartman
` (726 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hari Mishal, Christoph Hellwig,
Kanchan Joshi, Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kanchan Joshi <joshi.k@samsung.com>
[ Upstream commit 56e1c6bbe4bb084d7ecf61698afdf70be23dd35f ]
nvme_query_fdp_info() is called per-path and therefore prone to races.
It populates head->nr_plids/head->plids for fdp registration.
But nothing protects that pair from concurrent access - two paths scanning
the same namespace can race to populate it.
Avoid the race by moving this initialization work to nvme_alloc_ns_head()
which is called once per shared namespace.
Fixes: 30b5f20bb2dd ("nvme: register fdp parameters with the block layer")
Reported-by: Hari Mishal <harimishal1@gmail.com>
Link: https://lore.kernel.org/linux-nvme/20260725135111.14041-2-harimishal1@gmail.com/
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Kanchan Joshi <joshi.k@samsung.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 30 +++++++++++-------------------
drivers/nvme/host/nvme.h | 1 +
2 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index e5051a6b33578..706df45b26e77 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -2323,14 +2323,6 @@ static int nvme_query_fdp_info(struct nvme_ns *ns, struct nvme_ns_info *info)
size_t size;
int i, ret;
- /*
- * The FDP configuration is static for the lifetime of the namespace,
- * so return immediately if we've already registered this namespace's
- * streams.
- */
- if (head->nr_plids)
- return 0;
-
ret = nvme_get_features(ctrl, NVME_FEAT_FDP, info->endgid, NULL, 0,
&fdp);
if (ret) {
@@ -2377,6 +2369,7 @@ static int nvme_query_fdp_info(struct nvme_ns *ns, struct nvme_ns_info *info)
for (i = 0; i < head->nr_plids; i++)
head->plids[i] = le16_to_cpu(ruhs->ruhsd[i].pid);
+ head->write_stream_granularity = min(info->runs, U32_MAX);
free:
kfree(ruhs);
return ret;
@@ -2424,12 +2417,6 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
goto out;
}
- if (ns->ctrl->ctratt & NVME_CTRL_ATTR_FDPS) {
- ret = nvme_query_fdp_info(ns, info);
- if (ret < 0)
- goto out;
- }
-
if (nvme_invalid_lba_sz(le64_to_cpu(id->nsze),
id->lbaf[lbaf].ds - SECTOR_SHIFT, &capacity)) {
dev_warn_once(ns->ctrl->device,
@@ -2489,10 +2476,7 @@ static int nvme_update_ns_info_block(struct nvme_ns *ns,
capacity = 0;
lim.max_write_streams = ns->head->nr_plids;
- if (lim.max_write_streams)
- lim.write_stream_granularity = min(info->runs, U32_MAX);
- else
- lim.write_stream_granularity = 0;
+ lim.write_stream_granularity = ns->head->write_stream_granularity;
/*
* Only set the DEAC bit if the device guarantees that reads from
@@ -4028,15 +4012,23 @@ static struct nvme_ns_head *nvme_alloc_ns_head(struct nvme_ns *ns,
} else
head->effects = ctrl->effects;
+ if (ctrl->ctratt & NVME_CTRL_ATTR_FDPS) {
+ ret = nvme_query_fdp_info(ns, info);
+ if (ret < 0)
+ goto out_cleanup_srcu;
+ }
+
ret = nvme_mpath_alloc_disk(ctrl, head);
if (ret)
- goto out_cleanup_srcu;
+ goto out_cleanup_fdp;
list_add_tail(&head->entry, &ctrl->subsys->nsheads);
kref_get(&ctrl->subsys->ref);
return head;
+out_cleanup_fdp:
+ kfree(head->plids);
out_cleanup_srcu:
cleanup_srcu_struct(&head->srcu);
out_ida_remove:
diff --git a/drivers/nvme/host/nvme.h b/drivers/nvme/host/nvme.h
index 5e2e45ef7dadf..cfdcf53db5abd 100644
--- a/drivers/nvme/host/nvme.h
+++ b/drivers/nvme/host/nvme.h
@@ -568,6 +568,7 @@ struct nvme_ns_head {
u16 nr_plids;
u16 *plids;
+ u32 write_stream_granularity;
#ifdef CONFIG_NVME_MULTIPATH
struct bio_list requeue_list;
spinlock_t requeue_lock;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 019/733] nvmet-rdma: fix queue leak when connect backlog is exceeded
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (17 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 018/733] nvme: fix racy access to FDP placement id array Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 020/733] sched_ext: Fix nonexistent field in sched-ext.rst example Greg Kroah-Hartman
` (725 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Hellwig, Xixin Liu,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
[ Upstream commit fb1ed67788e21832b614c23767a088c08cfdd2f2 ]
When pending disconnecting queues exceed the backlog limit, the
connect path only drops the device reference and leaks the newly
allocated queue and its IB resources.
Fixes: badc53620fe8 ("nvme: target: rdma: fix ndev refcount leak on queue connect")
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/rdma.c | 15 +++++++--------
1 file changed, 7 insertions(+), 8 deletions(-)
diff --git a/drivers/nvme/target/rdma.c b/drivers/nvme/target/rdma.c
index de5a88fbb2337..542138fd669f4 100644
--- a/drivers/nvme/target/rdma.c
+++ b/drivers/nvme/target/rdma.c
@@ -1627,19 +1627,13 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
mutex_unlock(&nvmet_rdma_queue_mutex);
if (pending > NVMET_RDMA_BACKLOG) {
ret = NVME_SC_CONNECT_CTRL_BUSY;
- goto put_device;
+ goto free_queue;
}
}
ret = nvmet_rdma_cm_accept(cm_id, queue, &event->param.conn);
- if (ret) {
- /*
- * Don't destroy the cm_id in free path, as we implicitly
- * destroy the cm_id here with non-zero ret code.
- */
- queue->cm_id = NULL;
+ if (ret)
goto free_queue;
- }
mutex_lock(&nvmet_rdma_queue_mutex);
list_add_tail(&queue->queue_list, &nvmet_rdma_queue_list);
@@ -1648,6 +1642,11 @@ static int nvmet_rdma_queue_connect(struct rdma_cm_id *cm_id,
return 0;
free_queue:
+ /*
+ * Don't destroy the cm_id in free path, as we implicitly
+ * destroy the cm_id here with non-zero ret code.
+ */
+ queue->cm_id = NULL;
nvmet_rdma_free_queue(queue);
put_device:
kref_put(&ndev->ref, nvmet_rdma_free_dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 020/733] sched_ext: Fix nonexistent field in sched-ext.rst example
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (18 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 019/733] nvmet-rdma: fix queue leak when connect backlog is exceeded Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 021/733] selftests/cgroup: set the test plan after the setup checks Greg Kroah-Hartman
` (724 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Liang Luo, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liang Luo <luoliang@kylinos.cn>
[ Upstream commit 4fb8d6379d2c7ceecb2b3e111954d29089d59492 ]
The ops.exit() example in sched-ext.rst reads ei->type, but
struct scx_exit_info has never had a type field - the exit reason is
exposed as ei->kind since the struct was introduced. A scheduler
written following the example fails to compile with
error: no member named 'type' in 'struct scx_exit_info'
Use ei->kind.
Fixes: fa48e8d2c7b5 ("sched_ext: Documentation: scheduler: Document extensible scheduler class")
Signed-off-by: Liang Luo <luoliang@kylinos.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/scheduler/sched-ext.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/scheduler/sched-ext.rst b/Documentation/scheduler/sched-ext.rst
index 2771ea4cc14af..96ff66c91ceb2 100644
--- a/Documentation/scheduler/sched-ext.rst
+++ b/Documentation/scheduler/sched-ext.rst
@@ -229,7 +229,7 @@ optional. The following modified excerpt is from
void BPF_STRUCT_OPS(simple_exit, struct scx_exit_info *ei)
{
- exit_type = ei->type;
+ exit_type = ei->kind;
}
SEC(".struct_ops")
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 021/733] selftests/cgroup: set the test plan after the setup checks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (19 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 020/733] sched_ext: Fix nonexistent field in sched-ext.rst example Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 022/733] selftests/cgroup: Fix cg_run_in_subcgroups ignoring arg parameter Greg Kroah-Hartman
` (723 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hemanth Selam, Sarthak Sharma,
Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hemanth Selam <hemanth.selam@gmail.com>
[ Upstream commit 0c893d170ff8efe7b4067552932d26e7defba307 ]
The cgroup tests announce their plan before checking whether cgroup v2 is
available, so on a host without it they promise a number of results and
then skip out after the first one:
TAP version 13
1..3
ok 1 # SKIP cgroup v2 isn't mounted
# Planned tests != run tests (3 != 1)
# Totals: pass:0 fail:0 xfail:0 xpass:0 skip:1 error:0
ksft_exit_skip() can only emit a well formed "1..0 # SKIP" line while no
plan has been printed, as the comment above it in kselftest.h points out.
Move ksft_set_plan() below the setup checks that can skip, so that a
skipped run reports:
TAP version 13
1..0 # SKIP cgroup v2 isn't mounted
Several of the tests skip more than once while setting up, for a missing
or unwritable controller as well, so the plan goes after the last of
them. test_core joins its two setup paths at the post_v2_setup label and
sets the plan there.
Reporting each planned test as skipped instead would keep the plan where
it is, but the setup failures here mean the whole test cannot run rather
than its individual cases being skipped, which is what "1..0 # SKIP" is
for.
Fixes: 1dc830ee4c15 ("selftests/cgroup: conform test to KTAP format output")
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Reviewed-by: Sarthak Sharma <sarthak.sharma@arm.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/cgroup/test_core.c | 2 +-
tools/testing/selftests/cgroup/test_cpu.c | 2 +-
tools/testing/selftests/cgroup/test_cpuset.c | 2 +-
tools/testing/selftests/cgroup/test_freezer.c | 2 +-
tools/testing/selftests/cgroup/test_kill.c | 2 +-
tools/testing/selftests/cgroup/test_kmem.c | 2 +-
tools/testing/selftests/cgroup/test_memcontrol.c | 2 +-
tools/testing/selftests/cgroup/test_pids.c | 2 +-
tools/testing/selftests/cgroup/test_zswap.c | 2 +-
9 files changed, 9 insertions(+), 9 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_core.c b/tools/testing/selftests/cgroup/test_core.c
index 88ca832d4fc13..64f4962a4659d 100644
--- a/tools/testing/selftests/cgroup/test_core.c
+++ b/tools/testing/selftests/cgroup/test_core.c
@@ -927,7 +927,6 @@ int main(int argc, char *argv[])
int i;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), &nsdelegate)) {
if (setup_named_v1_root(root, sizeof(root), CG_NAMED_NAME))
ksft_exit_skip("cgroup v2 isn't mounted and could not setup named v1 hierarchy\n");
@@ -940,6 +939,7 @@ int main(int argc, char *argv[])
ksft_exit_skip("Failed to set memory controller\n");
post_v2_setup:
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_cpu.c b/tools/testing/selftests/cgroup/test_cpu.c
index 7a40d76b95487..8f96bfd19ab9f 100644
--- a/tools/testing/selftests/cgroup/test_cpu.c
+++ b/tools/testing/selftests/cgroup/test_cpu.c
@@ -799,7 +799,6 @@ int main(int argc, char *argv[])
int i;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
@@ -807,6 +806,7 @@ int main(int argc, char *argv[])
if (cg_write(root, "cgroup.subtree_control", "+cpu"))
ksft_exit_skip("Failed to set cpu controller\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_cpuset.c b/tools/testing/selftests/cgroup/test_cpuset.c
index c5cf8b56ceb8f..52ed8fba685ae 100644
--- a/tools/testing/selftests/cgroup/test_cpuset.c
+++ b/tools/testing/selftests/cgroup/test_cpuset.c
@@ -250,7 +250,6 @@ int main(int argc, char *argv[])
int i;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
@@ -258,6 +257,7 @@ int main(int argc, char *argv[])
if (cg_write(root, "cgroup.subtree_control", "+cpuset"))
ksft_exit_skip("Failed to set cpuset controller\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_freezer.c b/tools/testing/selftests/cgroup/test_freezer.c
index 0569e93fa6b00..f28bb02e9783b 100644
--- a/tools/testing/selftests/cgroup/test_freezer.c
+++ b/tools/testing/selftests/cgroup/test_freezer.c
@@ -1491,9 +1491,9 @@ int main(int argc, char *argv[])
int i;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_kill.c b/tools/testing/selftests/cgroup/test_kill.c
index f6cd23a8ecc71..99cafd9dc0136 100644
--- a/tools/testing/selftests/cgroup/test_kill.c
+++ b/tools/testing/selftests/cgroup/test_kill.c
@@ -278,9 +278,9 @@ int main(int argc, char *argv[])
int i;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_kmem.c b/tools/testing/selftests/cgroup/test_kmem.c
index 1db0ba1226b9b..cb47561b4b443 100644
--- a/tools/testing/selftests/cgroup/test_kmem.c
+++ b/tools/testing/selftests/cgroup/test_kmem.c
@@ -426,7 +426,6 @@ int main(int argc, char **argv)
int i;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
@@ -441,6 +440,7 @@ int main(int argc, char **argv)
if (cg_write(root, "cgroup.subtree_control", "+memory"))
ksft_exit_skip("Failed to set memory controller\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_memcontrol.c b/tools/testing/selftests/cgroup/test_memcontrol.c
index 0ebf796f3cffe..3a84d068fbf36 100644
--- a/tools/testing/selftests/cgroup/test_memcontrol.c
+++ b/tools/testing/selftests/cgroup/test_memcontrol.c
@@ -1798,7 +1798,6 @@ int main(int argc, char **argv)
page_size = BUF_SIZE;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
@@ -1823,6 +1822,7 @@ int main(int argc, char **argv)
ksft_exit_skip("Failed to query cgroup mount option\n");
has_localevents = proc_status;
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_pids.c b/tools/testing/selftests/cgroup/test_pids.c
index 9a387c815d2cd..710109b53dfe9 100644
--- a/tools/testing/selftests/cgroup/test_pids.c
+++ b/tools/testing/selftests/cgroup/test_pids.c
@@ -148,7 +148,6 @@ int main(int argc, char **argv)
char root[PATH_MAX];
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
@@ -163,6 +162,7 @@ int main(int argc, char **argv)
if (cg_write(root, "cgroup.subtree_control", "+pids"))
ksft_exit_skip("Failed to set pids controller\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (int i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
diff --git a/tools/testing/selftests/cgroup/test_zswap.c b/tools/testing/selftests/cgroup/test_zswap.c
index 49b36ee791606..6e7b89315bbf3 100644
--- a/tools/testing/selftests/cgroup/test_zswap.c
+++ b/tools/testing/selftests/cgroup/test_zswap.c
@@ -810,7 +810,6 @@ int main(int argc, char **argv)
page_size = BUF_SIZE;
ksft_print_header();
- ksft_set_plan(ARRAY_SIZE(tests));
if (cg_find_unified_root(root, sizeof(root), NULL))
ksft_exit_skip("cgroup v2 isn't mounted\n");
@@ -827,6 +826,7 @@ int main(int argc, char **argv)
if (cg_write(root, "cgroup.subtree_control", "+memory"))
ksft_exit_skip("Failed to set memory controller\n");
+ ksft_set_plan(ARRAY_SIZE(tests));
for (i = 0; i < ARRAY_SIZE(tests); i++) {
switch (tests[i].fn(root)) {
case KSFT_PASS:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 022/733] selftests/cgroup: Fix cg_run_in_subcgroups ignoring arg parameter
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (20 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 021/733] selftests/cgroup: set the test plan after the setup checks Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 023/733] bpf: Fix REG INVARIANTS VIOLATION on speculative pointer arithmetic Greg Kroah-Hartman
` (722 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hongfu Li, Michal Koutný,
Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hongfu Li <lihongfu@kylinos.cn>
[ Upstream commit a8c6daab4b0e276508b7ffdd66c60fd3020a9178 ]
cg_run_in_subcgroups() discards its arg and always passes NULL to cg_run(),
turning the (void *)100 from test_kmem_dead_cgroups() into NULL so no
allocation occurs.
This makes test_kmem_dead_cgroups() falsely pass without exercising the
"dying cgroup with charged slab" scenario it intends to test.
Pass the arg through to cg_run() to fix this.
Fixes: 933dc80ec262 ("kselftests: cgroup: add kernel memory accounting tests")
Signed-off-by: Hongfu Li <lihongfu@kylinos.cn>
Reviewed-by: Michal Koutný <mkoutny@suse.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/cgroup/test_kmem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/testing/selftests/cgroup/test_kmem.c b/tools/testing/selftests/cgroup/test_kmem.c
index cb47561b4b443..437f2d35f205e 100644
--- a/tools/testing/selftests/cgroup/test_kmem.c
+++ b/tools/testing/selftests/cgroup/test_kmem.c
@@ -145,7 +145,7 @@ static int cg_run_in_subcgroups(const char *parent,
return -1;
}
- if (cg_run(child, fn, NULL)) {
+ if (cg_run(child, fn, arg)) {
cg_destroy(child);
free(child);
return -1;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 023/733] bpf: Fix REG INVARIANTS VIOLATION on speculative pointer arithmetic
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (21 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 022/733] selftests/cgroup: Fix cg_run_in_subcgroups ignoring arg parameter Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 024/733] bpf: Fix BPF_F_CPU validation for sparse CPU IDs Greg Kroah-Hartman
` (721 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hiker Cl, Jiayuan Chen,
Eduard Zingerman, Kumar Kartikeya Dwivedi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 150aeba624e8b7cac51c39440d7e8e1fd11de9a0 ]
Take the following unprivileged program as an example:
r0 = bpf_map_lookup_elem(...) /* PTR_TO_MAP_VALUE, offset 0 */
...
14: r0 += r1 /* r1 is a bounded scalar */
15: r9 = r0
Loading it triggers a verifier warning from reg_bounds_sanity_check():
verifier bug: REG INVARIANTS VIOLATION (alu): const subreg tnum out
of sync with range bounds r64={.base=0x0, .size=0x0}
r32={.base=0x0, .size=0xffffffff} var_off=(0x0, 0x0)
What happens:
1. Processing insn 14 (r0 += r1) in adjust_ptr_min_max_vals(), the new
offset is computed into dst_reg's var_off and 32/64-bit ranges.
2. Because pointer registers do not track 32-bit subregister bounds,
__mark_reg32_unbounded() first sets r32 to the full range; r32 is
re-derived from the offset at the end of the function by
reg_bounds_sync().
3. On the unprivileged path, sanitize_ptr_alu() is called and, via
sanitize_speculative_path() -> push_stack(), snapshots the current
register state and schedules the next instruction (insn 15) to be
verified directly as a speculative path.
4. That snapshot is taken between step 2 and the final reg_bounds_sync():
at this point dst_reg's var_off still holds the (const) original
offset while r32 has just been blanked to the full range, i.e. the two
are out of sync. When the speculative path later verifies insn 15
(r9 = r0), the inconsistent state reaches reg_bounds_sanity_check() and
trips the warning.
var_off and the 32-bit range must always be consistent. There are two
ways to keep the snapshot consistent:
1. sync var_off and r32 before the snapshot so they match, or
2. leave r32 at its original (already consistent) value and blank it
only after the snapshot.
The whole point of sanitize_ptr_alu() is to insert a harmless masking
sequence that keeps the access in bounds under speculation, so the state
it snapshots should faithfully represent that. Take approach 2: move
__mark_reg32_unbounded() to after sanitize_ptr_alu(), so the speculative
snapshot keeps the pointer's original, consistent r32. The non-speculative
path is unchanged: r32 is still blanked before the offset is applied and
re-derived by reg_bounds_sync().
Fixes: 5f99f312bd3b ("bpf: add register bounds sanity checks and sanitization")
Reported-by: Hiker Cl <clhiker365@gmail.com>
Closes: https://lore.kernel.org/bpf/CAGM=xGB1fJ9kT8XTitVo74B0WGqgjkoUHdLwzytwV0AyqeVApw@mail.gmail.com/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260819125840.286434-1-jiayuan.chen@linux.dev
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 14a9fd2d54720..03187bab806a7 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -13794,9 +13794,6 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
!check_reg_sane_offset_ptr(env, ptr_reg, ptr_reg->type))
return -EINVAL;
- /* pointer types do not carry 32-bit bounds at the moment. */
- __mark_reg32_unbounded(dst_reg);
-
if (sanitize_needed(opcode)) {
ret = sanitize_ptr_alu(env, insn, ptr_reg, off_reg, dst_reg,
&info, false);
@@ -13804,6 +13801,14 @@ static int adjust_ptr_min_max_vals(struct bpf_verifier_env *env,
return sanitize_err(env, insn, ret);
}
+ /*
+ * Pointer types do not carry 32-bit bounds at the moment. Blank r32
+ * only after sanitize_ptr_alu() may have snapshotted dst_reg into a
+ * speculative path: otherwise reg_bounds_sanity_check() might hit some
+ * constraints violations.
+ */
+ __mark_reg32_unbounded(dst_reg);
+
switch (opcode) {
case BPF_ADD:
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 024/733] bpf: Fix BPF_F_CPU validation for sparse CPU IDs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (22 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 023/733] bpf: Fix REG INVARIANTS VIOLATION on speculative pointer arithmetic Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 025/733] bpf: Fix percpu map update indexing with " Greg Kroah-Hartman
` (720 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Su, Andrii Nakryiko, Leon Hwang,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit ed54bf564ac52699cf4def3d0c2125d493e756f9 ]
BPF_F_CPU stores the target CPU ID in the upper 32 bits of the map
operation flags. bpf_map_check_op_flags() currently compares that ID
with num_possible_cpus(), which is the number of possible CPUs rather
than a bound on CPU IDs.
On an arm64 QEMU guest with a CPU device-tree hole, the possible CPU
mask was 0,2-3. A userspace program using raw bpf() syscalls creates
a BPF_MAP_TYPE_PERCPU_ARRAY and performs update and lookup operations
for each CPU by setting BPF_F_CPU and the CPU ID in the flags.
With the old check, CPU 1 is incorrectly accepted while valid CPU 3 is
rejected with -ERANGE. The CPU 1 update then reaches the per-CPU map
access path and triggers:
Unable to handle kernel paging request at virtual address ...
pc : __pi_memcpy_generic+0x5c/0x22c
lr : bpf_percpu_array_update+0x2dc/0x2e8
Call trace:
__pi_memcpy_generic
bpf_map_update_value
map_update_elem
__sys_bpf
Check the CPU ID against nr_cpu_ids and cpu_possible() instead. This
rejects CPU IDs outside the valid range and CPUs absent from the
possible mask, while allowing valid sparse CPU IDs.
Fixes: 2b421662c788 ("bpf: Introduce BPF_F_CPU and BPF_F_ALL_CPUS flags")
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Leon Hwang <leon.hwang@linux.dev>
Link: https://lore.kernel.org/bpf/20260813160858.1042834-3-sh_def@163.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 77e2075f77c73..7798abc7d637b 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -4184,7 +4184,7 @@ static inline int bpf_map_check_op_flags(struct bpf_map *map, u64 flags, u64 all
return -EINVAL;
cpu = flags >> 32;
- if ((flags & BPF_F_CPU) && cpu >= num_possible_cpus())
+ if ((flags & BPF_F_CPU) && (cpu >= nr_cpu_ids || !cpu_possible(cpu)))
return -ERANGE;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 025/733] bpf: Fix percpu map update indexing with sparse CPU IDs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (23 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 024/733] bpf: Fix BPF_F_CPU validation for sparse CPU IDs Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 026/733] sched_ext: Fix spurious aborts in scx_bpf_dsq_move() on ownership change races Greg Kroah-Hartman
` (719 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Su, Andrii Nakryiko, Leon Hwang,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit 75b0a6db4300e4c2c9e97a0848deaa7acfb42fb7 ]
Per-CPU array, hash, and cgroup storage map updates without BPF_F_CPU
or BPF_F_ALL_CPUS use a value buffer whose per-CPU slots are packed in
possible-CPU order. The buffer is sized as:
round_up(value_size, 8) * num_possible_cpus()
The update paths iterate over possible CPUs, but use the logical CPU ID
to calculate the source offset:
value + size * cpu
This only works when possible CPU IDs are contiguous starting at zero.
For example, with a possible CPU mask of 0,2-3, the buffer contains
three slots corresponding to CPUs 0, 2, and 3. CPU2 is therefore
expected to use slot 1 and CPU3 slot 2. Instead, the current code uses
slots 2 and 3 respectively, causing incorrect per-CPU values and an
out-of-bounds read from the update buffer for CPU3.
The corresponding lookup paths already use a dense offset while
iterating over possible CPUs. Do the same for the array, hash, and
cgroup storage update paths, advancing the source offset once for each
possible CPU. BPF_F_ALL_CPUS continues to use the same value for every
CPU.
Fixes: 8eb76cb03f0f ("bpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu_array maps")
Fixes: c6936161fd55 ("bpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu_hash and lru_percpu_hash maps")
Fixes: 47c79f05aa0d ("bpf: Add BPF_F_CPU and BPF_F_ALL_CPUS flags support for percpu_cgroup_storage maps")
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Andrii Nakryiko <andrii@kernel.org>
Acked-by: Leon Hwang <leon.hwang@linux.dev>
Link: https://lore.kernel.org/bpf/20260813155131.1022745-3-sh_def@163.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/arraymap.c | 5 +++--
kernel/bpf/hashtab.c | 5 +++--
kernel/bpf/local_storage.c | 5 +++--
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/kernel/bpf/arraymap.c b/kernel/bpf/arraymap.c
index 248b4818178cd..cc3f8c25a28b5 100644
--- a/kernel/bpf/arraymap.c
+++ b/kernel/bpf/arraymap.c
@@ -405,7 +405,7 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
void __percpu *pptr;
void *ptr, *val;
u32 size;
- int cpu;
+ int cpu, off = 0;
if (unlikely((map_flags & BPF_F_LOCK) || (u32)map_flags > BPF_F_ALL_CPUS))
/* unknown flags */
@@ -437,9 +437,10 @@ int bpf_percpu_array_update(struct bpf_map *map, void *key, void *value,
}
for_each_possible_cpu(cpu) {
ptr = per_cpu_ptr(pptr, cpu);
- val = (map_flags & BPF_F_ALL_CPUS) ? value : value + size * cpu;
+ val = (map_flags & BPF_F_ALL_CPUS) ? value : value + off;
copy_map_value(map, ptr, val);
bpf_obj_cancel_fields(map, ptr);
+ off += size;
}
unlock:
rcu_read_unlock();
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 9f394e1aa2e85..dd4da18312ac1 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -1026,7 +1026,7 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr,
} else {
u32 size = round_up(htab->map.value_size, 8);
void *val;
- int cpu;
+ int cpu, off = 0;
if (map_flags & BPF_F_CPU) {
cpu = map_flags >> 32;
@@ -1038,9 +1038,10 @@ static void pcpu_copy_value(struct bpf_htab *htab, void __percpu *pptr,
for_each_possible_cpu(cpu) {
ptr = per_cpu_ptr(pptr, cpu);
- val = (map_flags & BPF_F_ALL_CPUS) ? value : value + size * cpu;
+ val = (map_flags & BPF_F_ALL_CPUS) ? value : value + off;
copy_map_value(&htab->map, ptr, val);
bpf_obj_cancel_fields(&htab->map, ptr);
+ off += size;
}
}
}
diff --git a/kernel/bpf/local_storage.c b/kernel/bpf/local_storage.c
index 23267213a17fb..83cd527a2542b 100644
--- a/kernel/bpf/local_storage.c
+++ b/kernel/bpf/local_storage.c
@@ -220,7 +220,7 @@ int bpf_percpu_cgroup_storage_update(struct bpf_map *_map, void *key,
struct bpf_cgroup_storage *storage;
void *val;
u32 size;
- int cpu;
+ int cpu, off = 0;
if ((u32)map_flags & ~(BPF_ANY | BPF_EXIST | BPF_F_CPU | BPF_F_ALL_CPUS))
return -EINVAL;
@@ -245,8 +245,9 @@ int bpf_percpu_cgroup_storage_update(struct bpf_map *_map, void *key,
}
size = round_up(_map->value_size, 8);
for_each_possible_cpu(cpu) {
- val = (map_flags & BPF_F_ALL_CPUS) ? value : value + size * cpu;
+ val = (map_flags & BPF_F_ALL_CPUS) ? value : value + off;
copy_map_value(_map, per_cpu_ptr(storage->percpu_buf, cpu), val);
+ off += size;
}
unlock:
rcu_read_unlock();
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 026/733] sched_ext: Fix spurious aborts in scx_bpf_dsq_move() on ownership change races
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (24 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 025/733] bpf: Fix percpu map update indexing with " Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 027/733] drm/gud: validate GUD_ROTATION_0 is present in supported rotations Greg Kroah-Hartman
` (718 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <tj@kernel.org>
[ Upstream commit cca061dccf563907061766191b2ce3f66b7c285a ]
scx_dsq_move() verifies that the task belongs to the calling scheduler
before taking any locks and aborts the scheduler on mismatch. The task can
lose the sched association at any point: It can run and fully exit, which
clears the association, or get rehomed to a different sub-sched. Both are
benign races, but the early ownership check escalates them into scheduler
aborts.
Move the ownership check below the cursor-lost check. Every ownership change
dequeues the task first, so a task that is still on the iterated DSQ under
the lock while owned elsewhere indicates a genuine violation and should
abort.
Also fix two stale comments still referencing sched_ext_free(), which has
been renamed to sched_ext_dead().
Fixes: bb4d9fd55158 ("sched_ext: scx_dsq_move() should validate the task belongs to the right scheduler")
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/ext/ext.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/kernel/sched/ext/ext.c b/kernel/sched/ext/ext.c
index 558be0cdebef8..548f46a427883 100644
--- a/kernel/sched/ext/ext.c
+++ b/kernel/sched/ext/ext.c
@@ -7435,7 +7435,7 @@ static void scx_root_enable_workfn(struct kthread_work *work)
/*
* Enable ops for every task. Fork is excluded by scx_fork_rwsem
* preventing new tasks from being added. No need to exclude tasks
- * leaving as sched_ext_free() can handle both prepped and enabled
+ * leaving as sched_ext_dead() can handle both prepped and enabled
* tasks. Prep all tasks first and then enable them with preemption
* disabled.
*
@@ -7524,7 +7524,7 @@ static void scx_root_enable_workfn(struct kthread_work *work)
/*
* We're fully committed and can't fail. The task READY -> ENABLED
- * transitions here are synchronized against sched_ext_free() through
+ * transitions here are synchronized against sched_ext_dead() through
* scx_tasks_lock.
*/
percpu_down_write(&scx_fork_rwsem);
@@ -9019,12 +9019,6 @@ static bool scx_dsq_move(struct bpf_iter_scx_dsq_kern *kit,
if (unlikely(READ_ONCE(sch->aborting)))
return false;
- if (unlikely(!scx_task_on_sched(sch, p))) {
- scx_error(sch, "scx_bpf_dsq_move[_vtime]() on %s[%d] but the task belongs to a different scheduler",
- p->comm, p->pid);
- return false;
- }
-
/*
* Can be called from either ops.dispatch() holding the dispatched rq's
* lock or any context where no rq lock is held. If latter, lock @p's
@@ -9056,6 +9050,17 @@ static bool scx_dsq_move(struct bpf_iter_scx_dsq_kern *kit,
goto out;
}
+ /*
+ * @p has been on $src_dsq and can't move anymore. If @p is not on @sch,
+ * the caller didn't have authority over @p at the time of the call.
+ */
+ if (unlikely(!scx_task_on_sched(sch, p))) {
+ scx_error(sch, "scx_bpf_dsq_move[_vtime]() on %s[%d] but the task belongs to a different scheduler",
+ p->comm, p->pid);
+ raw_spin_unlock(&src_dsq->lock);
+ goto out;
+ }
+
/* @p is still on $src_dsq and stable, determine the destination */
dst_dsq = find_dsq_for_dispatch(sch, locked_rq ?: this_rq(), dsq_id, task_cpu(p));
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 027/733] drm/gud: validate GUD_ROTATION_0 is present in supported rotations
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (25 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 026/733] sched_ext: Fix spurious aborts in scx_bpf_dsq_move() on ownership change races Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 028/733] printk: Dont WARN on kthread_run failure Greg Kroah-Hartman
` (717 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+efe2810681f1b065d3a8,
Sajal Gupta, Ruben Wauters, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sajal Gupta <sajal2005gupta@gmail.com>
[ Upstream commit cb732d027aa18e1fcf9d2797f47d20b179ebc59c ]
The rotation argument to drm_plane_create_rotation_property() is set to
DRM_MODE_ROTATE_0, and the device reported rotation bitmask is used as
the supported_rotations argument. The driver never validates that
GUD_ROTATION_0 is present, so a device that omits it from its
GUD_PROPERTY_ROTATION triggers the
WARN_ON(rotation & ~supported_rotations) in
drm_plane_create_rotation_property()
Fix this by skipping the creation of rotation property if the device
doesn't have the GUD_ROTATION_0 bit
Fixes: 40e1a70b4aed ("drm: Add GUD USB Display driver")
Reported-by: syzbot+efe2810681f1b065d3a8@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=efe2810681f1b065d3a8
Tested-by: syzbot+efe2810681f1b065d3a8@syzkaller.appspotmail.com
Signed-off-by: Sajal Gupta <sajal2005gupta@gmail.com>
Acked-by: Ruben Wauters <rubenru09@aol.com>
Signed-off-by: Ruben Wauters <rubenru09@aol.com>
Link: https://patch.msgid.link/20260821071812.16500-1-sajal2005gupta@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/gud/gud_drv.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/gud/gud_drv.c b/drivers/gpu/drm/gud/gud_drv.c
index 89bd6ca36003f..3a1b9e2a2eaa1 100644
--- a/drivers/gpu/drm/gud/gud_drv.c
+++ b/drivers/gpu/drm/gud/gud_drv.c
@@ -289,6 +289,8 @@ static int gud_plane_add_properties(struct gud_device *gdrm)
* but mask out any additions on future devices.
*/
val &= GUD_ROTATION_MASK;
+ if (!(val & GUD_ROTATION_0))
+ continue;
ret = drm_plane_create_rotation_property(&gdrm->plane,
DRM_MODE_ROTATE_0, val);
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 028/733] printk: Dont WARN on kthread_run failure.
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (26 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 027/733] drm/gud: validate GUD_ROTATION_0 is present in supported rotations Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 029/733] accel/amdxdna: Remove __counted_by from struct amdxdna_cmd_chain Greg Kroah-Hartman
` (716 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+1ebbc20f223b99446034,
Tetsuo Handa, John Ogness, Petr Mladek, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
[ Upstream commit 72dd0ec09e7cc98ed58ddeac26575e5d1ab8a93d ]
Since __kthread_create_on_node() returns -EINTR upon SIGKILL,
we should not use WARN_ON() in order to catch kthread_run() failure.
Reported-by: syzbot+1ebbc20f223b99446034@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=1ebbc20f223b99446034
Fixes: 5f53ca3ff83b ("printk: Implement legacy printer kthread for PREEMPT_RT")
Fixes: 76f258bf3f2a ("printk: nbcon: Introduce printer kthreads")
Signed-off-by: Tetsuo Handa <penguin-kernel@I-love.SAKURA.ne.jp>
Reviewed-by: John Ogness <john.ogness@linutronix.de>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Link: https://patch.msgid.link/76bb4c1c-5d85-4635-b3bb-fc06f292c59e@I-love.SAKURA.ne.jp
Signed-off-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/printk/nbcon.c | 2 +-
kernel/printk/printk.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index 4b03b019cd5ee..a5921a84a80ed 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -1382,7 +1382,7 @@ bool nbcon_kthread_create(struct console *con)
return true;
kt = kthread_run(nbcon_kthread_func, con, "pr/%s%d", con->name, con->index);
- if (WARN_ON(IS_ERR(kt))) {
+ if (IS_ERR(kt)) {
con_printk(KERN_ERR, con, "failed to start printing thread\n");
return false;
}
diff --git a/kernel/printk/printk.c b/kernel/printk/printk.c
index 6d363e42e2a05..96ff9547e888b 100644
--- a/kernel/printk/printk.c
+++ b/kernel/printk/printk.c
@@ -3732,7 +3732,7 @@ static bool legacy_kthread_create(void)
lockdep_assert_console_list_lock_held();
kt = kthread_run(legacy_kthread_func, NULL, "pr/legacy");
- if (WARN_ON(IS_ERR(kt))) {
+ if (IS_ERR(kt)) {
pr_err("failed to start legacy printing thread\n");
return false;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 029/733] accel/amdxdna: Remove __counted_by from struct amdxdna_cmd_chain
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (27 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 028/733] printk: Dont WARN on kthread_run failure Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 030/733] accel/amdxdna: reject a command chain that carries no commands Greg Kroah-Hartman
` (715 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Max Zhen, Lizhi Hou, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Hou <lizhi.hou@amd.com>
[ Upstream commit b3709d354545e70388177500761f92d906c4dfd6 ]
struct amdxdna_cmd_chain contains a flexible array annotated with
__counted_by(command_count). Since the structure is stored in shared
AMDXDNA_BO_SHARE memory, userspace can modify command_count concurrently.
If command_count is changed to zero, the bounds check generated from
__counted_by may fail and trigger a kernel panic.
Remove __counted_by to avoid relying on the userspace-controlled
command_count for the flexible array bounds check.
Fixes: aac243092b70 ("accel/amdxdna: Add command execution")
Reviewed-by: Max Zhen <max.zhen@amd.com>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260821033543.1839719-1-lizhi.hou@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/amdxdna/amdxdna_ctx.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/accel/amdxdna/amdxdna_ctx.h b/drivers/accel/amdxdna/amdxdna_ctx.h
index b6bef3af7dab4..6e78bab8a02c0 100644
--- a/drivers/accel/amdxdna/amdxdna_ctx.h
+++ b/drivers/accel/amdxdna/amdxdna_ctx.h
@@ -55,7 +55,7 @@ struct amdxdna_cmd_chain {
u32 submit_index;
u32 error_index;
u32 reserved[3];
- u64 data[] __counted_by(command_count);
+ u64 data[];
};
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 030/733] accel/amdxdna: reject a command chain that carries no commands
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (28 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 029/733] accel/amdxdna: Remove __counted_by from struct amdxdna_cmd_chain Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 031/733] accel/amdxdna: put the chained BO when its mapping fails Greg Kroah-Hartman
` (714 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taimuraz Kaitmazov, Lizhi Hou,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taimuraz Kaitmazov <taimuraz@kaitmazov.com>
[ Upstream commit ef6d27af71e1dc43181ec797a6aaa77c27c36786 ]
A chain whose command_count is zero passes the payload length check,
because struct_size(payload, data, 0) is just the header. The fill loop
then does not run, so offset stays zero and the request is submitted with
a zero-length buffer.
On firmware without AIE2_NPU_COMMAND that ends at the opcode check, since
op is still ERT_INVALID_CMD and aie2_get_chain_msg_op() answers
MSG_OP_MAX_OPCODE. aie2_get_npu_chain_msg_op() answers
MSG_OP_CHAIN_EXEC_NPU whatever it is given, so there the submission
continues to drm_clflush_virt_range(cmd_buf, 0), which reads the byte
before the buffer and faults on the vmap guard page. EXEC_CMD is
reachable by any process that can open the render node.
Reject the request instead.
Fixes: 8ed8b0239617 ("accel/amdxdna: Add debug prints for command submission")
Signed-off-by: Taimuraz Kaitmazov <taimuraz@kaitmazov.com>
Reviewed-by: Lizhi Hou <lizhi.hou@amd.com>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260818000019.369366-1-taimuraz@kaitmazov.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/amdxdna/aie2_message.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/accel/amdxdna/aie2_message.c b/drivers/accel/amdxdna/aie2_message.c
index dfe0fbdf066d2..b4c49259a1a23 100644
--- a/drivers/accel/amdxdna/aie2_message.c
+++ b/drivers/accel/amdxdna/aie2_message.c
@@ -994,7 +994,7 @@ int aie2_cmdlist_multi_execbuf(struct amdxdna_hwctx *hwctx,
}
ccnt = payload->command_count;
- if (payload_len < struct_size(payload, data, ccnt)) {
+ if (!ccnt || payload_len < struct_size(payload, data, ccnt)) {
XDNA_DBG(xdna, "Invalid command count %d", ccnt);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 031/733] accel/amdxdna: put the chained BO when its mapping fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (29 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 030/733] accel/amdxdna: reject a command chain that carries no commands Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 032/733] selftests/cgroup: Drop invalid boot isolation comparison Greg Kroah-Hartman
` (713 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taimuraz Kaitmazov, Lizhi Hou,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taimuraz Kaitmazov <taimuraz@kaitmazov.com>
[ Upstream commit 7e33ba3a1d48c2d20ed270dec9d2d08332585c8e ]
amdxdna_cmd_set_error() looks up the first BO of a command chain, which
takes a reference, and drops it at the end of the function. The mapping of
that BO is established in between, and the failure path returns without the
put, so the reference is leaked.
Ordinary use does not reach it. The chain has been submitted before any of
this runs, so aie2_cmdlist_fill_slot() has already called
amdxdna_cmd_get_op() on that BO and amdxdna_gem_vmap() has cached its
address. What makes it reachable is that the BO is resolved again by
handle here, and the handle is userspace's to recycle: closing it after
submission and importing a dma-buf whose exporter implements no vmap onto
the same id leaves amdxdna_gem_get_obj() returning an object this cannot
map, since prime_import() types every import AMDXDNA_BO_SHARE.
Fixes: d76856beb4a4 ("accel/amdxdna: Refactor GEM BO handling and add helper APIs for address retrieval")
Signed-off-by: Taimuraz Kaitmazov <taimuraz@kaitmazov.com>
Reviewed-by: Lizhi Hou <lizhi.hou@amd.com>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260819230852.287751-1-taimuraz@kaitmazov.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/amdxdna/amdxdna_ctx.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/accel/amdxdna/amdxdna_ctx.c b/drivers/accel/amdxdna/amdxdna_ctx.c
index 31a414c3f0d96..888e857ec5582 100644
--- a/drivers/accel/amdxdna/amdxdna_ctx.c
+++ b/drivers/accel/amdxdna/amdxdna_ctx.c
@@ -183,8 +183,10 @@ int amdxdna_cmd_set_error(struct amdxdna_gem_obj *abo,
if (!abo)
return -EINVAL;
cmd = amdxdna_gem_vmap(abo);
- if (!cmd)
+ if (!cmd) {
+ amdxdna_gem_put_obj(abo);
return -ENOMEM;
+ }
}
memset(cmd->data, 0xff, abo->mem.size - sizeof(*cmd));
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 032/733] selftests/cgroup: Drop invalid boot isolation comparison
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (30 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 031/733] accel/amdxdna: put the chained BO when its mapping fails Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 033/733] cgroup/cpuset: Preserve boot-isolated CPUs on partition release Greg Kroah-Hartman
` (712 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guopeng Zhang, Waiman Long,
Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <zhangguopeng@kylinos.cn>
[ Upstream commit 2bf404b1bd94f50747443234c0a4a5e18e2569bf ]
check_isolcpus() clears ISOLCPUS before rebuilding it from sched domain
data. Comparing that empty value with
/sys/devices/system/cpu/isolated makes the test fail whenever
isolcpus=domain is present.
That sysfs file is generated from HK_TYPE_DOMAIN_BOOT and does not change
when cpuset updates HK_TYPE_DOMAIN. Re-reading it cannot validate dynamic
housekeeping updates. The cpuset.cpus.isolated and sched domain checks
already cover the two dynamic interfaces, so remove the invalid comparison.
This can be reproduced on a kernel booted with isolcpus=domain,15:
# tools/testing/selftests/cgroup/test_cpuset_prs.sh
The test fails its first state-matrix isolation check before the change and
continues past that check afterward.
Fixes: 6df415aa46ec ("cgroup/cpuset: Defer housekeeping_update() calls from CPU hotplug to workqueue")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Reviewed-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/cgroup/test_cpuset_prs.sh | 6 ------
1 file changed, 6 deletions(-)
diff --git a/tools/testing/selftests/cgroup/test_cpuset_prs.sh b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
index b2e60671273ec..ebbc5b4def243 100755
--- a/tools/testing/selftests/cgroup/test_cpuset_prs.sh
+++ b/tools/testing/selftests/cgroup/test_cpuset_prs.sh
@@ -791,7 +791,6 @@ check_isolcpus()
EXPECTED_ISOLCPUS=$1
ISCPUS=${CGROUP2}/cpuset.cpus.isolated
ISOLCPUS=$(cat $ISCPUS)
- HKICPUS=$(cat /sys/devices/system/cpu/isolated)
LASTISOLCPU=
SCHED_DOMAINS=/sys/kernel/debug/sched/domains
if [[ $EXPECTED_ISOLCPUS = . ]]
@@ -829,11 +828,6 @@ check_isolcpus()
ISOLCPUS=
EXPECTED_ISOLCPUS=$EXPECTED_SDOMAIN
- #
- # The inverse of HK_TYPE_DOMAIN cpumask in $HKICPUS should match $ISOLCPUS
- #
- [[ "$ISOLCPUS" != "$HKICPUS" ]] && return 1
-
#
# Use the sched domain in debugfs to check isolated CPUs, if available
#
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 033/733] cgroup/cpuset: Preserve boot-isolated CPUs on partition release
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (31 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 032/733] selftests/cgroup: Drop invalid boot isolation comparison Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 034/733] accel: ethosu: Dont read the U65 rounding mode as a storage mode Greg Kroah-Hartman
` (711 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Guopeng Zhang, Waiman Long,
Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guopeng Zhang <zhangguopeng@kylinos.cn>
[ Upstream commit 6c37d7e074a4be1ba8da59f4ed5df8977b3daa43 ]
isolated_cpus tracks CPUs isolated with isolcpus= as well as CPUs in
isolated cpuset partitions. When an isolated partition is released,
isolated_cpus_update() removes its whole CPU mask. This also clears CPUs
which were already isolated at boot.
This can be reproduced on a cgroup v2 system booted with
isolcpus=domain,15:
cd /sys/fs/cgroup
echo +cpuset > cgroup.subtree_control
mkdir cpuset-repro
echo 15 > cpuset-repro/cpuset.cpus
echo isolated > cpuset-repro/cpuset.cpus.partition
echo member > cpuset-repro/cpuset.cpus.partition
cat cpuset.cpus.isolated
CPU 15 is absent before the change. It must remain in
cpuset.cpus.isolated after the partition is released.
Update isolated_cpus one CPU at a time and keep CPUs outside the
boot-time domain housekeeping mask isolated.
Fixes: c188f33c864e ("cgroup/cpuset: Account for boot time isolated CPUs")
Signed-off-by: Guopeng Zhang <zhangguopeng@kylinos.cn>
Acked-by: Waiman Long <longman@redhat.com>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/cgroup/cpuset.c | 39 +++++++++++++++++++++++++++++----------
1 file changed, 29 insertions(+), 10 deletions(-)
diff --git a/kernel/cgroup/cpuset.c b/kernel/cgroup/cpuset.c
index 1c6d568006688..69ff86e03c630 100644
--- a/kernel/cgroup/cpuset.c
+++ b/kernel/cgroup/cpuset.c
@@ -1220,6 +1220,28 @@ static void reset_partition_data(struct cpuset *cs)
cpumask_copy(cs->effective_cpus, parent->effective_cpus);
}
+/* Return true if isolated_cpus changes. */
+static bool isolated_cpu_update(int new_prs, int cpu)
+{
+ lockdep_assert_held(&callback_lock);
+ lockdep_assert_held(&cpuset_mutex);
+
+ if (new_prs == PRS_ISOLATED) {
+ if (cpumask_test_cpu(cpu, isolated_cpus))
+ return false;
+ cpumask_set_cpu(cpu, isolated_cpus);
+ return true;
+ }
+
+ /* CPUs isolated at boot must remain isolated. */
+ if (!cpumask_test_cpu(cpu,
+ housekeeping_cpumask(HK_TYPE_DOMAIN_BOOT)) ||
+ !cpumask_test_cpu(cpu, isolated_cpus))
+ return false;
+ cpumask_clear_cpu(cpu, isolated_cpus);
+ return true;
+}
+
/*
* isolated_cpus_update - Update the isolated_cpus mask
* @old_prs: old partition_root_state
@@ -1228,19 +1250,16 @@ static void reset_partition_data(struct cpuset *cs)
*/
static void isolated_cpus_update(int old_prs, int new_prs, struct cpumask *xcpus)
{
+ bool updated = false;
+ int cpu;
+
WARN_ON_ONCE(old_prs == new_prs);
lockdep_assert_held(&callback_lock);
lockdep_assert_held(&cpuset_mutex);
- if (new_prs == PRS_ISOLATED) {
- if (cpumask_subset(xcpus, isolated_cpus))
- return;
- cpumask_or(isolated_cpus, isolated_cpus, xcpus);
- } else {
- if (!cpumask_intersects(xcpus, isolated_cpus))
- return;
- cpumask_andnot(isolated_cpus, isolated_cpus, xcpus);
- }
- update_housekeeping = true;
+ for_each_cpu(cpu, xcpus)
+ updated |= isolated_cpu_update(new_prs, cpu);
+ if (updated)
+ update_housekeeping = true;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 034/733] accel: ethosu: Dont read the U65 rounding mode as a storage mode
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (32 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 033/733] cgroup/cpuset: Preserve boot-isolated CPUs on partition release Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 035/733] ufs: do not treat unreadable directory blocks as empty Greg Kroah-Hartman
` (710 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tomeu Vizoso, Rob Herring (Arm),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomeu Vizoso <tomeu@tomeuvizoso.net>
[ Upstream commit db9deec5a345abc538d081fb221dc0b00a9695bd ]
Bits 15:14 of NPU_SET_{IFM,OFM}_PRECISION select the activation storage
mode on U85 only. On U65 the same field holds the rounding mode, and the
command stream parser has read it as a storage mode since the driver was
added.
That went unnoticed while unknown values fell through the switch, but
now that they are rejected, every U65 command stream that asks for
natural rounding (2) fails CMDSTREAM_BO_CREATE with -EINVAL. Mesa emits
it for average pooling, concatenation, split, unpack, strided slice, LUT
and argmax, which is 72 failures of the Teflon test suite on an i.MX93.
Truncating rounding (1) is misread as well: it picks the two-tile
address path and computes a bogus feature map size from tile bases the
command stream never set.
Read the field as a storage mode only on the hardware where it is one.
Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Fixes: 6b7e0066294d ("accel: ethosu: Handle U85 internal chaining buffer")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Tomeu Vizoso <tomeu@tomeuvizoso.net>
Link: https://patch.msgid.link/20260824152612.751007-1-tomeu@tomeuvizoso.net
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/ethosu/ethosu_gem.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/accel/ethosu/ethosu_gem.c b/drivers/accel/ethosu/ethosu_gem.c
index d50fed64d4d93..fa37a190e9fff 100644
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -204,7 +204,7 @@ static u64 feat_matrix_length(struct ethosu_device *edev,
struct feat_matrix *fm,
u32 x, u32 y, u32 c, bool ofm)
{
- u32 element_size, storage = fm->precision >> 14;
+ u32 element_size, storage = ethosu_is_u65(edev) ? 0 : fm->precision >> 14;
int tile = 0;
u64 addr;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 035/733] ufs: do not treat unreadable directory blocks as empty
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (33 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 034/733] accel: ethosu: Dont read the U65 rounding mode as a storage mode Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 036/733] drm/cirrus-qemu: Validate BAR0 size during probe Greg Kroah-Hartman
` (709 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis, Jan Kara,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
[ Upstream commit 08edfb34ee9ca54383970c65ed3a6013e84f5e16 ]
ufs_empty_dir() scans every directory block to decide whether a
directory is empty before rmdir() removes it. When ufs_get_folio()
cannot read or validate a block it returns an error pointer, and the
loop currently skips that block with continue and keeps scanning the
remaining blocks.
If none of the readable blocks hold an entry, the function returns 1
and the caller unlinks the directory. A directory whose contents live
in a block that cannot be read, for example because of an I/O error or
corrupted directory metadata, is therefore seen as empty and removed,
losing the entries it still holds.
Follow the ext2 behaviour and treat an unreadable block as a reason to
consider the directory not empty, so rmdir() fails instead of
discarding data that could not be verified.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260801013942.279992-1-ali@iusegentoo.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ufs/dir.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index e62fe56676710..ce43cf20b07c9 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -590,7 +590,7 @@ int ufs_empty_dir(struct inode * inode)
kaddr = ufs_get_folio(inode, i, &folio);
if (IS_ERR(kaddr))
- continue;
+ return 0;
de = (struct ufs_dir_entry *)kaddr;
kaddr += ufs_last_byte(inode, i) - UFS_DIR_REC_LEN(1);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 036/733] drm/cirrus-qemu: Validate BAR0 size during probe
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (34 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 035/733] ufs: do not treat unreadable directory blocks as empty Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 037/733] ntfs: return DT_UNKNOWN on inode lookup failure in readdir Greg Kroah-Hartman
` (708 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+2442951a6abb004df963,
Slawomir Stepien, Thomas Zimmermann, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Slawomir Stepien <sst@poczta.fm>
[ Upstream commit 92312d333bf700798f92f30406c721bce87506f3 ]
The `cirrus-qemu` driver relies on `CIRRUS_VRAM_SIZE` (4 MB) to validate
framebuffer sizes. However, during PCI probe, the driver mapped BAR0
without verifying that its size matches `CIRRUS_VRAM_SIZE`.
If a PCI device with a BAR0 smaller than 4 MB is bound to the driver, the
mapped VRAM will be smaller than expected. Because validation checks assume
4 MB VRAM, framebuffers larger than the mapped memory can be created.
When the display plane is updated (e.g. during release),
`cirrus_primary_plane_helper_atomic_update()` copies the framebuffer to
VRAM using `drm_fb_memcpy()`. Writing past the end of the mapped I/O memory
causes a supervisor write page fault:
BUG: unable to handle page fault for address: ffffc9000389c000
...
RIP: 0010:memcpy_toio+0x7c/0xe0 arch/x86/lib/iomem.c:110
...
Call Trace:
<TASK>
iosys_map_memcpy_to include/linux/iosys-map.h:285 [inline]
drm_fb_memcpy+0x325/0x5d0 drivers/gpu/drm/drm_format_helper.c:442
cirrus_primary_plane_helper_atomic_update+0x98a/0xb00
drivers/gpu/drm/tiny/cirrus-qemu.c:358
drm_atomic_helper_commit_planes+0x626/0xea0
drivers/gpu/drm/drm_atomic_helper.c:3038
drm_atomic_helper_commit_tail+0x60/0x510
drivers/gpu/drm/drm_atomic_helper.c:1989
commit_tail+0x2b1/0x3c0 drivers/gpu/drm/drm_atomic_helper.c:2074
drm_atomic_helper_commit+0xa77/0xb10
drivers/gpu/drm/drm_atomic_helper.c:2312
Fix this by validating in `cirrus_pci_probe()` that the PCI BAR0 resource
is not less than `CIRRUS_VRAM_SIZE`, returning `-ENODEV` if it is less.
Fixes: ab3e023b1b4c ("drm/cirrus: rewrite and modernize driver.")
Assisted-by: Gemini:gemini-3.6-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+2442951a6abb004df963@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=2442951a6abb004df963
Link: https://syzkaller.appspot.com/ai_job?id=ba262a3a-bccf-4ad8-a1b0-583c55d34fd6
Signed-off-by: Slawomir Stepien <sst@poczta.fm>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260825120729.493611-1-sst@poczta.fm
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/tiny/cirrus-qemu.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/gpu/drm/tiny/cirrus-qemu.c b/drivers/gpu/drm/tiny/cirrus-qemu.c
index 075221b431d37..3bf23fcf65749 100644
--- a/drivers/gpu/drm/tiny/cirrus-qemu.c
+++ b/drivers/gpu/drm/tiny/cirrus-qemu.c
@@ -582,6 +582,9 @@ static int cirrus_pci_probe(struct pci_dev *pdev,
struct cirrus_device *cirrus;
int ret;
+ if (pci_resource_len(pdev, 0) < CIRRUS_VRAM_SIZE)
+ return -ENODEV;
+
ret = aperture_remove_conflicting_pci_devices(pdev, cirrus_driver.name);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 037/733] ntfs: return DT_UNKNOWN on inode lookup failure in readdir
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (35 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 036/733] drm/cirrus-qemu: Validate BAR0 size during probe Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 038/733] ntfs: propagate reparse index insertion failure Greg Kroah-Hartman
` (707 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit 3d3de2aee17d1431694aa085039479b5679e5ad4 ]
ntfs_reparse_tag_dt_types() returns PTR_ERR(vi) when ntfs_iget()
fails, but its return type is unsigned int and the caller passes
the value straight to dir_emit() as d_type. A stale or corrupt MFT
reference in a directory index thus makes readdir report a garbage
d_type value to userspace.
Return DT_UNKNOWN on lookup failure instead.
Fixes: fc053f05ca28 ("ntfs: add reparse and ea operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/reparse.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ntfs/reparse.c b/fs/ntfs/reparse.c
index fa523dc3691ea..f2377e3a56ca9 100644
--- a/fs/ntfs/reparse.c
+++ b/fs/ntfs/reparse.c
@@ -332,7 +332,7 @@ unsigned int ntfs_reparse_tag_dt_types(struct ntfs_volume *vol, unsigned long mr
vi = ntfs_iget(vol->sb, mref);
if (IS_ERR(vi))
- return PTR_ERR(vi);
+ return DT_UNKNOWN;
reparse_attr = (struct reparse_point *)ntfs_attr_readall(NTFS_I(vi),
AT_REPARSE_POINT, NULL, 0, &attr_size);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 038/733] ntfs: propagate reparse index insertion failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (36 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 037/733] ntfs: return DT_UNKNOWN on inode lookup failure in readdir Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 039/733] ntfs: return -ERANGE for undersized xattr buffer Greg Kroah-Hartman
` (706 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit 9692b1b4fc00cf89628bc43f71729ab21f14f8d3 ]
update_reparse_data() ignores the return value of
set_reparse_index(). When index insertion fails, the code removes
the just-written reparse data as cleanup but still returns 0, so
symlink(2) (and WSL special file creation) reports success while
no reparse data exists on disk. When there was no previous reparse
data (oldsize == 0), the failure was likewise silently ignored.
Propagate the error to the caller.
Fixes: fc053f05ca28 ("ntfs: add reparse and ea operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/reparse.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/fs/ntfs/reparse.c b/fs/ntfs/reparse.c
index f2377e3a56ca9..f8b88a110cb67 100644
--- a/fs/ntfs/reparse.c
+++ b/fs/ntfs/reparse.c
@@ -620,8 +620,9 @@ static int update_reparse_data(struct ntfs_inode *ni, struct ntfs_index_context
goto put_rp_inode;
}
- if (set_reparse_index(ni, xr, ((const struct reparse_point *)value)->reparse_tag) &&
- oldsize > 0) {
+ err = set_reparse_index(ni, xr,
+ ((const struct reparse_point *)value)->reparse_tag);
+ if (err && oldsize > 0) {
/*
* If cannot index, try to remove the reparse
* data and log the error. There will be an
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 039/733] ntfs: return -ERANGE for undersized xattr buffer
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (37 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 038/733] ntfs: propagate reparse index insertion failure Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 040/733] ntfs: preserve error code in ntfs_resident_attr_record_add() Greg Kroah-Hartman
` (705 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit ada728801999e25e610091362447372f1b25dd25 ]
When the value buffer passed to getxattr(2) for system.dos_attrib,
system.ntfs_attrib or system.ntfs_attrib_be is smaller than the
attribute value, ntfs_getxattr() returns -ENODATA, which tells
userspace the attribute does not exist. The xattr API expects
-ERANGE in this case, and ntfs_get_ea() in the same file already
returns -ERANGE for regular EAs.
Fixes: fc053f05ca28 ("ntfs: add reparse and ea operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/ea.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/ntfs/ea.c b/fs/ntfs/ea.c
index 25ff159dbfd38..08c35f9751114 100644
--- a/fs/ntfs/ea.c
+++ b/fs/ntfs/ea.c
@@ -591,7 +591,7 @@ static int ntfs_getxattr(const struct xattr_handler *handler,
if (!buffer) {
err = sizeof(u8);
} else if (size < sizeof(u8)) {
- err = -ENODATA;
+ err = -ERANGE;
} else {
err = sizeof(u8);
*(u8 *)buffer = (u8)(le32_to_cpu(ni->flags) & 0x3F);
@@ -604,7 +604,7 @@ static int ntfs_getxattr(const struct xattr_handler *handler,
if (!buffer) {
err = sizeof(u32);
} else if (size < sizeof(u32)) {
- err = -ENODATA;
+ err = -ERANGE;
} else {
err = sizeof(u32);
*(u32 *)buffer = le32_to_cpu(ni->flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 040/733] ntfs: preserve error code in ntfs_resident_attr_record_add()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (38 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 039/733] ntfs: return -ERANGE for undersized xattr buffer Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 041/733] ntfs: return real error from ntfs_non_resident_attr_record_add() Greg Kroah-Hartman
` (704 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit 8efe00b098b5b3618c885d2a35a5edccfbfbec7d ]
ntfs_resident_attr_record_add() collapses every failure to -EIO at
its put_err_out label. This defeats the resident-to-non-resident
fallback in ntfs_attr_add(), which relies on seeing -ENOSPC to
convert the attribute when the MFT record has no room, and also
hides -EEXIST and -ENOMEM from callers.
Return the actual error code. Every path reaching the label has
err set to a negative errno.
Fixes: 495e90fa3348 ("ntfs: update attrib operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/attrib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index b4c6137c037b6..fbb1c5f4da18a 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -2495,7 +2495,7 @@ int ntfs_resident_attr_record_add(struct ntfs_inode *ni, __le32 type,
return offset;
put_err_out:
ntfs_attr_put_search_ctx(ctx);
- return -EIO;
+ return err;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 041/733] ntfs: return real error from ntfs_non_resident_attr_record_add()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (39 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 040/733] ntfs: preserve error code in ntfs_resident_attr_record_add() Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 042/733] ntfs: fix kmap_local leak in write_mft_record_nolock() error paths Greg Kroah-Hartman
` (703 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit ba1b61ddaa764f31b14abe1d547049682cc5824e ]
ntfs_non_resident_attr_record_add() returns -1 at its put_err_out
label, which callers propagate as -EPERM to userspace.
Return the actual error code. Every path reaching the label has
err set to a negative errno.
Fixes: 495e90fa3348 ("ntfs: update attrib operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/attrib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index fbb1c5f4da18a..950fc1b727cb2 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -2634,7 +2634,7 @@ static int ntfs_non_resident_attr_record_add(struct ntfs_inode *ni, __le32 type,
return offset;
put_err_out:
ntfs_attr_put_search_ctx(ctx);
- return -1;
+ return err;
}
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 042/733] ntfs: fix kmap_local leak in write_mft_record_nolock() error paths
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (40 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 041/733] ntfs: return real error from ntfs_non_resident_attr_record_add() Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 043/733] ntfs: only count successfully cleared runs when freeing clusters Greg Kroah-Hartman
` (702 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit cf06dcd572845723821b54a608fc2da995c3c8e2 ]
write_mft_record_nolock() maps the MFT record folio with
kmap_local_folio(), but the pre_write_mst_fixup() and
bio_add_folio() failure paths jump to the error label without
unmapping it. kmap_local mappings are stack-ordered per task, so
leaking one corrupts the nesting for any outer mapping.
Unmap the folio on those error paths too.
Fixes: 115380f9a2f9 ("ntfs: update mft operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/mft.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs/mft.c b/fs/ntfs/mft.c
index 271a265491280..3ad739179c7a1 100644
--- a/fs/ntfs/mft.c
+++ b/fs/ntfs/mft.c
@@ -580,7 +580,7 @@ int write_mft_record_nolock(struct ntfs_inode *ni, struct mft_record *m, int syn
err = pre_write_mst_fixup((struct ntfs_record *)fixup_m, vol->mft_record_size);
if (err) {
ntfs_error(vol->sb, "Failed to apply mst fixups!");
- goto err_out;
+ goto unmap_err_out;
}
folio_size = vol->mft_record_size / ni->mft_lcn_count;
@@ -645,6 +645,8 @@ int write_mft_record_nolock(struct ntfs_inode *ni, struct mft_record *m, int syn
return 0;
put_bio_out:
bio_put(bio);
+unmap_err_out:
+ kunmap_local(kaddr);
err_out:
/*
* The caller should mark the base inode as bad so no more I/O
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 043/733] ntfs: only count successfully cleared runs when freeing clusters
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (41 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 042/733] ntfs: fix kmap_local leak in write_mft_record_nolock() error paths Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 044/733] ntfs: skip free cluster decrement when rollback fails Greg Kroah-Hartman
` (701 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit be9e89ccb8e52a3e4b67feeb03ebd8133091dc7e ]
ntfs_cluster_free_from_rl_nolock() adds a run's length to nr_freed
whenever the error bookkeeping condition is false, which includes
cases where ntfs_bitmap_clear_run() actually failed - e.g. a second
run failing with the same errno as an earlier one, or any failure
after a non-ENOMEM error was already recorded. Since a failed
ntfs_bitmap_clear_run() rolls back its partial modifications, no
bits were cleared for that run, yet its length still inflates
vol->free_clusters, corrupting statfs output and the allocator's
free space gate.
Only count runs whose bitmap clear succeeded.
Fixes: 11ccc9107dc4 ("ntfs: update runlist handling and cluster allocator")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/lcnalloc.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index aa2e017a43844..795f71d26895f 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -53,10 +53,10 @@ int ntfs_cluster_free_from_rl_nolock(struct ntfs_volume *vol,
if (rl->lcn < 0)
continue;
err = ntfs_bitmap_clear_run(lcnbmp_vi, rl->lcn, rl->length);
- if (unlikely(err && (!ret || ret == -ENOMEM) && ret != err))
- ret = err;
- else
+ if (likely(!err))
nr_freed += rl->length;
+ else if (!ret || ret == -ENOMEM)
+ ret = err;
}
ntfs_inc_free_clusters(vol, nr_freed);
ntfs_debug("Done.");
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 044/733] ntfs: skip free cluster decrement when rollback fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (42 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 043/733] ntfs: only count successfully cleared runs when freeing clusters Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 045/733] ntfs: do not mark the volume clean in sync_fs when errors were recorded Greg Kroah-Hartman
` (700 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baolin Liu, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit 5f2a22b36fe34c98f6d5e35ddb759ee53d684145 ]
When the rollback in __ntfs_cluster_free() fails, the recursive
call returns a negative errno and the subsequent
ntfs_dec_free_clusters(vol, delta) subtracts that negative value,
adding bogus clusters to the counter on an already-failing volume.
Skip the decrement when the rollback failed.
Fixes: 11ccc9107dc4 ("ntfs: update runlist handling and cluster allocator")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/lcnalloc.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs/lcnalloc.c b/fs/ntfs/lcnalloc.c
index 795f71d26895f..0d6cd08ee2e76 100644
--- a/fs/ntfs/lcnalloc.c
+++ b/fs/ntfs/lcnalloc.c
@@ -1045,8 +1045,9 @@ s64 __ntfs_cluster_free(struct ntfs_inode *ni, const s64 start_vcn, s64 count,
"Failed to rollback (error %i). Leaving inconsistent metadata! Unmount and run chkdsk.",
(int)delta);
NVolSetErrors(vol);
+ } else {
+ ntfs_dec_free_clusters(vol, delta);
}
- ntfs_dec_free_clusters(vol, delta);
up_write(&vol->lcnbmp_lock);
memalloc_nofs_restore(memalloc_flags);
ntfs_error(vol->sb, "Aborting (error %i).", err);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 045/733] ntfs: do not mark the volume clean in sync_fs when errors were recorded
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (43 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 044/733] ntfs: skip free cluster decrement when rollback fails Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 046/733] ntfs: treat any nonzero dio zero-range return as an error Greg Kroah-Hartman
` (699 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dennis Tighe, Hyunchul Lee,
Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dennis Tighe <dennis.tighe@gmail.com>
[ Upstream commit 0e4c839905418d55bafe571a92533a1d1ac7b0a8 ]
ntfs_put_super() and the remount-read-only path both clear the dirty bit
only when NVolErrors(vol) is false. ntfs_sync_fs() clears it
unconditionally, so any sync() on a volume that recorded an error marks
that volume clean. A volume without this set is then seen as not needing
recovery and it does not run one, so whatever went wrong is never repaired.
This change skips resetting the dirty bit when there are volume errors.
Reproduced on a volume whose $MFTMirr does not match $MFT, which sets the
error flag while leaving the mount read-write: after a write and a sync,
the on-disk volume flags read 0x0000 with this driver and 0x0001 with the
guard in place.
Fixes: 6251f0b0de7d ("ntfs: update super block operations")
Assisted-by: claude:claude-opus-5
Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
Reviewed-by: Hyunchul Lee <hyc.lee@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/super.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index cd8fa2c133700..d287140b3fc61 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1862,7 +1862,8 @@ static int ntfs_sync_fs(struct super_block *sb, int wait)
return 0;
/* If there are some dirty buffers in the bdev inode */
- if (ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY)) {
+ if (!NVolErrors(vol) &&
+ ntfs_clear_volume_flags(vol, VOLUME_IS_DIRTY)) {
ntfs_warning(sb, "Failed to clear dirty bit in volume information flags. Run chkdsk.");
err = -EIO;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 046/733] ntfs: treat any nonzero dio zero-range return as an error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (44 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 045/733] ntfs: do not mark the volume clean in sync_fs when errors were recorded Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 047/733] ntfs: bound $AttrDef table walk to the loaded table size Greg Kroah-Hartman
` (698 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wentao Guan, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Guan <guanwentao@uniontech.com>
[ Upstream commit 607a9478833db656e7ceac8e9e382fa4acfde545 ]
ntfs_dio_zero_range() returns either 0 or a negative errno from
blkdev_issue_zeroout(); it never returns a positive value. The
zeroing failure check in ntfs_attr_fallocate() therefore never fired,
so a failed zeroing operation was silently ignored: the loop kept
going, the newly allocated clusters were folded into initialized_size
and the write could succeed leaving stale on-disk data.
Treat any nonzero return as an error and abort the allocation.
Fixes: 495e90fa33482 ("ntfs: update attrib operations")
Assisted-by: atomcode:deepseek-v4-flash
Signed-off-by: Wentao Guan <guanwentao@uniontech.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/attrib.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 950fc1b727cb2..9e41ba97e024d 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -5693,7 +5693,7 @@ int ntfs_attr_fallocate(struct ntfs_inode *ni, loff_t start, loff_t byte_len, bo
lcn << vol->cluster_size_bits,
alloc_cnt <<
vol->cluster_size_bits);
- if (err > 0)
+ if (err)
goto out;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 047/733] ntfs: bound $AttrDef table walk to the loaded table size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (45 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 046/733] ntfs: treat any nonzero dio zero-range return as an error Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 048/733] ntfs: reject invalid sectors_per_cluster in the boot sector Greg Kroah-Hartman
` (697 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Dennis Tighe, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dennis Tighe <dennis.tighe@gmail.com>
[ Upstream commit c8504fc1245f5322af5fa5c325ab05f9cf792b87 ]
ntfs_attr_find_in_attrdef() walks the in-memory $AttrDef table, but the
loop condition bounds only the start of each entry, not the whole entry:
for (ad = vol->attrdef; (u8 *)ad - (u8 *)vol->attrdef <
vol->attrdef_size && ad->type; ++ad)
struct attr_def is 160 bytes; the guard reads ad->type at offset 128 and
the loop body reads further fields. vol->attrdef is kvzalloc(i_size),
where i_size is the on-disk $AttrDef data size, checked in
load_and_init_attrdef() only as 0 < i_size <= 0x7fffffff. A volume whose
$AttrDef data size is smaller than one entry (e.g. 120 bytes) makes the
read of ad->type run past the allocation. Creating a file reaches this
through ntfs_attr_size_bounds_check() and reads out of bounds:
BUG: KASAN: slab-out-of-bounds in ntfs_attr_find_in_attrdef+0x66/0xa0
Read of size 4 at addr ffff888005833280 by task init/1
ntfs_attr_find_in_attrdef
ntfs_attr_size_bounds_check
ntfs_attr_can_be_non_resident
ntfs_attr_add
Require the whole entry to lie within attrdef_size in the loop guard, and
reject at mount a $AttrDef too small to hold one attr_def entry.
Fixes: 1e9ea7e04472 ("Revert "fs: Remove NTFS classic"")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/attrib.c | 4 ++--
fs/ntfs/super.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/fs/ntfs/attrib.c b/fs/ntfs/attrib.c
index 9e41ba97e024d..918ff4db75f73 100644
--- a/fs/ntfs/attrib.c
+++ b/fs/ntfs/attrib.c
@@ -1732,8 +1732,8 @@ static struct attr_def *ntfs_attr_find_in_attrdef(const struct ntfs_volume *vol,
struct attr_def *ad;
WARN_ON(!type);
- for (ad = vol->attrdef; (u8 *)ad - (u8 *)vol->attrdef <
- vol->attrdef_size && ad->type; ++ad) {
+ for (ad = vol->attrdef; (u8 *)ad - (u8 *)vol->attrdef <=
+ vol->attrdef_size - (s32)sizeof(*ad) && ad->type; ++ad) {
/* We have not found it yet, carry on searching. */
if (likely(le32_to_cpu(ad->type) < le32_to_cpu(type)))
continue;
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index d287140b3fc61..242f6f9b5598e 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -1241,9 +1241,9 @@ static bool load_and_init_attrdef(struct ntfs_volume *vol)
goto failed;
}
NInoSetSparseDisabled(NTFS_I(ino));
- /* The size of FILE_AttrDef must be above 0 and fit inside 31 bits. */
+ /* FILE_AttrDef must hold at least one entry and fit inside 31 bits. */
i_size = i_size_read(ino);
- if (i_size <= 0 || i_size > 0x7fffffff)
+ if (i_size < (s64)sizeof(struct attr_def) || i_size > 0x7fffffff)
goto iput_failed;
vol->attrdef = kvzalloc(i_size, GFP_NOFS);
if (!vol->attrdef)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 048/733] ntfs: reject invalid sectors_per_cluster in the boot sector
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (46 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 047/733] ntfs: bound $AttrDef table walk to the loaded table size Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 049/733] bpf: check_cond_jmp_op(): properly infer if register is null Greg Kroah-Hartman
` (696 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Dennis Tighe, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dennis Tighe <dennis.tighe@gmail.com>
[ Upstream commit 323751a604e7533fa473874d999371592a614207 ]
is_boot_sector_ntfs() checks the boot sector's sectors_per_cluster field
with a range test that rejects 0x81..0xf3 but accepts 0 and other
non-power-of-two counts. A zero value reaches parse_ntfs_boot_sector():
sectors_per_cluster_bits = ffs(sectors_per_cluster) - 1;
...
vol->cluster_size = vol->sector_size << sectors_per_cluster_bits;
ffs(0) is 0, so sectors_per_cluster_bits becomes (unsigned)-1 and the
shift is undefined:
UBSAN: shift-out-of-bounds in fs/ntfs/super.c:673:39
shift exponent 4294967295 is too large for 32-bit type 'int'
This change rejects any non-power-of-two value, since it feeds the
aforementioned shift via ffs() - 1, which only yields the correct shift for a
power of two.
Fixes: 6251f0b0de7d ("ntfs: update super block operations")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Dennis Tighe <dennis.tighe@gmail.com>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/super.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/ntfs/super.c b/fs/ntfs/super.c
index 242f6f9b5598e..63aa83ff77f5d 100644
--- a/fs/ntfs/super.c
+++ b/fs/ntfs/super.c
@@ -557,8 +557,8 @@ static bool is_boot_sector_ntfs(const struct super_block *sb,
* Check sectors per cluster value is valid and the cluster size
* is not above the maximum (2MB).
*/
- if (b->bpb.sectors_per_cluster > 0x80 &&
- b->bpb.sectors_per_cluster < 0xf4)
+ if (b->bpb.sectors_per_cluster < 0xf4 &&
+ !is_power_of_2(b->bpb.sectors_per_cluster))
goto not_ntfs;
/* Check reserved/unused fields are really zero. */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 049/733] bpf: check_cond_jmp_op(): properly infer if register is null
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (47 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 048/733] ntfs: reject invalid sectors_per_cluster in the boot sector Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 050/733] ntfs: leave HasEA flag untouched on setxattr failure Greg Kroah-Hartman
` (695 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit d3ef6c097ba078e1f8c7239d76a0ce8b61e75095 ]
Nicholas Carlini reported a bug when verifier can incorrectly infer
that a pointer is non-null. The bug occurs when two pointers are
compared and one of them has a type w/o PTR_MAYBE_NULL flag,
but which allows a value to be NULL at runtime.
Here is an example:
// `a` is PTR_TO_MEM | MEM_RDONLY | PTR_UNTRUSTED
// `a` is 0 at runtime.
// `b` is PTR_TO_MAP_VALUE | PTR_MAYBE_NULL
void *a = bpf_rdonly_cast(0, 0);
int *b = bpf_map_lookup_elem(...);
if (a == b)
*b = 42; // verifier does not catch null pointer dereference
This happens because of a special case in check_cond_jmp_op(),
which attempts to strip PTR_MAYBE_NULL flags from pointer types,
when processing comparisons like `rA == rB`, if either rA or rB can't
be null.
The non-null property is derived based on the absence of
PTR_MAYBE_NULL flag on rA's or rB's type. But that is not sufficient
for types like PTR_TO_MEM, as in the example.
This patch replaces type_may_be_null() call with reg_not_null(),
which contains an allowlist of types for which absence of
PTR_MAYBE_NULL actually means that the value can't be NULL at runtime.
At the moment, the list in the reg_not_null() omits two types for
which PTR_MAYBE_NULL is applicable: PTR_TO_XDP_SOCK and PTR_TO_BUF.
In order to remain backward compatible, and assuming that only
comparison between pointers of the same type makes sense,
this commit extends reg_not_null(). W/o such an extension e.g.
verifier_jeq_infer_not_null/null_ptr_to_map_value fails.
reg_not_null() can be extended further, but I deem that out of scope
for the fix at hand. Explicit base_type(...) != PTR_TO_BTF_ID
checks in the check_cond_jmp_op() can be removed with migration to
reg_not_null(), but that is a behavioural change, as the special case
would start matching for PTR_TO_BTF_ID that is also is_trusted_reg().
I omit the behavioural change from this commit.
Fixes: befae75856ab ("bpf: propagate nullness information for reg to reg comparisons")
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260826-bug-029-bad-non-null-inference-v2-1-136789ace9e9@localhost
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 03187bab806a7..59f12ba70eb6e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -370,6 +370,8 @@ static bool reg_not_null(struct bpf_verifier_env *env, const struct bpf_reg_stat
type = base_type(type);
return type == PTR_TO_SOCKET ||
type == PTR_TO_TCP_SOCK ||
+ type == PTR_TO_XDP_SOCK ||
+ type == PTR_TO_BUF ||
type == PTR_TO_MAP_VALUE ||
type == PTR_TO_MAP_KEY ||
type == PTR_TO_SOCK_COMMON ||
@@ -16173,7 +16175,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
*/
if (!is_jmp32 && BPF_SRC(insn->code) == BPF_X &&
__is_pointer_value(false, src_reg) && __is_pointer_value(false, dst_reg) &&
- type_may_be_null(src_reg->type) != type_may_be_null(dst_reg->type) &&
base_type(src_reg->type) != PTR_TO_BTF_ID &&
base_type(dst_reg->type) != PTR_TO_BTF_ID) {
eq_branch_regs = NULL;
@@ -16189,9 +16190,11 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
break;
}
if (eq_branch_regs) {
- if (type_may_be_null(src_reg->type))
+ /* src == dst && dst != NULL => src != NULL */
+ if (reg_not_null(env, dst_reg) && type_may_be_null(src_reg->type))
mark_ptr_not_null_reg(&eq_branch_regs[insn->src_reg]);
- else
+ /* src == dst && src != NULL => dst != NULL */
+ if (reg_not_null(env, src_reg) && type_may_be_null(dst_reg->type))
mark_ptr_not_null_reg(&eq_branch_regs[insn->dst_reg]);
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 050/733] ntfs: leave HasEA flag untouched on setxattr failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (48 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 049/733] bpf: check_cond_jmp_op(): properly infer if register is null Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:05 ` [PATCH 7.2 051/733] bpf: dont downgrade half-dead scalar zero spills to STACK_ZERO Greg Kroah-Hartman
` (694 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Baolin Liu, Namjae Jeon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baolin Liu <liubaolin@kylinos.cn>
[ Upstream commit ac727d86fb84bdc9626ba9c756c26767459f3083 ]
In ntfs_set_ea(), the exit path unconditionally updates the HasEA
flag based on ea_info_qsize. When an error occurs before
ea_info_qsize is updated, NInoClearHasEA() hides existing on-disk
EAs until the inode is evicted.
Only update the flag on success.
Fixes: fc053f05ca28 ("ntfs: add reparse and ea operations")
Signed-off-by: Baolin Liu <liubaolin@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/ntfs/ea.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
diff --git a/fs/ntfs/ea.c b/fs/ntfs/ea.c
index 08c35f9751114..75a251ec4ebcb 100644
--- a/fs/ntfs/ea.c
+++ b/fs/ntfs/ea.c
@@ -390,10 +390,12 @@ static int ntfs_set_ea(struct inode *inode, const char *name, size_t name_len,
*packed_ea_size = p_ea_info->ea_length;
mark_mft_record_dirty(ni);
out:
- if (ea_info_qsize > 0)
- NInoSetHasEA(ni);
- else
- NInoClearHasEA(ni);
+ if (!err) {
+ if (ea_info_qsize > 0)
+ NInoSetHasEA(ni);
+ else
+ NInoClearHasEA(ni);
+ }
kvfree(ea_buf);
kvfree(old_ea_buf);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 051/733] bpf: dont downgrade half-dead scalar zero spills to STACK_ZERO
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (49 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 050/733] ntfs: leave HasEA flag untouched on setxattr failure Greg Kroah-Hartman
@ 2026-09-17 15:05 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 052/733] net: icmp: avoid invalid transport header access in icmp_send tracepoint Greg Kroah-Hartman
` (693 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:05 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 2f3536bff8823d3c5fdbbe15e17bfca696cc2b2e ]
states.c:__clean_func_state() can downgrade scalar zero spill to
STACK_ZERO in the following case:
*(u64 *)(r10 - 8) = 0;
... checkpoint ...
r1 = *(u32 *)(r10 - 4);
... no reads from r10-8 ...
Here 4 bytes at r10-8 are dead and verifier changes scalar spill to a
combination: 0000pppp (p stands for poison). Such a change breaks
precision propagation chains. All places that produce STACK_ZERO
should call bpf_mark_chain_precision() for the zero source.
This patch fixes the bug in a simplest way possible:
avoids converting stack spills of zero to STACK_ZERO.
Two smarter approaches are possible:
- do bpf_mark_chain_precision() from __clean_func_state()
- check slot liveness information in check_stack_write_fixed_off()
I investigated both and the changes required are a bit tricky,
hence go with a simple fix for the time being.
Fixes: be23266b4a08 ("bpf: 4-byte precise clean_verifier_state")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260827-bug-011-cleanfunc-stack-zero-simple-v1-v1-1-c0e996589a52@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/states.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/kernel/bpf/states.c b/kernel/bpf/states.c
index 4e6aafad33bd2..66fb11b6c6a76 100644
--- a/kernel/bpf/states.c
+++ b/kernel/bpf/states.c
@@ -445,22 +445,19 @@ static void __clean_func_state(struct bpf_verifier_env *env,
struct bpf_reg_state *spill = &st->stack[i].spilled_ptr;
if (lo_live && stype == STACK_SPILL) {
- u8 val = STACK_MISC;
-
if (spill->type != SCALAR_VALUE)
continue;
-
/*
- * 8 byte spill of scalar 0 where half slot is dead
- * should become STACK_ZERO in lo 4 bytes.
+ * Can't replace with STACK_ZERO, because
+ * that requires bpf_mark_chain_precision().
*/
if (bpf_register_is_null(spill))
- val = STACK_ZERO;
+ continue;
for (j = 0; j < 4; j++) {
u8 *t = &st->stack[i].slot_type[j];
if (*t == STACK_SPILL)
- *t = val;
+ *t = STACK_MISC;
}
}
bpf_mark_reg_not_init(env, spill);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 052/733] net: icmp: avoid invalid transport header access in icmp_send tracepoint
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (50 preceding siblings ...)
2026-09-17 15:05 ` [PATCH 7.2 051/733] bpf: dont downgrade half-dead scalar zero spills to STACK_ZERO Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 053/733] tcp: use GFP_ATOMIC in tcp_send_active_reset() Greg Kroah-Hartman
` (692 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6d2762674103618994b0,
Eric Dumazet, Peilin He, xu xin, Steven Rostedt, Jiayuan Chen,
David Ahern, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 7fcc2fe39fed1cb98a7374a113ff3800e8f9af80 ]
syzbot reported a WARNING triggered by DEBUG_NET_WARN_ON_ONCE():
WARNING: at skb_transport_header include/linux/skbuff.h:3087 [inline]
WARNING: at udp_hdr include/linux/udp.h:23 [inline]
WARNING: at do_trace_event_raw_event_icmp_send include/trace/events/icmp.h:30 [inline]
WARNING: at trace_event_raw_event_icmp_send+0x48c/0x6ec include/trace/events/icmp.h:11
Call trace:
skb_transport_header include/linux/skbuff.h:3087 [inline]
udp_hdr include/linux/udp.h:23 [inline]
do_trace_event_raw_event_icmp_send include/trace/events/icmp.h:30 [inline]
trace_event_raw_event_icmp_send+0x48c/0x6ec include/trace/events/icmp.h:11
__traceiter_icmp_send include/trace/events/icmp.h:11 [inline]
__do_trace_icmp_send include/trace/events/icmp.h:11 [inline]
trace_icmp_send+0x320/0x49c include/trace/events/icmp.h:11
__icmp_send+0xcfc/0x11d8 net/ipv4/icmp.c:1013
ipv4_send_dest_unreach net/ipv4/route.c:1280 [inline]
ipv4_link_failure+0x57c/0x8dc net/ipv4/route.c:1287
dst_link_failure include/net/dst.h:438 [inline]
vti_tunnel_xmit+0xe40/0x17a4 net/ipv4/ip_vti.c:307
TP_fast_assign() unconditionally calls udp_hdr(skb) before checking
whether the packet is UDP. Furthermore, __icmp_send() can be invoked
from paths (e.g., link failures, ARP errors, forwarding, AF_PACKET)
where skb->transport_header was never initialized (~0U).
Under CONFIG_DEBUG_NET=y, calling skb_transport_header(skb) triggers
DEBUG_NET_WARN_ON_ONCE(!skb_transport_header_was_set(skb)).
Fix this by:
1. Only parsing transport info when iph->protocol == IPPROTO_UDP.
2. Using skb_header_pointer() at skb_network_offset(skb) + (iph->ihl << 2)
to safely fetch the UDP header without assuming transport_header is set.
Fixes: db3efdcf70c7 ("net/ipv4: add tracepoint for icmp_send")
Reported-by: syzbot+6d2762674103618994b0@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a8d5538.91706f20.ef82.0009.GAE@google.com/T/#u
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Peilin He <he.peilin@zte.com.cn>
Cc: xu xin <xu.xin16@zte.com.cn>
Cc: Steven Rostedt <rostedt@goodmis.org>
Reviewed-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Reviewed-by: David Ahern <dsahern@kernel.org>
Link: https://patch.msgid.link/20260825084551.1562967-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/trace/events/icmp.h | 13 ++++++++-----
1 file changed, 8 insertions(+), 5 deletions(-)
diff --git a/include/trace/events/icmp.h b/include/trace/events/icmp.h
index 31559796949a7..acfcf2b132d60 100644
--- a/include/trace/events/icmp.h
+++ b/include/trace/events/icmp.h
@@ -27,17 +27,20 @@ TRACE_EVENT(icmp_send,
TP_fast_assign(
struct iphdr *iph = ip_hdr(skb);
- struct udphdr *uh = udp_hdr(skb);
- int proto_4 = iph->protocol;
+ struct udphdr _uh, *uh = NULL;
__be32 *p32;
__entry->skbaddr = skb;
__entry->type = type;
__entry->code = code;
- if (proto_4 != IPPROTO_UDP || (u8 *)uh < skb->head ||
- (u8 *)uh + sizeof(struct udphdr)
- > skb_tail_pointer(skb)) {
+ if (iph->protocol == IPPROTO_UDP)
+ uh = skb_header_pointer(skb,
+ skb_network_offset(skb) +
+ (iph->ihl << 2),
+ sizeof(_uh), &_uh);
+
+ if (!uh) {
__entry->sport = 0;
__entry->dport = 0;
__entry->ulen = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 053/733] tcp: use GFP_ATOMIC in tcp_send_active_reset()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (51 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 052/733] net: icmp: avoid invalid transport header access in icmp_send tracepoint Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 054/733] net: stmmac: fix dma mapping leak in stmmac_tso_xmit() Greg Kroah-Hartman
` (691 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 18666c73afe95eeca8707c699b63f96ce3acda42 ]
tcp_send_active_reset() can be called from contexts where gfp_any()
(in tcp_disconnect()) or sk->sk_allocation (in __tcp_close() and
mptcp_do_fastclose()) evaluates to GFP_KERNEL, which includes
__GFP_FS and __GFP_DIRECT_RECLAIM.
Allocating with GFP_KERNEL while holding the socket lock (sk_lock) creates
a lockdep dependency:
sk_lock -> fs_reclaim
This causes false-positive lockdep circular locking warnings with storage
subsystems (such as nvme-tcp) that acquire socket locks in block I/O paths
and invoke tcp_disconnect() or close sockets upon teardown:
set->srcu -> sk_lock -> fs_reclaim -> elevator_lock -> set->srcu
Active resets are small RST packet headers that should never
enter direct reclaim or block while holding socket locks.
Use sk_gfp_mask(sk, GFP_ATOMIC | __GFP_NOWARN) inside tcp_send_active_reset()
and remove its priority argument. This preserves __GFP_MEMALLOC access
for SOCK_MEMALLOC sockets, suppresses allocation failure warnings,
and aligns with other control packet allocations (e.g. tcp_send_fin(),
__tcp_send_ack(), tcp_xmit_probe_skb()).
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260827095936.551524-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/tcp.h | 3 +--
net/ipv4/tcp.c | 14 ++++++--------
net/ipv4/tcp_output.c | 4 ++--
net/ipv4/tcp_timer.c | 6 +++---
net/mptcp/protocol.c | 3 +--
net/mptcp/protocol.h | 2 +-
6 files changed, 14 insertions(+), 18 deletions(-)
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 670c20876f265..436495ff2271d 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -765,8 +765,7 @@ int tcp_fragment(struct sock *sk, enum tcp_queue tcp_queue,
void tcp_send_probe0(struct sock *);
int tcp_write_wakeup(struct sock *, int mib);
void tcp_send_fin(struct sock *sk);
-void tcp_send_active_reset(struct sock *sk, gfp_t priority,
- enum sk_rst_reason reason);
+void tcp_send_active_reset(struct sock *sk, enum sk_rst_reason reason);
int tcp_send_synack(struct sock *);
void tcp_push_one(struct sock *, unsigned int mss_now);
void __tcp_send_ack(struct sock *sk, u32 rcv_nxt, u16 flags);
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 10f58281be17b..47a34a993972a 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -3181,8 +3181,7 @@ void __tcp_close(struct sock *sk, long timeout)
/* Unread data was tossed, zap the connection. */
NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONCLOSE);
tcp_set_state(sk, TCP_CLOSE);
- tcp_send_active_reset(sk, sk->sk_allocation,
- SK_RST_REASON_TCP_ABORT_ON_CLOSE);
+ tcp_send_active_reset(sk, SK_RST_REASON_TCP_ABORT_ON_CLOSE);
} else if (sock_flag(sk, SOCK_LINGER) && !sk->sk_lingertime) {
/* Check zero linger _after_ checking for unread data. */
sk->sk_prot->disconnect(sk, 0);
@@ -3256,7 +3255,7 @@ void __tcp_close(struct sock *sk, long timeout)
struct tcp_sock *tp = tcp_sk(sk);
if (READ_ONCE(tp->linger2) < 0) {
tcp_set_state(sk, TCP_CLOSE);
- tcp_send_active_reset(sk, GFP_ATOMIC,
+ tcp_send_active_reset(sk,
SK_RST_REASON_TCP_ABORT_ON_LINGER);
__NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPABORTONLINGER);
@@ -3275,7 +3274,7 @@ void __tcp_close(struct sock *sk, long timeout)
if (sk->sk_state != TCP_CLOSE) {
if (tcp_check_oom(sk, 0)) {
tcp_set_state(sk, TCP_CLOSE);
- tcp_send_active_reset(sk, GFP_ATOMIC,
+ tcp_send_active_reset(sk,
SK_RST_REASON_TCP_ABORT_ON_MEMORY);
__NET_INC_STATS(sock_net(sk),
LINUX_MIB_TCPABORTONMEMORY);
@@ -3376,14 +3375,14 @@ int tcp_disconnect(struct sock *sk, int flags)
} else if (unlikely(tp->repair)) {
WRITE_ONCE(sk->sk_err, ECONNABORTED);
} else if (tcp_need_reset(old_state)) {
- tcp_send_active_reset(sk, gfp_any(), SK_RST_REASON_TCP_STATE);
+ tcp_send_active_reset(sk, SK_RST_REASON_TCP_STATE);
WRITE_ONCE(sk->sk_err, ECONNRESET);
} else if (tp->snd_nxt != tp->write_seq &&
(1 << old_state) & (TCPF_CLOSING | TCPF_LAST_ACK)) {
/* The last check adjusts for discrepancy of Linux wrt. RFC
* states
*/
- tcp_send_active_reset(sk, gfp_any(),
+ tcp_send_active_reset(sk,
SK_RST_REASON_TCP_DISCONNECT_WITH_DATA);
WRITE_ONCE(sk->sk_err, ECONNRESET);
} else if (old_state == TCP_SYN_SENT)
@@ -5146,8 +5145,7 @@ int tcp_abort(struct sock *sk, int err)
bh_lock_sock(sk);
if (tcp_need_reset(sk->sk_state))
- tcp_send_active_reset(sk, GFP_ATOMIC,
- SK_RST_REASON_TCP_STATE);
+ tcp_send_active_reset(sk, SK_RST_REASON_TCP_STATE);
tcp_done_with_error(sk, err);
bh_unlock_sock(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 8d243e91761a9..f72a6b1fe749b 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -3849,9 +3849,9 @@ void tcp_send_fin(struct sock *sk)
* was unread data in the receive queue. This behavior is recommended
* by RFC 2525, section 2.17. -DaveM
*/
-void tcp_send_active_reset(struct sock *sk, gfp_t priority,
- enum sk_rst_reason reason)
+void tcp_send_active_reset(struct sock *sk, enum sk_rst_reason reason)
{
+ gfp_t priority = sk_gfp_mask(sk, GFP_ATOMIC | __GFP_NOWARN);
struct sk_buff *skb;
TCP_INC_STATS(sock_net(sk), TCP_MIB_OUTRSTS);
diff --git a/net/ipv4/tcp_timer.c b/net/ipv4/tcp_timer.c
index 4df1c9745c5d5..95296b1cf0ca2 100644
--- a/net/ipv4/tcp_timer.c
+++ b/net/ipv4/tcp_timer.c
@@ -126,7 +126,7 @@ static int tcp_out_of_resources(struct sock *sk, bool do_reset)
(!tp->snd_wnd && !tp->packets_out))
do_reset = true;
if (do_reset)
- tcp_send_active_reset(sk, GFP_ATOMIC,
+ tcp_send_active_reset(sk,
SK_RST_REASON_TCP_ABORT_ON_MEMORY);
tcp_done(sk);
__NET_INC_STATS(sock_net(sk), LINUX_MIB_TCPABORTONMEMORY);
@@ -809,7 +809,7 @@ static void tcp_keepalive_timer(struct timer_list *t)
goto out;
}
}
- tcp_send_active_reset(sk, GFP_ATOMIC, SK_RST_REASON_TCP_STATE);
+ tcp_send_active_reset(sk, SK_RST_REASON_TCP_STATE);
goto death;
}
@@ -836,7 +836,7 @@ static void tcp_keepalive_timer(struct timer_list *t)
icsk->icsk_probes_out > 0) ||
(user_timeout == 0 &&
icsk->icsk_probes_out >= keepalive_probes(tp))) {
- tcp_send_active_reset(sk, GFP_ATOMIC,
+ tcp_send_active_reset(sk,
SK_RST_REASON_TCP_KEEPALIVE_TIMEOUT);
tcp_write_err(sk);
goto out;
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 7c8180d8d5eff..8adf699894e32 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -2985,8 +2985,7 @@ static void mptcp_do_fastclose(struct sock *sk)
*/
inet_csk(ssk)->icsk_ack.rcv_mss = TCP_MIN_MSS;
- tcp_send_active_reset(ssk, ssk->sk_allocation,
- SK_RST_REASON_TCP_ABORT_ON_CLOSE);
+ tcp_send_active_reset(ssk, SK_RST_REASON_TCP_ABORT_ON_CLOSE);
unlock:
release_sock(ssk);
}
diff --git a/net/mptcp/protocol.h b/net/mptcp/protocol.h
index 1b80f2d6ec5a2..32b771e658500 100644
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -687,7 +687,7 @@ mptcp_send_active_reset_reason(struct sock *sk)
enum sk_rst_reason reason;
reason = sk_rst_convert_mptcp_reason(subflow->reset_reason);
- tcp_send_active_reset(sk, GFP_ATOMIC, reason);
+ tcp_send_active_reset(sk, reason);
}
/* Made the fwd mem carried by the given skb available to the msk,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 054/733] net: stmmac: fix dma mapping leak in stmmac_tso_xmit()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (52 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 053/733] tcp: use GFP_ATOMIC in tcp_send_active_reset() Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 055/733] net: iptunnel: fix stale transport header during tunnel decapsulation Greg Kroah-Hartman
` (690 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit a5d946466a95621fa2769720d59ea336003aa1a5 ]
In stmmac_tso_xmit(), if the DMA mapping of an skb fragment fails, the
frame is dropped but the DMA mappings already created for the linear
part and for the fragments mapped before the failure are never
unmapped, leaking DMA mappings.
Fix the leak by walking back over the descriptors used by the frame and
releasing each of them with stmmac_free_tx_buffer(). Moreover, release
the descriptors with stmmac_release_tx_desc() unmapping the DMA buffers.
Fixes: f748be531d70 ("stmmac: support new GMAC4")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260826-stmmac_dma_unmap_tso-v1-1-a2753d1576ba@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 53 ++++++++++++-------
1 file changed, 34 insertions(+), 19 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 3a437409f78ae..1946361081fc2 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4319,6 +4319,7 @@ static bool stmmac_vlan_insert(struct stmmac_priv *priv, struct sk_buff *skb,
/**
* stmmac_tso_allocator - close entry point of the driver
* @priv: driver private structure
+ * @entry: TX queue buffer index
* @des: buffer start address
* @total_len: total length to fill in descriptors
* @last_segment: condition for the last descriptor
@@ -4327,8 +4328,9 @@ static bool stmmac_vlan_insert(struct stmmac_priv *priv, struct sk_buff *skb,
* This function fills descriptor and request new descriptors according to
* buffer length to fill
*/
-static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
- int total_len, bool last_segment, u32 queue)
+static void stmmac_tso_allocator(struct stmmac_priv *priv, u32 *entry,
+ dma_addr_t des, int total_len,
+ bool last_segment, u32 queue)
{
struct stmmac_tx_queue *tx_q = &priv->dma_conf.tx_queue[queue];
struct dma_desc *desc;
@@ -4340,14 +4342,13 @@ static void stmmac_tso_allocator(struct stmmac_priv *priv, dma_addr_t des,
while (tmp_len > 0) {
dma_addr_t curr_addr;
- tx_q->cur_tx = STMMAC_NEXT_ENTRY(tx_q->cur_tx,
- priv->dma_conf.dma_tx_size);
- WARN_ON(tx_q->tx_skbuff[tx_q->cur_tx]);
+ *entry = STMMAC_NEXT_ENTRY(*entry, priv->dma_conf.dma_tx_size);
+ WARN_ON(tx_q->tx_skbuff[*entry]);
if (tx_q->tbs & STMMAC_TBS_AVAIL)
- desc = &tx_q->dma_entx[tx_q->cur_tx].basic;
+ desc = &tx_q->dma_entx[*entry].basic;
else
- desc = &tx_q->dma_tx[tx_q->cur_tx];
+ desc = &tx_q->dma_tx[*entry];
curr_addr = des + (total_len - tmp_len);
stmmac_set_desc_addr(priv, desc, curr_addr);
@@ -4486,7 +4487,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct dma_desc *desc, *first, *mss_desc = NULL;
struct stmmac_priv *priv = netdev_priv(dev);
- unsigned int first_entry, tx_packets;
+ unsigned int first_entry, entry, tx_packets;
struct stmmac_txq_stats *txq_stats;
struct stmmac_tx_queue *tx_q;
bool set_ic, is_last_segment;
@@ -4549,22 +4550,24 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
}
first_entry = tx_q->cur_tx;
- WARN_ON(tx_q->tx_skbuff[first_entry]);
+ entry = first_entry;
+
+ WARN_ON(tx_q->tx_skbuff[entry]);
if (tx_q->tbs & STMMAC_TBS_AVAIL)
- desc = &tx_q->dma_entx[first_entry].basic;
+ desc = &tx_q->dma_entx[entry].basic;
else
- desc = &tx_q->dma_tx[first_entry];
+ desc = &tx_q->dma_tx[entry];
first = desc;
/* first descriptor: fill Headers on Buf1 */
des = dma_map_single(priv->device, skb->data, skb_headlen(skb),
DMA_TO_DEVICE);
if (dma_mapping_error(priv->device, des))
- goto dma_map_err;
+ goto error;
stmmac_set_desc_addr(priv, first, des);
- stmmac_tso_allocator(priv, des + proto_hdr_len, pay_len,
+ stmmac_tso_allocator(priv, &entry, des + proto_hdr_len, pay_len,
(nfrags == 0), queue);
/* In case two or more DMA transmit descriptors are allocated for this
@@ -4579,8 +4582,7 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
* this DMA buffer right after the DMA engine completely finishes the
* full buffer transmission.
*/
- stmmac_set_tx_skb_dma_entry(tx_q, tx_q->cur_tx, des, skb_headlen(skb),
- false);
+ stmmac_set_tx_skb_dma_entry(tx_q, entry, des, skb_headlen(skb), false);
/* Prepare fragments */
for (i = 0; i < nfrags; i++) {
@@ -4590,14 +4592,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
skb_frag_size(frag),
DMA_TO_DEVICE);
if (dma_mapping_error(priv->device, des))
- goto dma_map_err;
+ goto error_dma_unmap;
- stmmac_tso_allocator(priv, des, skb_frag_size(frag),
+ stmmac_tso_allocator(priv, &entry, des, skb_frag_size(frag),
(i == nfrags - 1), queue);
- stmmac_set_tx_skb_dma_entry(tx_q, tx_q->cur_tx, des,
+ stmmac_set_tx_skb_dma_entry(tx_q, entry, des,
skb_frag_size(frag), true);
}
+ tx_q->cur_tx = entry;
stmmac_set_tx_dma_last_segment(tx_q, tx_q->cur_tx);
@@ -4700,7 +4703,19 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_OK;
-dma_map_err:
+error_dma_unmap:
+ for (;;) {
+ desc = stmmac_get_tx_desc(priv, tx_q, first_entry);
+ stmmac_release_tx_desc(priv, desc, priv->descriptor_mode);
+ stmmac_free_tx_buffer(priv, &priv->dma_conf, queue,
+ first_entry);
+ if (first_entry == entry)
+ break;
+
+ first_entry = STMMAC_NEXT_ENTRY(first_entry,
+ priv->dma_conf.dma_tx_size);
+ }
+error:
dev_err(priv->device, "Tx dma map failed\n");
dev_kfree_skb(skb);
priv->xstats.tx_dropped++;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 055/733] net: iptunnel: fix stale transport header during tunnel decapsulation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (53 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 054/733] net: stmmac: fix dma mapping leak in stmmac_tso_xmit() Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 056/733] net/sched: act_api: budget all shared attributes in notify skbs Greg Kroah-Hartman
` (689 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+83181a31faf9455499c5,
Eric Dumazet, Dong Chenchen, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dong Chenchen <dongchenchen2@huawei.com>
[ Upstream commit 28a57fb2c5df4deb42a06e52fd36c14b37aa0034 ]
Syzbot reported a crash in qdisc_pkt_len_segs_init() caused by a stale
transport_header offset after tunnel decapsulation.
BUG: unable to handle page fault for address: ffffed102091a42e
Oops: Oops: 0000 [#1] SMP KASAN NOPTI
CPU: 0 UID: 0 PID: 340 Comm: qdisc_uaf_repro Not tainted 7.2.0-rc4-00061-g248951ddc14d #256 PREEMPT(full)
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
RIP: 0010:__asan_load2
<IRQ>
qdisc_pkt_len_segs_init (net/core/dev.c:4145)
__dev_queue_xmit (net/core/dev.c:4787)
br_dev_queue_push_xmit (net/bridge/br_forward.c:53)
br_handle_frame_finish (net/bridge/br_input.c:229)
br_handle_frame (net/bridge/br_input.c:315)
__netif_receive_skb_core.constprop.0 (net/core/dev.c:6099)
__netif_receive_skb_list_core (net/core/dev.c:6287)
netif_receive_skb_list_internal (net/core/dev.c:6445)
napi_complete_done (net/core/dev.c:6813)
gro_cell_poll (net/core/gro_cells.c:74)
__napi_poll (net/core/dev.c:7735)
net_rx_action (net/core/dev.c:7798 net/core/dev.c:7955)
handle_softirqs (kernel/softirq.c:622)
do_softirq (kernel/softirq.c:523 kernel/softirq.c:510 )
__local_bh_enable_ip (kernel/softirq.c:450)
tun_get_user (drivers/net/tun.c:1986 (discriminator 1))
tun_chr_write_iter (drivers/net/tun.c:2032)
The issue is completely latent until qdisc read transport header in
commit 7fb4c1967011 ("net: pull headers in qdisc_pkt_len_segs_init()").
The crash requires four conditions to line up:
1. The incoming packet is encapsulated and carries GSO metadata. The outer
transport header offset is stored in skb->transport_header while the
packet is still in the outer tunnel context.
2. The tunnel receiver strips the outer headers. skb->data is advanced to
the inner frame, but skb->transport_header is left pointing to the
now-removed outer L4 header, so it becomes a negative offset relative to
the new data.
3. The inner frame is not delivered to the local IP stack. Instead, it
is forwarded at L2 by a bridge or HSR, so ip_rcv_core() never runs and
the transport header is not reset to the inner L4 offset.
4. The forwarding path calls __dev_queue_xmit(), which enters
qdisc_pkt_len_segs_init(). That function computes the GSO header length
from skb_transport_offset(skb). Because the offset is negative, the
unsigned cast overflows and pskb_may_pull(skb, hdr_len +
sizeof(struct tcphdr)) reads past the end of the skb, triggering a
KASAN fault or page fault.
The issue specifically requires GSO packets (shinfo->gso_size != 0), which
are processed/aggregated through gro_cells. Fix this by clearing
transport_header to the ~0U sentinel in gro_cell for all tunnnel driver.
GTP does not support GRO/GSO, drop the evil GSO packets in GTP directly.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+83181a31faf9455499c5@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/69de2bee.a00a0220.475f0.0041.GAE@google.com/T/
Suggested-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Dong Chenchen <dongchenchen2@huawei.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260825123909.1463121-1-dongchenchen2@huawei.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/gtp.c | 5 +++++
include/linux/skbuff.h | 5 +++++
net/core/gro_cells.c | 2 ++
3 files changed, 12 insertions(+)
diff --git a/drivers/net/gtp.c b/drivers/net/gtp.c
index 298efc76a56b0..69fe5717846b5 100644
--- a/drivers/net/gtp.c
+++ b/drivers/net/gtp.c
@@ -318,6 +318,11 @@ static int gtp_inner_proto(struct sk_buff *skb, unsigned int hdrlen,
static int gtp_rx(struct pdp_ctx *pctx, struct sk_buff *skb,
unsigned int hdrlen, unsigned int role, __u16 inner_proto)
{
+ if (skb_is_gso(skb)) {
+ netdev_dbg(pctx->dev, "GSO is not supported in GTP\n");
+ goto err;
+ }
+
if (!gtp_check_ms(skb, pctx, hdrlen, role, inner_proto)) {
netdev_dbg(pctx->dev, "No PDP ctx for this MS\n");
return 1;
diff --git a/include/linux/skbuff.h b/include/linux/skbuff.h
index ed6a2bc23db51..f7dd3db9459c6 100644
--- a/include/linux/skbuff.h
+++ b/include/linux/skbuff.h
@@ -3082,6 +3082,11 @@ static inline bool skb_transport_header_was_set(const struct sk_buff *skb)
return skb->transport_header != (typeof(skb->transport_header))~0U;
}
+static inline void skb_unset_transport_header(struct sk_buff *skb)
+{
+ skb->transport_header = (typeof(skb->transport_header))~0U;
+}
+
static inline unsigned char *skb_transport_header(const struct sk_buff *skb)
{
DEBUG_NET_WARN_ON_ONCE(!skb_transport_header_was_set(skb));
diff --git a/net/core/gro_cells.c b/net/core/gro_cells.c
index 1b84385c04bd9..d8c0a28671201 100644
--- a/net/core/gro_cells.c
+++ b/net/core/gro_cells.c
@@ -22,6 +22,8 @@ int gro_cells_receive(struct gro_cells *gcells, struct sk_buff *skb)
if (unlikely(!(dev->flags & IFF_UP)))
goto drop;
+ skb_unset_transport_header(skb);
+
if (!gcells->cells || skb_cloned(skb) || netif_elide_gro(dev)) {
res = netif_rx(skb);
goto unlock;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 056/733] net/sched: act_api: budget all shared attributes in notify skbs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (54 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 055/733] net: iptunnel: fix stale transport header during tunnel decapsulation Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 057/733] net/sched: act_api: size the RTM_GETACTION reply from the actions Greg Kroah-Hartman
` (688 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jamal Hadi Salim,
Victor Nogueira, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit 13eb543cebef6d6c3ec42e31afe3856f51b7126b ]
tcf_action_shared_attrs_size() is supposed to return an upper bound on the
netlink attributes every action dump emits outside of TCA_ACT_OPTIONS, so
that tcf_add_notify_msg(), tcf_del_notify_msg() and friends can allocate
an skb large enough for the reply. It has fallen behind the dump path and
is now an underestimate for every single action.
Attributes, such as, TCA_ACT_IN_HW_COUNT and TCA_STATS_BASIC_HW are
emitted unconditionally and never accounted for. TCA_STATS_PKT64,
TCA_ACT_USED_HW_STATS, TCA_STATS_RATE_EST, TCA_STATS_RATE_EST64 require
specific conditions, but are also not accounted for.
Fix the issue by budgeting all of them so that we have a legitimate
upper bound. Even tough for of them require specific conditions, they
are cheap so, to avoid overcomplicating, we opted to account for them
unconditionally as well to account for a real worst case scenario.
Fixes: 4e76e75d6aba ("net sched actions: calculate add/delete event message size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260810164357.1653956-1-victor%40mojatatu.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/20260824153903.4143642-2-victor@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_api.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index b4415d358c911..766162b0b8102 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -443,12 +443,21 @@ static size_t tcf_action_shared_attrs_size(const struct tc_action *act)
+ nla_total_size(IFNAMSIZ) /* TCA_ACT_KIND */
+ cookie_len /* TCA_ACT_COOKIE */
+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_HW_STATS */
+ /* TCA_ACT_USED_HW_STATS */
+ + nla_total_size(sizeof(struct nla_bitfield32))
+ + nla_total_size(sizeof(u32)) /* TCA_ACT_IN_HW_COUNT */
+ nla_total_size(0) /* TCA_ACT_STATS nested */
+ nla_total_size(sizeof(struct nla_bitfield32)) /* TCA_ACT_FLAGS */
/* TCA_STATS_BASIC */
+ nla_total_size_64bit(sizeof(struct gnet_stats_basic))
- /* TCA_STATS_PKT64 */
- + nla_total_size_64bit(sizeof(u64))
+ /* TCA_STATS_BASIC_HW */
+ + nla_total_size_64bit(sizeof(struct gnet_stats_basic))
+ /* TCA_STATS_PKT64, emitted by both of the basic copies above */
+ + 2 * nla_total_size_64bit(sizeof(u64))
+ /* TCA_STATS_RATE_EST */
+ + nla_total_size_64bit(sizeof(struct gnet_stats_rate_est))
+ /* TCA_STATS_RATE_EST64 */
+ + nla_total_size_64bit(sizeof(struct gnet_stats_rate_est64))
/* TCA_STATS_QUEUE */
+ nla_total_size_64bit(sizeof(struct gnet_stats_queue))
+ nla_total_size(0) /* TCA_ACT_OPTIONS nested */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 057/733] net/sched: act_api: size the RTM_GETACTION reply from the actions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (55 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 056/733] net/sched: act_api: budget all shared attributes in notify skbs Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 058/733] net/sched: act_api: fix skb sizing and action leak on reoffload delete Greg Kroah-Hartman
` (687 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jamal Hadi Salim,
Victor Nogueira, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit e9ca46ebc3262b498626c4095826b8fa034bbf21 ]
tca_action_gd() already walks every requested action and accumulates
attr_size += tcf_action_fill_size(act), then wraps the result in
tcf_action_full_attrs_size(). For RTM_DELACTION that value is handed to
tcf_del_notify_msg(), which allocates max(attr_size, NLMSG_GOODSIZE). For
RTM_GETACTION it is silently discarded and tcf_get_notify() allocates a
fixed NLMSG_GOODSIZE skb instead.
Any action whose dump exceeds that fixed budget therefore cannot be read
back. For example, act_pedit overruns the budget with 32 actions of four
munge keys each, act_police with 32 policers once the optional
rate/peakrate/result/avrate attributes are present
Fix this by passing attr_size through and allocate the reply the way the
add and delete paths do.
Note on exposure: RTM_GETACTION is the only one of the three action
commands that is not capability checked - tc_ctl_action() requires
CAP_NET_ADMIN for RTM_NEWACTION and RTM_DELACTION only - so this turns a
fixed NLMSG_GOODSIZE reply into a user sized allocation on an
unprivileged path. It is bounded by TCA_ACT_MAX_PRIO actions per
request, and tca_action_gd() does not reject duplicate indices, so a
single large action can be requested 32 times; an act_bpf program near
BPF_MAXINSNS is about 32KB of dump, or roughly 1MB for one request.
Creating such an action still requires CAP_NET_ADMIN, and the add and
delete paths have sized their skbs this way since the Fixes commit.
Should this ever need bounding, GFP_KERNEL_ACCOUNT would charge the
reply to the caller's memcg.
Fixes: 4e76e75d6aba ("net sched actions: calculate add/delete event message size")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260810164357.1653956-1-victor%40mojatatu.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/20260824153903.4143642-3-victor@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_api.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 766162b0b8102..20b6501fd33b2 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1697,12 +1697,12 @@ static int tca_get_fill(struct sk_buff *skb, struct tc_action *actions[],
static int
tcf_get_notify(struct net *net, u32 portid, struct nlmsghdr *n,
- struct tc_action *actions[], int event,
+ struct tc_action *actions[], size_t attr_size, int event,
struct netlink_ext_ack *extack)
{
struct sk_buff *skb;
- skb = alloc_skb(NLMSG_GOODSIZE, GFP_KERNEL);
+ skb = alloc_skb(max(attr_size, NLMSG_GOODSIZE), GFP_KERNEL);
if (!skb)
return -ENOBUFS;
if (tca_get_fill(skb, actions, portid, n->nlmsg_seq, 0, event,
@@ -2053,7 +2053,8 @@ tca_action_gd(struct net *net, struct nlattr *nla, struct nlmsghdr *n,
attr_size = tcf_action_full_attrs_size(attr_size);
if (event == RTM_GETACTION)
- ret = tcf_get_notify(net, portid, n, actions, event, extack);
+ ret = tcf_get_notify(net, portid, n, actions, attr_size, event,
+ extack);
else { /* delete */
ret = tcf_del_notify(net, n, actions, portid, attr_size, extack);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 058/733] net/sched: act_api: fix skb sizing and action leak on reoffload delete
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (56 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 057/733] net/sched: act_api: size the RTM_GETACTION reply from the actions Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 059/733] sctp: fix a TOCTOU race in SCTP_CMD_TIMER_START Greg Kroah-Hartman
` (686 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jamal Hadi Salim,
Victor Nogueira, Pedro Tammela, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit 251367a0a3319fa565daf7468b0afd933b1f5ab1 ]
tcf_reoffload_del_notify_msg() sizes the RTM_DELACTION skb with
tcf_action_fill_size(action) alone. Unlike every other notification path
it never wraps that in tcf_action_full_attrs_size(), so the nlmsg_put()
header, struct tcamsg and the TCA_ACT_TAB nest that tca_get_fill() emits -
24 bytes on x86_64 - are not budgeted. As long as the single action stays
well under NLMSG_GOODSIZE the floor in alloc_skb() hides this, but once its
fill size crosses NLMSG_GOODSIZE the allocation is exactly 24 bytes short
and tca_get_fill() runs out of tailroom. That is now easy to reach for an
offloadable act_pedit with a large tcfp_nkeys, which commit 8e2efb3f45a5
("net/sched: add get_fill_size callbacks for actions missing them") started
accounting for properly.
When that happens tcf_reoffload_del_notify() returns early, before
tcf_idr_release_unsafe(), and tcf_action_reoffload_cb() discards the return
value:
if (tc_act_skip_sw(p->tcfa_flags) && !tc_act_in_hw(p))
tcf_reoffload_del_notify(net, p);
The action has just lost its last hardware instance and is skip_sw, so it
is left installed while processing no packets, and with no notification to
tell userspace about it. An -ENOBUFS from alloc_skb() gets the same
treatment.
Fix this by budgeting the message header the way the add and delete paths
do, and release the action even when the notification cannot be built -
dropping the notification is strictly better than leaking a dead action,
and there is no caller left to report the error to.
Fixes: 13926d19a11e ("flow_offload: add reoffload process to update hw_count")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260810164357.1653956-1-victor%40mojatatu.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Reviewed-by: Pedro Tammela <pctammela@mojatatu.com>
Link: https://patch.msgid.link/20260824153903.4143642-4-victor@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/act_api.c | 17 +++++++++++------
1 file changed, 11 insertions(+), 6 deletions(-)
diff --git a/net/sched/act_api.c b/net/sched/act_api.c
index 20b6501fd33b2..37eced84dfa5f 100644
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1867,11 +1867,13 @@ static int tcf_action_delete(struct net *net, struct tc_action *actions[])
static struct sk_buff *tcf_reoffload_del_notify_msg(struct net *net,
struct tc_action *action)
{
- size_t attr_size = tcf_action_fill_size(action);
struct tc_action *actions[TCA_ACT_MAX_PRIO] = {
[0] = action,
};
struct sk_buff *skb;
+ size_t attr_size;
+
+ attr_size = tcf_action_full_attrs_size(tcf_action_fill_size(action));
skb = alloc_skb(max(attr_size, NLMSG_GOODSIZE), GFP_KERNEL);
if (!skb)
@@ -1888,15 +1890,18 @@ static struct sk_buff *tcf_reoffload_del_notify_msg(struct net *net,
static int tcf_reoffload_del_notify(struct net *net, struct tc_action *action)
{
const struct tc_action_ops *ops = action->ops;
- struct sk_buff *skb;
+ struct sk_buff *skb = NULL;
int ret;
- if (!rtnl_notify_needed(net, 0, RTNLGRP_TC)) {
- skb = NULL;
- } else {
+ if (rtnl_notify_needed(net, 0, RTNLGRP_TC)) {
skb = tcf_reoffload_del_notify_msg(net, action);
+ /* The action has already lost its hardware instance and is
+ * skip_sw, so it must be released whether or not the
+ * notification can be built. Drop the notification rather
+ * than leave an action behind that processes no packets.
+ */
if (IS_ERR(skb))
- return PTR_ERR(skb);
+ skb = NULL;
}
ret = tcf_idr_release_unsafe(action);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 059/733] sctp: fix a TOCTOU race in SCTP_CMD_TIMER_START
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (57 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 058/733] net/sched: act_api: fix skb sizing and action leak on reoffload delete Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 060/733] scsi: mpi3mr: Fix NULL pointer dereference in mpi3mr_sas_port_add() Greg Kroah-Hartman
` (685 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zero Day Initiative, Xin Long,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xin Long <lucien.xin@gmail.com>
[ Upstream commit 2188569e7e1b0bc3f3b557dc97ab7a02befc11c8 ]
The SCTP_CMD_TIMER_START handler checks timer_pending() before calling
timer_reduce(). The timer can expire and detach between these operations,
causing timer_reduce() to rearm the timer without taking the association
reference required for the newly armed timer.
The timer callback later unconditionally drops its association reference,
which can leave the association reference count unbalanced and result in
use-after-free during association teardown.
Use the return value of timer_reduce() to determine whether the timer was
actually armed. Take the association reference only when timer_reduce()
successfully starts a new timer, closing the race between checking the
timer state and rearming it.
This issue was reported by Nico Yip (@_cyeaa_) working with TrendAI Zero
Day Initiative.
Fixes: 20a785aa52c8 ("sctp: Don't add the shutdown timer if its already been added")
Reported-by: Zero Day Initiative <zdi-disclosures@trendmicro.com>
Signed-off-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/9d8f1b5c50329d5ea7c642128d35681abaa9ed20.1787773744.git.lucien.xin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sctp/sm_sideeffect.c | 11 +----------
1 file changed, 1 insertion(+), 10 deletions(-)
diff --git a/net/sctp/sm_sideeffect.c b/net/sctp/sm_sideeffect.c
index 94716406d602c..0d99b7e8c082f 100644
--- a/net/sctp/sm_sideeffect.c
+++ b/net/sctp/sm_sideeffect.c
@@ -1545,17 +1545,8 @@ static int sctp_cmd_interpreter(enum sctp_event_type event_type,
timeout = asoc->timeouts[cmd->obj.to];
BUG_ON(!timeout);
- /*
- * SCTP has a hard time with timer starts. Because we process
- * timer starts as side effects, it can be hard to tell if we
- * have already started a timer or not, which leads to BUG
- * halts when we call add_timer. So here, instead of just starting
- * a timer, if the timer is already started, and just mod
- * the timer with the shorter of the two expiration times
- */
- if (!timer_pending(timer))
+ if (!timer_reduce(timer, jiffies + timeout))
sctp_association_hold(asoc);
- timer_reduce(timer, jiffies + timeout);
break;
case SCTP_CMD_TIMER_RESTART:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 060/733] scsi: mpi3mr: Fix NULL pointer dereference in mpi3mr_sas_port_add()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (58 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 059/733] sctp: fix a TOCTOU race in SCTP_CMD_TIMER_START Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 061/733] scsi: mpi3mr: Fix target device refcount leak " Greg Kroah-Hartman
` (684 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Milan P. Gandhi, Laurence Oberman,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milan P. Gandhi <mgandhi@redhat.com>
[ Upstream commit dba9e2181ca5e875f98b8b9b4535cdaab87dcb0d ]
sas_port_alloc_num() can return NULL on memory allocation failure. The
return value is passed directly to sas_port_add() without a NULL check,
which causes a NULL pointer dereference.
Additionally, if sas_port_add() fails, the allocated port is not freed
before jumping to out_fail, leaking the sas_port structure. Call
sas_port_free() to properly release it.
Fixes: e22bae30667a ("scsi: mpi3mr: Add expander devices to STL")
Signed-off-by: Milan P. Gandhi <mgandhi@redhat.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Link: https://patch.msgid.link/20260812103344.174247-2-mgandhi@redhat.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpi3mr/mpi3mr_transport.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
index 240f67a8e2e3b..ea2c04384a0e1 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
@@ -1428,9 +1428,15 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
}
port = sas_port_alloc_num(mr_sas_node->parent_dev);
+ if (!port) {
+ ioc_err(mrioc, "failure at %s:%d/%s()!\n",
+ __FILE__, __LINE__, __func__);
+ goto out_fail;
+ }
if ((sas_port_add(port))) {
ioc_err(mrioc, "failure at %s:%d/%s()!\n",
__FILE__, __LINE__, __func__);
+ sas_port_free(port);
goto out_fail;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 061/733] scsi: mpi3mr: Fix target device refcount leak in mpi3mr_sas_port_add()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (59 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 060/733] scsi: mpi3mr: Fix NULL pointer dereference in mpi3mr_sas_port_add() Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 062/733] scsi: ufs: ufs-pci: Add support for Intel UFS 4.0 HS-Gear5 Greg Kroah-Hartman
` (683 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Milan P. Gandhi, Laurence Oberman,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Milan P. Gandhi <mgandhi@redhat.com>
[ Upstream commit 419d129f970aaa6567dbac366b0c93784bf9ec97 ]
mpi3mr_get_tgtdev_by_addr() increments the target device kref when it
returns a device. If a subsequent error triggers a goto out_fail after
the tgtdev reference is acquired, the reference is never released
because the out_fail path does not call mpi3mr_tgtdev_put(). This
prevents the target device structure from ever being freed.
Add a tgtdev put in the out_fail path, guarded by a NULL check since
tgtdev is only acquired for SAS_END_DEVICE types and the same cleanup
path is shared by earlier error cases where tgtdev is still NULL.
Fixes: e22bae30667a ("scsi: mpi3mr: Add expander devices to STL")
Signed-off-by: Milan P. Gandhi <mgandhi@redhat.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Link: https://patch.msgid.link/20260812103344.174247-3-mgandhi@redhat.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpi3mr/mpi3mr_transport.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/scsi/mpi3mr/mpi3mr_transport.c b/drivers/scsi/mpi3mr/mpi3mr_transport.c
index ea2c04384a0e1..232af978d7372 100644
--- a/drivers/scsi/mpi3mr/mpi3mr_transport.c
+++ b/drivers/scsi/mpi3mr/mpi3mr_transport.c
@@ -1507,6 +1507,8 @@ static struct mpi3mr_sas_port *mpi3mr_sas_port_add(struct mpi3mr_ioc *mrioc,
list_for_each_entry_safe(mr_sas_phy, next, &mr_sas_port->phy_list,
port_siblings)
list_del(&mr_sas_phy->port_siblings);
+ if (tgtdev)
+ mpi3mr_tgtdev_put(tgtdev);
kfree(mr_sas_port);
return NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 062/733] scsi: ufs: ufs-pci: Add support for Intel UFS 4.0 HS-Gear5
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (60 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 061/733] scsi: mpi3mr: Fix target device refcount leak " Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 063/733] scsi: ufs: ufs-pci: Add MCQ support for Intel UFS 4.0 controllers Greg Kroah-Hartman
` (682 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sangram kumar yerra, Adrian Hunter,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: sangram kumar yerra <sangram.k.y@intel.com>
[ Upstream commit ef675ea168453a9b3e635b8ac543f92938bdd03b ]
Reliable HS-Gear5 operation on Intel UFS 4.0 controllers requires
configuring PA_INITIAL_ADAPT before changing the power mode. Without
this setting, the link fails to train reliably at Gear5.
Add a pwr_change_notify() hook to configure the adaptation mode before
the power mode transition. Enable this only for UFS 4.0 and later
controllers by checking hba->ufs_version.
Wire the hook into the existing Meteor Lake family variant operations
table (ufs_intel_mtl_hba_vops) instead of introducing a separate table,
since the Intel UFS 4.0 PCI variant (PCI ID 8086:D335) already uses this
vops table and the hook is internally gated on UFS version >= 4.0.
Use PA_INITIAL_ADAPT when the negotiated TX power mode is FAST_MODE or
FASTAUTO_MODE. Otherwise, reset the adaptation mode to PA_NO_ADAPT,
which is the default setting.
Fixes: 096cd6b7adf2 ("scsi: ufs: ufs-pci: Add support for Intel Nova Lake")
Signed-off-by: sangram kumar yerra <sangram.k.y@intel.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20260818112830.453402-2-sangram.k.y@intel.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/host/ufshcd-pci.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c
index f2433879b0eba..93bfafc25018b 100644
--- a/drivers/ufs/host/ufshcd-pci.c
+++ b/drivers/ufs/host/ufshcd-pci.c
@@ -181,6 +181,25 @@ static int ufs_intel_lkf_pwr_change_notify(struct ufs_hba *hba,
return err;
}
+static int ufs_intel_nvl_pwr_change_notify(struct ufs_hba *hba,
+ enum ufs_notify_change_status stage,
+ struct ufs_pa_layer_attr *dev_req_params)
+{
+ int adapt_val;
+
+ if (stage != PRE_CHANGE || hba->ufs_version < ufshci_version(4, 0))
+ return 0;
+
+ if (dev_req_params->pwr_tx == FAST_MODE || dev_req_params->pwr_tx == FASTAUTO_MODE)
+ adapt_val = PA_INITIAL_ADAPT;
+ else
+ adapt_val = PA_NO_ADAPT;
+
+ ufshcd_dme_configure_adapt(hba, dev_req_params->gear_tx, adapt_val);
+
+ return 0;
+}
+
static int ufs_intel_lkf_apply_dev_quirks(struct ufs_hba *hba)
{
u32 granularity, peer_granularity;
@@ -527,6 +546,7 @@ static struct ufs_hba_variant_ops ufs_intel_mtl_hba_vops = {
.exit = ufs_intel_common_exit,
.hce_enable_notify = ufs_intel_hce_enable_notify,
.link_startup_notify = ufs_intel_link_startup_notify,
+ .pwr_change_notify = ufs_intel_nvl_pwr_change_notify,
.resume = ufs_intel_resume,
.device_reset = ufs_intel_device_reset,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 063/733] scsi: ufs: ufs-pci: Add MCQ support for Intel UFS 4.0 controllers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (61 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 062/733] scsi: ufs: ufs-pci: Add support for Intel UFS 4.0 HS-Gear5 Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 064/733] smb/client: validate new EOF for insert range Greg Kroah-Hartman
` (681 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sangram kumar yerra, Adrian Hunter,
Bart Van Assche, Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: sangram kumar yerra <sangram.k.y@intel.com>
[ Upstream commit c46cc9cee39bd6f395ab9ac98b1794705df13d7c ]
The Intel UFS 4.0 PCI variant (PCI ID 8086:D335) advertises MCQ support
in its capability register. However, ufshcd_alloc_mcq() also requires an
.op_runtime_config hook to locate the per-queue operation and runtime
(OPR) register blocks, which was not provided by this variant operations
table.
As a result, MCQ initialization fails and ufshcd_add_scsi_host() prints
"MCQ mode is disabled, err=%d\n" before falling back to legacy
single-doorbell (SDB) mode.
Add ufs_intel_mcq_config_resource() to initialize the MCQ configuration
base and add ufs_intel_op_runtime_config() to set up the OPR register
offsets and stride.
Wire both hooks into the variant operations table so MCQ is enabled when
supported by the hardware.
Fixes: 096cd6b7adf2 ("scsi: ufs: ufs-pci: Add support for Intel Nova Lake")
Signed-off-by: sangram kumar yerra <sangram.k.y@intel.com>
Reviewed-by: Adrian Hunter <adrian.hunter@intel.com>
Reviewed-by: Bart Van Assche <bvanassche@acm.org>
Link: https://patch.msgid.link/20260818112830.453402-3-sangram.k.y@intel.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/ufs/host/ufshcd-pci.c | 39 +++++++++++++++++++++++++++++++++++
1 file changed, 39 insertions(+)
diff --git a/drivers/ufs/host/ufshcd-pci.c b/drivers/ufs/host/ufshcd-pci.c
index 93bfafc25018b..21bb11c724bea 100644
--- a/drivers/ufs/host/ufshcd-pci.c
+++ b/drivers/ufs/host/ufshcd-pci.c
@@ -460,6 +460,43 @@ static int ufs_intel_mtl_init(struct ufs_hba *hba)
return ufs_intel_common_init(hba);
}
+static int ufs_intel_mcq_config_resource(struct ufs_hba *hba)
+{
+ hba->mcq_base = hba->mmio_base + ufshcd_mcq_queue_cfg_addr(hba);
+
+ return 0;
+}
+
+/*
+ * This Intel UFS4.0 controller maps MCQ doorbell and interrupt-status
+ * registers into the same PCI BAR as the legacy HCI space, at this
+ * fixed offset/stride.
+ */
+#define UFS_INTEL_SQDAO0 0x2800
+#define UFS_INTEL_SQISAO0 0x2814
+#define UFS_INTEL_CQDAO0 0x281C
+#define UFS_INTEL_CQISAO0 0x2824
+#define UFS_INTEL_MCQ_STRIDE 0x30
+
+static int ufs_intel_op_runtime_config(struct ufs_hba *hba)
+{
+ struct ufshcd_mcq_opr_info_t *opr;
+ int i;
+
+ hba->mcq_opr[OPR_SQD].offset = UFS_INTEL_SQDAO0;
+ hba->mcq_opr[OPR_SQIS].offset = UFS_INTEL_SQISAO0;
+ hba->mcq_opr[OPR_CQD].offset = UFS_INTEL_CQDAO0;
+ hba->mcq_opr[OPR_CQIS].offset = UFS_INTEL_CQISAO0;
+
+ for (i = 0; i < OPR_MAX; i++) {
+ opr = &hba->mcq_opr[i];
+ opr->stride = UFS_INTEL_MCQ_STRIDE;
+ opr->base = hba->mmio_base + opr->offset;
+ }
+
+ return 0;
+}
+
static int ufs_qemu_get_hba_mac(struct ufs_hba *hba)
{
return MAX_SUPP_MAC;
@@ -547,6 +584,8 @@ static struct ufs_hba_variant_ops ufs_intel_mtl_hba_vops = {
.hce_enable_notify = ufs_intel_hce_enable_notify,
.link_startup_notify = ufs_intel_link_startup_notify,
.pwr_change_notify = ufs_intel_nvl_pwr_change_notify,
+ .mcq_config_resource = ufs_intel_mcq_config_resource,
+ .op_runtime_config = ufs_intel_op_runtime_config,
.resume = ufs_intel_resume,
.device_reset = ufs_intel_device_reset,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 064/733] smb/client: validate new EOF for insert range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (62 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 063/733] scsi: ufs: ufs-pci: Add MCQ support for Intel UFS 4.0 controllers Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 065/733] smb/client: validate new EOF for zero range Greg Kroah-Hartman
` (680 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, ChenXiaoSong, Namjae Jeon,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit 1519dc88c87f5346dae0464d7d6da1b6bf1f6e8e ]
smb3_insert_range() does not check if the new file size
(i_size + len) is valid. This allows FALLOC_FL_INSERT_RANGE to bypass
RLIMIT_FSIZE, exceed s_maxbytes, or produce a size outside the loff_t
range.
Use check_add_overflow() to calculate the new EOF. Validate it with
inode_newsize_ok() before modifying the file.
Reproducer, using a file on a CIFS mount:
bash -c '
FILE=/mnt/cifs/repro
trap "" SIGXFSZ
ulimit -f 3072 # RLIMIT_FSIZE = 3 MiB
# A regular write is stopped at 3 MiB.
dd if=/dev/zero of="$FILE" bs=1M count=4 status=none
stat -c "size after write: %s" "$FILE"
# Insert 2 MiB into a 2 MiB file.
truncate -s 2M "$FILE"
fallocate -i -o 0 -l 2M "$FILE"
stat -c "size after insert: %s" "$FILE"
'
Before this change, the regular write stops at the 3 MiB limit, but
insert range grows the file to 4 MiB:
dd: error writing '/mnt/cifs/repro': File too large
size after write: 3145728
size after insert: 4194304
After this change, insert range also fails at the limit and leaves the
2 MiB file unchanged:
dd: error writing '/mnt/cifs/repro': File too large
size after write: 3145728
fallocate: fallocate failed: File too large
size after insert: 2097152
Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 0e872d58fae7c..476afb4e49fd8 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3982,7 +3982,8 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
struct cifsFileInfo *cfile = file->private_data;
struct inode *inode = file_inode(file);
struct cifsInodeInfo *cifsi = CIFS_I(inode);
- __u64 count, old_eof, new_eof;
+ u64 count;
+ loff_t old_eof, new_eof;
xid = get_xid();
@@ -3992,8 +3993,15 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
goto out;
}
+ if (check_add_overflow(old_eof, len, &new_eof)) {
+ rc = -EFBIG;
+ goto out;
+ }
+ rc = inode_newsize_ok(inode, new_eof);
+ if (rc)
+ goto out;
+
count = old_eof - off;
- new_eof = old_eof + len;
filemap_invalidate_lock(inode->i_mapping);
rc = filemap_write_and_wait_range(inode->i_mapping, off, new_eof - 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 065/733] smb/client: validate new EOF for zero range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (63 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 064/733] smb/client: validate new EOF for insert range Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 066/733] smb/client: mark file sparse before emulating insert range Greg Kroah-Hartman
` (679 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, ChenXiaoSong, Namjae Jeon,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit 88972e35750792e717af287dc71f42a03b5cbce4 ]
When FALLOC_FL_ZERO_RANGE is used without FALLOC_FL_KEEP_SIZE,
smb3_zero_range() may extend EOF without checking RLIMIT_FSIZE, allowing
the file to grow beyond the caller's file-size limit.
Fix this by calling inode_newsize_ok() before sending the zero-range
request when the operation would extend EOF.
Reproducer, using a file on a CIFS mount:
bash -c '
FILE=/mnt/cifs/repro
trap "" SIGXFSZ
ulimit -f 3072
truncate -s 2M "$FILE"
fallocate --zero-range -o 0 -l 4M "$FILE"
echo "fallocate rc=$?"
stat -c "file size=%s" "$FILE"
'
Before this change, the operation succeeds despite the 3 MiB limit:
fallocate rc=0
file size=4194304
After this change, fallocate fails and leaves the file at 2 MiB.
Fixes: 72c419d9b073 ("cifs: fix smb3_zero_range so it can expand the file-size when required")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 476afb4e49fd8..3b96dc3615ab4 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3441,6 +3441,13 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
trace_smb3_zero_enter(xid, cfile->fid.persistent_fid, tcon->tid,
ses->Suid, offset, len);
+ new_size = offset + len;
+ if (!keep_size && i_size_read(inode) < new_size) {
+ rc = inode_newsize_ok(inode, new_size);
+ if (rc)
+ goto out;
+ }
+
filemap_invalidate_lock(inode->i_mapping);
netfs_read_sizes(inode, &i_size, &remote_i_size, &zero_point);
@@ -3471,7 +3478,6 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
/*
* do we also need to change the size of the file?
*/
- new_size = offset + len;
if (keep_size == false && (unsigned long long)i_size_read(inode) < new_size) {
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
cfile->fid.volatile_fid, cfile->pid, new_size);
@@ -3488,6 +3494,7 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
zero_range_exit:
filemap_invalidate_unlock(inode->i_mapping);
+ out:
free_xid(xid);
if (rc)
trace_smb3_zero_err(xid, cfile->fid.persistent_fid, tcon->tid,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 066/733] smb/client: mark file sparse before emulating insert range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (64 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 065/733] smb/client: validate new EOF for zero range Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 067/733] smb/client: fix data corruption in emulated " Greg Kroah-Hartman
` (678 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, ChenXiaoSong, Namjae Jeon,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit cd03ce4950d80147ac8f20bc03c42b75b0352407 ]
The SMB client emulates FALLOC_FL_INSERT_RANGE with SET_EOF, COPYCHUNK
and SET_ZERO_DATA.
SET_ZERO_DATA creates a hole only when the file is sparse. On a
non-sparse file, it clears the inserted range but leaves its blocks
allocated, causing the extent count check in xfstests generic/064 to
fail.
Fix this by marking the file sparse before modifying it.
This patch produces the expected sparse extents in xfstests generic/064
only when the server-reported block size is compatible with the server's
deallocation granularity.
For ksmbd, the reported block size follows the backing filesystem,
and the test passes. For Samba, the test passes with a block size
matching the backend granularity, for example, 4 KiB on Btrfs, but not
with the default 1 KiB value. For Windows Server 2022, 4 KiB inserts do
not generate holes, while aligned inserts of 64 KiB or larger do.
Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 3b96dc3615ab4..a2fe71df2d4fb 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4010,6 +4010,11 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
count = old_eof - off;
+ /* SET_ZERO_DATA creates a hole only in a sparse file. */
+ rc = smb2_set_sparse(xid, tcon, cfile, inode, true);
+ if (rc)
+ goto out;
+
filemap_invalidate_lock(inode->i_mapping);
rc = filemap_write_and_wait_range(inode->i_mapping, off, new_eof - 1);
if (rc < 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 067/733] smb/client: fix data corruption in emulated insert range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (65 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 066/733] smb/client: mark file sparse before emulating insert range Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 068/733] smb/client: fix integer truncation in collapse range Greg Kroah-Hartman
` (677 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, ChenXiaoSong, Namjae Jeon,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit 0923ae9f23cc9460b0df6fc124cd56ec4436411b ]
smb3_insert_range() shifts [off, EOF) right with COPYCHUNK, copying from
low to high offsets. When the ranges overlap, the copy can overwrite
source data that has not yet been copied. For a 1 MiB insert at offset 0:
offset: 0 1M 2M 3M 4M 5M
before: | A | B | C | D |
expected: | hole | A | B | C | D |
current: | hole | A | A | A | A | (corrupted)
Let x be the insertion offset, L the total length to move, delta the
insert length, and C the normal chunk size allowed by the server.
Insert range maps
[x, x + L) -> [x + delta, x + delta + L).
When delta >= L, the complete source and target ranges are disjoint, so
the normal copy order and chunk size are safe:
offset: 0 4 8 12 16 20 24 28 32
source: [--S0--][--S1--][--S2--][--S3--]
target: [--T0--][--T1--][--T2--][--T3--]
When delta < L, the complete source and target ranges overlap, so the
copy must proceed from EOF backwards. There are two subcases.
If delta >= C, each corresponding source and target chunk is disjoint.
The 1 MiB example has L = 4 MiB and delta = C = 1 MiB:
offset: 0 1M 2M 3M 4M 5M
source: [--S0--][--S1--][--S2--][--S3--]
target: [--T0--][--T1--][--T2--][--T3--]
Copying S0 from [0, 1M) to [1M, 2M) overwrites S1 before it is copied.
Processing chunks from EOF backwards prevents this inter-chunk
overwrite.
If delta < C, the source and target ranges of a normal chunk also
overlap. For example, with L = 16, delta = 2 and C = 4:
offset: 0 2 4 6 8 10 12 14 16 18
source: [--S0--][--S1--][--S2--][--S3--]
target: [--T0--][--T1--][--T2--][--T3--]
Here S0 and T0 overlap over [2,4), S1 and T1 over [6,8), and so on.
Backward ordering cannot control how the server copies bytes inside one
descriptor, so the chunk size must be limited to delta.
Fix this by copying overlapping right shifts from EOF backwards. Limit
the chunk size to delta when delta < C so that each chunk's source and
target ranges do not overlap. Using larger chunks would require a way to
identify servers that safely handle overlapping COPYCHUNK descriptors.
Therefore:
delta >= L:
keep the normal copy order and chunk size
delta < L:
delta >= C: copy backwards and keep the normal chunk size
delta < C: copy backwards and limit the chunk size to delta
Only the delta < C subcase requires reducing the chunk size for data
integrity.
Reproducer:
bash -c '
MNT=/mnt/scratch
# Generate four 1 MiB random blocks: [A][B][C][D].
dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none
# With C = 1 MiB, test delta = C and delta < C.
for delta in 1M 1K; do
truncate -s 0 /tmp/expected
truncate -s "$delta" /tmp/expected
cat /tmp/src >> /tmp/expected
cp /tmp/src "$MNT/file"
fallocate --insert-range -o 0 -l "$delta" "$MNT/file"
if cmp -s /tmp/expected "$MNT/file"; then
echo "delta=$delta: OK"
else
echo "delta=$delta: CORRUPTED"
fi
done
'
The corruption reproduces with Samba and ksmbd, while Windows handles
the overlapping COPYCHUNK ranges safely.
The 1 MiB case tests delta >= C, while the 1 KiB case tests delta < C.
Before this change, the reproducer reports:
delta=1M: CORRUPTED
delta=1K: CORRUPTED
After this change, it passes against both ksmbd and Samba:
delta=1M: OK
delta=1K: OK
Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 132 ++++++++++++++++++++++++++++++++--------
1 file changed, 106 insertions(+), 26 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index a2fe71df2d4fb..d113e28b5c3b7 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -1839,31 +1839,31 @@ smb2_ioctl_query_info(const unsigned int xid,
*
* @tcon: destination file tcon
* @bytes_left: how many bytes are left to copy
+ * @chunk_size: maximum size of a single chunk
*
* Return: maximum number of chunks with which Chunks[] can be filled.
*/
static inline u32
-calc_chunk_count(struct cifs_tcon *tcon, u64 bytes_left)
+calc_chunk_count(struct cifs_tcon *tcon, u64 bytes_left, u32 chunk_size)
{
u32 max_chunks = READ_ONCE(tcon->max_chunks);
u32 max_bytes_copy = READ_ONCE(tcon->max_bytes_copy);
- u32 max_bytes_chunk = READ_ONCE(tcon->max_bytes_chunk);
u64 need;
u32 allowed;
- if (!max_bytes_chunk || !max_bytes_copy || !max_chunks)
+ if (!chunk_size || !max_bytes_copy || !max_chunks)
return 0;
/* chunks needed for the remaining bytes */
- need = DIV_ROUND_UP_ULL(bytes_left, max_bytes_chunk);
+ need = DIV_ROUND_UP_ULL(bytes_left, chunk_size);
/* chunks allowed per cc request */
- allowed = DIV_ROUND_UP(max_bytes_copy, max_bytes_chunk);
+ allowed = DIV_ROUND_UP(max_bytes_copy, chunk_size);
return (u32)umin(need, umin(max_chunks, allowed));
}
/**
- * smb2_copychunk_range - server-side copy of data range
+ * __smb2_copychunk_range - server-side copy of data range
*
* @xid: transaction id
* @src_file: source file
@@ -1875,15 +1875,15 @@ calc_chunk_count(struct cifs_tcon *tcon, u64 bytes_left)
* Obtains a resume key for @src_file and issues FSCTL_SRV_COPYCHUNK_WRITE
* IOCTLs, splitting the request into chunks limited by tcon->max_*.
*
- * Return: @len on success; negative errno on failure.
+ * Return: 0 on success; negative errno on failure.
*/
-static ssize_t
-smb2_copychunk_range(const unsigned int xid,
- struct cifsFileInfo *src_file,
- struct cifsFileInfo *dst_file,
- u64 src_off,
- u64 len,
- u64 dst_off)
+static int
+__smb2_copychunk_range(const unsigned int xid,
+ struct cifsFileInfo *src_file,
+ struct cifsFileInfo *dst_file,
+ u64 src_off,
+ u64 len,
+ u64 dst_off)
{
int rc = 0;
unsigned int ret_data_len = 0;
@@ -1891,12 +1891,14 @@ smb2_copychunk_range(const unsigned int xid,
struct copychunk_ioctl_rsp *cc_rsp = NULL;
struct cifs_tcon *tcon;
struct srv_copychunk *chunk;
- u32 chunks, chunk_count, chunk_bytes;
+ u32 chunks, chunk_count, chunk_bytes, chunk_size;
u32 copy_bytes, copy_bytes_left;
u32 chunks_written, bytes_written;
u64 total_bytes_left = len;
u64 src_off_prev, dst_off_prev;
+ u64 max_chunk = 0;
u32 retries = 0;
+ bool reverse = false;
tcon = tlink_tcon(dst_file->tlink);
@@ -1904,8 +1906,50 @@ smb2_copychunk_range(const unsigned int xid,
dst_file->fid.volatile_fid, tcon->tid,
tcon->ses->Suid, src_off, dst_off, len);
+ /*
+ * Same-file left shifts are safe in forward order. For a right shift,
+ * let L be the copy length, delta the distance between the source and
+ * destination, and C the normal chunk size:
+ *
+ * delta >= L: copy forwards using C
+ * delta < L:
+ * delta >= C: copy backwards using C
+ * delta < C: copy backwards with chunks limited to delta
+ *
+ * Copying backwards prevents one chunk from overwriting data needed by
+ * a later chunk. Limiting the chunk size to delta prevents an individual
+ * chunk from overlapping itself.
+ * This limit can be removed once all supported servers handle overlapping
+ * descriptors safely.
+ *
+ * A small right shift over a large range may therefore require many
+ * chunks.
+ */
+ if (src_file == dst_file && dst_off > src_off) {
+ u64 delta = dst_off - src_off;
+
+ if (delta < len) {
+ reverse = true;
+ max_chunk = delta;
+ }
+ }
+
+ /*
+ * A backward copy walks the offsets down from the end of the range.
+ * Do this once, outside the retry loop, so a retry does not move the
+ * offsets again.
+ */
+ if (reverse) {
+ src_off += len;
+ dst_off += len;
+ }
+
retry:
- chunk_count = calc_chunk_count(tcon, total_bytes_left);
+ chunk_size = READ_ONCE(tcon->max_bytes_chunk);
+ if (max_chunk && max_chunk < chunk_size)
+ chunk_size = (u32)max_chunk;
+
+ chunk_count = calc_chunk_count(tcon, total_bytes_left, chunk_size);
if (!chunk_count) {
rc = -EOPNOTSUPP;
goto out;
@@ -1946,16 +1990,21 @@ smb2_copychunk_range(const unsigned int xid,
while (copy_bytes_left > 0 && chunks < chunk_count) {
chunk = &cc_req->Chunks[chunks++];
+ chunk_bytes = umin(copy_bytes_left, chunk_size);
+ if (reverse) {
+ src_off -= chunk_bytes;
+ dst_off -= chunk_bytes;
+ }
+
chunk->SourceOffset = cpu_to_le64(src_off);
chunk->TargetOffset = cpu_to_le64(dst_off);
-
- chunk_bytes = umin(copy_bytes_left, tcon->max_bytes_chunk);
-
chunk->Length = cpu_to_le32(chunk_bytes);
/* Buffer is zeroed, no need to set chunk->Reserved = 0 */
- src_off += chunk_bytes;
- dst_off += chunk_bytes;
+ if (!reverse) {
+ src_off += chunk_bytes;
+ dst_off += chunk_bytes;
+ }
copy_bytes_left -= chunk_bytes;
copy_bytes += chunk_bytes;
@@ -2003,6 +2052,18 @@ smb2_copychunk_range(const unsigned int xid,
goto out;
}
+ /*
+ * A successful COPYCHUNK should copy every descriptor (MS-SMB2
+ * 3.3.5.15.6). Reject a short backward copy because the rewind
+ * below only supports forward copying.
+ */
+ if (unlikely(reverse && bytes_written < copy_bytes)) {
+ cifs_tcon_dbg(VFS, "Copychunk short write %u/%u (reverse)\n",
+ bytes_written, copy_bytes);
+ rc = -EIO;
+ goto out;
+ }
+
/* Partial write: rewind */
if (bytes_written < copy_bytes) {
u32 delta = copy_bytes - bytes_written;
@@ -2064,10 +2125,27 @@ smb2_copychunk_range(const unsigned int xid,
trace_smb3_copychunk_done(xid, src_file->fid.volatile_fid,
dst_file->fid.volatile_fid, tcon->tid,
tcon->ses->Suid, src_off, dst_off, len);
- return len;
+ return 0;
}
}
+static ssize_t
+smb2_copychunk_range(const unsigned int xid,
+ struct cifsFileInfo *src_file,
+ struct cifsFileInfo *dst_file,
+ u64 src_off,
+ u64 len,
+ u64 dst_off)
+{
+ int rc;
+
+ rc = __smb2_copychunk_range(xid, src_file, dst_file, src_off, len,
+ dst_off);
+ if (rc)
+ return rc;
+ return len;
+}
+
static int
smb2_flush_file(const unsigned int xid, struct cifs_tcon *tcon,
struct cifs_fid *fid)
@@ -3989,7 +4067,6 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
struct cifsFileInfo *cfile = file->private_data;
struct inode *inode = file_inode(file);
struct cifsInodeInfo *cifsi = CIFS_I(inode);
- u64 count;
loff_t old_eof, new_eof;
xid = get_xid();
@@ -4008,8 +4085,6 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
if (rc)
goto out;
- count = old_eof - off;
-
/* SET_ZERO_DATA creates a hole only in a sparse file. */
rc = smb2_set_sparse(xid, tcon, cfile, inode, true);
if (rc)
@@ -4033,7 +4108,12 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
spin_unlock(&inode->i_lock);
fscache_resize_cookie(cifs_inode_cookie(inode), i_size_read(inode));
- rc = smb2_copychunk_range(xid, cfile, cfile, off, count, off + len);
+ /*
+ * Move [off, old_eof) right by len. The helper copies backwards if the
+ * source and destination ranges overlap.
+ */
+ rc = __smb2_copychunk_range(xid, cfile, cfile, off, old_eof - off,
+ off + len);
if (rc < 0)
goto out_2;
spin_lock(&inode->i_lock);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 068/733] smb/client: fix integer truncation in collapse range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (66 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 067/733] smb/client: fix data corruption in emulated " Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 069/733] smb/client: fix stale page cache in insert/collapse range Greg Kroah-Hartman
` (676 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, ChenXiaoSong, Namjae Jeon,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit 7811701d6af7db76481a82b9bc3c4adf7863acf5 ]
smb3_collapse_range() stores the ssize_t return value of
smb2_copychunk_range() in an int. A successful copy larger than
INT_MAX is truncated to a negative value and treated as an error.
Reproducer:
MNT=/mnt/scratch
truncate -s 2056M "$MNT/file"
fallocate --collapse-range -o 1M -l 1M "$MNT/file"
Fix this by using __smb2_copychunk_range(), which reports success as
zero instead of returning the copied byte count.
Before this change, the reproducer fails with:
fallocate: fallocate failed: Success
and the file size remains unchanged at 2056 MiB. After this change, the
reproducer succeeds and the file size becomes the expected 2055 MiB.
Fixes: 5476b5dd82c8 ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index d113e28b5c3b7..ae4e855f80500 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4033,8 +4033,8 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
spin_unlock(&inode->i_lock);
netfs_wait_for_outstanding_io(inode);
- rc = smb2_copychunk_range(xid, cfile, cfile, off + len,
- old_eof - off - len, off);
+ rc = __smb2_copychunk_range(xid, cfile, cfile, off + len,
+ old_eof - off - len, off);
if (rc < 0)
goto out_2;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 069/733] smb/client: fix stale page cache in insert/collapse range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (67 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 068/733] smb/client: fix integer truncation in collapse range Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 070/733] smb/client: invalidate fscache for fallocate range operations Greg Kroah-Hartman
` (675 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, ChenXiaoSong, Namjae Jeon,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit 01261a6fa48b62f5ead8e88aaca1e27cb9ab9032 ]
smb3_insert_range() and smb3_collapse_range() use
truncate_pagecache_range() to invalidate the affected page cache.
However, if off or old_eof is not page-aligned, the boundary pages are
only partially zeroed and remain uptodate. As a result, the client may
return stale data after a successful insert/collapse range operation.
For example, with 4K pages:
page 0 page 1 page 2
0------4K 4K------8K 8K------12K
^ ^
off=2K old_eof=10K
Page 1 is removed from the page cache, while the boundary pages are
only partially zeroed. After COPYCHUNK moves the data on the server,
these cached pages may still return stale data.
This can be reproduced on a CIFS mount:
bash -c '
FILE=/mnt/scratch/repro
# Use a 6 KiB file so EOF is not page-aligned.
dd if=/dev/urandom of=/tmp/src bs=1K count=6 status=none
# Expected: a 4 KiB hole followed by the original data.
rm -f /tmp/expected
truncate -s 4K /tmp/expected
cat /tmp/src >> /tmp/expected
cp /tmp/src "$FILE"
# Prime the page cache before moving data on the server.
cat "$FILE" > /dev/null
fallocate --insert-range -o 0 -l 4K "$FILE"
if cmp -s /tmp/expected "$FILE"; then
echo "readback: OK"
else
echo "readback: STALE DATA"
fi
'
Fix this by writing back dirty data and discarding the page cache from
the start of the page containing off to EOF before moving data on the
server.
Fixes: 9c8b7a293f50 ("smb3: fix temporary data corruption in insert range")
Fixes: fa30a81f255a ("smb3: fix temporary data corruption in collapse range")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 23 ++++++++++++++++++-----
1 file changed, 18 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index ae4e855f80500..9b662635fa134 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -4023,15 +4023,22 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
}
filemap_invalidate_lock(inode->i_mapping);
- rc = filemap_write_and_wait_range(inode->i_mapping, off, old_eof - 1);
+ rc = filemap_write_and_wait_range(inode->i_mapping,
+ round_down(off, PAGE_SIZE),
+ old_eof - 1);
if (rc < 0)
goto out_2;
- truncate_pagecache_range(inode, off, old_eof);
+ netfs_wait_for_outstanding_io(inode);
+ /*
+ * Invalidate cached folios from the page containing off to EOF before
+ * moving data on the server, so subsequent reads do not see stale data.
+ */
+ truncate_pagecache_range(inode, round_down(off, PAGE_SIZE), -1);
+
spin_lock(&inode->i_lock);
netfs_write_zero_point(inode, old_eof);
spin_unlock(&inode->i_lock);
- netfs_wait_for_outstanding_io(inode);
rc = __smb2_copychunk_range(xid, cfile, cfile, off + len,
old_eof - off - len, off);
@@ -4091,11 +4098,17 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
goto out;
filemap_invalidate_lock(inode->i_mapping);
- rc = filemap_write_and_wait_range(inode->i_mapping, off, new_eof - 1);
+ rc = filemap_write_and_wait_range(inode->i_mapping,
+ round_down(off, PAGE_SIZE),
+ old_eof - 1);
if (rc < 0)
goto out_2;
- truncate_pagecache_range(inode, off, old_eof);
netfs_wait_for_outstanding_io(inode);
+ /*
+ * Invalidate cached folios from the page containing off to EOF before
+ * moving data on the server, so subsequent reads do not see stale data.
+ */
+ truncate_pagecache_range(inode, round_down(off, PAGE_SIZE), -1);
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
cfile->fid.volatile_fid, cfile->pid, new_eof);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 070/733] smb/client: invalidate fscache for fallocate range operations
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (68 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 069/733] smb/client: fix stale page cache in insert/collapse range Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 071/733] smb: client: transport: Fix debug printing in __release_mid() Greg Kroah-Hartman
` (674 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Huiwen He, Namjae Jeon, ChenXiaoSong,
Paulo Alcantara, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Huiwen He <hehuiwen@kylinos.cn>
[ Upstream commit 448ba0ae65ca61064183564d2983c9aa59bd6ba7 ]
smb3_zero_range(), smb3_punch_hole(), smb3_insert_range(), and
smb3_collapse_range() modify file contents through server-side range
operations. These operations discard the affected page cache, but leave
the FS-Cache cookie valid, so a later read may return data cached before
the range operation.
Fix this by invalidating FS-Cache after outstanding I/O has completed
and before modifying the file on the server.
Run the following as root on a CIFS mount with fsc enabled and an active
CacheFiles backend:
bash -c '
MNT=/mnt/cifs
FILE="$MNT/repro"
# Generate four 1 MiB random blocks: [A][B][C][D].
dd if=/dev/urandom of=/tmp/src bs=1M count=4 status=none
# Expected contents after zeroing B: [A][zero][C][D].
cp /tmp/src /tmp/expected
dd if=/dev/zero of=/tmp/expected bs=1M seek=1 count=1 \
conv=notrunc status=none
cp /tmp/src "$FILE"
# Populate FS-Cache, then discard the page cache.
sync
echo 1 > /proc/sys/vm/drop_caches
cat "$FILE" > /dev/null
sync
echo 1 > /proc/sys/vm/drop_caches
fallocate --zero-range -o 1M -l 1M "$FILE"
if cmp -s /tmp/expected "$FILE"; then
echo "readback: OK"
else
echo "readback: STALE DATA"
fi
'
Before this change, the readback differs from /tmp/expected:
readback: STALE DATA
After this change, it matches:
readback: OK
Fixes: 30175628bf7f ("[SMB3] Enable fallocate -z support for SMB3 mounts")
Fixes: 31742c5a3317 ("enable fallocate punch hole ("fallocate -p") for SMB3")
Fixes: 5476b5dd82c8 ("cifs: add support for FALLOC_FL_COLLAPSE_RANGE")
Fixes: 7fe6fe95b936 ("cifs: add FALLOC_FL_INSERT_RANGE support")
Signed-off-by: Huiwen He <hehuiwen@kylinos.cn>
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Reviewed-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/smb2ops.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/fs/smb/client/smb2ops.c b/fs/smb/client/smb2ops.c
index 9b662635fa134..5f616384c75c0 100644
--- a/fs/smb/client/smb2ops.c
+++ b/fs/smb/client/smb2ops.c
@@ -3549,6 +3549,9 @@ static long smb3_zero_range(struct file *file, struct cifs_tcon *tcon,
if (keep_size == false && !CIFS_CACHE_READ(cifsi))
goto zero_range_exit;
+ fscache_invalidate(cifs_inode_cookie(inode), NULL,
+ i_size_read(inode), 0);
+
rc = smb3_zero_data(file, tcon, offset, len, xid);
if (rc < 0)
goto zero_range_exit;
@@ -3618,6 +3621,8 @@ static long smb3_punch_hole(struct file *file, struct cifs_tcon *tcon,
*/
truncate_pagecache_range(inode, offset, offset + len - 1);
netfs_wait_for_outstanding_io(inode);
+ fscache_invalidate(cifs_inode_cookie(inode), NULL,
+ i_size_read(inode), 0);
cifs_dbg(FYI, "Offset %lld len %lld\n", offset, len);
@@ -4035,6 +4040,7 @@ static long smb3_collapse_range(struct file *file, struct cifs_tcon *tcon,
* moving data on the server, so subsequent reads do not see stale data.
*/
truncate_pagecache_range(inode, round_down(off, PAGE_SIZE), -1);
+ fscache_invalidate(cifs_inode_cookie(inode), NULL, old_eof, 0);
spin_lock(&inode->i_lock);
netfs_write_zero_point(inode, old_eof);
@@ -4109,6 +4115,7 @@ static long smb3_insert_range(struct file *file, struct cifs_tcon *tcon,
* moving data on the server, so subsequent reads do not see stale data.
*/
truncate_pagecache_range(inode, round_down(off, PAGE_SIZE), -1);
+ fscache_invalidate(cifs_inode_cookie(inode), NULL, old_eof, 0);
rc = SMB2_set_eof(xid, tcon, cfile->fid.persistent_fid,
cfile->fid.volatile_fid, cfile->pid, new_eof);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 071/733] smb: client: transport: Fix debug printing in __release_mid()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (69 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 070/733] smb/client: invalidate fscache for fallocate range operations Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 072/733] sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration Greg Kroah-Hartman
` (673 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Shevchenko, Paulo Alcantara,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit d83a21bb26015bfdd79b0440fe816b271b8bbab3 ]
Long time ago during upgrading printk():s to the respective pr_<level>()
calls one misconversion happened and nobody has noticed that. So,
previously printk(KERN_DEBUG) + printk() worked as one long debug print
since the trailing '\n' is only present in the followup printk() format
string. The culprit change missed that and split the message to two on
the different levels. Restore the original behaviour to make users be
less confused in the most likely never happen cases of partially getting
that message.
Fixes: 0b456f04bcdf ("cifs: convert printk(LEVEL...) to pr_<level>")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/client/transport.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
diff --git a/fs/smb/client/transport.c b/fs/smb/client/transport.c
index fdf4e50c27ceb..e266859818a44 100644
--- a/fs/smb/client/transport.c
+++ b/fs/smb/client/transport.c
@@ -101,12 +101,11 @@ void __release_mid(struct TCP_Server_Info *server, struct mid_q_entry *midEntry)
trace_smb3_slow_rsp(smb_cmd, midEntry->mid, midEntry->pid,
midEntry->when_sent, midEntry->when_received);
if (cifsFYI & CIFS_TIMER) {
- pr_debug("slow rsp: cmd %d mid %llu",
- midEntry->command, midEntry->mid);
- cifs_info("A: 0x%lx S: 0x%lx R: 0x%lx\n",
- now - midEntry->when_alloc,
- now - midEntry->when_sent,
- now - midEntry->when_received);
+ pr_debug("slow rsp: cmd %d mid %llu A: 0x%lx S: 0x%lx R: 0x%lx\n",
+ midEntry->command, midEntry->mid,
+ now - midEntry->when_alloc,
+ now - midEntry->when_sent,
+ now - midEntry->when_received);
}
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 072/733] sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (70 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 071/733] smb: client: transport: Fix debug printing in __release_mid() Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 073/733] raw: annotate disconnect-side IPv4 match writers Greg Kroah-Hartman
` (672 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Henry Martin, Xin Long,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin <bsdhenrymartin@gmail.com>
[ Upstream commit 2cb0b0b1ed69430bf73740377ea0a1c44c50db63 ]
sctp_verify_asconf() walks ASCONF-ACK parameters with
sctp_walk_params(), which advances by SCTP_PAD4(length), while the
consumer sctp_get_asconf_response() iterates the same parameters
advancing by the raw length, without padding. A single odd-length
parameter desynchronises the two walks and makes the consumer
interpret attacker-controlled bytes at a misaligned offset.
When those bytes yield a length of zero, the while loop over
asconf_ack_len makes no progress, spinning forever in softirq
context, and the watchdog reports a soft lockup. All reads stay
within the received skb, so the lockup is a pure remote denial of
service. A remote peer can trigger it with a crafted ASCONF-ACK on
an ADD-IP enabled association with an outstanding ASCONF (RFC 5061
section 4.1.2 requires the chunk to be authenticated, but the
predefined empty key id 0 allows the peer to compute the same
association HMAC from publicly exchanged parameters, so the gate
does not help).
The SCTP_PARAM_ERR_CAUSE case of sctp_verify_asconf() also performs
no length check, letting a parameter without a complete error
header reach the consumer, which reads errhdr.cause past the end of
the parameter, an out-of-bounds read.
Reject SCTP_PARAM_ERR_CAUSE parameters shorter than
sizeof(struct sctp_addip_param) + sizeof(struct sctp_errhdr) at the
verifier, and advance the consumer iterator with the same padding
rule as the verifier to keep the two walks in lockstep. The verifier
change guarantees a complete error header in every ERR_CAUSE
parameter the consumer can see, so the consumer's asconf_ack_len
check is dropped and it returns err_param->cause directly. The
consumer padding fix is still required because odd lengths remain
valid for SCTP_PARAM_ERR_CAUSE per RFC 5061.
The issue was found by ZeroHive, a vulnerability hunting agent at
Tencent Yunding Lab.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Acked-by: Xin Long <lucien.xin@gmail.com>
Link: https://patch.msgid.link/20260828042431.3873725-1-bsdhenrymartin@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sctp/sm_make_chunk.c | 14 ++++++--------
1 file changed, 6 insertions(+), 8 deletions(-)
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 236e25abc7a42..84a4c97d0f755 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -3215,6 +3215,9 @@ bool sctp_verify_asconf(const struct sctp_association *asoc,
*errp = param.p;
switch (param.p->type) {
case SCTP_PARAM_ERR_CAUSE:
+ if (length < sizeof(struct sctp_addip_param) +
+ sizeof(struct sctp_errhdr))
+ return false;
break;
case SCTP_PARAM_IPV4_ADDRESS:
if (length != sizeof(struct sctp_ipv4addr_param))
@@ -3448,20 +3451,15 @@ static __be16 sctp_get_asconf_response(struct sctp_chunk *asconf_ack,
case SCTP_PARAM_ERR_CAUSE:
length = sizeof(*asconf_ack_param);
err_param = (void *)asconf_ack_param + length;
- asconf_ack_len -= length;
- if (asconf_ack_len > 0)
- return err_param->cause;
- else
- return SCTP_ERROR_INV_PARAM;
- break;
+ return err_param->cause;
default:
return SCTP_ERROR_INV_PARAM;
}
}
length = ntohs(asconf_ack_param->param_hdr.length);
- asconf_ack_param = (void *)asconf_ack_param + length;
- asconf_ack_len -= length;
+ asconf_ack_param = (void *)asconf_ack_param + SCTP_PAD4(length);
+ asconf_ack_len -= SCTP_PAD4(length);
}
return err_code;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 073/733] raw: annotate disconnect-side IPv4 match writers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (71 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 072/733] sctp: fix soft lockup from unpadded ASCONF-ACK parameter iteration Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 074/733] net: amd-xgbe: discard rx packets with bad FCS Greg Kroah-Hartman
` (671 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Jackie Liu,
Xuanqiang Luo, Eric Dumazet, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
[ Upstream commit ac08d183dac0441e41f77bbad50798fe609d90f1 ]
raw_v4_match() reads inet_daddr, inet_rcv_saddr and
sk_bound_dev_if locklessly under RCU. Bind and connect writers are
annotated, but __udp_disconnect() still clears the same fields using
plain stores.
Commit 18f116931f52e ("raw: annotate lockless match fields in
raw_v4_match()") added the lockless readers and annotated the raw bind
and datagram connect writers. Its v4 revision intentionally left the
shared disconnect-side IPv4 writers for follow-up cleanup.
Complete that follow-up by using WRITE_ONCE() for the disconnect-side
stores, including the inet_rcv_saddr reset in inet_reset_saddr(), to
pair with the lockless raw socket matcher.
Fixes: 0daf07e52709 ("raw: convert raw sockets to RCU")
Link: https://lore.kernel.org/netdev/20260716142958.3064224-1-runyu.xiao@seu.edu.cn/
Suggested-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Signed-off-by: Jackie Liu <liuyun01@kylinos.cn>
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260828012918.1461-1-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/ip.h | 3 ++-
net/ipv4/udp.c | 4 ++--
2 files changed, 4 insertions(+), 3 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index a8f57b4f4aa23..6f602df72ee62 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -704,7 +704,8 @@ static inline void ip_ipgre_mc_map(__be32 naddr, const unsigned char *broadcast,
static __inline__ void inet_reset_saddr(struct sock *sk)
{
- inet_sk(sk)->inet_rcv_saddr = inet_sk(sk)->inet_saddr = 0;
+ inet_sk(sk)->inet_saddr = 0;
+ WRITE_ONCE(inet_sk(sk)->inet_rcv_saddr, 0);
#if IS_ENABLED(CONFIG_IPV6)
if (sk->sk_family == PF_INET6) {
struct ipv6_pinfo *np = inet6_sk(sk);
diff --git a/net/ipv4/udp.c b/net/ipv4/udp.c
index 70f6cbd4ef73b..45e96b7219896 100644
--- a/net/ipv4/udp.c
+++ b/net/ipv4/udp.c
@@ -2164,10 +2164,10 @@ int __udp_disconnect(struct sock *sk, int flags)
*/
sk->sk_state = TCP_CLOSE;
- inet->inet_daddr = 0;
+ WRITE_ONCE(inet->inet_daddr, 0);
inet->inet_dport = 0;
sock_rps_reset_rxhash(sk);
- sk->sk_bound_dev_if = 0;
+ WRITE_ONCE(sk->sk_bound_dev_if, 0);
if (!(sk->sk_userlocks & SOCK_BINDADDR_LOCK)) {
inet_reset_saddr(sk);
if (sk->sk_prot->rehash &&
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 074/733] net: amd-xgbe: discard rx packets with bad FCS
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (72 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 073/733] raw: annotate disconnect-side IPv4 match writers Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 075/733] vxlan: mdb: Fix use-after-free in vxlan_mdb_remote_src_del() Greg Kroah-Hartman
` (670 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, James Nugraha, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Nugraha <aslan.jnn@gmail.com>
[ Upstream commit ac8d6b28d48c5d951dcd923d33e461588e762a6d ]
amd-xgbe driver currently sets the MAC_RCR.DCRCC bit whenever
RX is enabled. This disables hardware FCS validation, causing packets
with bad FCS to be accepted unconditionally.
This change unsets DCRCC so that packets with bad FCS will be dropped,
in-line with typical behaviours of many other network controllers.
Tests:
- Verified that packets with bad FCS are now dropped.
- Verified that receiving packets with bad FCS will increment the
`rx_crc_errors` counter.
Fixes: c5aa9e3b8156 ("amd-xgbe: Initial AMD 10GbE platform driver")
Signed-off-by: James Nugraha <aslan.jnn@gmail.com>
Link: https://patch.msgid.link/20260827232220.69907-1-aslan.jnn@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/amd/xgbe/xgbe-dev.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
index 2de974213090c..e2e850c1b90b1 100644
--- a/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
+++ b/drivers/net/ethernet/amd/xgbe/xgbe-dev.c
@@ -3400,7 +3400,7 @@ static void xgbe_enable_rx(struct xgbe_prv_data *pdata)
XGMAC_IOWRITE(pdata, MAC_RQC0R, reg_val);
/* Enable MAC Rx */
- XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 1);
+ XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 0);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 1);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 1);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 1);
@@ -3411,7 +3411,6 @@ static void xgbe_disable_rx(struct xgbe_prv_data *pdata)
unsigned int i;
/* Disable MAC Rx */
- XGMAC_IOWRITE_BITS(pdata, MAC_RCR, DCRCC, 0);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, CST, 0);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, ACS, 0);
XGMAC_IOWRITE_BITS(pdata, MAC_RCR, RE, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 075/733] vxlan: mdb: Fix use-after-free in vxlan_mdb_remote_src_del()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (73 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 074/733] net: amd-xgbe: discard rx packets with bad FCS Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 076/733] watchdog: msc313e: Fix NULL pointer dereference in PM callbacks Greg Kroah-Hartman
` (669 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Baul Lee, Ido Schimmel,
Nikolay Aleksandrov, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baul Lee <baul.lee@xbow.com>
[ Upstream commit 4aa61c88b4e292e10abdfd791334b8272108d68a ]
vxlan_mdb_is_valid_source(), which validates MDBE_ATTR_SOURCE and every
MDBE_ATTR_SRC_LIST member, accepts the all-zeros address.
A source list is only accepted on a (*, G) entry, whose source is the
all-zeros address, and for each member of the list an (S, G) entry is
derived from it by substituting the source. Entries are keyed by a plain
memcmp() of struct vxlan_mdb_entry_key, so if MDBE_ATTR_SOURCE is present
and holds the all-zeros address and the source list holds it as well, the
derived (S, G) key is byte-identical to the (*, G) key and resolves to the
same entry. Omitting MDBE_ATTR_SOURCE is not equivalent, as the key is
then left with a zero address family.
vxlan_mdb_remote_src_del() removes the forwarding entry of a source before
freeing the source entry:
vxlan_mdb_remote_src_fwd_del(vxlan, group, remote, &ent->addr);
vxlan_mdb_remote_src_entry_del(ent);
With the keys aliased, the first call deletes the remote of the entry that
owns 'ent' instead of a separate (S, G) entry, and frees 'ent'. The second
call then runs on the freed entry, and its hlist_del() reads ->pprev and
->next out of it and writes through them.
Adding the (*, G) entry with NLM_F_REPLACE and no source list marks the
all-zeros source for deletion and reaches this from the sweep at the end
of vxlan_mdb_remote_srcs_replace().
BUG: KASAN: slab-use-after-free in __vxlan_mdb_add+0x1cd/0xd70
Read of size 8 at addr ffff888102852500 by task poc/84
__vxlan_mdb_add+0x1cd/0xd70
vxlan_mdb_add+0xc0/0x140
rtnl_mdb_add+0x157/0x2a0
rtnetlink_rcv_msg+0x207/0x5a0
Allocated by task 84:
__kmalloc_cache_noprof+0x153/0x360
vxlan_mdb_remote_srcs_add+0x2eb/0x440
__vxlan_mdb_add+0x803/0xd70
Freed by task 84:
kfree+0x14c/0x3b0
vxlan_mdb_remote_del+0x129/0x1a0
__vxlan_mdb_del+0x4f/0xe0
vxlan_mdb_remote_src_fwd_del.isra.0+0x162/0x1b0
__vxlan_mdb_add+0x1c5/0xd70
The MDB operations are netns-scoped, so an unprivileged user can perform
them in a new user and network namespace.
Reject the all-zeros address in vxlan_mdb_is_valid_source(), which covers
both call sites. A (*, G) entry is expressed by omitting the source, so
nothing legitimate is refused.
Discovered by XBOW, triaged by Baul Lee <baul.lee@xbow.com>
Fixes: a3a48de5eade ("vxlan: mdb: Add MDB control path support")
Signed-off-by: Baul Lee <baul.lee@xbow.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260826173604.90158-1-baul.lee@xbow.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_mdb.c | 8 ++++++++
tools/testing/selftests/net/test_vxlan_mdb.sh | 6 ++++++
2 files changed, 14 insertions(+)
diff --git a/drivers/net/vxlan/vxlan_mdb.c b/drivers/net/vxlan/vxlan_mdb.c
index d71e1925ecfdb..841f42ffecb9a 100644
--- a/drivers/net/vxlan/vxlan_mdb.c
+++ b/drivers/net/vxlan/vxlan_mdb.c
@@ -354,6 +354,10 @@ static bool vxlan_mdb_is_valid_source(const struct nlattr *attr, __be16 proto,
NL_SET_ERR_MSG_MOD(extack, "IPv4 multicast source address is not allowed");
return false;
}
+ if (ipv4_is_zeronet(nla_get_in_addr(attr))) {
+ NL_SET_ERR_MSG_MOD(extack, "IPv4 all-zeros source address is not allowed");
+ return false;
+ }
break;
#if IS_ENABLED(CONFIG_IPV6)
case htons(ETH_P_IPV6): {
@@ -368,6 +372,10 @@ static bool vxlan_mdb_is_valid_source(const struct nlattr *attr, __be16 proto,
NL_SET_ERR_MSG_MOD(extack, "IPv6 multicast source address is not allowed");
return false;
}
+ if (ipv6_addr_any(&src)) {
+ NL_SET_ERR_MSG_MOD(extack, "IPv6 all-zeros source address is not allowed");
+ return false;
+ }
break;
}
#endif
diff --git a/tools/testing/selftests/net/test_vxlan_mdb.sh b/tools/testing/selftests/net/test_vxlan_mdb.sh
index 58da5de99ac45..f9600aabd4a29 100755
--- a/tools/testing/selftests/net/test_vxlan_mdb.sh
+++ b/tools/testing/selftests/net/test_vxlan_mdb.sh
@@ -685,6 +685,9 @@ star_g_common()
run_cmd "bridge -n $ns1 mdb add dev vx0 port vx0 grp $grp permanent filter_mode exclude source_list $grp dst $vtep_ip src_vni 10010"
log_test $? 255 "Invalid source in source list"
+ run_cmd "bridge -n $ns1 mdb add dev vx0 port vx0 grp $grp permanent filter_mode exclude source_list $all_zeros_grp dst $vtep_ip src_vni 10010"
+ log_test $? 255 "All-zeros source in source list"
+
run_cmd "bridge -n $ns1 mdb add dev vx0 port vx0 grp $grp permanent source_list $src1 dst $vtep_ip src_vni 10010"
log_test $? 255 "Source list without filter mode"
}
@@ -784,6 +787,9 @@ sg_common()
run_cmd "bridge -n $ns1 mdb add dev vx0 port vx0 grp $grp src $grp permanent dst $vtep_ip src_vni 10010"
log_test $? 255 "(S, G) with an invalid source list"
+ run_cmd "bridge -n $ns1 mdb add dev vx0 port vx0 grp $grp src $all_zeros_grp permanent dst $vtep_ip src_vni 10010"
+ log_test $? 255 "(S, G) with an all-zeros source"
+
run_cmd "bridge -n $ns1 mdb add dev vx0 port vx0 grp $all_zeros_grp src $src permanent dst $vtep_ip src_vni 10010"
log_test $? 255 "All-zeros group with source"
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 076/733] watchdog: msc313e: Fix NULL pointer dereference in PM callbacks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (74 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 075/733] vxlan: mdb: Fix use-after-free in vxlan_mdb_remote_src_del() Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 077/733] perf symbol: Do not use debug file as the binary type Greg Kroah-Hartman
` (668 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit e3eceb76515910746e6268c4e4ac1c07516ebd7b ]
msc313e_wdt_probe() doesn't set the driver data for the platform device.
As a result, dev_get_drvdata() in msc313e_wdt_suspend() and
msc313e_wdt_resume() will return NULL, leading to a NULL pointer
dereference afterward.
Set the platform device driver data in msc313e_wdt_probe().
Fixes: e9800b799464 ("watchdog: Add Mstar MSC313e WDT driver")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260827044700.554333-2-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index d962589e2c55a..f69d66971c41d 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -124,6 +124,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
set_bit(WDOG_HW_RUNNING, &priv->wdev.status);
watchdog_set_drvdata(&priv->wdev, priv);
+ platform_set_drvdata(pdev, priv);
watchdog_init_timeout(&priv->wdev, timeout, dev);
watchdog_stop_on_reboot(&priv->wdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 077/733] perf symbol: Do not use debug file as the binary type
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (75 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 076/733] watchdog: msc313e: Fix NULL pointer dereference in PM callbacks Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 078/733] OPP: of: Fix potential multiplication overflow when calculating freq Greg Kroah-Hartman
` (667 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Todd Lipcon, Adrian Hunter,
Namhyung Kim, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Hunter <adrian.hunter@intel.com>
[ Upstream commit ae9464c65e9d1ad4df4fed516cee9bca3bc614cc ]
dso__load() sets the binary type of a DSO to the type of the first symbol
source found. For a DSO with a separate debug file linked via
.gnu-debuglink, that is DSO_BINARY_TYPE__DEBUGLINK, which makes
dso__get_filename() return the name of the debug file instead of the file
that was actually executed.
Consumers that need to read instruction bytes, such as Intel PT decoding
in 'perf script', then read from the debug file and produce wrong
instructions.
Prefer DSO_BINARY_TYPE__BUILD_ID_CACHE, and otherwise
DSO_BINARY_TYPE__SYSTEM_PATH_DSO, over debug-only types, which restores
the behaviour of using a file that contains the executed instructions.
This is a workaround. Properly separating the binary file used for
instructions from the file used for debug symbols is left for later.
Example:
Create a shared object with a separate .gnu_debuglink debug file. Note
that 'objcopy --only-keep-debug' leaves .text as NOBITS, so instructions
read from the debug file are zeros:
# cat > foo.c << EOF
unsigned long foo_work(unsigned long n)
{
unsigned long s = 0;
for (unsigned long i = 0; i < n; i++)
s = s * 31 + i;
return s;
}
EOF
# cat > main.c << EOF
#include <stdio.h>
unsigned long foo_work(unsigned long n);
int main(void)
{
printf("%lu\n", foo_work(1000));
return 0;
}
EOF
# gcc -g -O2 -shared -fPIC -o libfoo.so foo.c
# gcc -g -O2 -o main main.c -L. -lfoo -Wl,-rpath,'$ORIGIN'
# objcopy --only-keep-debug libfoo.so libfoo.so.debug
# objcopy --strip-debug libfoo.so
# objcopy --add-gnu-debuglink=libfoo.so.debug libfoo.so
# perf record -e intel_pt//u ./main
Note that branch samples must be requested, because it is the resolving
of the branch target symbol that causes dso__load() to be called, and
hence the binary type to be set, before the decoder walks the code.
With '--itrace=e' alone, nothing loads symbols for libfoo.so, the binary
type is left as DSO_BINARY_TYPE__NOT_FOUND, the correct file is read
anyway, and no errors are reported either way.
Before:
# perf.before script --itrace=be 2>&1 | grep "instruction trace error"
instruction trace error type 1 time 2350.467489498 cpu 9 pid 75634 tid 75634 ip 0x77d48480718f code 6: Trace doesn't match instruction
instruction trace error type 1 time 2350.467489832 cpu 9 pid 75634 tid 75634 ip 0x77d484807341 code 6: Trace doesn't match instruction
instruction trace error type 1 time 2350.467496412 cpu 9 pid 75634 tid 75634 ip 0x5b4de37a8074 code 6: Trace doesn't match instruction
instruction trace error type 1 time 2350.467593393 cpu 9 pid 75634 tid 75634 ip 0x77d4848070d0 code 6: Trace doesn't match instruction
instruction trace error type 1 time 2350.467593954 cpu 9 pid 75634 tid 75634 ip 0x77d4848075a8 code 6: Trace doesn't match instruction
instruction trace error type 1 time 2350.467595728 cpu 9 pid 75634 tid 75634 ip 0x77d4848324de code 6: Trace doesn't match instruction
6 instruction trace errors
After:
# perf script --itrace=be 2>&1 | grep "instruction trace error"
#
Fixes: 5363c306787c8 ("perf symbol: Set binary_type of dso when loading")
Reported-by: Todd Lipcon <tlipcon@google.com>
Closes: https://lore.kernel.org/all/CAGH6UiG=RJLqBU3kLu9XJciPyPO1HZkbAPERguVUMRuWQgqf=A@mail.gmail.com/
Signed-off-by: Adrian Hunter <adrian.hunter@intel.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/util/symbol.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/tools/perf/util/symbol.c b/tools/perf/util/symbol.c
index 35104a56d8e38..1de5796fc4ff6 100644
--- a/tools/perf/util/symbol.c
+++ b/tools/perf/util/symbol.c
@@ -1947,7 +1947,16 @@ int dso__load(struct dso *dso, struct map *map)
if (next_slot) {
ss_pos++;
- if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND)
+ /*
+ * The binary type is used to find the file containing
+ * the executed instructions, so prefer the types that
+ * refer to the actual object over debug-only files such
+ * as DSO_BINARY_TYPE__DEBUGLINK.
+ */
+ if (dso__binary_type(dso) == DSO_BINARY_TYPE__NOT_FOUND ||
+ symtab_type == DSO_BINARY_TYPE__BUILD_ID_CACHE ||
+ (symtab_type == DSO_BINARY_TYPE__SYSTEM_PATH_DSO &&
+ dso__binary_type(dso) != DSO_BINARY_TYPE__BUILD_ID_CACHE))
dso__set_binary_type(dso, symtab_type);
if (syms_ss && runtime_ss)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 078/733] OPP: of: Fix potential multiplication overflow when calculating freq
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (76 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 077/733] perf symbol: Do not use debug file as the binary type Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 079/733] perf powerpc-vpadtl: Fix raw_size of DTL samples Greg Kroah-Hartman
` (666 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Colin Ian King, Viresh Kumar,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Colin Ian King <colin.i.king@gmail.com>
[ Upstream commit e11811a552252740bd396ec38378e9570ee16578 ]
The multiplication be32_to_cpup(val++) * 1000 is performed using 32 bit
unsigned integers and hence uses a 32 bit multiplication; this will
overflow if be32_to_cpup(val++) is greater than 4294967 (which is
very unlikely at present). The result is assigned to an unsigned long
(which is a 64 bit value on 64 bit systems), so fix this potential
overflow by casting the first operand of the multiplication to
an unsigned int.
Fixes: b496dfbc94ab ("PM / OPP: Initialize OPP table from device tree")
Signed-off-by: Colin Ian King <colin.i.king@gmail.com>
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/opp/of.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/opp/of.c b/drivers/opp/of.c
index c02e20632fa64..9c4fd1f0e944a 100644
--- a/drivers/opp/of.c
+++ b/drivers/opp/of.c
@@ -1039,7 +1039,7 @@ static int _of_add_opp_table_v1(struct device *dev, struct opp_table *opp_table)
val = prop->value;
while (nr) {
- unsigned long freq = be32_to_cpup(val++) * 1000;
+ unsigned long freq = (unsigned long)be32_to_cpup(val++) * 1000;
unsigned long volt = be32_to_cpup(val++);
struct dev_pm_opp_data data = {
.freq = freq,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 079/733] perf powerpc-vpadtl: Fix raw_size of DTL samples
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (77 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 078/733] OPP: of: Fix potential multiplication overflow when calculating freq Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 080/733] netfs: Fix unbuffered/DIO write partial transfer error return Greg Kroah-Hartman
` (665 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Wang Yan, Athira Rajeev,
Arnaldo Carvalho de Melo, Namhyung Kim, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Yan <wangyan01@kylinos.cn>
[ Upstream commit aadea57f532882d8bab444646863c7ef8a778ff1 ]
In powerpc_vpadtl_sample(), raw_data of the synthetic sample points to a
struct powerpc_vpadtl_entry (48 bytes), but raw_size is set to
sizeof(record). record is a struct powerpc_vpadtl_entry pointer, so
sizeof(record) is the size of the pointer (8 bytes on 64-bit) rather
than the size of the record itself.
As a result, consumers that bound their access to raw_data by raw_size
only see or copy the first 8 bytes of each DTL entry instead of the full
record.
Use sizeof(*record) so that raw_size reflects the actual length of the
raw data.
Fixes: 8644834a482a ("perf powerpc: Process the DTL entries in queue and deliver samples")
Signed-off-by: Wang Yan <wangyan01@kylinos.cn>
Reviewed-by: Athira Rajeev <atrajeev@linux.ibm.com>
Reviewed-by: Arnaldo Carvalho de Melo <acme@redhat.com>
Signed-off-by: Namhyung Kim <namhyung@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/perf/util/powerpc-vpadtl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/perf/util/powerpc-vpadtl.c b/tools/perf/util/powerpc-vpadtl.c
index 710f3093f3f90..af6783cfdb53d 100644
--- a/tools/perf/util/powerpc-vpadtl.c
+++ b/tools/perf/util/powerpc-vpadtl.c
@@ -196,7 +196,7 @@ static int powerpc_vpadtl_sample(struct powerpc_vpadtl_entry *record,
sample.cpumode = PERF_RECORD_MISC_KERNEL;
sample.time = save;
sample.raw_data = record;
- sample.raw_size = sizeof(record);
+ sample.raw_size = sizeof(*record);
event.sample.header.type = PERF_RECORD_SAMPLE;
event.sample.header.misc = sample.cpumode;
event.sample.header.size = sizeof(struct perf_event_header);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 080/733] netfs: Fix unbuffered/DIO write partial transfer error return
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (78 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 079/733] perf powerpc-vpadtl: Fix raw_size of DTL samples Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 081/733] netfs: Fix error vs transferred passed to ->ki_complete() Greg Kroah-Hartman
` (664 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
netfs, linux-fsdevel, Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit c753a33664e4e86246f7491a93d9a77c1a673b5d ]
Fix unbuffered/DIO write to return the amount of data transferred in
preference to an error if a partial transfer has been achieved, and to
prefer an error stashed in the request over the one returned by
netfs_unbuffered_write() (likely -EINTR or -ERESTARTSYS).
Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-3-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/direct_write.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index c16fbad286a17..d53b42ceadd23 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -139,13 +139,11 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq)
if (test_bit(NETFS_SREQ_NEED_RETRY, &subreq->flags)) {
retry = true;
} else if (test_bit(NETFS_SREQ_FAILED, &subreq->flags)) {
- ret = subreq->error;
- wreq->error = ret;
+ wreq->error = subreq->error;
netfs_see_subrequest(subreq, netfs_sreq_trace_see_failed);
subreq = NULL;
break;
}
- ret = 0;
if (!retry) {
netfs_unbuffered_write_collect(wreq, stream, subreq);
@@ -288,11 +286,11 @@ ssize_t netfs_unbuffered_write_iter_locked(struct kiocb *iocb, struct iov_iter *
ret = -EIOCBQUEUED;
} else {
ret = netfs_unbuffered_write(wreq);
- if (ret < 0) {
- _debug("begin = %zd", ret);
- } else {
+ if (wreq->transferred) {
iocb->ki_pos += wreq->transferred;
- ret = wreq->transferred ?: wreq->error;
+ ret = wreq->transferred;
+ } else if (wreq->error) {
+ ret = wreq->error;
}
netfs_put_request(wreq, netfs_rreq_trace_put_complete);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 081/733] netfs: Fix error vs transferred passed to ->ki_complete()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (79 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 080/733] netfs: Fix unbuffered/DIO write partial transfer error return Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 082/733] netfs: Fix i_size update for partial transfer Greg Kroah-Hartman
` (663 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
netfs, linux-fsdevel, Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 0bfe2571a6af653611860d0e24c4e4c83bae7a54 ]
Fix netfs_unbuffered_write_done() to pass the amount written to
->ki_complete() rather than the error in the event of a partially complete
transfer.
Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-4-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/direct_write.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index d53b42ceadd23..e563532c2e598 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -51,7 +51,7 @@ static void netfs_unbuffered_write_done(struct netfs_io_request *wreq)
wreq->iocb->ki_pos += written;
if (wreq->iocb->ki_complete) {
trace_netfs_rreq(wreq, netfs_rreq_trace_ki_complete);
- wreq->iocb->ki_complete(wreq->iocb, wreq->error ?: written);
+ wreq->iocb->ki_complete(wreq->iocb, written ?: wreq->error);
}
wreq->iocb = VFS_PTR_POISON;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 082/733] netfs: Fix i_size update for partial transfer
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (80 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 081/733] netfs: Fix error vs transferred passed to ->ki_complete() Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 083/733] netfs: Fix subreq ref leak Greg Kroah-Hartman
` (662 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
netfs, linux-fsdevel, Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 741416a8003b77e636dafade408f808d96ac3f47 ]
Fix netfs_unbuffered_write_done() to pass the amount written to
netfs_update_i_size() in the event of a partial transfer that ends in an
error.
That said, it might be better for the filesystem to mark the inode data as
invalid and recheck it in case something like a network error occurred that
prevented the reply from the server from being received.
Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-5-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/direct_write.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index e563532c2e598..e07e7850a5a21 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -21,7 +21,7 @@ static void netfs_unbuffered_write_done(struct netfs_io_request *wreq)
/* Okay, declare that all I/O is complete. */
trace_netfs_rreq(wreq, netfs_rreq_trace_write_done);
- if (!wreq->error)
+ if (wreq->transferred)
netfs_update_i_size(ictx, &ictx->inode, wreq->start, wreq->transferred);
if (wreq->origin == NETFS_DIO_WRITE &&
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 083/733] netfs: Fix subreq ref leak
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (81 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 082/733] netfs: Fix i_size update for partial transfer Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 084/733] netfs: break unbuffered write when netfs_alloc_subrequest() fails Greg Kroah-Hartman
` (661 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
netfs, linux-fsdevel, Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 3c30087e27598d9d359763e8be9bd3017fe08348 ]
Fix a subrequest ref leak in netfs_unbuffered_write() in the event that
subreq->io_iter ends up zero length during preparation.
Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-6-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/direct_write.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index e07e7850a5a21..86beeb337ed7f 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -121,8 +121,14 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq)
}
iov_iter_truncate(&subreq->io_iter, wreq->len - wreq->transferred);
- if (!iov_iter_count(&subreq->io_iter))
+ if (!iov_iter_count(&subreq->io_iter)) {
+ pr_warn("netfs: Unexpected zero-length iterator R=%08x\n",
+ wreq->debug_id);
+ __set_bit(NETFS_SREQ_FAILED, &subreq->flags);
+ netfs_write_subrequest_terminated(subreq, -EIO);
+ wreq->error = -EIO;
break;
+ }
subreq->len = netfs_limit_iter(&subreq->io_iter, 0,
stream->sreq_max_len,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 084/733] netfs: break unbuffered write when netfs_alloc_subrequest() fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (82 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 083/733] netfs: Fix subreq ref leak Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 085/733] netfs: Fix readahead synchronisation issues by loading all folios upfront Greg Kroah-Hartman
` (660 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6a13fc77eb6f0802be2d,
Edward Adam Davis, David Howells, Paulo Alcantara,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <eadavis@qq.com>
[ Upstream commit 8fb45a934661419c04a44d4cfea1e0df7dcf2805 ]
syzbot reported a null-ptr-deref below [1] following a fault injection in
netfs_alloc_subrequest(). [0]
When netfs_alloc_subrequest() fails, subreq is NULL.
Later, netfs_prepare_write() tries to initialize members of
subreq(e.g., source), the issue in [1] is triggered.
Let's handle the error of netfs_prepare_write() properly.
[0]
FAULT_INJECTION: forcing a failure.
name failslab, interval 1, probability 0, space 0, times 0
Call Trace:
netfs_alloc_subrequest+0x116/0x3f0
netfs_prepare_write+0x76/0x7b0
netfs_unbuffered_write+0x75c/0x2020
netfs_unbuffered_write_iter_locked+0x7d6/0xa80
netfs_unbuffered_write_iter+0x442/0x720
v9fs_file_write_iter+0xbf/0x100
vfs_write+0x6ac/0x1050
[1]
KASAN: null-ptr-deref in range [0x00000000000000a8-0x00000000000000af]
RIP: 0010:netfs_prepare_write+0xbc/0x7b0 fs/netfs/write_issue.c:173
Call Trace:
netfs_unbuffered_write+0x75c/0x2020 fs/netfs/direct_write.c:111
netfs_unbuffered_write_iter_locked+0x7d6/0xa80 fs/netfs/direct_write.c:290
netfs_unbuffered_write_iter+0x442/0x720 fs/netfs/direct_write.c:382
v9fs_file_write_iter+0xbf/0x100 fs/9p/vfs_file.c:409
new_sync_write fs/read_write.c:595 [inline]
Fixes: 288ace2f57c9 ("netfs: New writeback implementation")
Reported-by: syzbot+6a13fc77eb6f0802be2d@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6a13fc77eb6f0802be2d
Tested-by: syzbot+6a13fc77eb6f0802be2d@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@qq.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-7-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/direct_write.c | 5 +++++
fs/netfs/write_issue.c | 2 ++
2 files changed, 7 insertions(+)
diff --git a/fs/netfs/direct_write.c b/fs/netfs/direct_write.c
index 86beeb337ed7f..982b78d7bdb98 100644
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -110,6 +110,11 @@ static int netfs_unbuffered_write(struct netfs_io_request *wreq)
if (!subreq) {
netfs_prepare_write(wreq, stream, wreq->start + wreq->transferred);
subreq = stream->construct;
+ if (!subreq) {
+ wreq->error = -ENOMEM;
+ ret = -ENOMEM;
+ break;
+ }
stream->construct = NULL;
}
diff --git a/fs/netfs/write_issue.c b/fs/netfs/write_issue.c
index 2d9cfcd43658f..851f6f93ad45a 100644
--- a/fs/netfs/write_issue.c
+++ b/fs/netfs/write_issue.c
@@ -170,6 +170,8 @@ void netfs_prepare_write(struct netfs_io_request *wreq,
rolling_buffer_make_space(&wreq->buffer, wreq->gfp);
subreq = netfs_alloc_subrequest(wreq);
+ if (!subreq)
+ return;
subreq->source = stream->source;
subreq->start = start;
subreq->stream_nr = stream->stream_nr;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 085/733] netfs: Fix readahead synchronisation issues by loading all folios upfront
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (83 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 084/733] netfs: break unbuffered write when netfs_alloc_subrequest() fails Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 086/733] netfs: Mark folios with COPY_TO_CACHE whilst issuing subreqs Greg Kroah-Hartman
` (659 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
Matthew Wilcox, netfs, linux-mm, linux-fsdevel,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit fed0b33e6c584986ba70018ec9f9787a98216e64 ]
There are some synchronisation issues that derive from the app thread
adding more folios to the rolling buffer whilst the collector thread is
looking at them or trying to clear them, such as determining the setting of
front_folio_order when the next folio hasn't been added yet,
The reason for the rolling buffer approach is that loading the buffer
upfront and then dropping all the refs just acquired is quite a slow
operation, and loading progressively allows some of the cost to be deferred
until after at least some of the I/O is started.
Instead, a better way is to load all the folios into the rolling buffer
upfront - and then drop the refs later, once the I/O is in progress. (Even
better would be for the refs not to be there at all.)
Fix this by changing the rolling buffer loader to load all the folios
selected by the VM for readahead upfront into the folio queue. The folio
queue is allocated a batch worth at a time as we don't know how many folios
are involved (the readahead_control struct, alas, has a page count, not a
folio count).
The folio refs acquired from readahead are then dropped in bulk once the
first subrequest is dispatched as it's quite a slow operation. The
collector waits for NETFS_RREQ_NEED_PUT_RA_REFS to be cleared so that it
doesn't unlock folios before the xarray has been scanned for them.
This simplifies the buffer handling later and isn't noticeably slower as
the xarray doesn't need to be modified and the folios are all already
pre-locked.
Fixes: ee4cdf7ba857 ("netfs: Speed up buffered reading")
Link: https://sashiko.dev/#/patchset/20260824120224.504575-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-8-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara (Red Hat) <pc@manguebit.org>
cc: Matthew Wilcox <willy@infradead.org>
cc: netfs@lists.linux.dev
cc: linux-mm@kvack.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/buffered_read.c | 101 ++++++++++++++++++++-------------
fs/netfs/internal.h | 1 +
fs/netfs/misc.c | 19 +++++++
fs/netfs/read_collect.c | 7 +++
fs/netfs/read_retry.c | 7 +++
fs/netfs/rolling_buffer.c | 81 ++++++++++++++++----------
include/linux/netfs.h | 1 +
include/linux/rolling_buffer.h | 6 +-
include/trace/events/netfs.h | 3 +
9 files changed, 154 insertions(+), 72 deletions(-)
diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 7fdfa4f27e349..303fdce54fbaf 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -54,6 +54,42 @@ static void netfs_rreq_expand(struct netfs_io_request *rreq,
}
}
+/*
+ * Drop the folio refs acquired from the readahead API.
+ */
+static void netfs_bulk_drop_ra_refs(struct netfs_io_request *rreq)
+{
+ struct folio_batch fbatch;
+ struct folio *folio;
+ pgoff_t nr_pages = DIV_ROUND_UP(rreq->len, PAGE_SIZE);
+ pgoff_t first = rreq->start / PAGE_SIZE;
+ XA_STATE(xas, &rreq->mapping->i_pages, first);
+
+ folio_batch_init(&fbatch);
+
+ rcu_read_lock();
+
+ xas_for_each(&xas, folio, first + nr_pages - 1) {
+ if (xas_retry(&xas, folio))
+ continue;
+
+ if (!folio_batch_add(&fbatch, folio))
+ folio_batch_release(&fbatch);
+ }
+
+ rcu_read_unlock();
+ folio_batch_release(&fbatch);
+ trace_netfs_rreq(rreq, netfs_rreq_trace_ra_put_ref);
+ clear_bit_unlock(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags);
+ wake_up(&rreq->waitq);
+}
+
+static void netfs_maybe_bulk_drop_ra_refs(struct netfs_io_request *rreq)
+{
+ if (test_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags))
+ netfs_bulk_drop_ra_refs(rreq);
+}
+
/*
* Begin an operation, and fetch the stored zero point value from the cookie if
* available.
@@ -74,12 +110,8 @@ static int netfs_begin_cache_read(struct netfs_io_request *rreq, struct netfs_in
*
* Returns the limited size if successful and -ENOMEM if insufficient memory
* available.
- *
- * [!] NOTE: This must be run in the same thread as ->issue_read() was called
- * in as we access the readahead_control struct.
*/
-static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq,
- struct readahead_control *ractl)
+static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq)
{
struct netfs_io_request *rreq = subreq->rreq;
size_t rsize = subreq->len;
@@ -87,30 +119,6 @@ static ssize_t netfs_prepare_read_iterator(struct netfs_io_subrequest *subreq,
if (subreq->source == NETFS_DOWNLOAD_FROM_SERVER)
rsize = umin(rsize, rreq->io_streams[0].sreq_max_len);
- if (ractl) {
- /* If we don't have sufficient folios in the rolling buffer,
- * extract a folioq's worth from the readahead region at a time
- * into the buffer. Note that this acquires a ref on each page
- * that we will need to release later - but we don't want to do
- * that until after we've started the I/O.
- */
- struct folio_batch put_batch;
-
- folio_batch_init(&put_batch);
- while (rreq->submitted < subreq->start + rsize) {
- ssize_t added;
-
- added = rolling_buffer_load_from_ra(&rreq->buffer, ractl,
- &put_batch);
- if (added < 0) {
- folio_batch_release(&put_batch);
- return added;
- }
- rreq->submitted += added;
- }
- folio_batch_release(&put_batch);
- }
-
subreq->len = rsize;
if (unlikely(rreq->io_streams[0].sreq_max_segs)) {
size_t limit = netfs_limit_iter(&rreq->buffer.iter, 0, rsize,
@@ -208,8 +216,7 @@ static void netfs_issue_read(struct netfs_io_request *rreq,
* slicing up the region to be read according to available cache blocks and
* network rsize.
*/
-static void netfs_read_to_pagecache(struct netfs_io_request *rreq,
- struct readahead_control *ractl)
+static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
{
unsigned long long start = rreq->start;
ssize_t size = rreq->len;
@@ -288,7 +295,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq,
break;
issue:
- slice = netfs_prepare_read_iterator(subreq, ractl);
+ slice = netfs_prepare_read_iterator(subreq);
if (slice < 0) {
ret = slice;
netfs_cancel_read(subreq, ret);
@@ -302,6 +309,7 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq,
}
netfs_issue_read(rreq, subreq);
+ netfs_maybe_bulk_drop_ra_refs(rreq);
if (test_bit(NETFS_RREQ_PAUSE, &rreq->flags))
netfs_wait_for_paused_read(rreq);
@@ -339,7 +347,8 @@ void netfs_readahead(struct readahead_control *ractl)
{
struct netfs_io_request *rreq;
struct netfs_inode *ictx = netfs_inode(ractl->mapping->host);
- unsigned long long start = readahead_pos(ractl);
+ ssize_t added;
+ uoff_t start = readahead_pos(ractl);
size_t size = readahead_length(ractl);
int ret;
@@ -360,11 +369,23 @@ void netfs_readahead(struct readahead_control *ractl)
netfs_rreq_expand(rreq, ractl);
- rreq->submitted = rreq->start;
- if (rolling_buffer_init(&rreq->buffer, rreq->debug_id, ITER_DEST, rreq->gfp) < 0)
+ /* Load the folios to be read into a bvecq chain. Note that this
+ * acquires a ref on each folio that we will need to release later -
+ * but we don't want to do that until after we've started the I/O.
+ */
+ added = rolling_buffer_bulk_load_from_ra(&rreq->buffer, ractl,
+ rreq->debug_id, rreq->gfp);
+ if (added < 0) {
+ ret = added;
goto cleanup_free;
- netfs_read_to_pagecache(rreq, ractl);
+ }
+ __set_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags);
+
+ rreq->submitted = rreq->start + added;
+ rreq->cleaned_to = rreq->start;
+ netfs_read_to_pagecache(rreq);
+ netfs_maybe_bulk_drop_ra_refs(rreq);
return netfs_put_request(rreq, netfs_rreq_trace_put_return);
cleanup_free:
@@ -457,7 +478,7 @@ static int netfs_read_gaps(struct file *file, struct folio *folio)
iov_iter_bvec(&rreq->buffer.iter, ITER_DEST, bvec, i, rreq->len);
rreq->submitted = rreq->start + flen;
- netfs_read_to_pagecache(rreq, NULL);
+ netfs_read_to_pagecache(rreq);
ret = netfs_wait_for_read(rreq);
if (ret >= 0) {
@@ -532,7 +553,7 @@ int netfs_read_folio(struct file *file, struct folio *folio)
if (ret < 0)
goto discard;
- netfs_read_to_pagecache(rreq, NULL);
+ netfs_read_to_pagecache(rreq);
ret = netfs_wait_for_read(rreq);
netfs_put_request(rreq, netfs_rreq_trace_put_return);
return ret < 0 ? ret : 0;
@@ -689,7 +710,7 @@ int netfs_write_begin(struct netfs_inode *ctx,
if (ret < 0)
goto error_put;
- netfs_read_to_pagecache(rreq, NULL);
+ netfs_read_to_pagecache(rreq);
ret = netfs_wait_for_read(rreq);
netfs_put_request(rreq, netfs_rreq_trace_put_return);
if (ret < 0)
@@ -754,7 +775,7 @@ int netfs_prefetch_for_write(struct file *file, struct folio *folio,
if (ret < 0)
goto error_put;
- netfs_read_to_pagecache(rreq, NULL);
+ netfs_read_to_pagecache(rreq);
ret = netfs_wait_for_read(rreq);
netfs_put_request(rreq, netfs_rreq_trace_put_return);
return ret < 0 ? ret : 0;
diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
index 420ee7b26580f..bd8b2d633f968 100644
--- a/fs/netfs/internal.h
+++ b/fs/netfs/internal.h
@@ -79,6 +79,7 @@ ssize_t netfs_wait_for_read(struct netfs_io_request *rreq);
ssize_t netfs_wait_for_write(struct netfs_io_request *rreq);
void netfs_wait_for_paused_read(struct netfs_io_request *rreq);
void netfs_wait_for_paused_write(struct netfs_io_request *rreq);
+void netfs_wait_for_put_ra_refs(struct netfs_io_request *rreq);
/*
* objects.c
diff --git a/fs/netfs/misc.c b/fs/netfs/misc.c
index 5d554512ed23a..f5c1c463f4ff7 100644
--- a/fs/netfs/misc.c
+++ b/fs/netfs/misc.c
@@ -563,3 +563,22 @@ void netfs_wait_for_paused_write(struct netfs_io_request *rreq)
{
return netfs_wait_for_pause(rreq, netfs_write_collection);
}
+
+/*
+ * Wait for the readahead-acquired refs to be put.
+ */
+void netfs_wait_for_put_ra_refs(struct netfs_io_request *rreq)
+{
+ DEFINE_WAIT(myself);
+
+ for (;;) {
+ trace_netfs_rreq(rreq, netfs_rreq_trace_wait_put_ra_refs);
+ prepare_to_wait(&rreq->waitq, &myself, TASK_UNINTERRUPTIBLE);
+ if (!test_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags))
+ break;
+ schedule();
+ }
+
+ trace_netfs_rreq(rreq, netfs_rreq_trace_waited_put_ra_refs);
+ finish_wait(&rreq->waitq, &myself);
+}
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
index 23660a5901246..edf7cea7e2f91 100644
--- a/fs/netfs/read_collect.c
+++ b/fs/netfs/read_collect.c
@@ -118,6 +118,13 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
slot = 0;
}
+ /* We have to wait for readahead refs to have been released before we
+ * can unlock any folios as the ref-dropper walks i_pages and the only
+ * thing preventing these folios from being removed is the folio lock.
+ */
+ if (test_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags))
+ netfs_wait_for_put_ra_refs(rreq);
+
for (;;) {
struct folio *folio;
unsigned long long fpos, fend;
diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c
index 2b42758e01ec9..dd463a485139c 100644
--- a/fs/netfs/read_retry.c
+++ b/fs/netfs/read_retry.c
@@ -292,6 +292,13 @@ void netfs_unlock_abandoned_read_pages(struct netfs_io_request *rreq)
{
struct folio_queue *p;
+ /* We have to wait for readahead refs to have been released before we
+ * can unlock any folios as the ref-dropper walks i_pages and the only
+ * thing preventing these folios from being removed is the folio lock.
+ */
+ if (test_bit(NETFS_RREQ_NEED_PUT_RA_REFS, &rreq->flags))
+ netfs_wait_for_put_ra_refs(rreq);
+
for (p = rreq->buffer.tail; p; p = p->next) {
for (int slot = 0; slot < folioq_count(p); slot++) {
struct folio *folio = folioq_folio(p, slot);
diff --git a/fs/netfs/rolling_buffer.c b/fs/netfs/rolling_buffer.c
index 8c0026836f9c1..424e77a9a1098 100644
--- a/fs/netfs/rolling_buffer.c
+++ b/fs/netfs/rolling_buffer.c
@@ -115,42 +115,65 @@ int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp)
}
/*
- * Decant the list of folios to read into a rolling buffer.
+ * Decant the entire list of folios to read into a rolling buffer.
*/
-ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll,
- struct readahead_control *ractl,
- struct folio_batch *put_batch)
+ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll,
+ struct readahead_control *ractl,
+ unsigned int rreq_id, gfp_t gfp)
{
struct folio_queue *fq;
- struct page **vec;
- int nr, ix, to;
- ssize_t size = 0;
+ ssize_t loaded = 0;
- if (rolling_buffer_make_space(roll, GFP_KERNEL) < 0)
- return -ENOMEM;
+ while (ractl->_nr_pages - ractl->_batch_count > 0) {
+ unsigned int nr;
- fq = roll->head;
- vec = (struct page **)fq->vec.folios;
- nr = __readahead_batch(ractl, vec + folio_batch_count(&fq->vec),
- folio_batch_space(&fq->vec));
- ix = fq->vec.nr;
- to = ix + nr;
- fq->vec.nr = to;
- for (; ix < to; ix++) {
- struct folio *folio = folioq_folio(fq, ix);
- unsigned int order = folio_order(folio);
-
- fq->orders[ix] = order;
- size += PAGE_SIZE << order;
- trace_netfs_folio(folio, netfs_folio_trace_read);
- if (!folio_batch_add(put_batch, folio))
- folio_batch_release(put_batch);
+ /* Allocate a folioq to put some folios into and attach it to
+ * the rolling buffer.
+ */
+ fq = netfs_folioq_alloc(rreq_id, gfp,
+ netfs_trace_folioq_make_space);
+ if (!fq)
+ goto nomem_unlock;
+ fq->prev = roll->head;
+ if (!roll->tail)
+ roll->tail = fq;
+ else
+ roll->head->next = fq;
+ roll->head = fq;
+
+ /* Get a batch of folios and note their orders. */
+ nr = __readahead_batch(ractl, (struct page **)fq->vec.folios,
+ folioq_nr_slots(fq));
+ if (WARN_ON_ONCE(!nr))
+ break;
+ fq->vec.nr = nr;
+
+ for (int slot = 0; slot < nr; slot++) {
+ struct folio *folio = folioq_folio(fq, slot);
+ unsigned int order;
+
+ order = folio_order(folio);
+ fq->orders[slot] = order;
+ loaded += PAGE_SIZE << order;
+ trace_netfs_folio(folio, netfs_folio_trace_read);
+ }
}
- WRITE_ONCE(roll->iter.count, roll->iter.count + size);
- /* Store the counter after setting the slot. */
- smp_store_release(&roll->next_head_slot, to);
- return size;
+ WRITE_ONCE(roll->iter.count, loaded);
+ iov_iter_folio_queue(&roll->iter, ITER_DEST, roll->tail, 0, 0, loaded);
+ return loaded;
+
+nomem_unlock:
+ for (fq = roll->tail; fq; fq = fq->next) {
+ for (int slot = 0; slot < folioq_count(fq); slot++) {
+ folio_unlock(fq->vec.folios[slot]);
+ folioq_mark(fq, slot);
+ }
+ }
+ rolling_buffer_clear(roll);
+ roll->head = NULL;
+ roll->tail = NULL;
+ return -ENOMEM;
}
/*
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index d0b62d53eea99..e60539f039f19 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -279,6 +279,7 @@ struct netfs_io_request {
#define NETFS_RREQ_FOLIO_COPY_TO_CACHE 10 /* Copy current folio to cache from read */
#define NETFS_RREQ_UPLOAD_TO_SERVER 11 /* Need to write to the server */
#define NETFS_RREQ_USE_IO_ITER 12 /* Use ->io_iter rather than ->i_pages */
+#define NETFS_RREQ_NEED_PUT_RA_REFS 17 /* Need to put the folio refs RA gave us */
#define NETFS_RREQ_USE_PGPRIV2 31 /* [DEPRECATED] Use PG_private_2 to mark
* write to cache on read */
const struct netfs_request_ops *netfs_ops;
diff --git a/include/linux/rolling_buffer.h b/include/linux/rolling_buffer.h
index 9e5dad29669cf..a97f7cfaacaad 100644
--- a/include/linux/rolling_buffer.h
+++ b/include/linux/rolling_buffer.h
@@ -45,9 +45,9 @@ struct rolling_buffer_snapshot {
int rolling_buffer_init(struct rolling_buffer *roll, unsigned int rreq_id,
unsigned int direction, gfp_t gfp);
int rolling_buffer_make_space(struct rolling_buffer *roll, gfp_t gfp);
-ssize_t rolling_buffer_load_from_ra(struct rolling_buffer *roll,
- struct readahead_control *ractl,
- struct folio_batch *put_batch);
+ssize_t rolling_buffer_bulk_load_from_ra(struct rolling_buffer *roll,
+ struct readahead_control *ractl,
+ unsigned int rreq_id, gfp_t gfp);
ssize_t rolling_buffer_append(struct rolling_buffer *roll, struct folio *folio,
unsigned int flags, gfp_t gfp);
struct folio_queue *rolling_buffer_delete_spent(struct rolling_buffer *roll);
diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
index 082cb03c61316..9bda9302be90c 100644
--- a/include/trace/events/netfs.h
+++ b/include/trace/events/netfs.h
@@ -59,6 +59,7 @@
EM(netfs_rreq_trace_free, "FREE ") \
EM(netfs_rreq_trace_intr, "INTR ") \
EM(netfs_rreq_trace_ki_complete, "KI-CMPL") \
+ EM(netfs_rreq_trace_ra_put_ref, "RA-PUT ") \
EM(netfs_rreq_trace_recollect, "RECLLCT") \
EM(netfs_rreq_trace_redirty, "REDIRTY") \
EM(netfs_rreq_trace_resubmit, "RESUBMT") \
@@ -70,9 +71,11 @@
EM(netfs_rreq_trace_unpause, "UNPAUSE") \
EM(netfs_rreq_trace_wait_ip, "WAIT-IP") \
EM(netfs_rreq_trace_wait_pause, "--PAUSED--") \
+ EM(netfs_rreq_trace_wait_put_ra_refs, "WAIT-P-RA") \
EM(netfs_rreq_trace_wait_quiesce, "WAIT-QUIESCE") \
EM(netfs_rreq_trace_waited_ip, "DONE-IP") \
EM(netfs_rreq_trace_waited_pause, "--UNPAUSED--") \
+ EM(netfs_rreq_trace_waited_put_ra_refs, "DONE-P-RA") \
EM(netfs_rreq_trace_waited_quiesce, "DONE-QUIESCE") \
EM(netfs_rreq_trace_wake_ip, "WAKE-IP") \
EM(netfs_rreq_trace_wake_queue, "WAKE-Q ") \
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 086/733] netfs: Mark folios with COPY_TO_CACHE whilst issuing subreqs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (84 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 085/733] netfs: Fix readahead synchronisation issues by loading all folios upfront Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 087/733] netfs: Fix read progress reporting Greg Kroah-Hartman
` (658 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
Matthew Wilcox, netfs, linux-mm, linux-fsdevel,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit 533203c4183123dad8ffecd694e7573a0ccd0da0 ]
Mark folios with NETFS_FOLIO_COPY_TO_CACHE whilst issuing subreqs rather than
when collecting them. This means that the collector thread doesn't have to
try and keep track of which subreqs contribute to which folios - and thus
which folios will need to be copied to the cache because at least one byte
wasn't in the cache. Instead, this is marked on the folios up front and the
collector need only consider the folios.
For PG_private_2-using filesystems, PG_private_2 is set instead of
NETFS_FOLIO_COPY_TO_CACHE, but otherwise it works the same.
The NETFS_RREQ_COPY_TO_CACHE is replaced with NETFS_RREQ_CANCEL_CACHING, which
is now set if caching fails somewhere, thereby causing the collection thread
to cancel the copy-to-cache marks on the remaining folios.
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-9-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara (Red Hat) <pc@manguebit.org>
cc: Matthew Wilcox <willy@infradead.org>
cc: netfs@lists.linux.dev
cc: linux-mm@kvack.org
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Stable-dep-of: e00827a4d0cf ("netfs: Fix read progress reporting")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/buffered_read.c | 61 +++++++++++++++++++++++++++++++-
fs/netfs/internal.h | 1 +
fs/netfs/read_collect.c | 67 ++++++++++++++++++++++--------------
fs/netfs/read_pgpriv2.c | 15 ++++----
fs/netfs/read_retry.c | 6 +++-
include/linux/netfs.h | 2 +-
include/trace/events/netfs.h | 6 ++--
7 files changed, 121 insertions(+), 37 deletions(-)
diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 303fdce54fbaf..16d4db776f6ae 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -211,6 +211,56 @@ static void netfs_issue_read(struct netfs_io_request *rreq,
}
}
+/*
+ * Mark folios that we want to copy to the cache. For filesystems that use
+ * netfslib fully, we set folio->private to NETFS_FOLIO_COPY_TO_CACHE;
+ * otherwise we set the deprecated PG_private_2.
+ */
+static void netfs_mark_copy_to_cache(struct netfs_io_request *rreq,
+ struct folio_queue **fq,
+ unsigned int *offset,
+ int *slot,
+ size_t len,
+ bool copy)
+{
+ while (len > 0) {
+ struct folio *folio;
+ size_t fsize, overlap;
+
+ if (!*fq)
+ break;
+ if (*slot >= folioq_count(*fq)) {
+ *fq = (*fq)->next;
+ *slot = 0;
+ *offset = 0;
+ continue;
+ }
+
+ /* Determine how much the subreq overlaps the folio, if at all. */
+ fsize = folioq_folio_size(*fq, *slot);
+ overlap = min(len, fsize - *offset);
+
+ if (overlap > 0 && copy) {
+ folio = folioq_folio(*fq, *slot);
+ if (unlikely(test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags))) {
+ if (!folio_test_private_2(folio))
+ folio_start_private_2(folio);
+ } else {
+ if (!folio_get_private(folio))
+ folio_attach_private(folio, NETFS_FOLIO_COPY_TO_CACHE);
+ }
+ trace_netfs_folio(folio, netfs_folio_trace_mark_copy);
+ }
+
+ len -= overlap;
+ *offset += overlap;
+ if (*offset >= fsize) {
+ *slot += 1;
+ *offset = 0;
+ }
+ }
+}
+
/*
* Perform a read to the pagecache from a series of sources of different types,
* slicing up the region to be read according to available cache blocks and
@@ -218,9 +268,11 @@ static void netfs_issue_read(struct netfs_io_request *rreq,
*/
static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
{
+ struct folio_queue *fq = rreq->buffer.tail;
unsigned long long start = rreq->start;
+ unsigned int offset = 0;
ssize_t size = rreq->len;
- int ret = 0;
+ int ret = 0, slot = 0;
do {
struct netfs_io_subrequest *subreq;
@@ -308,6 +360,13 @@ static void netfs_read_to_pagecache(struct netfs_io_request *rreq)
set_bit(NETFS_RREQ_ALL_QUEUED, &rreq->flags);
}
+ if (fq) {
+ /* See if the cache indicated this should be cached. */
+ bool copy = test_bit(NETFS_SREQ_COPY_TO_CACHE, &subreq->flags);
+
+ netfs_mark_copy_to_cache(rreq, &fq, &slot, &offset, slice, copy);
+ }
+
netfs_issue_read(rreq, subreq);
netfs_maybe_bulk_drop_ra_refs(rreq);
diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
index bd8b2d633f968..dfe7939f35f37 100644
--- a/fs/netfs/internal.h
+++ b/fs/netfs/internal.h
@@ -110,6 +110,7 @@ static inline void netfs_see_subrequest(struct netfs_io_subrequest *subreq,
/*
* read_collect.c
*/
+void netfs_cancel_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio);
bool netfs_read_collection(struct netfs_io_request *rreq);
void netfs_read_collection_worker(struct work_struct *work);
void netfs_cancel_read(struct netfs_io_subrequest *subreq, int error);
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
index edf7cea7e2f91..12a786be1ea26 100644
--- a/fs/netfs/read_collect.c
+++ b/fs/netfs/read_collect.c
@@ -19,7 +19,6 @@
#define MADE_PROGRESS 0x04 /* Made progress cleaning up a stream or the folio set */
#define BUFFERED 0x08 /* The pagecache needs cleaning up */
#define NEED_RETRY 0x10 /* A front op requests retrying */
-#define COPY_TO_CACHE 0x40 /* Need to copy subrequest to cache */
#define ABANDON_SREQ 0x80 /* Need to abandon untransferred part of subrequest */
/*
@@ -34,6 +33,30 @@ static void netfs_clear_unread(struct netfs_io_subrequest *subreq)
__set_bit(NETFS_SREQ_HIT_EOF, &subreq->flags);
}
+/*
+ * Cancel the copy-to-cache mark on a folio.
+ */
+void netfs_cancel_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)
+{
+ if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+ if (folio_get_private(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
+ folio_detach_private(folio);
+ trace_netfs_folio(folio, netfs_folio_trace_cancel_copy);
+ } else if (netfs_folio_group(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
+ struct netfs_folio *finfo = netfs_folio_info(folio);
+
+ finfo->netfs_group = NULL;
+ trace_netfs_folio(folio, netfs_folio_trace_cancel_copy);
+ }
+ } else {
+ // TODO: Use of PG_private_2 is deprecated.
+ if (folio_test_private_2(folio)) {
+ folio_end_private_2(folio);
+ trace_netfs_folio(folio, netfs_folio_trace_cancel_copy);
+ }
+ }
+}
+
/*
* Flush, mark and unlock a folio that's now completely read. If we want to
* cache the folio, we set the group to NETFS_FOLIO_COPY_TO_CACHE, mark it
@@ -48,37 +71,37 @@ static void netfs_unlock_read_folio(struct netfs_io_request *rreq,
if (unlikely(folio_pos(folio) < rreq->abandon_to)) {
trace_netfs_folio(folio, netfs_folio_trace_abandon);
+ netfs_cancel_copy_to_cache(rreq, folio);
goto just_unlock;
}
flush_dcache_folio(folio);
folio_mark_uptodate(folio);
- if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
- finfo = netfs_folio_info(folio);
- if (finfo) {
- trace_netfs_folio(folio, netfs_folio_trace_filled_gaps);
- if (finfo->netfs_group)
- folio_change_private(folio, finfo->netfs_group);
- else
- folio_detach_private(folio);
- kfree(finfo);
- }
+ if (unlikely(test_bit(NETFS_RREQ_CANCEL_CACHING, &rreq->flags)))
+ netfs_cancel_copy_to_cache(rreq, folio);
- if (test_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags)) {
- if (!WARN_ON_ONCE(folio_get_private(folio) != NULL)) {
- trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
- folio_attach_private(folio, NETFS_FOLIO_COPY_TO_CACHE);
- folio_mark_dirty(folio);
- }
+ if (!test_bit(NETFS_RREQ_USE_PGPRIV2, &rreq->flags)) {
+ if (netfs_folio_group(folio) == NETFS_FOLIO_COPY_TO_CACHE) {
+ trace_netfs_folio(folio, netfs_folio_trace_sched_copy);
+ folio_mark_dirty(folio);
} else {
+ finfo = netfs_folio_info(folio);
+ if (finfo) {
+ trace_netfs_folio(folio, netfs_folio_trace_filled_gaps);
+ if (finfo->netfs_group)
+ folio_change_private(folio, finfo->netfs_group);
+ else
+ folio_detach_private(folio);
+ kfree(finfo);
+ }
trace_netfs_folio(folio, netfs_folio_trace_read_done);
}
folioq_clear(folioq, slot);
} else {
// TODO: Use of PG_private_2 is deprecated.
- if (test_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags))
+ if (folio_test_private_2(folio))
netfs_pgpriv2_copy_to_cache(rreq, folio);
}
@@ -131,9 +154,6 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
unsigned int order;
size_t fsize;
- if (*notes & COPY_TO_CACHE)
- set_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);
-
folio = folioq_folio(folioq, slot);
if (WARN_ONCE(!folio_test_locked(folio),
"R=%08x: folio %lx is not locked\n",
@@ -156,8 +176,6 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
WRITE_ONCE(rreq->cleaned_to, fpos + fsize);
*notes |= MADE_PROGRESS;
- clear_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);
-
/* Clean up the head folioq. If we clear an entire folioq, then
* we can get rid of it provided it's not also the tail folioq
* being filled by the issuer.
@@ -255,9 +273,6 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
stream->collected_to = front->start + transferred;
rreq->collected_to = stream->collected_to;
- if (test_bit(NETFS_SREQ_COPY_TO_CACHE, &front->flags))
- notes |= COPY_TO_CACHE;
-
if (test_bit(NETFS_SREQ_FAILED, &front->flags)) {
rreq->abandon_to = front->start + front->len;
front->transferred = front->len;
diff --git a/fs/netfs/read_pgpriv2.c b/fs/netfs/read_pgpriv2.c
index c31190993b762..a4b7bb88cbdb6 100644
--- a/fs/netfs/read_pgpriv2.c
+++ b/fs/netfs/read_pgpriv2.c
@@ -54,8 +54,8 @@ static void netfs_pgpriv2_copy_folio(struct netfs_io_request *creq, struct folio
/* Attach the folio to the rolling buffer. */
if (rolling_buffer_append(&creq->buffer, folio, 0, creq->gfp) < 0) {
+ set_bit(NETFS_RREQ_CANCEL_CACHING, &creq->flags);
folio_end_private_2(folio);
- clear_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &creq->flags);
return;
}
@@ -122,13 +122,14 @@ static struct netfs_io_request *netfs_pgpriv2_begin_copy_to_cache(
netfs_put_failed_request(creq);
cancel:
rreq->copy_to_cache = ERR_PTR(-ENOBUFS);
- clear_bit(NETFS_RREQ_FOLIO_COPY_TO_CACHE, &rreq->flags);
+ set_bit(NETFS_RREQ_CANCEL_CACHING, &rreq->flags);
return ERR_PTR(-ENOBUFS);
}
/*
* [DEPRECATED] Mark page as requiring copy-to-cache using PG_private_2 and add
- * it to the copy write request.
+ * it to the copy write request. PG_private_2 should already be set on the
+ * folio.
*/
void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio)
{
@@ -136,11 +137,13 @@ void netfs_pgpriv2_copy_to_cache(struct netfs_io_request *rreq, struct folio *fo
if (!creq)
creq = netfs_pgpriv2_begin_copy_to_cache(rreq, folio);
- if (IS_ERR(creq))
+ if (IS_ERR(creq)) {
+ set_bit(NETFS_RREQ_CANCEL_CACHING, &rreq->flags);
+ netfs_cancel_copy_to_cache(rreq, folio);
return;
+ }
- trace_netfs_folio(folio, netfs_folio_trace_copy_to_cache);
- folio_start_private_2(folio);
+ trace_netfs_folio(folio, netfs_folio_trace_pgpriv2_copy);
netfs_pgpriv2_copy_folio(creq, folio);
}
diff --git a/fs/netfs/read_retry.c b/fs/netfs/read_retry.c
index dd463a485139c..4f6a36c6e214f 100644
--- a/fs/netfs/read_retry.c
+++ b/fs/netfs/read_retry.c
@@ -303,7 +303,11 @@ void netfs_unlock_abandoned_read_pages(struct netfs_io_request *rreq)
for (int slot = 0; slot < folioq_count(p); slot++) {
struct folio *folio = folioq_folio(p, slot);
- if (folio && !folioq_is_marked2(p, slot)) {
+ if (!folio)
+ continue;
+ netfs_cancel_copy_to_cache(rreq, folio);
+
+ if (!folioq_is_marked2(p, slot)) {
if (folio == rreq->no_unlock_folio &&
test_bit(NETFS_RREQ_NO_UNLOCK_FOLIO,
&rreq->flags)) {
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index e60539f039f19..029456e034849 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -276,7 +276,7 @@ struct netfs_io_request {
#define NETFS_RREQ_SHORT_TRANSFER 5 /* Set if we have a short transfer */
#define NETFS_RREQ_OFFLOAD_COLLECTION 8 /* Offload collection to workqueue */
#define NETFS_RREQ_NO_UNLOCK_FOLIO 9 /* Don't unlock no_unlock_folio on completion */
-#define NETFS_RREQ_FOLIO_COPY_TO_CACHE 10 /* Copy current folio to cache from read */
+#define NETFS_RREQ_CANCEL_CACHING 10 /* Set to cancel caching */
#define NETFS_RREQ_UPLOAD_TO_SERVER 11 /* Need to write to the server */
#define NETFS_RREQ_USE_IO_ITER 12 /* Use ->io_iter rather than ->i_pages */
#define NETFS_RREQ_NEED_PUT_RA_REFS 17 /* Need to put the folio refs RA gave us */
diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
index 9bda9302be90c..a22084813cb59 100644
--- a/include/trace/events/netfs.h
+++ b/include/trace/events/netfs.h
@@ -198,7 +198,6 @@
EM(netfs_folio_trace_clear_cc, "clear-cc") \
EM(netfs_folio_trace_clear_g, "clear-g") \
EM(netfs_folio_trace_clear_s, "clear-s") \
- EM(netfs_folio_trace_copy_to_cache, "mark-copy") \
EM(netfs_folio_trace_end_copy, "end-copy") \
EM(netfs_folio_trace_filled_gaps, "filled-gaps") \
EM(netfs_folio_trace_invalidate_all, "inval-all") \
@@ -209,16 +208,19 @@
EM(netfs_folio_trace_kill_cc, "kill-cc") \
EM(netfs_folio_trace_kill_g, "kill-g") \
EM(netfs_folio_trace_kill_s, "kill-s") \
+ EM(netfs_folio_trace_mark_copy, "mark-copy") \
EM(netfs_folio_trace_mkwrite, "mkwrite") \
EM(netfs_folio_trace_mkwrite_plus, "mkwrite+") \
- EM(netfs_folio_trace_not_under_wback, "!wback") \
EM(netfs_folio_trace_not_locked, "!locked") \
+ EM(netfs_folio_trace_not_under_wback, "!wback") \
+ EM(netfs_folio_trace_pgpriv2_copy, "pgpriv2-copy") \
EM(netfs_folio_trace_put, "put") \
EM(netfs_folio_trace_read, "read") \
EM(netfs_folio_trace_read_done, "read-done") \
EM(netfs_folio_trace_read_gaps, "read-gaps") \
EM(netfs_folio_trace_read_unlock, "read-unlock") \
EM(netfs_folio_trace_redirtied, "redirtied") \
+ EM(netfs_folio_trace_sched_copy, "sched-copy") \
EM(netfs_folio_trace_store, "store") \
EM(netfs_folio_trace_store_copy, "store-copy") \
EM(netfs_folio_trace_store_plus, "store+") \
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 087/733] netfs: Fix read progress reporting
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (85 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 086/733] netfs: Mark folios with COPY_TO_CACHE whilst issuing subreqs Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 088/733] cachefiles: Fix potential UAF/KASAN warning Greg Kroah-Hartman
` (657 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
netfs, linux-fsdevel, Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit e00827a4d0cfebf8d78dfd0a9a024237f57c9273 ]
For really big read RPC ops that span multiple folios, netfslib allows the
filesystem to give progress notifications to wake up the collector thread
to do a collection of folios that have now been fetched, even if the RPC is
still ongoing, thereby allowing the application to make progress.
This works by taking the current rreq->cleaned_to value (which indicates
which folios have been unlocked) and adding the stashed size of the next
folio to it. cleaned_to, however, is subject to 64-bit tearing on a 32-bit
arch.
Fix this by stashing the next progress notification point as a size_t
(which won't tear) to be added to rreq->start (which won't change), with
the collector thread calculating that from cleaned_to plus the next folio
size.
Further, however, if the folios are small, the collector thread gets
constantly woken up - which has a negative performance impact on the
system.
Fix that too by setting a minimum trigger of 256KiB or the size of the
folio at the front of the queue, whichever is larger. Note that this has
an issue that different subreqs have different need-to-be-cached
properties; this is solved by a preceding patch that marks the property on
the folios whilst issuing subreqs rather than when collecting them.
Also, make sure rreq->cleaned_to is initialised up front, along with
rreq->collected_to and stream->collected_to.
Fixes: e2d46f2ec332 ("netfs: Change the read result collector to only use one work item")
Link: https://sashiko.dev/#/patchset/20260804100224.2748935-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-10-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/netfs/buffered_read.c | 2 ++
fs/netfs/internal.h | 1 +
fs/netfs/objects.c | 32 +++++++++++++--------
fs/netfs/read_collect.c | 54 ++++++++++++++++++++++++++++--------
fs/netfs/read_single.c | 2 ++
include/linux/netfs.h | 2 +-
include/trace/events/netfs.h | 21 ++++++++++++++
7 files changed, 89 insertions(+), 25 deletions(-)
diff --git a/fs/netfs/buffered_read.c b/fs/netfs/buffered_read.c
index 16d4db776f6ae..424df70a5c30f 100644
--- a/fs/netfs/buffered_read.c
+++ b/fs/netfs/buffered_read.c
@@ -442,6 +442,7 @@ void netfs_readahead(struct readahead_control *ractl)
rreq->submitted = rreq->start + added;
rreq->cleaned_to = rreq->start;
+ netfs_read_set_unlock_at(rreq);
netfs_read_to_pagecache(rreq);
netfs_maybe_bulk_drop_ra_refs(rreq);
@@ -467,6 +468,7 @@ static int netfs_create_singular_buffer(struct netfs_io_request *rreq, struct fo
if (added < 0)
return added;
rreq->submitted = rreq->start + added;
+ rreq->progress_at = added;
return 0;
}
diff --git a/fs/netfs/internal.h b/fs/netfs/internal.h
index dfe7939f35f37..c79c8e69d60ca 100644
--- a/fs/netfs/internal.h
+++ b/fs/netfs/internal.h
@@ -111,6 +111,7 @@ static inline void netfs_see_subrequest(struct netfs_io_subrequest *subreq,
* read_collect.c
*/
void netfs_cancel_copy_to_cache(struct netfs_io_request *rreq, struct folio *folio);
+void netfs_read_set_unlock_at(struct netfs_io_request *rreq);
bool netfs_read_collection(struct netfs_io_request *rreq);
void netfs_read_collection_worker(struct work_struct *work);
void netfs_cancel_read(struct netfs_io_subrequest *subreq, int error);
diff --git a/fs/netfs/objects.c b/fs/netfs/objects.c
index 01461a74642d6..7f6a3e912602e 100644
--- a/fs/netfs/objects.c
+++ b/fs/netfs/objects.c
@@ -41,24 +41,32 @@ struct netfs_io_request *netfs_alloc_request(struct address_space *mapping,
memset(rreq, 0, kmem_cache_size(cache));
INIT_WORK(&rreq->cleanup_work, netfs_free_request);
- rreq->gfp = gfp;
- rreq->start = start;
- rreq->len = len;
- rreq->origin = origin;
- rreq->netfs_ops = ctx->ops;
- rreq->mapping = mapping;
- rreq->inode = inode;
- rreq->i_size = i_size_read(inode);
- rreq->debug_id = atomic_inc_return(&debug_ids);
- rreq->wsize = INT_MAX;
+ rreq->gfp = gfp;
+ rreq->start = start;
+ rreq->collected_to = start;
+ rreq->cleaned_to = start;
+ rreq->len = len;
+ rreq->progress_at = 0;
+ rreq->origin = origin;
+ rreq->netfs_ops = ctx->ops;
+ rreq->mapping = mapping;
+ rreq->inode = inode;
+ rreq->i_size = i_size_read(inode);
+ rreq->debug_id = atomic_inc_return(&debug_ids);
+ rreq->wsize = INT_MAX;
rreq->io_streams[0].sreq_max_len = ULONG_MAX;
rreq->io_streams[0].sreq_max_segs = 0;
spin_lock_init(&rreq->lock);
- INIT_LIST_HEAD(&rreq->io_streams[0].subrequests);
- INIT_LIST_HEAD(&rreq->io_streams[1].subrequests);
init_waitqueue_head(&rreq->waitq);
refcount_set(&rreq->ref, 2);
+ for (int s = 0; s < NR_IO_STREAMS; s++) {
+ struct netfs_io_stream *stream = &rreq->io_streams[s];
+
+ INIT_LIST_HEAD(&stream->subrequests);
+ stream->collected_to = rreq->start;
+ }
+
if (origin == NETFS_READAHEAD ||
origin == NETFS_READPAGE ||
origin == NETFS_READ_GAPS ||
diff --git a/fs/netfs/read_collect.c b/fs/netfs/read_collect.c
index 12a786be1ea26..5cf22087d2439 100644
--- a/fs/netfs/read_collect.c
+++ b/fs/netfs/read_collect.c
@@ -117,6 +117,35 @@ static void netfs_unlock_read_folio(struct netfs_io_request *rreq,
folioq_clear(folioq, slot);
}
+/*
+ * Determine how much to gather before unlocking more folios.
+ */
+void netfs_read_set_unlock_at(struct netfs_io_request *rreq)
+{
+ struct folio_queue *folioq = rreq->buffer.tail;
+ unsigned int slot = rreq->buffer.first_tail_slot;
+ size_t cleaned_to = rreq->cleaned_to - rreq->start;
+ size_t progress_at = cleaned_to;
+ size_t minimum = 256 * 1024;
+
+ while (progress_at < rreq->len) {
+ if (slot >= folioq_count(folioq)) {
+ folioq = folioq->next;
+ if (!folioq)
+ break;
+ slot = 0;
+ }
+
+ progress_at += folioq_folio_size(folioq, slot);
+ if (progress_at - cleaned_to >= minimum)
+ break;
+ slot++;
+ }
+
+ WRITE_ONCE(rreq->progress_at, progress_at);
+ trace_netfs_read_progress_at(rreq);
+}
+
/*
* Unlock any folios we've finished with.
*/
@@ -135,7 +164,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
if (slot >= folioq_nr_slots(folioq)) {
folioq = rolling_buffer_delete_spent(&rreq->buffer);
if (!folioq) {
- rreq->front_folio_order = 0;
+ WRITE_ONCE(rreq->progress_at, rreq->len);
return;
}
slot = 0;
@@ -151,7 +180,6 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
for (;;) {
struct folio *folio;
unsigned long long fpos, fend;
- unsigned int order;
size_t fsize;
folio = folioq_folio(folioq, slot);
@@ -160,9 +188,7 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
rreq->debug_id, folio->index))
trace_netfs_folio(folio, netfs_folio_trace_not_locked);
- order = folioq_folio_order(folioq, slot);
- rreq->front_folio_order = order;
- fsize = PAGE_SIZE << order;
+ fsize = folioq_folio_size(folioq, slot);
fpos = folio_pos(folio);
fend = fpos + fsize;
@@ -197,6 +223,8 @@ static void netfs_read_unlock_folios(struct netfs_io_request *rreq,
rreq->buffer.tail = folioq;
done:
rreq->buffer.first_tail_slot = slot;
+
+ netfs_read_set_unlock_at(rreq);
}
/*
@@ -257,7 +285,7 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
* subreqs.
*/
if (notes & BUFFERED) {
- size_t fsize = PAGE_SIZE << rreq->front_folio_order;
+ uoff_t unlock_at = rreq->start + rreq->progress_at;
/* Clear the tail of a short read. */
if (!(notes & HIT_PENDING) &&
@@ -279,7 +307,7 @@ static void netfs_collect_read_results(struct netfs_io_request *rreq)
transferred = front->len;
trace_netfs_rreq(rreq, netfs_rreq_trace_set_abandon);
}
- if (front->start + transferred >= rreq->cleaned_to + fsize ||
+ if (front->start + transferred >= unlock_at ||
test_bit(NETFS_SREQ_HIT_EOF, &front->flags))
netfs_read_unlock_folios(rreq, ¬es);
} else {
@@ -499,20 +527,22 @@ void netfs_read_collection_worker(struct work_struct *work)
void netfs_read_subreq_progress(struct netfs_io_subrequest *subreq)
{
struct netfs_io_request *rreq = subreq->rreq;
- struct netfs_io_stream *stream = &rreq->io_streams[0];
- size_t fsize = PAGE_SIZE << rreq->front_folio_order;
-
- trace_netfs_sreq(subreq, netfs_sreq_trace_progress);
+ struct netfs_io_stream *stream = &rreq->io_streams[subreq->stream_nr];
+ size_t progress_at = READ_ONCE(rreq->progress_at);
+ uoff_t update_at = rreq->start + progress_at;
+ uoff_t transferred_to = subreq->start + subreq->transferred;
/* If we are at the head of the queue, wake up the collector,
* getting a ref to it if we were the ones to do so.
*/
- if (subreq->start + subreq->transferred > rreq->cleaned_to + fsize &&
+ if (progress_at < rreq->len &&
+ transferred_to >= update_at &&
(rreq->origin == NETFS_READAHEAD ||
rreq->origin == NETFS_READPAGE ||
rreq->origin == NETFS_READ_FOR_WRITE) &&
list_is_first(&subreq->rreq_link, &stream->subrequests)
) {
+ trace_netfs_sreq(subreq, netfs_sreq_trace_progress);
__set_bit(NETFS_SREQ_MADE_PROGRESS, &subreq->flags);
netfs_wake_collector(rreq);
}
diff --git a/fs/netfs/read_single.c b/fs/netfs/read_single.c
index 8833550d2eb60..de67ac41548d1 100644
--- a/fs/netfs/read_single.c
+++ b/fs/netfs/read_single.c
@@ -170,6 +170,8 @@ ssize_t netfs_read_single(struct inode *inode, struct file *file, struct iov_ite
if (IS_ERR(rreq))
return PTR_ERR(rreq);
+ rreq->progress_at = rreq->len;
+
ret = netfs_single_begin_cache_read(rreq, ictx);
if (ret == -ENOMEM || ret == -EINTR || ret == -ERESTARTSYS)
goto cleanup_free;
diff --git a/include/linux/netfs.h b/include/linux/netfs.h
index 029456e034849..67c2d9ef7c623 100644
--- a/include/linux/netfs.h
+++ b/include/linux/netfs.h
@@ -247,6 +247,7 @@ struct netfs_io_request {
unsigned long long submitted; /* Amount submitted for I/O so far */
unsigned long long len; /* Length of the request */
size_t transferred; /* Amount to be indicated as transferred */
+ size_t progress_at; /* Report read progress when hit this much read */
long error; /* 0 or error that occurred */
unsigned long long i_size; /* Size of the file */
unsigned long long start; /* Start position */
@@ -263,7 +264,6 @@ struct netfs_io_request {
atomic_t subreq_counter; /* Next subreq->debug_index */
unsigned int nr_group_rel; /* Number of refs to release on ->group */
spinlock_t lock; /* Lock for queuing subreqs */
- unsigned char front_folio_order; /* Order (size) of front folio */
enum netfs_io_origin origin; /* Origin of the request */
bool direct_bv_unpin; /* T if direct_bv[] must be unpinned */
refcount_t ref;
diff --git a/include/trace/events/netfs.h b/include/trace/events/netfs.h
index a22084813cb59..3fec3e8f91c85 100644
--- a/include/trace/events/netfs.h
+++ b/include/trace/events/netfs.h
@@ -791,6 +791,27 @@ TRACE_EVENT(netfs_folioq,
__print_symbolic(__entry->trace, netfs_folioq_traces))
);
+TRACE_EVENT(netfs_read_progress_at,
+ TP_PROTO(const struct netfs_io_request *rreq),
+
+ TP_ARGS(rreq),
+
+ TP_STRUCT__entry(
+ __field(unsigned int, rreq)
+ __field(size_t, progress_at)
+ __field(size_t, cleaned_to)
+ ),
+
+ TP_fast_assign(
+ __entry->rreq = rreq->debug_id;
+ __entry->cleaned_to = rreq->cleaned_to - rreq->start;
+ __entry->progress_at = rreq->progress_at;
+ ),
+
+ TP_printk("R=%08x cln=%zx prg=%zx",
+ __entry->rreq, __entry->cleaned_to, __entry->progress_at)
+ );
+
#undef EM
#undef E_
#endif /* _TRACE_NETFS_H */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 088/733] cachefiles: Fix potential UAF/KASAN warning
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (86 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 087/733] netfs: Fix read progress reporting Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 089/733] ALSA: pcm: Serialize PCM mmap with buffer reallocation to fix page UAF Greg Kroah-Hartman
` (656 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Paulo Alcantara,
netfs, linux-fsdevel, Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit a67632c8c2688d6e0091529bcefe54bc5ee80e9b ]
Currently, trace_cachefiles_coherency() is being passed a pointer to a
__be64 lain over the coherency data in struct cachefiles_xattr so that it
can display the first 8 bytes. However, the data is of variable length and
could even be 0 bytes. This could lead to a UAF or KASAN warning.
Fix this by making sure the buffer has room for at least 8 bytes and that
those 8 bytes are pre-cleared.
Further, those bytes are not 8-byte aligned, so fix the tracepoint to
extract the data as four 2-byte words (they are 2-byte aligned) and
reassemble the __be64. The compiler will convert this into a single 8-byte
load where the CPU supports it.
Fixes: 229105e5cfd9 ("cachefiles: Add auxiliary data trace")
Link: https://sashiko.dev/#/patchset/20260810144746.574036-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-11-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-fsdevel@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/cachefiles/xattr.c | 16 ++++++++--------
include/trace/events/cachefiles.h | 19 +++++++++++++++++--
2 files changed, 25 insertions(+), 10 deletions(-)
diff --git a/fs/cachefiles/xattr.c b/fs/cachefiles/xattr.c
index f8ae78b3f7b6d..c70bf67e52b01 100644
--- a/fs/cachefiles/xattr.c
+++ b/fs/cachefiles/xattr.c
@@ -13,6 +13,7 @@
#include <linux/quotaops.h>
#include <linux/xattr.h>
#include <linux/slab.h>
+#include <linux/unaligned.h>
#include "internal.h"
#define CACHEFILES_COOKIE_TYPE_DATA 1
@@ -50,7 +51,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
_enter("%x,#%d", object->debug_id, len);
- buf = kmalloc(sizeof(struct cachefiles_xattr) + len, GFP_KERNEL);
+ buf = kmalloc(sizeof(struct cachefiles_xattr) + max(len, sizeof(__be64)), GFP_KERNEL);
if (!buf)
return -ENOMEM;
@@ -60,6 +61,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
buf->content = object->content_info;
if (test_bit(FSCACHE_COOKIE_LOCAL_WRITE, &object->cookie->flags))
buf->content = CACHEFILES_CONTENT_DIRTY;
+ put_unaligned_be64(0, (__be64 *)buf->data);
if (len > 0)
memcpy(buf->data, fscache_get_aux(object->cookie), len);
@@ -77,8 +79,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
trace_cachefiles_vfs_error(object, file_inode(file), ret,
cachefiles_trace_setxattr_error);
trace_cachefiles_coherency(object, file_inode(file)->i_ino,
- be64_to_cpup((__be64 *)buf->data),
- buf->content,
+ buf->data, buf->content,
cachefiles_coherency_set_fail);
if (ret != -ENOMEM)
cachefiles_io_error_obj(
@@ -86,8 +87,7 @@ int cachefiles_set_object_xattr(struct cachefiles_object *object)
"Failed to set xattr with error %d", ret);
} else {
trace_cachefiles_coherency(object, file_inode(file)->i_ino,
- be64_to_cpup((__be64 *)buf->data),
- buf->content,
+ buf->data, buf->content,
cachefiles_coherency_set_ok);
}
@@ -110,9 +110,10 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file
int ret = -ESTALE;
tlen = sizeof(struct cachefiles_xattr) + len;
- buf = kmalloc(tlen, GFP_KERNEL);
+ buf = kmalloc(sizeof(struct cachefiles_xattr) + max(len, sizeof(__be64)), GFP_KERNEL);
if (!buf)
return -ENOMEM;
+ put_unaligned_be64(0, (__be64 *)buf->data);
xlen = cachefiles_inject_read_error();
if (xlen == 0)
@@ -148,8 +149,7 @@ int cachefiles_check_auxdata(struct cachefiles_object *object, struct file *file
out:
trace_cachefiles_coherency(object, file_inode(file)->i_ino,
- be64_to_cpup((__be64 *)buf->data),
- buf->content, why);
+ buf->data, buf->content, why);
kfree(buf);
return ret;
}
diff --git a/include/trace/events/cachefiles.h b/include/trace/events/cachefiles.h
index 6e3b1424eea4d..d002ed508a435 100644
--- a/include/trace/events/cachefiles.h
+++ b/include/trace/events/cachefiles.h
@@ -380,7 +380,7 @@ TRACE_EVENT(cachefiles_rename,
TRACE_EVENT(cachefiles_coherency,
TP_PROTO(struct cachefiles_object *obj,
ino_t ino,
- u64 disk_aux,
+ const void *disk_aux,
enum cachefiles_content content,
enum cachefiles_coherency_trace why),
@@ -397,12 +397,27 @@ TRACE_EVENT(cachefiles_coherency,
),
TP_fast_assign(
+ union {
+ __be16 s[4];
+ __be64 ll;
+ } x;
+
__entry->obj = obj->debug_id;
__entry->why = why;
__entry->content = content;
__entry->ino = ino;
__entry->aux = be64_to_cpup((__be64 *)obj->cookie->inline_aux);
- __entry->disk_aux = disk_aux;
+
+ /* cachefiles_xattr::data is 2-byte aligned but not 8-byte aligned. */
+ if (disk_aux) {
+ x.s[0] = ((__be16 *)disk_aux)[0];
+ x.s[1] = ((__be16 *)disk_aux)[1];
+ x.s[2] = ((__be16 *)disk_aux)[2];
+ x.s[3] = ((__be16 *)disk_aux)[3];
+ __entry->disk_aux = be64_to_cpu(x.ll);
+ } else {
+ __entry->disk_aux = 0;
+ }
),
TP_printk("o=%08x %s B=%llx c=%u aux=%llx dsk=%llx",
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 089/733] ALSA: pcm: Serialize PCM mmap with buffer reallocation to fix page UAF
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (87 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 088/733] cachefiles: Fix potential UAF/KASAN warning Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 090/733] dma-buf: fix some kernel-doc warnings Greg Kroah-Hartman
` (655 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kimi Security Team, Yilin Zhang,
Takashi Iwai, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yilin Zhang <yilinzhang@moonshot.ai>
[ Upstream commit 9b110a9dcecc59516c77cb3c0caf1f492f75df2d ]
snd_pcm_hw_params() and snd_pcm_hw_free() guard buffer reallocation
with an mmap_count check performed under the PCM stream lock, but the
lock is released long before the buffer is actually freed:
snd_pcm_sync_stop(), constraint refinement and do_free_pages() all
happen in between. snd_pcm_mmap_data(), on the other hand, takes no
lock at all: it validates against the old buffer's state and
dma_bytes, remaps its pages into the VMA, and only then increments
mmap_count.
A concurrent mmap() can therefore slip in between the check and the
free. remap_pfn_range() installs writable PTEs for the old buffer's
pages without taking page references, and the subsequent
do_free_pages() returns those pages to the page allocator while the
VMA still maps them. This leaves a stale, writable mapping of freed
pages: a page-level use-after-free that can be leveraged for local
privilege escalation.
Make snd_pcm_mmap_data() participate in the buffer-access scheme
introduced for hw_params/hw_free: acquire runtime->buffer_accessing
before validating and remapping, and release it afterwards. Buffer
reallocation already fails with -EBUSY while accessors are active,
and the mmap side now fails with -EBUSY while a reallocation is in
progress, so the validate/remap sequence and the check/free sequence
can no longer interleave.
A reproducer that turns this race into a stale writable mapping of
the freed DMA buffer pages is available on request.
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Fixes: 92ee3c60ec9f ("ALSA: pcm: Fix races among concurrent hw_params and hw_free calls")
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
Link: https://patch.msgid.link/20260831045506.889070-1-yilinzhang@moonshot.ai
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/pcm_native.c | 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
diff --git a/sound/core/pcm_native.c b/sound/core/pcm_native.c
index fa6723a6e8271..2fcdde09a0305 100644
--- a/sound/core/pcm_native.c
+++ b/sound/core/pcm_native.c
@@ -4019,20 +4019,33 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
return -EINVAL;
}
runtime = substream->runtime;
- if (runtime->state == SNDRV_PCM_STATE_OPEN)
- return -EBADFD;
- if (!(runtime->info & SNDRV_PCM_INFO_MMAP))
- return -ENXIO;
+ /* don't race with buffer reallocation in hw_params/hw_free */
+ if (!atomic_inc_unless_negative(&runtime->buffer_accessing))
+ return -EBUSY;
+ if (runtime->state == SNDRV_PCM_STATE_OPEN) {
+ err = -EBADFD;
+ goto out;
+ }
+ if (!(runtime->info & SNDRV_PCM_INFO_MMAP)) {
+ err = -ENXIO;
+ goto out;
+ }
if (runtime->access == SNDRV_PCM_ACCESS_RW_INTERLEAVED ||
- runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED)
- return -EINVAL;
+ runtime->access == SNDRV_PCM_ACCESS_RW_NONINTERLEAVED) {
+ err = -EINVAL;
+ goto out;
+ }
size = area->vm_end - area->vm_start;
offset = area->vm_pgoff << PAGE_SHIFT;
dma_bytes = PAGE_ALIGN(runtime->dma_bytes);
- if ((size_t)size > dma_bytes)
- return -EINVAL;
- if (offset > dma_bytes - size)
- return -EINVAL;
+ if ((size_t)size > dma_bytes) {
+ err = -EINVAL;
+ goto out;
+ }
+ if (offset > dma_bytes - size) {
+ err = -EINVAL;
+ goto out;
+ }
area->vm_ops = &snd_pcm_vm_ops_data;
area->vm_private_data = substream;
@@ -4042,6 +4055,8 @@ int snd_pcm_mmap_data(struct snd_pcm_substream *substream, struct file *file,
err = snd_pcm_lib_default_mmap(substream, area);
if (!err)
atomic_inc(&substream->mmap_count);
+out:
+ atomic_dec(&runtime->buffer_accessing);
return err;
}
EXPORT_SYMBOL(snd_pcm_mmap_data);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 090/733] dma-buf: fix some kernel-doc warnings
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (88 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 089/733] ALSA: pcm: Serialize PCM mmap with buffer reallocation to fix page UAF Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 091/733] octeontx2-af: fix CN20K default MCAM rule removal on port cleanup Greg Kroah-Hartman
` (654 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Randy Dunlap, Christian König,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Randy Dunlap <rdunlap@infradead.org>
[ Upstream commit c8329cb590df4a8b3a4e878d289d4b17824db8d1 ]
- drop Excess description of @lock from kernel-doc
- add missing function/macro short descriptions
WARNING: include/linux/dma-fence-array.h:47 Excess struct member 'lock' description in 'dma_fence_array'
WARNING: include/linux/dma-fence-chain.h:48 Excess struct member 'lock' description in 'dma_fence_chain'
Warning: include/linux/dma-fence-chain.h:82 missing initial short description on line:
* dma_fence_chain_alloc
Warning: include/linux/dma-fence-chain.h:94 missing initial short description on line:
* dma_fence_chain_free
Fixes: 5943243914b9 ("dma-buf: use inline lock for the dma-fence-array")
Fixes: a408c0ca0c41 ("dma-buf: use inline lock for the dma-fence-chain")
Signed-off-by: Randy Dunlap <rdunlap@infradead.org>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/r/20260831031956.3410813-1-rdunlap@infradead.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/dma-fence-array.h | 1 -
include/linux/dma-fence-chain.h | 9 ++++-----
2 files changed, 4 insertions(+), 6 deletions(-)
diff --git a/include/linux/dma-fence-array.h b/include/linux/dma-fence-array.h
index 1b1d87579c382..0c49d7ccefb64 100644
--- a/include/linux/dma-fence-array.h
+++ b/include/linux/dma-fence-array.h
@@ -28,7 +28,6 @@ struct dma_fence_array_cb {
/**
* struct dma_fence_array - fence to represent an array of fences
* @base: fence base class
- * @lock: spinlock for fence handling
* @num_fences: number of fences in the array
* @num_pending: fences in the array still pending
* @fences: array of the fences
diff --git a/include/linux/dma-fence-chain.h b/include/linux/dma-fence-chain.h
index df3beadf15157..705c4394ac0d0 100644
--- a/include/linux/dma-fence-chain.h
+++ b/include/linux/dma-fence-chain.h
@@ -20,7 +20,6 @@
* @prev: previous fence of the chain
* @prev_seqno: original previous seqno before garbage collection
* @fence: encapsulated fence
- * @lock: spinlock for fence handling
*/
struct dma_fence_chain {
struct dma_fence base;
@@ -81,9 +80,8 @@ dma_fence_chain_contained(struct dma_fence *fence)
}
/**
- * dma_fence_chain_alloc
- *
- * Returns a new struct dma_fence_chain object or NULL on failure.
+ * dma_fence_chain_alloc - Returns a new &struct dma_fence_chain object or
+ * %NULL on failure.
*
* This specialized allocator has to be a macro for its allocations to be
* accounted separately (to have a separate alloc_tag). The typecast is
@@ -93,7 +91,8 @@ dma_fence_chain_contained(struct dma_fence *fence)
kmalloc_obj(struct dma_fence_chain)
/**
- * dma_fence_chain_free
+ * dma_fence_chain_free - Frees an allocated but not used
+ * &struct dma_fence_chain object.
* @chain: chain node to free
*
* Frees up an allocated but not used struct dma_fence_chain object. This
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 091/733] octeontx2-af: fix CN20K default MCAM rule removal on port cleanup
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (89 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 090/733] dma-buf: fix some kernel-doc warnings Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 092/733] drm/i915/dp_mst: Remove duplicate intel_pfit_compute_config() call Greg Kroah-Hartman
` (653 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiran Kumar K, Ratheesh Kannoth,
David S. Miller, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiran Kumar K <kirankumark@marvell.com>
[ Upstream commit 1376afc7660bad2a1a5ee0876898312a486cf8bd ]
npc_mcam_free_all_entries() disables every MCAM entry mapped to a
port before freeing it. On CN20K, that also disables the default
broadcast, multicast, promiscuous, and unicast rules, which causes
packet drops when all rules are removed per port.
Only disable and free non-default entries. Leave CN20K default rules
enabled when freeing the remaining port entries.
Fixes: 013717353c03 ("octeontx2-af: npc: cn20k: Tear down default MCAM rules explicitly on free")
Signed-off-by: Kiran Kumar K <kirankumark@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
index 38554d51164e1..6f2e6bce164de 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_npc.c
@@ -2957,10 +2957,9 @@ static void npc_mcam_free_all_entries(struct rvu *rvu, struct npc_mcam *mcam,
}
}
- /* Disable the entry */
- npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
-
if (!cn20k_dft_rl) {
+ /* Disable the entry */
+ npc_enable_mcam_entry(rvu, mcam, blkaddr, index, false);
mcam->entry2pfvf_map[index] = NPC_MCAM_INVALID_MAP;
/* Free the entry in bitmap */
npc_mcam_clear_bit(mcam, index);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 092/733] drm/i915/dp_mst: Remove duplicate intel_pfit_compute_config() call
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (90 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 091/733] octeontx2-af: fix CN20K default MCAM rule removal on port cleanup Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 093/733] drm/i915/cdclk: Fix dg2_power_well_count() return type Greg Kroah-Hartman
` (652 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rodrigo Vivi,
Ville Syrjälä, Nemesa Garg, Jani Nikula,
Chaitanya Kumar Borah, Jani Nikula, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
[ Upstream commit 6463655ab2946d13d2ec5efe04a5c2bf9d675f01 ]
mst_stream_compute_config() called intel_pfit_compute_config() twice
in a row.
commit 5ce9ac1531b8 ("drm/i915/mst: Call intel_pfit_compute_config()
for sharpness filter")
was erroneously cherry-picked to the fixes tree while
commit ca97f5546f19 ("drm/i915/mst: Call intel_pfit_compute_config()
for sharpness filter")
was already in there.
Drop the redundant duplicate call.
Cc: Rodrigo Vivi <rodrigo.vivi@intel.com>
Cc: Ville Syrjälä <ville.syrjala@linux.intel.com>
Cc: Nemesa Garg <nemesa.garg@intel.com>
Cc: Jani Nikula <jani.nikula@linux.intel.com>
Fixes: 5ce9ac1531b8 ("drm/i915/mst: Call intel_pfit_compute_config() for sharpness filter")
Signed-off-by: Chaitanya Kumar Borah <chaitanya.kumar.borah@intel.com>
Reviewed-by: Nemesa Garg <nemesa.garg@intel.com>
Link: https://patch.msgid.link/20260806074819.2631970-1-chaitanya.kumar.borah@intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
[Rodrigo: adjusted commit message]
(cherry picked from commit ea9f3470d33602fb776ea55443467baacf66f23a)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_dp_mst.c | 4 ----
1 file changed, 4 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_dp_mst.c b/drivers/gpu/drm/i915/display/intel_dp_mst.c
index 0aa3e6b4c781d..bcdc504913471 100644
--- a/drivers/gpu/drm/i915/display/intel_dp_mst.c
+++ b/drivers/gpu/drm/i915/display/intel_dp_mst.c
@@ -722,10 +722,6 @@ static int mst_stream_compute_config(struct intel_encoder *encoder,
pipe_config->sink_format = INTEL_OUTPUT_FORMAT_RGB;
pipe_config->output_format = INTEL_OUTPUT_FORMAT_RGB;
- ret = intel_pfit_compute_config(pipe_config, conn_state);
- if (ret)
- return ret;
-
ret = intel_pfit_compute_config(pipe_config, conn_state);
if (ret)
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 093/733] drm/i915/cdclk: Fix dg2_power_well_count() return type
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (91 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 092/733] drm/i915/dp_mst: Remove duplicate intel_pfit_compute_config() call Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 094/733] ovl: return EINVAL instead of EIO in case of mismatched user_ns Greg Kroah-Hartman
` (651 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ville Syrjälä, Matt Roper,
Jani Nikula, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
[ Upstream commit a154f2ae8eecbf2a4f97376d29b8d38c198b54e7 ]
dg2_power_well_count() is supposed to return an integer,
not a boolean. Make it so.
Fixes: 9112ce99c1d7 ("drm/i915/cdclk: Extract dg2_power_well_count()")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260826143100.19401-1-ville.syrjala@linux.intel.com
Reviewed-by: Matt Roper <matthew.d.roper@intel.com>
(cherry picked from commit dcf423710d0253d7d729c3992bbae0c6197c9c22)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/i915/display/intel_cdclk.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_cdclk.c b/drivers/gpu/drm/i915/display/intel_cdclk.c
index 7bc9b956554ba..44a6503b2be73 100644
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2697,8 +2697,8 @@ static void intel_set_cdclk(struct intel_display *display,
}
}
-static bool dg2_power_well_count(struct intel_display *display,
- const struct intel_cdclk_state *cdclk_state)
+static int dg2_power_well_count(struct intel_display *display,
+ const struct intel_cdclk_state *cdclk_state)
{
return display->platform.dg2 ? hweight8(cdclk_state->active_pipes) : 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 094/733] ovl: return EINVAL instead of EIO in case of mismatched user_ns
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (92 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 093/733] drm/i915/cdclk: Fix dg2_power_well_count() return type Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 095/733] smb/server: cancel async requests when closing connection Greg Kroah-Hartman
` (650 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miklos Szeredi, Amir Goldstein,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miklos Szeredi <mszeredi@redhat.com>
[ Upstream commit a518e63c377574784f49653ef5314c70e2463b0c ]
The EIO was used to signal an internal error (commit 9efb069de4ba ("ovl:
add warning on user_ns mismatch")), which is no longer the case.
Fixes: 63981fc786da ("ovl: don't warn when the mount is completed from another user namespace")
Signed-off-by: Miklos Szeredi <mszeredi@redhat.com>
Link: https://patch.msgid.link/20260825152330.850645-1-mszeredi@redhat.com
Reviewed-by: Amir Goldstein <amir73il@gmail.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/overlayfs/super.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/overlayfs/super.c b/fs/overlayfs/super.c
index 60b808b85fc43..43eb0c053dacd 100644
--- a/fs/overlayfs/super.c
+++ b/fs/overlayfs/super.c
@@ -1543,7 +1543,7 @@ int ovl_fill_super(struct super_block *sb, struct fs_context *fc)
struct ovl_fs *ofs = sb->s_fs_info;
int err;
- err = -EIO;
+ err = -EINVAL;
/* The fscontext fd may have been passed to another user namespace. */
if (fc->user_ns != current_user_ns())
goto out_err;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 095/733] smb/server: cancel async requests when closing connection
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (93 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 094/733] ovl: return EINVAL instead of EIO in case of mismatched user_ns Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 096/733] ksmbd: safely drain sessions during logoff Greg Kroah-Hartman
` (649 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Namjae Jeon, ChenXiaoSong,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: ChenXiaoSong <chenxiaosong@kylinos.cn>
[ Upstream commit 4fd5bad647bfa45eb86bfd2f03ba1bef3fcd5851 ]
An async request may still be waiting when a connection is closed.
This can stop the connection from closing.
Cancel active async requests before waiting for them to finish.
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: ChenXiaoSong <chenxiaosong@kylinos.cn>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Stable-dep-of: d12168084c8c ("ksmbd: safely drain sessions during logoff")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index af73c2ed5d249..17f4ac5597789 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -294,6 +294,26 @@ void ksmbd_conn_try_dequeue_request(struct ksmbd_work *work)
wake_up_all(&conn->req_running_q);
}
+static void ksmbd_conn_cancel_async_requests(struct ksmbd_conn *conn)
+{
+ struct ksmbd_work *work, *tmp;
+
+ ksmbd_debug(CONN, "Cancel pending async requests on releasing connection\n");
+ spin_lock(&conn->request_lock);
+ list_for_each_entry_safe(work, tmp, &conn->async_requests,
+ async_request_entry) {
+ if (work->state != KSMBD_WORK_ACTIVE)
+ continue;
+
+ ksmbd_debug(CONN, "Cancel async request id %d\n",
+ work->async_id);
+ work->state = KSMBD_WORK_CANCELLED;
+ if (work->cancel_fn)
+ work->cancel_fn(work->cancel_argv);
+ }
+ spin_unlock(&conn->request_lock);
+}
+
void ksmbd_conn_lock(struct ksmbd_conn *conn)
{
mutex_lock(&conn->srv_mutex);
@@ -608,6 +628,7 @@ int ksmbd_conn_handler_loop(void *p)
}
ksmbd_conn_set_releasing(conn);
+ ksmbd_conn_cancel_async_requests(conn);
/* Wait till all reference dropped to the Server object*/
ksmbd_debug(CONN, "Wait for all pending requests(%d)\n", atomic_read(&conn->r_count));
wait_event(conn->r_count_q, atomic_read(&conn->r_count) == 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 096/733] ksmbd: safely drain sessions during logoff
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (94 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 095/733] smb/server: cancel async requests when closing connection Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 097/733] ksmbd: propagate DACL parsing errors Greg Kroah-Hartman
` (648 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cheryl Babcock, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit d12168084c8c1b6d883c8eca5853929ac5136a9e ]
SMB3 multichannel allows requests for one session to run on multiple
connections. Wait for all channels bound to a session before freeing
shared session objects.
A deferred byte-range lock remains counted as a running request and only
wakes when its file closes. Wake blocked locks during the drain without
unpublishing or modifying their file objects. Synchronous CANCEL requests
must invoke their cancellation callback to wake pending operations, while
CHANGE_NOTIFY completion remains specific to the asynchronous path.
Serialize session teardown with channel registration and previous-session
cleanup, and use atomic work-state transitions so LOGOFF, CANCEL, and
connection teardown invoke cancellation callbacks only once.
Fixes: 76e98a158b20 ("ksmbd: fix race condition between destroy_previous_session() and smb2 operations()")
Reported-by: Cheryl Babcock <cheryl@renat.io>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/connection.c | 8 ++++--
fs/smb/server/mgmt/user_session.c | 13 ++++++++-
fs/smb/server/mgmt/user_session.h | 1 +
fs/smb/server/smb2pdu.c | 47 +++++++++++++++++++++++++++----
fs/smb/server/vfs_cache.c | 17 +++++++++--
fs/smb/server/vfs_cache.h | 1 +
6 files changed, 77 insertions(+), 10 deletions(-)
diff --git a/fs/smb/server/connection.c b/fs/smb/server/connection.c
index 17f4ac5597789..39ac777fd4527 100644
--- a/fs/smb/server/connection.c
+++ b/fs/smb/server/connection.c
@@ -13,6 +13,7 @@
#include "mgmt/ksmbd_ida.h"
#include "mgmt/user_session.h"
#include "connection.h"
+#include "vfs_cache.h"
#include "compress.h"
#include "transport_tcp.h"
#include "transport_rdma.h"
@@ -302,12 +303,12 @@ static void ksmbd_conn_cancel_async_requests(struct ksmbd_conn *conn)
spin_lock(&conn->request_lock);
list_for_each_entry_safe(work, tmp, &conn->async_requests,
async_request_entry) {
- if (work->state != KSMBD_WORK_ACTIVE)
+ if (cmpxchg(&work->state, KSMBD_WORK_ACTIVE,
+ KSMBD_WORK_CANCELLED) != KSMBD_WORK_ACTIVE)
continue;
ksmbd_debug(CONN, "Cancel async request id %d\n",
work->async_id);
- work->state = KSMBD_WORK_CANCELLED;
if (work->cancel_fn)
work->cancel_fn(work->cancel_argv);
}
@@ -391,6 +392,9 @@ int ksmbd_conn_wait_idle_sess(struct ksmbd_conn *curr_conn,
if (retry_count >= max_timeout)
return -EIO;
+ /* A blocked byte-range lock cannot drain until teardown wakes it. */
+ ksmbd_wake_session_blocked_works(sess);
+
down_read(&conn_list_lock);
hash_for_each(conn_list, bkt, conn, hlist) {
if (ksmbd_session_is_bound_to_conn(sess, conn)) {
diff --git a/fs/smb/server/mgmt/user_session.c b/fs/smb/server/mgmt/user_session.c
index d91dde3f9e619..10b31df185a60 100644
--- a/fs/smb/server/mgmt/user_session.c
+++ b/fs/smb/server/mgmt/user_session.c
@@ -650,10 +650,21 @@ void destroy_previous_session(struct ksmbd_conn *conn,
memcmp(user->passkey, prev_user->passkey, user->passkey_sz))
goto out;
+ down_write(&prev_sess->chann_lock);
+ if (prev_sess->tearing_down) {
+ up_write(&prev_sess->chann_lock);
+ goto out;
+ }
+ prev_sess->tearing_down = true;
+ up_write(&prev_sess->chann_lock);
+
ksmbd_all_conn_set_status(prev_sess, KSMBD_SESS_NEED_RECONNECT);
err = ksmbd_conn_wait_idle_sess(conn, prev_sess);
if (err) {
- ksmbd_all_conn_set_status(prev_sess, KSMBD_SESS_NEED_SETUP);
+ down_write(&prev_sess->chann_lock);
+ prev_sess->tearing_down = false;
+ up_write(&prev_sess->chann_lock);
+ ksmbd_all_conn_set_status(prev_sess, KSMBD_SESS_GOOD);
goto out;
}
diff --git a/fs/smb/server/mgmt/user_session.h b/fs/smb/server/mgmt/user_session.h
index f8a24c33f7fe4..3e52d4cc13247 100644
--- a/fs/smb/server/mgmt/user_session.h
+++ b/fs/smb/server/mgmt/user_session.h
@@ -42,6 +42,7 @@ struct ksmbd_session {
bool sign;
bool enc;
+ bool tearing_down;
int state;
__u8 *Preauth_HashValue;
diff --git a/fs/smb/server/smb2pdu.c b/fs/smb/server/smb2pdu.c
index 4cf7083f35ccd..184b28072a6f0 100644
--- a/fs/smb/server/smb2pdu.c
+++ b/fs/smb/server/smb2pdu.c
@@ -95,6 +95,11 @@ static int register_session_channel(struct ksmbd_session *sess,
int rc = 0;
down_write(&sess->chann_lock);
+ if (sess->tearing_down) {
+ rc = -ESHUTDOWN;
+ goto out;
+ }
+
if (xa_load(&sess->ksmbd_chann_list, (long)conn))
goto out;
@@ -2812,17 +2817,41 @@ int smb2_session_logoff(struct ksmbd_work *work)
smb2_set_err_rsp(work);
return -ENOENT;
}
+
+ down_write(&sess->chann_lock);
+ if (sess->tearing_down) {
+ up_write(&sess->chann_lock);
+ ksmbd_conn_unlock(conn);
+ rsp->hdr.Status = STATUS_USER_SESSION_DELETED;
+ smb2_set_err_rsp(work);
+ return -ENOENT;
+ }
+ sess->tearing_down = true;
+ up_write(&sess->chann_lock);
+
ksmbd_all_conn_set_status(sess, KSMBD_SESS_NEED_RECONNECT);
ksmbd_conn_unlock(conn);
+ err = ksmbd_conn_wait_idle_sess(conn, sess);
+ if (err) {
+ down_write(&sess->chann_lock);
+ sess->tearing_down = false;
+ up_write(&sess->chann_lock);
+ ksmbd_all_conn_set_status(sess, KSMBD_SESS_GOOD);
+ rsp->hdr.Status = STATUS_UNEXPECTED_IO_ERROR;
+ smb2_set_err_rsp(work);
+ return err;
+ }
+
ksmbd_close_session_fds(work);
- ksmbd_conn_wait_idle(conn);
if (ksmbd_tree_conn_session_logoff(sess)) {
ksmbd_debug(SMB, "Invalid tid %d\n", req->hdr.Id.SyncId.TreeId);
rsp->hdr.Status = STATUS_NETWORK_NAME_DELETED;
smb2_set_err_rsp(work);
- return -ENOENT;
+ err = -ENOENT;
+ } else {
+ err = 0;
}
down_write(&conn->session_lock);
@@ -2832,6 +2861,9 @@ int smb2_session_logoff(struct ksmbd_work *work)
ksmbd_all_conn_set_status(sess, KSMBD_SESS_NEED_SETUP);
+ if (err)
+ return err;
+
rsp->StructureSize = cpu_to_le16(4);
err = ksmbd_iov_pin_rsp(work, rsp, sizeof(struct smb2_logoff_rsp));
if (err) {
@@ -8488,14 +8520,14 @@ int smb2_cancel(struct ksmbd_work *work)
* still on conn->async_requests with a live cancel_fn
* pointing at the freed file_lock.
*/
- if (iter->state != KSMBD_WORK_ACTIVE)
+ if (cmpxchg(&iter->state, KSMBD_WORK_ACTIVE,
+ KSMBD_WORK_CANCELLED) != KSMBD_WORK_ACTIVE)
break;
ksmbd_debug(SMB,
"smb2 with AsyncId %llu cancelled command = 0x%x\n",
le64_to_cpu(hdr->Id.AsyncId),
le16_to_cpu(chdr->Command));
- iter->state = KSMBD_WORK_CANCELLED;
if (iter->cancel_fn == smb2_notify_cancel_fn)
cancelled_notify =
smb2_notify_cancel_claim(iter->cancel_argv);
@@ -8524,11 +8556,16 @@ int smb2_cancel(struct ksmbd_work *work)
iter == work)
continue;
+ if (cmpxchg(&iter->state, KSMBD_WORK_ACTIVE,
+ KSMBD_WORK_CANCELLED) != KSMBD_WORK_ACTIVE)
+ break;
+
ksmbd_debug(SMB,
"smb2 with mid %llu cancelled command = 0x%x\n",
le64_to_cpu(hdr->MessageId),
le16_to_cpu(chdr->Command));
- iter->state = KSMBD_WORK_CANCELLED;
+ if (iter->cancel_fn)
+ iter->cancel_fn(iter->cancel_argv);
break;
}
spin_unlock(&conn->request_lock);
diff --git a/fs/smb/server/vfs_cache.c b/fs/smb/server/vfs_cache.c
index 293dab9b43be1..a23bd9b1a68bc 100644
--- a/fs/smb/server/vfs_cache.c
+++ b/fs/smb/server/vfs_cache.c
@@ -727,12 +727,25 @@ static void set_close_state_blocked_works(struct ksmbd_file *fp)
spin_lock(&fp->f_lock);
list_for_each_entry(cancel_work, &fp->blocked_works,
fp_entry) {
- cancel_work->state = KSMBD_WORK_CLOSED;
- cancel_work->cancel_fn(cancel_work->cancel_argv);
+ if (xchg(&cancel_work->state, KSMBD_WORK_CLOSED) ==
+ KSMBD_WORK_ACTIVE)
+ cancel_work->cancel_fn(cancel_work->cancel_argv);
}
spin_unlock(&fp->f_lock);
}
+void ksmbd_wake_session_blocked_works(struct ksmbd_session *sess)
+{
+ struct ksmbd_file_table *ft = &sess->file_table;
+ struct ksmbd_file *fp;
+ unsigned int id;
+
+ read_lock(&ft->lock);
+ idr_for_each_entry(ft->idr, fp, id)
+ set_close_state_blocked_works(fp);
+ read_unlock(&ft->lock);
+}
+
int ksmbd_close_fd(struct ksmbd_work *work, u64 id)
{
struct ksmbd_file *fp;
diff --git a/fs/smb/server/vfs_cache.h b/fs/smb/server/vfs_cache.h
index 8bb4396f95238..d6a9cd4b6d563 100644
--- a/fs/smb/server/vfs_cache.h
+++ b/fs/smb/server/vfs_cache.h
@@ -211,6 +211,7 @@ void ksmbd_launch_ksmbd_durable_scavenger(void);
void ksmbd_stop_durable_scavenger(void);
void ksmbd_close_tree_conn_fds(struct ksmbd_work *work);
void ksmbd_close_session_fds(struct ksmbd_work *work);
+void ksmbd_wake_session_blocked_works(struct ksmbd_session *sess);
int ksmbd_close_inode_fds(struct ksmbd_work *work, struct inode *inode);
int ksmbd_init_global_file_table(void);
void ksmbd_free_global_file_table(void);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 097/733] ksmbd: propagate DACL parsing errors
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (95 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 096/733] ksmbd: safely drain sessions during logoff Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 098/733] ksmbd: rate limit unmapped SID errors Greg Kroah-Hartman
` (647 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cheryl Babcock, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit c61dc7b1b4a3234b4aa3965502908a292238805c ]
parse_dacl() silently accepts truncated ACEs and allocation failures,
allowing set_info_sec() to continue with an incomplete ACL conversion.
Return parsing and allocation errors to parse_sec_desc() so malformed
security descriptors are rejected before inode attributes or ACL xattrs
are updated.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Reported-by: Cheryl Babcock <cheryl@renat.io>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smbacl.c | 63 +++++++++++++++++++++++++-----------------
1 file changed, 38 insertions(+), 25 deletions(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index 33825c1356b47..7830f4fa836bb 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -380,10 +380,10 @@ void free_acl_state(struct posix_acl_state *state)
kfree(state->groups);
}
-static void parse_dacl(struct mnt_idmap *idmap,
- struct smb_acl *pdacl, char *end_of_acl,
- struct smb_sid *pownersid, struct smb_sid *pgrpsid,
- struct smb_fattr *fattr)
+static int parse_dacl(struct mnt_idmap *idmap,
+ struct smb_acl *pdacl, char *end_of_acl,
+ struct smb_sid *pownersid, struct smb_sid *pgrpsid,
+ struct smb_fattr *fattr)
{
int i, ret;
u16 num_aces = 0;
@@ -397,13 +397,13 @@ static void parse_dacl(struct mnt_idmap *idmap,
bool owner_found = false, group_found = false, others_found = false;
if (!pdacl)
- return;
+ return 0;
/* validate that we do not go past end of acl */
if (end_of_acl < (char *)pdacl + sizeof(struct smb_acl) ||
end_of_acl < (char *)pdacl + le16_to_cpu(pdacl->size)) {
pr_err("ACL too small to parse DACL\n");
- return;
+ return -EINVAL;
}
ksmbd_debug(SMB, "DACL revision %d size %d num aces %d\n",
@@ -415,31 +415,31 @@ static void parse_dacl(struct mnt_idmap *idmap,
num_aces = le16_to_cpu(pdacl->num_aces);
if (num_aces <= 0)
- return;
+ return 0;
dacl_size = le16_to_cpu(pdacl->size);
if (dacl_size < sizeof(struct smb_acl))
- return;
+ return -EINVAL;
if (num_aces > (dacl_size - sizeof(struct smb_acl)) /
(offsetof(struct smb_ace, sid) +
offsetof(struct smb_sid, sub_auth) + sizeof(__le16)))
- return;
+ return -EINVAL;
ret = init_acl_state(&acl_state, num_aces);
if (ret)
- return;
+ return ret;
ret = init_acl_state(&default_acl_state, num_aces);
if (ret) {
free_acl_state(&acl_state);
- return;
+ return ret;
}
ppace = kmalloc_objs(struct smb_ace *, num_aces, KSMBD_DEFAULT_GFP);
if (!ppace) {
free_acl_state(&default_acl_state);
free_acl_state(&acl_state);
- return;
+ return -ENOMEM;
}
/*
@@ -448,8 +448,10 @@ static void parse_dacl(struct mnt_idmap *idmap,
* user/group/other have no permissions
*/
for (i = 0; i < num_aces; ++i) {
- if (end_of_acl - acl_base < acl_size)
- break;
+ if (end_of_acl - acl_base < acl_size) {
+ ret = -EINVAL;
+ goto out;
+ }
ppace[i] = (struct smb_ace *)(acl_base + acl_size);
acl_base = (char *)ppace[i];
@@ -462,8 +464,10 @@ static void parse_dacl(struct mnt_idmap *idmap,
(end_of_acl - acl_base <
acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth) ||
(le16_to_cpu(ppace[i]->size) <
- acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth))
- break;
+ acl_size + sizeof(__le32) * ppace[i]->sid.num_subauth)) {
+ ret = -EINVAL;
+ goto out;
+ }
acl_size = le16_to_cpu(ppace[i]->size);
ppace[i]->access_req =
@@ -538,7 +542,6 @@ static void parse_dacl(struct mnt_idmap *idmap,
((acl_mode & 0700) >> 6) | 0004;
}
}
- kfree(ppace);
if (owner_found) {
/* The owner must be set to at least read-only. */
@@ -581,10 +584,12 @@ static void parse_dacl(struct mnt_idmap *idmap,
fattr->cf_acls =
posix_acl_alloc(acl_state.users->n +
acl_state.groups->n + 4, KSMBD_DEFAULT_GFP);
- if (fattr->cf_acls) {
- cf_pace = fattr->cf_acls->a_entries;
- posix_state_to_acl(&acl_state, cf_pace);
+ if (!fattr->cf_acls) {
+ ret = -ENOMEM;
+ goto out;
}
+ cf_pace = fattr->cf_acls->a_entries;
+ posix_state_to_acl(&acl_state, cf_pace);
}
}
@@ -595,14 +600,20 @@ static void parse_dacl(struct mnt_idmap *idmap,
fattr->cf_dacls =
posix_acl_alloc(default_acl_state.users->n +
default_acl_state.groups->n + 4, KSMBD_DEFAULT_GFP);
- if (fattr->cf_dacls) {
- cf_pdace = fattr->cf_dacls->a_entries;
- posix_state_to_acl(&default_acl_state, cf_pdace);
+ if (!fattr->cf_dacls) {
+ ret = -ENOMEM;
+ goto out;
}
+ cf_pdace = fattr->cf_dacls->a_entries;
+ posix_state_to_acl(&default_acl_state, cf_pdace);
}
}
+ ret = 0;
+out:
+ kfree(ppace);
free_acl_state(&acl_state);
free_acl_state(&default_acl_state);
+ return ret;
}
static void set_posix_acl_entries_dacl(struct mnt_idmap *idmap,
@@ -963,8 +974,10 @@ int parse_sec_desc(struct mnt_idmap *idmap, struct smb_ntsd *pntsd,
if (dacloffset < sizeof(struct smb_ntsd))
return -EINVAL;
- parse_dacl(idmap, dacl_ptr, end_of_acl,
- owner_sid_ptr, group_sid_ptr, fattr);
+ rc = parse_dacl(idmap, dacl_ptr, end_of_acl,
+ owner_sid_ptr, group_sid_ptr, fattr);
+ if (rc)
+ return rc;
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 098/733] ksmbd: rate limit unmapped SID errors
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (96 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 097/733] ksmbd: propagate DACL parsing errors Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 099/733] ksmbd: fix listener task lifetime on netdev events Greg Kroah-Hartman
` (646 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cheryl Babcock, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit feca5e70fc963b088377b20879e8cd8237c2fd7d ]
A client can include many structurally valid but unmapped SIDs in a DACL.
Logging every mapping failure lets one request generate hundreds of kernel
error messages.
Rate limit the message to prevent an authenticated client from flooding
the kernel log.
Fixes: e2f34481b24d ("cifsd: add server-side procedures for SMB3")
Reported-by: Cheryl Babcock <cheryl@renat.io>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/smbacl.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/fs/smb/server/smbacl.c b/fs/smb/server/smbacl.c
index 7830f4fa836bb..ae1527aa62697 100644
--- a/fs/smb/server/smbacl.c
+++ b/fs/smb/server/smbacl.c
@@ -525,8 +525,8 @@ static int parse_dacl(struct mnt_idmap *idmap,
temp_fattr.cf_uid = INVALID_UID;
ret = sid_to_id(idmap, &ppace[i]->sid, SIDOWNER, &temp_fattr);
if (ret || uid_eq(temp_fattr.cf_uid, INVALID_UID)) {
- pr_err("%s: Error %d mapping Owner SID to uid\n",
- __func__, ret);
+ pr_err_ratelimited("%s: Error %d mapping Owner SID to uid\n",
+ __func__, ret);
continue;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 099/733] ksmbd: fix listener task lifetime on netdev events
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (97 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 098/733] ksmbd: rate limit unmapped SID errors Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 100/733] s390/time: Use jiffies instead of jiffies_64 Greg Kroah-Hartman
` (645 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Farhad Alemi, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit a506290f59e1c6ce9ac0a13158640bb8fee93471 ]
The listener thread exits when its listening socket is shutdown. The
netdevice notifier shuts down the socket before calling kthread_stop(), so
the task_struct can be freed before kthread_stop() gets its reference.
Create the listener in a stopped state and hold an extra task_struct
reference until kthread_stop_put() completes. Also stop and release
listeners before freeing their interface records during TCP teardown.
Fixes: 3316a8fc840d ("ksmbd: server: avoid busy polling in accept loop")
Reported-by: Farhad Alemi <farhad.alemi@berkeley.edu>
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/transport_tcp.c | 36 ++++++++++++++++++++++++++---------
1 file changed, 27 insertions(+), 9 deletions(-)
diff --git a/fs/smb/server/transport_tcp.c b/fs/smb/server/transport_tcp.c
index 990b14e5d3ea2..668fc333c5be3 100644
--- a/fs/smb/server/transport_tcp.c
+++ b/fs/smb/server/transport_tcp.c
@@ -39,6 +39,7 @@ struct tcp_transport {
static const struct ksmbd_transport_ops ksmbd_tcp_transport_ops;
static void tcp_stop_kthread(struct task_struct *kthread);
+static void ksmbd_tcp_stop_listener(struct interface *iface);
static struct interface *alloc_iface(char *ifname);
static void ksmbd_tcp_disconnect(struct ksmbd_transport *t);
@@ -315,13 +316,20 @@ static int ksmbd_tcp_run_kthread(struct interface *iface)
int rc;
struct task_struct *kthread;
- kthread = kthread_run(ksmbd_kthread_fn, (void *)iface, "ksmbd-%s",
- iface->name);
+ kthread = kthread_create(ksmbd_kthread_fn, (void *)iface, "ksmbd-%s",
+ iface->name);
if (IS_ERR(kthread)) {
rc = PTR_ERR(kthread);
return rc;
}
+
+ /*
+ * The listener can exit after its socket is shutdown, so keep the
+ * task_struct alive until the caller has stopped it.
+ */
+ get_task_struct(kthread);
iface->ksmbd_kthread = kthread;
+ wake_up_process(kthread);
return 0;
}
@@ -585,12 +593,7 @@ static int ksmbd_netdev_event(struct notifier_block *nb, unsigned long event,
if (iface && iface->state == IFACE_STATE_CONFIGURED) {
ksmbd_debug(CONN, "netdev-down event: netdev(%s) is going down\n",
iface->name);
- kernel_sock_shutdown(iface->ksmbd_socket, SHUT_RDWR);
- tcp_stop_kthread(iface->ksmbd_kthread);
- iface->ksmbd_kthread = NULL;
- sock_release(iface->ksmbd_socket);
- iface->ksmbd_socket = NULL;
-
+ ksmbd_tcp_stop_listener(iface);
iface->state = IFACE_STATE_DOWN;
break;
}
@@ -618,11 +621,25 @@ static void tcp_stop_kthread(struct task_struct *kthread)
if (!kthread)
return;
- ret = kthread_stop(kthread);
+ ret = kthread_stop_put(kthread);
if (ret)
pr_err("failed to stop forker thread\n");
}
+static void ksmbd_tcp_stop_listener(struct interface *iface)
+{
+ if (iface->ksmbd_socket)
+ kernel_sock_shutdown(iface->ksmbd_socket, SHUT_RDWR);
+
+ tcp_stop_kthread(iface->ksmbd_kthread);
+ iface->ksmbd_kthread = NULL;
+
+ if (iface->ksmbd_socket) {
+ sock_release(iface->ksmbd_socket);
+ iface->ksmbd_socket = NULL;
+ }
+}
+
void ksmbd_tcp_destroy(void)
{
struct interface *iface, *tmp;
@@ -630,6 +647,7 @@ void ksmbd_tcp_destroy(void)
unregister_netdevice_notifier(&ksmbd_netdev_notifier);
list_for_each_entry_safe(iface, tmp, &iface_list, entry) {
+ ksmbd_tcp_stop_listener(iface);
list_del(&iface->entry);
kfree(iface->name);
kfree(iface);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 100/733] s390/time: Use jiffies instead of jiffies_64
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (98 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 099/733] ksmbd: fix listener task lifetime on netdev events Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 101/733] s390/ipl: Fix NULL deref in kdump without re-IPL parm block Greg Kroah-Hartman
` (644 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christoph Schlameuss,
Alexander Egorenkov, Vasily Gorbik, Heiko Carstens, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <hca@linux.ibm.com>
[ Upstream commit ca1f4a5ecab084af7f405baa902edbed171b57e6 ]
Christoph Schlameuss and Alexander Egorenkov reported a data-race
reported by KCSAN when jiffies_64 is read:
==================================================================
BUG: KCSAN: data-race in do_account_vtime / tick_do_update_jiffies64
write to 0x0000016599ea8600 of 8 bytes by interrupt on cpu 6:
tick_do_update_jiffies64+0x140/0x250
=============================================================>
BUG: KCSAN: data-race in do_account_vtime / tick_do_update_ji>
write to 0x0000016599ea8600 of 8 bytes by interrupt on cpu 6:
tick_do_update_jiffies64+0x140/0x250
tick_nohz_handler+0x2e6/0x300
__run_hrtimer+0x156/0x4d0
__hrtimer_run_queues+0xd2/0x150
...
system_call+0x72/0x90
read to 0x0000016599ea8600 of 8 bytes by interrupt on cpu 12:
do_account_vtime+0x7d6/0x860
vtime_flush+0x26/0xe0
update_process_times+0x32/0x160
tick_nohz_handler+0x12a/0x300
...
system_call+0x72/0x90
value changed: 0x00000000ffffaa6c -> 0x00000000ffffaa6d
...
=============================================================>
Problem is that jiffies_64 instead of jiffies is used. Both are at the
same address, but only jiffies is of volatile type, which prevents this
warning.
Change the vtime code so jiffies instead of jiffies_64 is used
everywhere. This addresses also the inconsistency that both jiffies and
jiffies_64 were used in the original patch which introduced this.
Fixes: f341b8dff982 ("s390/vtime: limit MT scaling value updates")
Reported-by: Christoph Schlameuss <schlameuss@linux.ibm.com>
Reported-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Reviewed-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Tested-by: Alexander Egorenkov <egorenar@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/vtime.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/s390/kernel/vtime.c b/arch/s390/kernel/vtime.c
index d804e1140c2e9..efcbf406f03e7 100644
--- a/arch/s390/kernel/vtime.c
+++ b/arch/s390/kernel/vtime.c
@@ -32,7 +32,7 @@ static atomic64_t virt_timer_elapsed;
DEFINE_PER_CPU(u64, mt_cycles[8]);
static DEFINE_PER_CPU(u64, mt_scaling_mult) = { 1 };
static DEFINE_PER_CPU(u64, mt_scaling_div) = { 1 };
-static DEFINE_PER_CPU(u64, mt_scaling_jiffies);
+static DEFINE_PER_CPU(unsigned long, mt_scaling_jiffies);
static inline void set_vtimer(u64 expires)
{
@@ -81,7 +81,7 @@ static void update_mt_scaling(void)
memcpy(cycles_old, cycles_new,
sizeof(u64) * (smp_cpu_mtid + 1));
}
- __this_cpu_write(mt_scaling_jiffies, jiffies_64);
+ __this_cpu_write(mt_scaling_jiffies, jiffies);
}
static inline u64 update_tsk_timer(unsigned long *tsk_vtime, u64 new)
@@ -144,7 +144,7 @@ static int do_account_vtime(struct task_struct *tsk)
lc->system_timer += timer;
/* Update MT utilization calculation */
- if (smp_cpu_mtid && time_after64(jiffies_64, __this_cpu_read(mt_scaling_jiffies)))
+ if (smp_cpu_mtid && time_after(jiffies, __this_cpu_read(mt_scaling_jiffies)))
update_mt_scaling();
/* Calculate cputime delta */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 101/733] s390/ipl: Fix NULL deref in kdump without re-IPL parm block
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (99 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 100/733] s390/time: Use jiffies instead of jiffies_64 Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 102/733] s390/ipl: Fix NULL deref in dump_reipl " Greg Kroah-Hartman
` (643 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Vasily Gorbik,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit 7f918871112e8e7c581e99eb8e545af4e59c8367 ]
Some IPL types, like HMC FTP boot or QEMU direct kernel boot, might
not provide an IPL parameter block. In this case, reipl_type_init()
selects IPL_TYPE_UNKNOWN, and reipl_block_actual remains NULL.
kdump passes the re-IPL parameter block to the dump kernel through
os_info. Before commit 3b9678472bab ("s390/ipl: correct kdump reipl
block checksum calculation"), the os_info entry was added only for
IPL types which initialized reipl_block_actual. That commit moved the
os_info update to machine_crash_shutdown(), making it unconditional. As
a result, set_os_info_reipl_block() dereferences reipl_block_actual for
IPL_TYPE_UNKNOWN. This may happen to work by chance when address zero
contains readable lowcore data and the resulting empty os_info entry is
ignored by the dump kernel.
Skip the os_info update when no re-IPL parameter block is available.
Kdump then collect the dump and reboot without setting re-IPL parameter
block.
Fixes: 3b9678472bab ("s390/ipl: correct kdump reipl block checksum calculation")
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/ipl.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 3c346b02ceb95..7024fc4137152 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1157,6 +1157,8 @@ static struct attribute_group reipl_nss_attr_group = {
void set_os_info_reipl_block(void)
{
+ if (!reipl_block_actual)
+ return;
os_info_entry_add_data(OS_INFO_REIPL_BLOCK, reipl_block_actual,
reipl_block_actual->hdr.len);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 102/733] s390/ipl: Fix NULL deref in dump_reipl without re-IPL parm block
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (100 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 101/733] s390/ipl: Fix NULL deref in kdump without re-IPL parm block Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 103/733] s390/diag324: Preserve -EBUSY return code Greg Kroah-Hartman
` (642 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Zaslonko, Vasily Gorbik,
Heiko Carstens, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit 37f61b71cbc0caefc01022a19ee56fc2510e2e6e ]
Unlike kdump, which passes the re-IPL parameter block through os_info,
the stand-alone dump passes it through the IPL parm block address and
checksum in lowcore.
Some IPL types, like HMC FTP boot or QEMU direct kernel boot, might not
provide an IPL parameter block. In this case reipl_type_init() selects
IPL_TYPE_UNKNOWN and reipl_block_actual remains NULL. Nevertheless,
dump_reipl_run() unconditionally dereferences it when preparing the
lowcore fields. This may happen to work by chance when address zero
contains readable lowcore data. A zero IPL parameter block address is
then stored in lowcore, causing the stand-alone dumper to enter disabled
wait after completing the dump.
Explicitly store a zero IPL parameter block address and checksum when no
re-IPL parameter block is available. This does not change the behavior:
the stand-alone dumper completes the dump and halts, while valid re-IPL
parameter blocks continue to be handled as before.
Fixes: 099b76513992 ("[S390] Automatic IPL after dump")
Reviewed-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/ipl.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/s390/kernel/ipl.c b/arch/s390/kernel/ipl.c
index 7024fc4137152..68fdd5616dfe1 100644
--- a/arch/s390/kernel/ipl.c
+++ b/arch/s390/kernel/ipl.c
@@ -1929,7 +1929,8 @@ static struct shutdown_action __refdata dump_action = {
static void dump_reipl_run(struct shutdown_trigger *trigger)
{
struct lowcore *abs_lc;
- unsigned int csum;
+ unsigned long ipib = 0;
+ unsigned int csum = 0;
/*
* Set REIPL_CLEAR flag in os_info flags entry indicating
@@ -1945,9 +1946,12 @@ static void dump_reipl_run(struct shutdown_trigger *trigger)
reipl_type == IPL_TYPE_UNKNOWN)
os_info_flags |= OS_INFO_FLAG_REIPL_CLEAR;
os_info_entry_add_data(OS_INFO_FLAGS_ENTRY, &os_info_flags, sizeof(os_info_flags));
- csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
+ if (reipl_block_actual) {
+ ipib = __pa(reipl_block_actual);
+ csum = (__force unsigned int)cksm(reipl_block_actual, reipl_block_actual->hdr.len, 0);
+ }
abs_lc = get_abs_lowcore();
- abs_lc->ipib = __pa(reipl_block_actual);
+ abs_lc->ipib = ipib;
abs_lc->ipib_checksum = csum;
put_abs_lowcore(abs_lc);
dump_run(trigger);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 103/733] s390/diag324: Preserve -EBUSY return code
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (101 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 102/733] s390/ipl: Fix NULL deref in dump_reipl " Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 104/733] s390/pai: Reduce excessive debug feature size Greg Kroah-Hartman
` (641 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sumanth Korikkar, Heiko Carstens,
Vasily Gorbik, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sumanth Korikkar <sumanthk@linux.ibm.com>
[ Upstream commit 439077c39d8f7108aea4dd8d4d819b9b864fe84c ]
When diag324 reports -EBUSY, the error code is
overwritten by the result of copy_to_user() and put_user(). As a result,
the ioctl may incorrectly return success instead of -EBUSY.
Preserve the original diag324 return code and only return -EFAULT when
copying data to userspace fails.
Fixes: 90e6f191e1ee ("s390/diag324: Retrieve power readings via diag 0x324")
Signed-off-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/diag/diag324.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/arch/s390/kernel/diag/diag324.c b/arch/s390/kernel/diag/diag324.c
index fe325c2a2d0dc..3eec0cc8fb9e0 100644
--- a/arch/s390/kernel/diag/diag324.c
+++ b/arch/s390/kernel/diag/diag324.c
@@ -182,8 +182,7 @@ long diag324_pibbuf(unsigned long arg)
goto out;
rc = copy_to_user((void __user *)address, data->pib, data->pib->len);
rc |= put_user(data->sequence, &udata->sequence);
- if (rc)
- rc = -EFAULT;
+ rc = rc ? -EFAULT : data->rc;
out:
mutex_unlock(&pibmutex);
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 104/733] s390/pai: Reduce excessive debug feature size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (102 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 103/733] s390/diag324: Preserve -EBUSY return code Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 105/733] sched_ext: Fix timer pinning and return value in scx_central Greg Kroah-Hartman
` (640 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Richter, Vasily Gorbik,
Heiko Carstens, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heiko Carstens <hca@linux.ibm.com>
[ Upstream commit 8cff0ac21658fedd4598e9904dd0c518bdaf5856 ]
The pai debug feature is registered with 256 areas, where each area
contains 32 pages. This sums up to a total of 32MiB. The code does not use
any debug exceptions, which means that 255 of those areas are never
used. In addition all existing debug feature calls have a lower level (5)
than the default level (3).
This in turn means that without user interaction the debug feature is
unused.
Reduce the number of areas to 1, and also reduce the number of pages for
the remaining area to 1. Since user interaction is required, the user can
also increase the size of the remaining area, instead of wasting memory by
default.
This reduces the total size of the debug feature to 4KiB.
Fixes: a3f8423622ef ("s390/pai_crypto: Add PAI crypto characteristics table for parameters")
Reviewed-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/perf_pai.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/kernel/perf_pai.c b/arch/s390/kernel/perf_pai.c
index cdb8006220ca0..ab76ed7ad791e 100644
--- a/arch/s390/kernel/perf_pai.c
+++ b/arch/s390/kernel/perf_pai.c
@@ -1221,7 +1221,7 @@ static int __init paipmu_setup(void)
static int __init pai_init(void)
{
/* Setup s390dbf facility */
- paidbg = debug_register("pai", 32, 256, 128);
+ paidbg = debug_register("pai", 1, 1, 128);
if (!paidbg) {
pr_err("Registration of s390dbf pai failed\n");
return -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 105/733] sched_ext: Fix timer pinning and return value in scx_central
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (103 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 104/733] s390/pai: Reduce excessive debug feature size Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 106/733] sched_ext: Fix vtime delta loss in scx_flatcg cgroup migration Greg Kroah-Hartman
` (639 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wanwu Li, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wanwu Li <liwanwu@kylinos.cn>
[ Upstream commit 23761359861ca4bb087540937dfea8b0716914c2 ]
central_timerfn() re-arms the timer with a hardcoded
BPF_F_TIMER_CPU_PIN flag and ignores the return value, defeating
start_central_timer()'s -EINVAL fallback for kernels without the flag
(<6.7): on such kernels the first tick kills the timer permanently
with no diagnostic. Honor timer_pinned and check the return like
the initial arm does.
Fixes: 22a920209ab6 ("sched_ext: Implement tickless support")
Signed-off-by: Wanwu Li <liwanwu@kylinos.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/sched_ext/scx_central.bpf.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/tools/sched_ext/scx_central.bpf.c b/tools/sched_ext/scx_central.bpf.c
index 64dd60b3e9223..65dae9e454009 100644
--- a/tools/sched_ext/scx_central.bpf.c
+++ b/tools/sched_ext/scx_central.bpf.c
@@ -299,6 +299,7 @@ static int central_timerfn(void *map, int *key, struct bpf_timer *timer)
u64 now = scx_bpf_now();
u64 nr_to_kick = nr_queued;
s32 i, curr_cpu;
+ int ret;
curr_cpu = bpf_get_smp_processor_id();
if (timer_pinned && (curr_cpu != central_cpu)) {
@@ -332,7 +333,10 @@ static int central_timerfn(void *map, int *key, struct bpf_timer *timer)
scx_bpf_kick_cpu(cpu, SCX_KICK_PREEMPT);
}
- bpf_timer_start(timer, TIMER_INTERVAL_NS, BPF_F_TIMER_CPU_PIN);
+ ret = bpf_timer_start(timer, TIMER_INTERVAL_NS,
+ timer_pinned ? BPF_F_TIMER_CPU_PIN : 0);
+ if (ret)
+ scx_bpf_error("bpf_timer_start failed (%d)", ret);
__sync_fetch_and_add(&nr_timers, 1);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 106/733] sched_ext: Fix vtime delta loss in scx_flatcg cgroup migration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (104 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 105/733] sched_ext: Fix timer pinning and return value in scx_central Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 107/733] Bluetooth: btintel_pcie: Clear automask on spurious interrupts Greg Kroah-Hartman
` (638 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Wanwu Li, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wanwu Li <liwanwu@kylinos.cn>
[ Upstream commit b6ee92d7f7f0498d1f776d0b125a2f6bcedf0891 ]
fcg_cgroup_move() lost the signed vtime offset across cgroup
migration in the mechanical conversion to time helpers:
time_delta() clamps negative deltas to 0, so a queued task (whose
dsq_vtime is normally behind the source frontier) loses its
accumulated vtime credit and lands exactly at the destination
frontier instead of keeping its relative position. Restore the
wrapping signed subtraction.
Fixes: 62addc6dbf36 ("sched_ext: Use time helpers in BPF schedulers")
Signed-off-by: Wanwu Li <liwanwu@kylinos.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/sched_ext/scx_flatcg.bpf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/tools/sched_ext/scx_flatcg.bpf.c b/tools/sched_ext/scx_flatcg.bpf.c
index ddcf6bc03b11c..98fdd4b040331 100644
--- a/tools/sched_ext/scx_flatcg.bpf.c
+++ b/tools/sched_ext/scx_flatcg.bpf.c
@@ -934,7 +934,7 @@ void BPF_STRUCT_OPS(fcg_cgroup_move, struct task_struct *p,
if (!(from_cgc = find_cgrp_ctx(from)) || !(to_cgc = find_cgrp_ctx(to)))
return;
- delta = time_delta(p->scx.dsq_vtime, from_cgc->tvtime_now);
+ delta = (s64)(p->scx.dsq_vtime - from_cgc->tvtime_now);
scx_bpf_task_set_dsq_vtime(p, to_cgc->tvtime_now + delta);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 107/733] Bluetooth: btintel_pcie: Clear automask on spurious interrupts
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (105 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 106/733] sched_ext: Fix vtime delta loss in scx_flatcg cgroup migration Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 108/733] workqueue: reject watchdog thresholds that overflow jiffies Greg Kroah-Hartman
` (637 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiran K, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiran K <kiran.k@intel.com>
[ Upstream commit ea2ee8b222306208d2b094d1a11894da6c106d42 ]
On spurious interrupt where the TX and RX causes are not set, driver was
not clearing the auto mask which can block all the interrupts. Driver
needs to clear the automask even if no causes are set.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 2b7231be5973d..6b6258d03dd84 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1634,6 +1634,9 @@ static irqreturn_t btintel_pcie_irq_msix_handler(int irq, void *dev_id)
if (unlikely(!(intr_fh | intr_hw))) {
/* Ignore interrupt, inta == 0 */
+ bt_warn_ratelimited("Bluetooth: btintel_pcie: Received spurious interrupt\n");
+ btintel_pcie_wr_reg32(data, BTINTEL_PCIE_CSR_MSIX_AUTOMASK_ST,
+ BIT(entry->entry));
return IRQ_NONE;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 108/733] workqueue: reject watchdog thresholds that overflow jiffies
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (106 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 107/733] Bluetooth: btintel_pcie: Clear automask on spurious interrupts Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 109/733] Bluetooth: btintel: validate version TLV value lengths Greg Kroah-Hartman
` (636 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Jiacheng Xu, Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiacheng Xu <stitch@zju.edu.cn>
[ Upstream commit 068c35b5d0546c8625b3d7c61910f73775cf1216 ]
The watchdog threshold is supplied in seconds but is multiplied by HZ
before being used as a jiffies interval. Reject values that exceed
MAX_JIFFY_OFFSET / HZ so the multiplication cannot wrap and the
time_after() comparisons remain within their supported range.
The check is performed before changing the threshold or watchdog timer.
Zero remains the value used to disable the watchdog.
Fixes: 82607adcf9cdf ("workqueue: implement lockup detector")
Signed-off-by: Jiacheng Xu <stitch@zju.edu.cn>
Signed-off-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/workqueue.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/workqueue.c b/kernel/workqueue.c
index 929c04a9581bd..36aaeb38e2174 100644
--- a/kernel/workqueue.c
+++ b/kernel/workqueue.c
@@ -7923,6 +7923,9 @@ static int wq_watchdog_param_set_thresh(const char *val,
if (ret)
return ret;
+ if (thresh > MAX_JIFFY_OFFSET / HZ)
+ return -ERANGE;
+
if (system_percpu_wq)
wq_watchdog_set_thresh(thresh);
else
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 109/733] Bluetooth: btintel: validate version TLV value lengths
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (107 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 108/733] workqueue: reject watchdog thresholds that overflow jiffies Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 110/733] Bluetooth: btintel: bound firmware ID by TLV length Greg Kroah-Hartman
` (635 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis,
Laxman Acharya Padhya, Kiran K, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
[ Upstream commit a086c0892969bf8a0151b0f12bd14a68827c88b2 ]
btintel_parse_version_tlv() verifies that a complete TLV is present in
the response, but it does not ensure that the value is long enough for
the specific TLV type. A short value can therefore cause an
out-of-bounds read through get_unaligned_le16(), get_unaligned_le32(),
or memcpy().
Reject values shorter than the minimum required by each known TLV type.
Also reject responses that do not contain the Command Complete Status
field.
Fixes: 57375beef71a ("Bluetooth: btintel: Add infrastructure to read controller information")
Reviewed-by: Ali Ahmet Memis <ali@iusegentoo.com>
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Tested-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index cc2234470960a..ecee50373f566 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -570,12 +570,44 @@ int btintel_version_info_tlv(struct hci_dev *hdev,
}
EXPORT_SYMBOL_GPL(btintel_version_info_tlv);
+static u8 btintel_version_tlv_min_len(u8 type)
+{
+ switch (type) {
+ case INTEL_TLV_CNVI_TOP:
+ case INTEL_TLV_CNVR_TOP:
+ case INTEL_TLV_CNVI_BT:
+ case INTEL_TLV_CNVR_BT:
+ case INTEL_TLV_BUILD_NUM:
+ case INTEL_TLV_GIT_SHA1:
+ return sizeof(u32);
+ case INTEL_TLV_DEV_REV_ID:
+ case INTEL_TLV_TIME_STAMP:
+ return sizeof(u16);
+ case INTEL_TLV_IMAGE_TYPE:
+ case INTEL_TLV_BUILD_TYPE:
+ case INTEL_TLV_SECURE_BOOT:
+ case INTEL_TLV_OTP_LOCK:
+ case INTEL_TLV_API_LOCK:
+ case INTEL_TLV_DEBUG_LOCK:
+ case INTEL_TLV_LIMITED_CCE:
+ case INTEL_TLV_SBE_TYPE:
+ return sizeof(u8);
+ case INTEL_TLV_MIN_FW:
+ return 3;
+ case INTEL_TLV_OTP_BDADDR:
+ return sizeof(bdaddr_t);
+ default:
+ return 0;
+ }
+}
+
int btintel_parse_version_tlv(struct hci_dev *hdev,
struct intel_version_tlv *version,
struct sk_buff *skb)
{
/* Consume Command Complete Status field */
- skb_pull(skb, 1);
+ if (!skb_pull(skb, 1))
+ return -EINVAL;
/* Event parameters contain multiple TLVs. Read each of them
* and only keep the required data. Also, it use existing legacy
@@ -595,6 +627,9 @@ int btintel_parse_version_tlv(struct hci_dev *hdev,
if (skb->len < tlv->len + sizeof(*tlv))
return -EINVAL;
+ if (tlv->len < btintel_version_tlv_min_len(tlv->type))
+ return -EINVAL;
+
switch (tlv->type) {
case INTEL_TLV_CNVI_TOP:
version->cnvi_top = get_unaligned_le32(tlv->val);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 110/733] Bluetooth: btintel: bound firmware ID by TLV length
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (108 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 109/733] Bluetooth: btintel: validate version TLV value lengths Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:06 ` [PATCH 7.2 111/733] Bluetooth: hci_core: Fix race condition during device registration Greg Kroah-Hartman
` (634 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis,
Laxman Acharya Padhya, Kiran K, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
[ Upstream commit ac8aa9e0ec93a12a60230066f199f49c3b9aac3d ]
The firmware ID is treated as a NUL-terminated string even though the
TLV length is its only boundary. If the value does not contain a NUL
terminator, snprintf() can read beyond the received response.
Limit the conversion to the advertised TLV value length.
Fixes: 164c62f958f8 ("Bluetooth: btintel: Add firmware ID to firmware name")
Reviewed-by: Ali Ahmet Memis <ali@iusegentoo.com>
Signed-off-by: Laxman Acharya Padhya <acharyalaxman8848@gmail.com>
Tested-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel.c b/drivers/bluetooth/btintel.c
index ecee50373f566..96a55d5badda1 100644
--- a/drivers/bluetooth/btintel.c
+++ b/drivers/bluetooth/btintel.c
@@ -701,7 +701,7 @@ int btintel_parse_version_tlv(struct hci_dev *hdev,
break;
case INTEL_TLV_FW_ID:
snprintf(version->fw_id, sizeof(version->fw_id),
- "%s", tlv->val);
+ "%.*s", tlv->len, tlv->val);
break;
default:
/* Ignore rest of information */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 111/733] Bluetooth: hci_core: Fix race condition during device registration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (109 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 110/733] Bluetooth: btintel: bound firmware ID by TLV length Greg Kroah-Hartman
@ 2026-09-17 15:06 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 112/733] Bluetooth: L2CAP: fix chan mode for LE_CONN_REQ + EXT_FLOWCTL pchan Greg Kroah-Hartman
` (633 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:06 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+14ce1b05b7d5a989abbe,
Aleksandr Nogikh, Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Nogikh <nogikh@google.com>
[ Upstream commit 57938bbdb9bf7fd41cbd5cd509ec10c4b22bec18 ]
In hci_register_dev(), the power_on work item is queued to
hdev->req_workqueue before initializing hdev->adv_monitors_idr and
registering the MSFT extension via msft_register(). For devices marked with
quirks such as HCI_QUIRK_RAW_DEVICE, the HCI_UNCONFIGURED flag is set on
the device. When the power_on work item runs concurrently on another CPU,
hci_power_on() detects that the device is unconfigured and immediately
invokes hci_dev_do_close(), which calls msft_do_close().
Concurrently, msft_register() allocates the msft structure and exposes it
to hdev->msft_data prior to calling mutex_init(&msft->filter_lock). If
msft_do_close() executes while hdev->msft_data is already assigned but the
mutex has not yet been initialized, mutex_lock(&msft->filter_lock) operates
on an uninitialized mutex, triggering a DEBUG_LOCKS warning:
DEBUG_LOCKS_WARN_ON(lock->magic != lock)
WARNING: kernel/locking/mutex.c:625 at __mutex_lock_common
kernel/locking/mutex.c:625 [inline]
WARNING: kernel/locking/mutex.c:625 at __mutex_lock+0x12d8/0x1550
kernel/locking/mutex.c:821
...
Call Trace:
<TASK>
msft_do_close+0x308/0x7b0 net/bluetooth/msft.c:693
hci_dev_close_sync+0x86b/0x10a0 net/bluetooth/hci_sync.c:5522
hci_dev_do_close net/bluetooth/hci_core.c:499 [inline]
hci_power_on+0x32c/0x750 net/bluetooth/hci_core.c:937
process_one_work kernel/workqueue.c:3322 [inline]
process_scheduled_works+0xa8e/0x14e0 kernel/workqueue.c:3405
worker_thread+0x92d/0xe10 kernel/workqueue.c:3486
kthread+0x388/0x470 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Fix this by moving the queue_work() call in hci_register_dev() to after
idr_init(&hdev->adv_monitors_idr) and msft_register(hdev) so that device
structures and extensions are fully initialized before asynchronous tasks
can access them. Additionally, assign hdev->msft_data in msft_register()
only after mutex_init(&msft->filter_lock) has completed.
Fixes: 9e14606d8f38 ("Bluetooth: msft: Extended monitor tracking by address filter")
Assisted-by: Gemini:gemini-3.7-flash Gemini:gemini-3.1-pro-preview syzbot
Reported-by: syzbot+14ce1b05b7d5a989abbe@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=14ce1b05b7d5a989abbe
Link: https://syzkaller.appspot.com/ai_job?id=2bc9e8aa-ca6d-43e2-be2c-fd5d9f649d7e
Signed-off-by: Aleksandr Nogikh <nogikh@google.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_core.c | 4 ++--
net/bluetooth/msft.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/bluetooth/hci_core.c b/net/bluetooth/hci_core.c
index f346505c3f88c..f747492da5f66 100644
--- a/net/bluetooth/hci_core.c
+++ b/net/bluetooth/hci_core.c
@@ -2629,11 +2629,11 @@ int hci_register_dev(struct hci_dev *hdev)
if (error)
BT_WARN("register suspend notifier failed error:%d\n", error);
- queue_work(hdev->req_workqueue, &hdev->power_on);
-
idr_init(&hdev->adv_monitors_idr);
msft_register(hdev);
+ queue_work(hdev->req_workqueue, &hdev->power_on);
+
return id;
err_wqueue:
diff --git a/net/bluetooth/msft.c b/net/bluetooth/msft.c
index ded68568e6c9b..d9dd722db3ebd 100644
--- a/net/bluetooth/msft.c
+++ b/net/bluetooth/msft.c
@@ -769,8 +769,8 @@ void msft_register(struct hci_dev *hdev)
INIT_LIST_HEAD(&msft->handle_map);
INIT_LIST_HEAD(&msft->address_filters);
- hdev->msft_data = msft;
mutex_init(&msft->filter_lock);
+ hdev->msft_data = msft;
}
void msft_release(struct hci_dev *hdev)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 112/733] Bluetooth: L2CAP: fix chan mode for LE_CONN_REQ + EXT_FLOWCTL pchan
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (110 preceding siblings ...)
2026-09-17 15:06 ` [PATCH 7.2 111/733] Bluetooth: hci_core: Fix race condition during device registration Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 113/733] Bluetooth: L2CAP: fix out-of-bounds write in l2cap_ecred_connect Greg Kroah-Hartman
` (632 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen,
Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <pav@iki.fi>
[ Upstream commit 4ef05db5b08b176a551b4a6287372045998806b0 ]
l2cap_new_connection() sets default value of channel mode to match the
parent channel. l2cap_le_connect_req() left this at the default, and
created L2CAP_MODE_EXT_FLOWCTL channels if listening pchan has that
mode. This causes FLAG_DEFER_SETUP channels to reply to
L2CAP_LE_CONN_REQ with L2CAP_ECRED_CONN_RSP, which is incorrect.
It can also result to stack OOB write (of l2cap_alloc_cid determined
values) in l2cap_ecred_rsp_defer(), as l2cap_le_connect_req() does not
limit maximum number of deferred channels or check for duplicate ident.
Fix by setting chan->mode correctly in l2cap_le_connect_req().
Also check channel mode in l2cap_ecred_rsp_defer(), and do WARN_ON_ONCE
instead of OOB write to make it less brittle.
Fixes: 15f02b910562 ("Bluetooth: L2CAP: Add initial code for Enhanced Credit Based Mode")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index 30d7120d3a150..d9d72cac9269b 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -3893,6 +3893,9 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
struct l2cap_ecred_conn_rsp *rsp_flex =
container_of(&rsp->pdu.rsp, struct l2cap_ecred_conn_rsp, hdr);
+ if (chan->mode != L2CAP_MODE_EXT_FLOWCTL)
+ return;
+
/* Check if channel for outgoing connection or if it wasn't deferred
* since in those cases it must be skipped.
*/
@@ -3903,6 +3906,10 @@ static void l2cap_ecred_rsp_defer(struct l2cap_chan *chan, void *data)
/* Reset ident so only one response is sent */
chan->ident = 0;
+ /* Unreachable, check in l2cap_ecred_conn_req. If reached, drop rest */
+ if (WARN_ON_ONCE(rsp->count >= ARRAY_SIZE(rsp->pdu.scid)))
+ rsp->pdu.rsp.result = cpu_to_le16(L2CAP_CR_LE_NO_MEM);
+
/* Include all channels pending with the same ident */
if (!rsp->pdu.rsp.result)
rsp_flex->dcid[rsp->count++] = cpu_to_le16(chan->scid);
@@ -5062,6 +5069,7 @@ static int l2cap_le_connect_req(struct l2cap_conn *conn,
__set_chan_timer(chan, chan->ops->get_sndtimeo(chan));
chan->ident = cmd->ident;
+ chan->mode = L2CAP_MODE_LE_FLOWCTL;
if (test_bit(FLAG_DEFER_SETUP, &chan->flags)) {
l2cap_state_change(chan, BT_CONNECT2);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 113/733] Bluetooth: L2CAP: fix out-of-bounds write in l2cap_ecred_connect
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (111 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 112/733] Bluetooth: L2CAP: fix chan mode for LE_CONN_REQ + EXT_FLOWCTL pchan Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 114/733] Bluetooth: L2CAP: clear FLAG_DEFER_SETUP only for same PID/PSM Greg Kroah-Hartman
` (631 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen,
Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <pav@iki.fi>
[ Upstream commit 56c2b5831d39dc84aad2573dc3e197af1a872a05 ]
l2cap_chan_connect() tries to ensure there are no more than
L2CAP_ECRED_CONN_SCID_MAX pending ECRED channels, so they fit in the
same L2CAP_ECRED_CONN_REQ that l2cap_ecred_connect() constructs.
However, the check only counts deferred channels. If 6 L2CAP sockets
are connected at the same time in order DDDDND (D=deferred,
N=non-deferred), the last can bump the total to max+1. It results to
one __le16 written out of bounds of the scid array, and an invalid
ECRED_CONN_REQ being sent.
Fix by leaving room for the non-deferred pending ECRED channels in the
counting in l2cap_chan_connect(), so the limit can't be exceeded.
Move counting under same critical section where the channel is added.
Although race conditions involving this appear unreachable, it's easier
to see.
Also add WARN_ON_ONCE check in l2cap_ecred_defer_connect() to make this
less brittle.
Fixes: da49b602f7f7 ("Bluetooth: L2CAP: Use DEFER_SETUP to group ECRED connections")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index d9d72cac9269b..b31afc4d7dae2 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1337,7 +1337,7 @@ static void l2cap_le_connect(struct l2cap_chan *chan)
struct l2cap_ecred_conn_data {
struct {
struct l2cap_ecred_conn_req_hdr req;
- __le16 scid[5];
+ __le16 scid[L2CAP_ECRED_CONN_SCID_MAX];
} __packed pdu;
struct l2cap_chan *chan;
struct pid *pid;
@@ -1365,6 +1365,10 @@ static void l2cap_ecred_defer_connect(struct l2cap_chan *chan, void *data)
if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
return;
+ /* Unreachable, checked in l2cap_connect (+timer drops it if reached) */
+ if (WARN_ON_ONCE(conn->count >= ARRAY_SIZE(conn->pdu.scid)))
+ return;
+
l2cap_ecred_init(chan, 0);
/* Set the same ident so we can match on the rsp */
@@ -7373,6 +7377,9 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
goto done;
}
+ mutex_lock(&conn->lock);
+ l2cap_chan_lock(chan);
+
if (chan->mode == L2CAP_MODE_EXT_FLOWCTL) {
struct l2cap_chan_data data;
@@ -7380,19 +7387,20 @@ int l2cap_chan_connect(struct l2cap_chan *chan, __le16 psm, u16 cid,
data.pid = chan->ops->get_peer_pid(chan);
data.count = 1;
- l2cap_chan_list(conn, l2cap_chan_by_pid, &data);
+ __l2cap_chan_list(conn, l2cap_chan_by_pid, &data);
+
+ /* Leave room for non-deferred channel that ends the group. */
+ if (test_bit(FLAG_DEFER_SETUP, &chan->flags))
+ data.count += 1;
/* Check if there isn't too many channels being connected */
if (data.count > L2CAP_ECRED_CONN_SCID_MAX) {
hci_conn_drop(hcon);
err = -EPROTO;
- goto done;
+ goto chan_unlock;
}
}
- mutex_lock(&conn->lock);
- l2cap_chan_lock(chan);
-
if (cid && __l2cap_get_chan_by_dcid(conn, cid)) {
hci_conn_drop(hcon);
err = -EBUSY;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 114/733] Bluetooth: L2CAP: clear FLAG_DEFER_SETUP only for same PID/PSM
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (112 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 113/733] Bluetooth: L2CAP: fix out-of-bounds write in l2cap_ecred_connect Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 115/733] Bluetooth: hci_mrvl: Fix wrong return value check of wait_on_bit_timeout() Greg Kroah-Hartman
` (630 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pauli Virtanen,
Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <pav@iki.fi>
[ Upstream commit 0d77683237270702fa93489ca759c89b4e970554 ]
l2cap_ecred_defer_connect() clears FLAG_DEFER_SETUP also for channels
with different PID/PSM, which will not be added to the same
ECRED_CONN_REQ in any case. Consequently, only one ECRED connection
group can work at a time although it appears intended they would be
separate for each PID/PSM combination.
Fix by clearing FLAG_DEFER_SETUP only for the connections that could be
added in the request. Retain test_bit(FLAG_DEFER_SETUP) before calling
get_peer_pid as it may be NULL otherwise.
Fixes: da49b602f7f7 ("Bluetooth: L2CAP: Use DEFER_SETUP to group ECRED connections")
Signed-off-by: Pauli Virtanen <pav@iki.fi>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/l2cap_core.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/net/bluetooth/l2cap_core.c b/net/bluetooth/l2cap_core.c
index b31afc4d7dae2..800f7517bfeb0 100644
--- a/net/bluetooth/l2cap_core.c
+++ b/net/bluetooth/l2cap_core.c
@@ -1352,7 +1352,7 @@ static void l2cap_ecred_defer_connect(struct l2cap_chan *chan, void *data)
if (chan == conn->chan)
return;
- if (!test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
+ if (!test_bit(FLAG_DEFER_SETUP, &chan->flags))
return;
pid = chan->ops->get_peer_pid(chan);
@@ -1362,6 +1362,9 @@ static void l2cap_ecred_defer_connect(struct l2cap_chan *chan, void *data)
chan->mode != L2CAP_MODE_EXT_FLOWCTL || chan->state != BT_CONNECT)
return;
+ if (!test_and_clear_bit(FLAG_DEFER_SETUP, &chan->flags))
+ return;
+
if (test_and_set_bit(FLAG_ECRED_CONN_REQ_SENT, &chan->flags))
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 115/733] Bluetooth: hci_mrvl: Fix wrong return value check of wait_on_bit_timeout()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (113 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 114/733] Bluetooth: L2CAP: clear FLAG_DEFER_SETUP only for same PID/PSM Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 116/733] platform/x86: asus-laptop: Fix ACPI event handling Greg Kroah-Hartman
` (629 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gongwei Li, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gongwei Li <ligongwei@kylinos.cn>
[ Upstream commit 2deb76c21b81e42b3282224f7dd2046fe73fd1e0 ]
wait_on_bit_timeout() returns 0 if the bit was cleared, -EINTR if the
process received a signal and the mode permitted wake up on that signal,
or -EAGAIN if the timeout elapsed. It never returns 1.
Hence the check "err == 1" in mrvl_load_firmware() is dead code: when
the waiting task is interrupted by a signal (-EINTR), the code falls
into the "else if (err)" branch and misreports it as "Firmware request
timeout" with -ETIMEDOUT instead of propagating -EINTR.
Fix this by testing for -EINTR so that an interrupted firmware load is
properly detected and reported.
Fixes: 162f812f23ba ("Bluetooth: hci_uart: Add Marvell support")
Signed-off-by: Gongwei Li <ligongwei@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/hci_mrvl.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/drivers/bluetooth/hci_mrvl.c b/drivers/bluetooth/hci_mrvl.c
index 516b8f74c4340..5798a8db016ee 100644
--- a/drivers/bluetooth/hci_mrvl.c
+++ b/drivers/bluetooth/hci_mrvl.c
@@ -307,9 +307,8 @@ static int mrvl_load_firmware(struct hci_dev *hdev, const char *name)
err = wait_on_bit_timeout(&mrvl->flags, STATE_FW_REQ_PENDING,
TASK_INTERRUPTIBLE,
msecs_to_jiffies(2000));
- if (err == 1) {
+ if (err == -EINTR) {
bt_dev_err(hdev, "Firmware load interrupted");
- err = -EINTR;
break;
} else if (err) {
bt_dev_err(hdev, "Firmware request timeout");
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 116/733] platform/x86: asus-laptop: Fix ACPI event handling
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (114 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 115/733] Bluetooth: hci_mrvl: Fix wrong return value check of wait_on_bit_timeout() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 117/733] ASoC: ab8500: Reset the audio block before configuring it Greg Kroah-Hartman
` (628 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mo Jun, Armin Wolf,
Rafael J. Wysocki, Ilpo Järvinen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Armin Wolf <W_Armin@gmx.de>
[ Upstream commit 6bb4fb72c00dc2a9cb663e2d16adce15e4170cdf ]
The event codes inside asus_keymap[] span a wide range from 0x02
till 0xC5, but using ACPI_DEVICE_NOTIFY prevents us from receiving
event codes below 0x80.
Fix this by using ACPI_ALL_NOTIFY instead.
Fixes: 378500dc1313 ("platform/x86: asus-laptop: Register ACPI notify handler directly")
Reported-by: Mo Jun <royclark086@gmail.com>
Closes: https://bugs.debian.org/1146124
Tested-by: Mo Jun <royclark086@gmail.com>
Signed-off-by: Armin Wolf <W_Armin@gmx.de>
Reviewed-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Link: https://patch.msgid.link/20260830235058.324140-1-W_Armin@gmx.de
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/asus-laptop.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/asus-laptop.c b/drivers/platform/x86/asus-laptop.c
index 140ac8a105372..19024fa3796e6 100644
--- a/drivers/platform/x86/asus-laptop.c
+++ b/drivers/platform/x86/asus-laptop.c
@@ -1887,7 +1887,7 @@ static int asus_acpi_probe(struct platform_device *pdev)
if (result && result != -ENODEV)
goto fail_pega_rfkill;
- result = acpi_dev_install_notify_handler(device, ACPI_DEVICE_NOTIFY,
+ result = acpi_dev_install_notify_handler(device, ACPI_ALL_NOTIFY,
asus_acpi_notify, asus);
if (result)
goto fail_pega_rfkill;
@@ -1917,7 +1917,7 @@ static void asus_acpi_remove(struct platform_device *pdev)
{
struct asus_laptop *asus = platform_get_drvdata(pdev);
- acpi_dev_remove_notify_handler(asus->device, ACPI_DEVICE_NOTIFY,
+ acpi_dev_remove_notify_handler(asus->device, ACPI_ALL_NOTIFY,
asus_acpi_notify);
asus_backlight_exit(asus);
asus_rfkill_exit(asus);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 117/733] ASoC: ab8500: Reset the audio block before configuring it
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (115 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 116/733] platform/x86: asus-laptop: Fix ACPI event handling Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 118/733] ASoC: ab8500: Repair the DAPM capture graph Greg Kroah-Hartman
` (627 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 8e839bca7793a0b03c005f4b2b0825464290d425 ]
ResetAudn is active low, but the codec probe only deasserts it. It also
clears Clk32kOut2Dis despite claiming to disable that output, and writes
codec registers before releasing reset.
Pulse ResetAudn before the first audio-bank access and leave the unused
32 kHz output disabled.
Fixes: 679d7abdc754 ("ASoC: codecs: Add AB8500 codec-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260831-ab8500-codec-fixes-v1-1-f85024e717e3@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 26 +++++++++++++-------------
1 file changed, 13 insertions(+), 13 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 6e8ef9cd1b31a..2f920eb907254 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -1640,18 +1640,18 @@ static struct snd_kcontrol_new ab8500_ctrls[] = {
static int ab8500_audio_init_audioblock(struct snd_soc_component *component)
{
int status;
+ u8 mask = AB8500_STW4500CTRL3_CLK32KOUT2DIS |
+ AB8500_STW4500CTRL3_RESETAUDN;
dev_dbg(component->dev, "%s: Enter.\n", __func__);
- /* Reset audio-registers and disable 32kHz-clock output 2 */
- status = ab8500_sysctrl_write(AB8500_STW4500CTRL3,
- AB8500_STW4500CTRL3_CLK32KOUT2DIS |
- AB8500_STW4500CTRL3_RESETAUDN,
- AB8500_STW4500CTRL3_RESETAUDN);
+ /* Reset the audio registers and disable the unused 32 kHz output. */
+ status = ab8500_sysctrl_write(AB8500_STW4500CTRL3, mask,
+ AB8500_STW4500CTRL3_CLK32KOUT2DIS);
if (status < 0)
return status;
- return 0;
+ return ab8500_sysctrl_write(AB8500_STW4500CTRL3, mask, mask);
}
static int ab8500_audio_setup_mics(struct snd_soc_component *component,
@@ -2183,6 +2183,13 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
ab8500_codec_of_probe(dev, np, &codec_pdata);
+ status = ab8500_audio_init_audioblock(component);
+ if (status < 0) {
+ dev_err(dev, "%s: failed to init audio-block (%d)!\n",
+ __func__, status);
+ return status;
+ }
+
status = ab8500_audio_setup_mics(component, &codec_pdata.amics);
if (status < 0) {
pr_err("%s: Failed to setup mics (%d)!\n", __func__, status);
@@ -2195,13 +2202,6 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
return status;
}
- status = ab8500_audio_init_audioblock(component);
- if (status < 0) {
- dev_err(dev, "%s: failed to init audio-block (%d)!\n",
- __func__, status);
- return status;
- }
-
/* Override HW-defaults */
snd_soc_component_write(component, AB8500_ANACONF5,
BIT(AB8500_ANACONF5_HSAUTOEN));
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 118/733] ASoC: ab8500: Repair the DAPM capture graph
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (116 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 117/733] ASoC: ab8500: Reset the audio block before configuring it Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 119/733] ASoC: ab8500: Correct digital interface format setup Greg Kroah-Hartman
` (626 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 103fe1a37f040ef6ac9ed1cf33be786149d2bb15 ]
The capture stream routes point away from the stream widget. Digital
microphone mux routes are unconditional and bypass their enable bits,
and several widgets independently own shared AD path enable bits. The
dummy ADC and DAC widgets hide the resulting power graph errors.
Connect each real AIF widget to the stream and main supply, use the mux
item names on digital microphone routes, and model shared AD enables as
supplies. Also make the ANC DAPM switch writable.
Fixes: 679d7abdc754 ("ASoC: codecs: Add AB8500 codec-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260831-ab8500-codec-fixes-v1-2-f85024e717e3@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 120 +++++++++++++++-----------------
1 file changed, 56 insertions(+), 64 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 2f920eb907254..7137561ef9309 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -258,7 +258,7 @@ static const struct snd_kcontrol_new dapm_anc_in_select[] = {
/* ANC - Enable/Disable */
static const struct snd_kcontrol_new dapm_anc_enable[] = {
SOC_DAPM_SINGLE("Switch", AB8500_ANCCONF1,
- AB8500_ANCCONF1_ENANC, 0, 0),
+ AB8500_ANCCONF1_ENANC, 1, 0),
};
/* ANC to Earpiece - Mute */
@@ -340,12 +340,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
/* DA/AD */
- SND_SOC_DAPM_INPUT("ADC Input"),
- SND_SOC_DAPM_ADC("ADC", "ab8500_0c", SND_SOC_NOPM, 0, 0),
-
- SND_SOC_DAPM_DAC("DAC", NULL, SND_SOC_NOPM, 0, 0),
- SND_SOC_DAPM_OUTPUT("DAC Output"),
-
SND_SOC_DAPM_AIF_IN("DA_IN1", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("DA_IN2", NULL, 0, SND_SOC_NOPM, 0, 0),
SND_SOC_DAPM_AIF_IN("DA_IN3", NULL, 0, SND_SOC_NOPM, 0, 0),
@@ -537,9 +531,8 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("AD3 Channel Volume",
SND_SOC_NOPM, 0, 0,
NULL, 0),
- SND_SOC_DAPM_MIXER("AD3 Enable",
- AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34, 0,
- NULL, 0),
+ SND_SOC_DAPM_SUPPLY("AD34 Enable", AB8500_ADPATHENA,
+ AB8500_ADPATHENA_ENAD34, 0, NULL, 0),
/* Mic 2 */
@@ -598,9 +591,8 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_NOPM, 0, 0,
NULL, 0),
- SND_SOC_DAPM_MIXER("AD12 Enable",
- AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD12, 0,
- NULL, 0),
+ SND_SOC_DAPM_SUPPLY("AD12 Enable", AB8500_ADPATHENA,
+ AB8500_ADPATHENA_ENAD12, 0, NULL, 0),
/* HD Capture path */
@@ -614,12 +606,8 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("AD6 Channel Volume",
SND_SOC_NOPM, 0, 0,
NULL, 0),
- SND_SOC_DAPM_MIXER("AD57 Enable",
- AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0,
- NULL, 0),
- SND_SOC_DAPM_MIXER("AD68 Enable",
- AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD5768, 0,
- NULL, 0),
+ SND_SOC_DAPM_SUPPLY("AD5768 Enable", AB8500_ADPATHENA,
+ AB8500_ADPATHENA_ENAD5768, 0, NULL, 0),
/* Digital Microphone path */
@@ -651,10 +639,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
SND_SOC_DAPM_MIXER("AD4 Channel Volume",
SND_SOC_NOPM, 0, 0,
NULL, 0),
- SND_SOC_DAPM_MIXER("AD4 Enable",
- AB8500_ADPATHENA, AB8500_ADPATHENA_ENAD34,
- 0, NULL, 0),
-
/* Acoustical Noise Cancellation path */
SND_SOC_DAPM_INPUT("ANC Configure Input"),
@@ -702,24 +686,17 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"Main Supply", NULL, "Audio Power"},
{"Main Supply", NULL, "Audio Analog Power"},
- {"DAC", NULL, "ab8500_0p"},
- {"DAC", NULL, "Main Supply"},
- {"ADC", NULL, "ab8500_0c"},
- {"ADC", NULL, "Main Supply"},
-
/* ANC Configure */
{"ANC Configure Input", NULL, "Main Supply"},
{"ANC Configure Output", NULL, "ANC Configure Input"},
- /* AD/DA */
- {"ADC", NULL, "ADC Input"},
- {"DAC Output", NULL, "DAC"},
-
/* Powerup charge pump if DA1/2 is in use */
{"DA_IN1", NULL, "ab8500_0p"},
+ {"DA_IN1", NULL, "Main Supply"},
{"DA_IN1", NULL, "Charge Pump"},
{"DA_IN2", NULL, "ab8500_0p"},
+ {"DA_IN2", NULL, "Main Supply"},
{"DA_IN2", NULL, "Charge Pump"},
/* Headset path */
@@ -754,8 +731,10 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
/* HF or LineOut path */
{"DA_IN3", NULL, "ab8500_0p"},
+ {"DA_IN3", NULL, "Main Supply"},
{"DA3 Channel Volume", NULL, "DA_IN3"},
{"DA_IN4", NULL, "ab8500_0p"},
+ {"DA_IN4", NULL, "Main Supply"},
{"DA4 Channel Volume", NULL, "DA_IN4"},
{"Speaker Left Source", "Audio Path", "DA3 Channel Volume"},
@@ -813,8 +792,10 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
/* Vibrator path */
{"DA_IN5", NULL, "ab8500_0p"},
+ {"DA_IN5", NULL, "Main Supply"},
{"DA5 Channel Volume", NULL, "DA_IN5"},
{"DA_IN6", NULL, "ab8500_0p"},
+ {"DA_IN6", NULL, "Main Supply"},
{"DA6 Channel Volume", NULL, "DA_IN6"},
{"VIB1 DAC", NULL, "DA5 Channel Volume"},
@@ -856,13 +837,15 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"AD1 Channel Volume", NULL, "AD1 Source Select"},
{"AD2 Channel Volume", NULL, "AD2 Source Select"},
- {"AD12 Enable", NULL, "AD1 Channel Volume"},
- {"AD12 Enable", NULL, "AD2 Channel Volume"},
+ {"AD1 Channel Volume", NULL, "AD12 Enable"},
+ {"AD2 Channel Volume", NULL, "AD12 Enable"},
- {"AD_OUT1", NULL, "ab8500_0c"},
- {"AD_OUT1", NULL, "AD12 Enable"},
- {"AD_OUT2", NULL, "ab8500_0c"},
- {"AD_OUT2", NULL, "AD12 Enable"},
+ {"ab8500_0c", NULL, "AD_OUT1"},
+ {"AD_OUT1", NULL, "Main Supply"},
+ {"AD_OUT1", NULL, "AD1 Channel Volume"},
+ {"ab8500_0c", NULL, "AD_OUT2"},
+ {"AD_OUT2", NULL, "Main Supply"},
+ {"AD_OUT2", NULL, "AD2 Channel Volume"},
/* Mic 1 */
@@ -879,11 +862,11 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"AD3 Source Select", "Mic 1", "MIC1 ADC"},
{"AD3 Channel Volume", NULL, "AD3 Source Select"},
+ {"AD3 Channel Volume", NULL, "AD34 Enable"},
- {"AD3 Enable", NULL, "AD3 Channel Volume"},
-
- {"AD_OUT3", NULL, "ab8500_0c"},
- {"AD_OUT3", NULL, "AD3 Enable"},
+ {"ab8500_0c", NULL, "AD_OUT3"},
+ {"AD_OUT3", NULL, "Main Supply"},
+ {"AD_OUT3", NULL, "AD3 Channel Volume"},
/* HD Capture path */
@@ -892,14 +875,15 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"AD5 Channel Volume", NULL, "AD5 Source Select"},
{"AD6 Channel Volume", NULL, "AD6 Source Select"},
+ {"AD5 Channel Volume", NULL, "AD5768 Enable"},
+ {"AD6 Channel Volume", NULL, "AD5768 Enable"},
- {"AD57 Enable", NULL, "AD5 Channel Volume"},
- {"AD68 Enable", NULL, "AD6 Channel Volume"},
-
- {"AD_OUT57", NULL, "ab8500_0c"},
- {"AD_OUT57", NULL, "AD57 Enable"},
- {"AD_OUT68", NULL, "ab8500_0c"},
- {"AD_OUT68", NULL, "AD68 Enable"},
+ {"ab8500_0c", NULL, "AD_OUT57"},
+ {"AD_OUT57", NULL, "Main Supply"},
+ {"AD_OUT57", NULL, "AD5 Channel Volume"},
+ {"ab8500_0c", NULL, "AD_OUT68"},
+ {"AD_OUT68", NULL, "Main Supply"},
+ {"AD_OUT68", NULL, "AD6 Channel Volume"},
/* Digital Microphone path */
@@ -910,17 +894,25 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"DMic 5", NULL, "V-DMIC"},
{"DMic 6", NULL, "V-DMIC"},
- {"AD1 Source Select", NULL, "DMic 1"},
- {"AD2 Source Select", NULL, "DMic 2"},
- {"AD3 Source Select", NULL, "DMic 3"},
- {"AD5 Source Select", NULL, "DMic 5"},
- {"AD6 Source Select", NULL, "DMic 6"},
+ {"DMIC1", NULL, "DMic 1"},
+ {"DMIC2", NULL, "DMic 2"},
+ {"DMIC3", NULL, "DMic 3"},
+ {"DMIC4", NULL, "DMic 4"},
+ {"DMIC5", NULL, "DMic 5"},
+ {"DMIC6", NULL, "DMic 6"},
+
+ {"AD1 Source Select", "DMic 1", "DMIC1"},
+ {"AD2 Source Select", "DMic 2", "DMIC2"},
+ {"AD3 Source Select", "DMic 3", "DMIC3"},
+ {"AD5 Source Select", "DMic 5", "DMIC5"},
+ {"AD6 Source Select", "DMic 6", "DMIC6"},
- {"AD4 Channel Volume", NULL, "DMic 4"},
- {"AD4 Enable", NULL, "AD4 Channel Volume"},
+ {"AD4 Channel Volume", NULL, "DMIC4"},
+ {"AD4 Channel Volume", NULL, "AD34 Enable"},
- {"AD_OUT4", NULL, "ab8500_0c"},
- {"AD_OUT4", NULL, "AD4 Enable"},
+ {"ab8500_0c", NULL, "AD_OUT4"},
+ {"AD_OUT4", NULL, "Main Supply"},
+ {"AD_OUT4", NULL, "AD4 Channel Volume"},
/* LineIn Bypass path */
@@ -945,13 +937,13 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
/* Sidetone Filter path */
- {"Sidetone Left Source", "LineIn Left", "AD12 Enable"},
- {"Sidetone Left Source", "LineIn Right", "AD12 Enable"},
- {"Sidetone Left Source", "Mic 1", "AD3 Enable"},
+ {"Sidetone Left Source", "LineIn Left", "AD1 Channel Volume"},
+ {"Sidetone Left Source", "LineIn Right", "AD2 Channel Volume"},
+ {"Sidetone Left Source", "Mic 1", "AD3 Channel Volume"},
{"Sidetone Left Source", "Headset Left", "DA_IN1"},
- {"Sidetone Right Source", "LineIn Right", "AD12 Enable"},
- {"Sidetone Right Source", "Mic 1", "AD3 Enable"},
- {"Sidetone Right Source", "DMic 4", "AD4 Enable"},
+ {"Sidetone Right Source", "LineIn Right", "AD2 Channel Volume"},
+ {"Sidetone Right Source", "Mic 1", "AD3 Channel Volume"},
+ {"Sidetone Right Source", "DMic 4", "AD4 Channel Volume"},
{"Sidetone Right Source", "Headset Right", "DA_IN2"},
{"STFIR1 Control", NULL, "Sidetone Left Source"},
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 119/733] ASoC: ab8500: Correct digital interface format setup
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (117 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 118/733] ASoC: ab8500: Repair the DAPM capture graph Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 120/733] ASoC: ab8500: Validate and program TDM slots correctly Greg Kroah-Hartman
` (625 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit f98785adf004db6b1c9f4cea9dadae7b800db72f ]
The codec programs I2S as an undelayed left-aligned format, although the
hardware manual defines delayed left-aligned as I2S compatible. It also
enables the master generator when the codec is a clock consumer, changes
registers before the complete format has been validated, and discards
register I/O errors.
Build all three interface register values before writing them, use the
required one-bit I2S delay, only run the master generator for a provider
configuration, and propagate write failures.
Fixes: 679d7abdc754 ("ASoC: codecs: Add AB8500 codec-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260831-ab8500-codec-fixes-v1-3-f85024e717e3@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 175 ++++++++++++--------------------
1 file changed, 64 insertions(+), 111 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 7137561ef9309..7d2c07419f3d8 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -1739,149 +1739,91 @@ static int ab8500_audio_set_ear_cmv(struct snd_soc_component *component,
return 0;
}
-static int ab8500_audio_set_bit_delay(struct snd_soc_dai *dai,
- unsigned int delay)
-{
- unsigned int mask, val;
- struct snd_soc_component *component = dai->component;
-
- mask = BIT(AB8500_DIGIFCONF2_IF0DEL);
- val = 0;
-
- switch (delay) {
- case 0:
- break;
- case 1:
- val |= BIT(AB8500_DIGIFCONF2_IF0DEL);
- break;
- default:
- dev_err(dai->component->dev,
- "%s: ERROR: Unsupported bit-delay (0x%x)!\n",
- __func__, delay);
- return -EINVAL;
- }
-
- dev_dbg(dai->component->dev, "%s: IF0 Bit-delay: %d bits.\n",
- __func__, delay);
- snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
-
- return 0;
-}
-
-/* Gates clocking according format mask */
-static int ab8500_codec_set_dai_clock_gate(struct snd_soc_component *component,
- unsigned int fmt)
-{
- unsigned int mask;
- unsigned int val;
-
- mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) |
- BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
-
- val = BIT(AB8500_DIGIFCONF1_ENMASTGEN);
-
- switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
- case SND_SOC_DAIFMT_CONT: /* continuous clock */
- dev_dbg(component->dev, "%s: IF0 Clock is continuous.\n",
- __func__);
- val |= BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
- break;
- case SND_SOC_DAIFMT_GATED: /* clock is gated */
- dev_dbg(component->dev, "%s: IF0 Clock is gated.\n",
- __func__);
- break;
- default:
- dev_err(component->dev,
- "%s: ERROR: Unsupported clock mask (0x%x)!\n",
- __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK);
- return -EINVAL;
- }
-
- snd_soc_component_update_bits(component, AB8500_DIGIFCONF1, mask, val);
-
- return 0;
-}
-
static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
{
- unsigned int mask;
- unsigned int val;
struct snd_soc_component *component = dai->component;
- int status;
+ unsigned int conf1_mask, conf1_val = 0;
+ unsigned int conf2_mask, conf2_val = 0;
+ unsigned int conf3_mask, conf3_val = 0;
+ bool provider = false;
+ int ret;
dev_dbg(component->dev, "%s: Enter (fmt = 0x%x)\n", __func__, fmt);
- mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) |
+ conf3_mask = BIT(AB8500_DIGIFCONF3_IF1DATOIF0AD) |
BIT(AB8500_DIGIFCONF3_IF1CLKTOIF0CLK) |
BIT(AB8500_DIGIFCONF3_IF0BFIFOEN) |
BIT(AB8500_DIGIFCONF3_IF0MASTER);
- val = 0;
switch (fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) {
case SND_SOC_DAIFMT_CBP_CFP:
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0 Master-mode: AB8500 provider.\n", __func__);
- val |= BIT(AB8500_DIGIFCONF3_IF0MASTER);
+ conf3_val |= BIT(AB8500_DIGIFCONF3_IF0MASTER);
+ provider = true;
break;
case SND_SOC_DAIFMT_CBC_CFC:
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0 Master-mode: AB8500 consumer.\n", __func__);
break;
case SND_SOC_DAIFMT_CBC_CFP:
case SND_SOC_DAIFMT_CBP_CFC:
- dev_err(dai->component->dev,
+ dev_err(component->dev,
"%s: ERROR: The device is either a provider or a consumer.\n",
__func__);
fallthrough;
default:
- dev_err(dai->component->dev,
- "%s: ERROR: Unsupporter clocking mask 0x%x\n",
+ dev_err(component->dev,
+ "%s: ERROR: Unsupported clocking mask 0x%x\n",
__func__, fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK);
return -EINVAL;
}
- snd_soc_component_update_bits(component, AB8500_DIGIFCONF3, mask, val);
-
- /* Set clock gating */
- status = ab8500_codec_set_dai_clock_gate(component, fmt);
- if (status) {
- dev_err(dai->component->dev,
- "%s: ERROR: Failed to set clock gate (%d).\n",
- __func__, status);
- return status;
+ conf1_mask = BIT(AB8500_DIGIFCONF1_ENMASTGEN) |
+ BIT(AB8500_DIGIFCONF1_ENFSBITCLK0);
+ switch (fmt & SND_SOC_DAIFMT_CLOCK_MASK) {
+ case SND_SOC_DAIFMT_CONT:
+ if (provider)
+ conf1_val = conf1_mask;
+ break;
+ case SND_SOC_DAIFMT_GATED:
+ if (provider)
+ conf1_val = BIT(AB8500_DIGIFCONF1_ENMASTGEN);
+ break;
+ default:
+ dev_err(component->dev, "%s: Unsupported clock mask 0x%x\n",
+ __func__, fmt & SND_SOC_DAIFMT_CLOCK_MASK);
+ return -EINVAL;
}
- /* Setting data transfer format */
-
- mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) |
- BIT(AB8500_DIGIFCONF2_IF0FORMAT1) |
- BIT(AB8500_DIGIFCONF2_FSYNC0P) |
- BIT(AB8500_DIGIFCONF2_BITCLK0P);
- val = 0;
+ conf2_mask = BIT(AB8500_DIGIFCONF2_IF0FORMAT0) |
+ BIT(AB8500_DIGIFCONF2_IF0FORMAT1) |
+ BIT(AB8500_DIGIFCONF2_IF0DEL) |
+ BIT(AB8500_DIGIFCONF2_FSYNC0P) |
+ BIT(AB8500_DIGIFCONF2_BITCLK0P);
switch (fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S: /* I2S mode */
- dev_dbg(dai->component->dev, "%s: IF0 Protocol: I2S\n", __func__);
- val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1);
- ab8500_audio_set_bit_delay(dai, 0);
+ dev_dbg(component->dev, "%s: IF0 Protocol: I2S\n", __func__);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT1) |
+ BIT(AB8500_DIGIFCONF2_IF0DEL);
break;
case SND_SOC_DAIFMT_DSP_A: /* L data MSB after FRM LRC */
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0 Protocol: DSP A (TDM)\n", __func__);
- val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
- ab8500_audio_set_bit_delay(dai, 1);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0) |
+ BIT(AB8500_DIGIFCONF2_IF0DEL);
break;
case SND_SOC_DAIFMT_DSP_B: /* L data MSB during FRM LRC */
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0 Protocol: DSP B (TDM)\n", __func__);
- val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
- ab8500_audio_set_bit_delay(dai, 0);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_IF0FORMAT0);
break;
default:
- dev_err(dai->component->dev,
+ dev_err(component->dev,
"%s: ERROR: Unsupported format (0x%x)!\n",
__func__, fmt & SND_SOC_DAIFMT_FORMAT_MASK);
return -EINVAL;
@@ -1889,39 +1831,50 @@ static int ab8500_codec_set_dai_fmt(struct snd_soc_dai *dai, unsigned int fmt)
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF: /* normal bit clock + frame */
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0: Normal bit clock, normal frame\n",
__func__);
break;
case SND_SOC_DAIFMT_NB_IF: /* normal BCLK + inv FRM */
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0: Normal bit clock, inverted frame\n",
__func__);
- val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
break;
case SND_SOC_DAIFMT_IB_NF: /* invert BCLK + nor FRM */
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0: Inverted bit clock, normal frame\n",
__func__);
- val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
break;
case SND_SOC_DAIFMT_IB_IF: /* invert BCLK + FRM */
- dev_dbg(dai->component->dev,
+ dev_dbg(component->dev,
"%s: IF0: Inverted bit clock, inverted frame\n",
__func__);
- val |= BIT(AB8500_DIGIFCONF2_FSYNC0P);
- val |= BIT(AB8500_DIGIFCONF2_BITCLK0P);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_FSYNC0P) |
+ BIT(AB8500_DIGIFCONF2_BITCLK0P);
break;
default:
- dev_err(dai->component->dev,
+ dev_err(component->dev,
"%s: ERROR: Unsupported INV mask 0x%x\n",
__func__, fmt & SND_SOC_DAIFMT_INV_MASK);
return -EINVAL;
}
- snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
+ ret = snd_soc_component_update_bits(component, AB8500_DIGIFCONF3,
+ conf3_mask, conf3_val);
+ if (ret < 0)
+ return ret;
- return 0;
+ ret = snd_soc_component_update_bits(component, AB8500_DIGIFCONF1,
+ conf1_mask, conf1_val);
+ if (ret < 0)
+ return ret;
+
+ ret = snd_soc_component_update_bits(component, AB8500_DIGIFCONF2,
+ conf2_mask, conf2_val);
+
+ return ret < 0 ? ret : 0;
}
static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 120/733] ASoC: ab8500: Validate and program TDM slots correctly
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (118 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 119/733] ASoC: ab8500: Correct digital interface format setup Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 121/733] ASoC: codecs: ab8500: Use guard() for mutex locks Greg Kroah-Hartman
` (624 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 85cef7e2004ef5c1a715feaddb55d3f3d27bac0a ]
The interface clock ratio is selected from the slot count alone, ffs()
and fls() produce one-based hardware slot numbers, eight-channel mode
does not program any mappings, and all register errors are ignored.
Invalid masks can also leave a partially programmed interface.
Validate the complete configuration first, derive the supported BCLK
ratio from slots times slot width, use zero-based slot indices, program
deterministic eight-channel maps, and propagate register failures.
Fixes: 679d7abdc754 ("ASoC: codecs: Add AB8500 codec-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260831-ab8500-codec-fixes-v1-4-f85024e717e3@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 216 ++++++++++++++++++--------------
1 file changed, 123 insertions(+), 93 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 7d2c07419f3d8..63b0d57341396 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -1882,23 +1882,27 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
int slots, int slot_width)
{
struct snd_soc_component *component = dai->component;
- unsigned int val, mask, slot, slots_active;
+ unsigned int active_mask, clock_ratio, slot, value, ad_out, reg;
+ unsigned int tx_active, rx_active;
+ unsigned int conf1_val, conf2_val;
+ unsigned int mask;
+ int channel, ret;
mask = BIT(AB8500_DIGIFCONF2_IF0WL0) |
BIT(AB8500_DIGIFCONF2_IF0WL1);
- val = 0;
+ conf2_val = 0;
switch (slot_width) {
case 16:
break;
case 20:
- val |= BIT(AB8500_DIGIFCONF2_IF0WL0);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_IF0WL0);
break;
case 24:
- val |= BIT(AB8500_DIGIFCONF2_IF0WL1);
+ conf2_val |= BIT(AB8500_DIGIFCONF2_IF0WL1);
break;
case 32:
- val |= BIT(AB8500_DIGIFCONF2_IF0WL1) |
+ conf2_val |= BIT(AB8500_DIGIFCONF2_IF0WL1) |
BIT(AB8500_DIGIFCONF2_IF0WL0);
break;
default:
@@ -1907,27 +1911,11 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
return -EINVAL;
}
- dev_dbg(dai->component->dev, "%s: IF0 slot-width: %d bits.\n",
- __func__, slot_width);
- snd_soc_component_update_bits(component, AB8500_DIGIFCONF2, mask, val);
-
- /* Setup TDM clocking according to slot count */
- dev_dbg(dai->component->dev, "%s: Slots, total: %d\n", __func__, slots);
- mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
- BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
switch (slots) {
case 2:
- val = AB8500_MASK_NONE;
- break;
case 4:
- val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0);
- break;
case 8:
- val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
- break;
case 16:
- val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
- BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
break;
default:
dev_err(dai->component->dev,
@@ -1935,92 +1923,134 @@ static int ab8500_codec_set_dai_tdm_slot(struct snd_soc_dai *dai,
__func__, slots);
return -EINVAL;
}
- snd_soc_component_update_bits(component, AB8500_DIGIFCONF1, mask, val);
-
- /* Setup TDM DA according to active tx slots */
- if (tx_mask & ~0xff)
- return -EINVAL;
-
- mask = AB8500_DASLOTCONFX_SLTODAX_MASK;
- tx_mask = tx_mask << AB8500_DA_DATA0_OFFSET;
- slots_active = hweight32(tx_mask);
-
- dev_dbg(dai->component->dev, "%s: Slots, active, TX: %d\n", __func__,
- slots_active);
-
- switch (slots_active) {
- case 0:
+ clock_ratio = slots * slot_width;
+ switch (clock_ratio) {
+ case 32:
+ conf1_val = 0;
break;
- case 1:
- slot = ffs(tx_mask);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF1, mask, slot);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF3, mask, slot);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF2, mask, slot);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF4, mask, slot);
+ case 64:
+ conf1_val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0);
break;
- case 2:
- slot = ffs(tx_mask);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF1, mask, slot);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF3, mask, slot);
- slot = fls(tx_mask);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF2, mask, slot);
- snd_soc_component_update_bits(component, AB8500_DASLOTCONF4, mask, slot);
+ case 128:
+ conf1_val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
break;
- case 8:
- dev_dbg(dai->component->dev,
- "%s: In 8-channel mode DA-from-slot mapping is set manually.",
- __func__);
+ case 256:
+ conf1_val = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
+ BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
break;
default:
- dev_err(dai->component->dev,
- "%s: Unsupported number of active TX-slots (%d)!\n",
- __func__, slots_active);
+ dev_err(component->dev, "%s: Unsupported BCLK ratio (%u)!\n",
+ __func__, clock_ratio);
return -EINVAL;
}
- /* Setup TDM AD according to active RX-slots */
+ active_mask = GENMASK(min(slots, 8) - 1, 0);
+ if ((tx_mask | rx_mask) & ~active_mask) {
+ dev_err(component->dev, "%s: Slot mask exceeds slot count\n",
+ __func__);
+ return -EINVAL;
+ }
- if (rx_mask & ~0xff)
+ tx_active = hweight32(tx_mask);
+ rx_active = hweight32(rx_mask);
+ if (tx_active != 0 && tx_active != 1 && tx_active != 2 &&
+ tx_active != 8) {
+ dev_err(component->dev, "%s: Unsupported active TX slots (%u)!\n",
+ __func__, tx_active);
+ return -EINVAL;
+ }
+ if (rx_active != 0 && rx_active != 1 && rx_active != 2 &&
+ rx_active != 8) {
+ dev_err(component->dev, "%s: Unsupported active RX slots (%u)!\n",
+ __func__, rx_active);
return -EINVAL;
+ }
+
+ dev_dbg(component->dev,
+ "%s: %d slots of %d bits, TX active: %u, RX active: %u\n",
+ __func__, slots, slot_width, tx_active, rx_active);
- rx_mask = rx_mask << AB8500_AD_DATA0_OFFSET;
- slots_active = hweight32(rx_mask);
+ ret = snd_soc_component_update_bits(component, AB8500_DIGIFCONF2,
+ mask, conf2_val);
+ if (ret < 0)
+ return ret;
- dev_dbg(dai->component->dev, "%s: Slots, active, RX: %d\n", __func__,
- slots_active);
+ mask = BIT(AB8500_DIGIFCONF1_IF0BITCLKOS0) |
+ BIT(AB8500_DIGIFCONF1_IF0BITCLKOS1);
+ ret = snd_soc_component_update_bits(component, AB8500_DIGIFCONF1,
+ mask, conf1_val);
+ if (ret < 0)
+ return ret;
- switch (slots_active) {
- case 0:
- break;
- case 1:
- slot = ffs(rx_mask);
- snd_soc_component_update_bits(component, AB8500_ADSLOTSEL(slot),
- AB8500_MASK_SLOT(slot),
- AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
- break;
- case 2:
- slot = ffs(rx_mask);
- snd_soc_component_update_bits(component,
- AB8500_ADSLOTSEL(slot),
- AB8500_MASK_SLOT(slot),
- AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3, slot));
- slot = fls(rx_mask);
- snd_soc_component_update_bits(component,
- AB8500_ADSLOTSEL(slot),
- AB8500_MASK_SLOT(slot),
- AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT2, slot));
- break;
- case 8:
- dev_dbg(dai->component->dev,
- "%s: In 8-channel mode AD-to-slot mapping is set manually.",
- __func__);
- break;
- default:
- dev_err(dai->component->dev,
- "%s: Unsupported number of active RX-slots (%d)!\n",
- __func__, slots_active);
- return -EINVAL;
+ mask = AB8500_DASLOTCONFX_SLTODAX_MASK;
+ if (tx_active == 1 || tx_active == 2) {
+ slot = __ffs(tx_mask) + AB8500_DA_DATA0_OFFSET;
+ reg = AB8500_DASLOTCONF1;
+ ret = snd_soc_component_update_bits(component, reg, mask, slot);
+ if (ret < 0)
+ return ret;
+ reg = AB8500_DASLOTCONF3;
+ ret = snd_soc_component_update_bits(component, reg, mask, slot);
+ if (ret < 0)
+ return ret;
+
+ if (tx_active == 2)
+ slot = __fls(tx_mask) + AB8500_DA_DATA0_OFFSET;
+ reg = AB8500_DASLOTCONF2;
+ ret = snd_soc_component_update_bits(component, reg, mask, slot);
+ if (ret < 0)
+ return ret;
+ reg = AB8500_DASLOTCONF4;
+ ret = snd_soc_component_update_bits(component, reg, mask, slot);
+ if (ret < 0)
+ return ret;
+ } else if (tx_active == 8) {
+ channel = 0;
+ for (slot = 0; slot < 8; slot++) {
+ if (!(tx_mask & BIT(slot)))
+ continue;
+ reg = AB8500_DASLOTCONF1 + channel++;
+ value = slot + AB8500_DA_DATA0_OFFSET;
+ ret = snd_soc_component_update_bits(component, reg, mask, value);
+ if (ret < 0)
+ return ret;
+ }
+ }
+
+ if (rx_active == 1 || rx_active == 2) {
+ slot = __ffs(rx_mask) + AB8500_AD_DATA0_OFFSET;
+ value = AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT3,
+ slot);
+ reg = AB8500_ADSLOTSEL(slot);
+ mask = AB8500_MASK_SLOT(slot);
+ ret = snd_soc_component_update_bits(component, reg, mask, value);
+ if (ret < 0)
+ return ret;
+
+ if (rx_active == 2) {
+ slot = __fls(rx_mask) + AB8500_AD_DATA0_OFFSET;
+ value = AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(AB8500_AD_OUT2,
+ slot);
+ reg = AB8500_ADSLOTSEL(slot);
+ mask = AB8500_MASK_SLOT(slot);
+ ret = snd_soc_component_update_bits(component, reg, mask, value);
+ if (ret < 0)
+ return ret;
+ }
+ } else if (rx_active == 8) {
+ channel = 0;
+ for (slot = 0; slot < 8; slot++) {
+ if (!(rx_mask & BIT(slot)))
+ continue;
+ ad_out = AB8500_AD_OUT1 + channel++;
+ value = AB8500_ADSLOTSELX_AD_OUT_TO_SLOT(ad_out, slot);
+ reg = AB8500_ADSLOTSEL(slot);
+ mask = AB8500_MASK_SLOT(slot);
+ ret = snd_soc_component_update_bits(component, reg, mask, value);
+ if (ret < 0)
+ return ret;
+ }
}
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 121/733] ASoC: codecs: ab8500: Use guard() for mutex locks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (119 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 120/733] ASoC: ab8500: Validate and program TDM slots correctly Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 122/733] ASoC: ab8500: Remove the nonfunctional sidetone apply control Greg Kroah-Hartman
` (623 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cezary Rojewski, bui duc phuc,
Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: bui duc phuc <phucduc.bui@gmail.com>
[ Upstream commit 350b7eae8e8b2bd3885a3e2424381494d6bde038 ]
Clean up the code using guard() for mutex locks.
Merely code refactoring, and no behavior change.
Reviewed-by: Cezary Rojewski <cezary.rojewski@intel.com>
Signed-off-by: bui duc phuc <phucduc.bui@gmail.com>
Link: https://patch.msgid.link/20260708125002.202515-2-phucduc.bui@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: ec75e653b70c ("ASoC: ab8500: Remove the nonfunctional sidetone apply control")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 63b0d57341396..167f021c7ecbc 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -14,6 +14,7 @@
* for ST-Ericsson.
*/
+#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
@@ -981,9 +982,8 @@ static int sid_status_control_get(struct snd_kcontrol *kcontrol,
struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
- mutex_lock(&drvdata->ctrl_lock);
+ guard(mutex)(&drvdata->ctrl_lock);
ucontrol->value.enumerated.item[0] = drvdata->sid_status;
- mutex_unlock(&drvdata->ctrl_lock);
return 0;
}
@@ -1006,7 +1006,7 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
return -EIO;
}
- mutex_lock(&drvdata->ctrl_lock);
+ guard(mutex)(&drvdata->ctrl_lock);
sidconf = snd_soc_component_read(component, AB8500_SIDFIRCONF);
if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
@@ -1017,7 +1017,8 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
} else {
status = -EBUSY;
}
- goto out;
+ dev_dbg(component->dev, "%s: Exit\n", __func__);
+ return status;
}
snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
@@ -1035,9 +1036,6 @@ static int sid_status_control_put(struct snd_kcontrol *kcontrol,
drvdata->sid_status = SID_FIR_CONFIGURED;
-out:
- mutex_unlock(&drvdata->ctrl_lock);
-
dev_dbg(component->dev, "%s: Exit\n", __func__);
return status;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 122/733] ASoC: ab8500: Remove the nonfunctional sidetone apply control
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (120 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 121/733] ASoC: codecs: ab8500: Use guard() for mutex locks Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 123/733] ASoC: ab8500: Skip missing DMIC GPIOs on AB8505 Greg Kroah-Hartman
` (622 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit ec75e653b70ce26ea68187c2069722baa80efadb ]
After the coefficient controls were removed, writing "Apply FIR"
programs 128 zero coefficients and reports that the sidetone filter is
configured. The associated ANC configuration DAPM pins are also now
unreachable dead infrastructure.
Remove the misleading status/apply control, its private state, and the
obsolete configuration-only DAPM pins. Keep the direct sidetone reset
and remaining hardware controls.
Fixes: e366ce8b22ec ("ASoC: codecs: ab8500: Remove suspicious code")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260831-ab8500-codec-fixes-v1-5-f85024e717e3@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 114 --------------------------------
1 file changed, 114 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 167f021c7ecbc..11142d15df450 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -14,17 +14,14 @@
* for ST-Ericsson.
*/
-#include <linux/cleanup.h>
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/device.h>
#include <linux/slab.h>
#include <linux/moduleparam.h>
#include <linux/init.h>
-#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/platform_device.h>
-#include <linux/mutex.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500-sysctrl.h>
@@ -54,32 +51,9 @@
/* Macrocell register definitions */
#define AB8500_GPIO_DIR4_REG 0x13 /* Bank AB8500_MISC */
-/* Nr of FIR/IIR-coeff banks in ANC-block */
-#define AB8500_NR_OF_ANC_COEFF_BANKS 2
-
-/* Minimum duration to keep ANC IIR Init bit high or
-low before proceeding with the configuration sequence */
-#define AB8500_ANC_SM_DELAY 2000
-
-/* Sidetone states */
-static const char * const enum_sid_state[] = {
- "Unconfigured",
- "Apply FIR",
- "FIR is configured",
-};
-enum sid_state {
- SID_UNCONFIGURED = 0,
- SID_APPLY_FIR = 1,
- SID_FIR_CONFIGURED = 2,
-};
-
/* Private data for AB8500 device-driver */
struct ab8500_codec_drvdata {
struct regmap *regmap;
- struct mutex ctrl_lock;
-
- /* Sidetone */
- enum sid_state sid_status;
};
static inline const char *amic_micbias_str(enum amic_micbias micbias)
@@ -642,9 +616,6 @@ static const struct snd_soc_dapm_widget ab8500_dapm_widgets[] = {
NULL, 0),
/* Acoustical Noise Cancellation path */
- SND_SOC_DAPM_INPUT("ANC Configure Input"),
- SND_SOC_DAPM_OUTPUT("ANC Configure Output"),
-
SND_SOC_DAPM_MUX("ANC Source",
SND_SOC_NOPM, 0, 0,
dapm_anc_in_select),
@@ -687,10 +658,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes[] = {
{"Main Supply", NULL, "Audio Power"},
{"Main Supply", NULL, "Audio Analog Power"},
- /* ANC Configure */
- {"ANC Configure Input", NULL, "Main Supply"},
- {"ANC Configure Output", NULL, "ANC Configure Input"},
-
/* Powerup charge pump if DA1/2 is in use */
{"DA_IN1", NULL, "ab8500_0p"},
@@ -972,75 +939,6 @@ static const struct snd_soc_dapm_route ab8500_dapm_routes_mic2_vamicx[] = {
{"MIC2 V-AMICx Enable", NULL, "V-AMIC2"},
};
-/*
- * Control-events
- */
-
-static int sid_status_control_get(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
-
- guard(mutex)(&drvdata->ctrl_lock);
- ucontrol->value.enumerated.item[0] = drvdata->sid_status;
-
- return 0;
-}
-
-/* Write sidetone FIR-coefficients configuration sequence */
-static int sid_status_control_put(struct snd_kcontrol *kcontrol,
- struct snd_ctl_elem_value *ucontrol)
-{
- struct snd_soc_component *component = snd_kcontrol_chip(kcontrol);
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(component->dev);
- unsigned int param, sidconf;
- int status = 1;
-
- dev_dbg(component->dev, "%s: Enter\n", __func__);
-
- if (ucontrol->value.enumerated.item[0] != SID_APPLY_FIR) {
- dev_err(component->dev,
- "%s: ERROR: This control supports '%s' only!\n",
- __func__, enum_sid_state[SID_APPLY_FIR]);
- return -EIO;
- }
-
- guard(mutex)(&drvdata->ctrl_lock);
-
- sidconf = snd_soc_component_read(component, AB8500_SIDFIRCONF);
- if (((sidconf & BIT(AB8500_SIDFIRCONF_FIRSIDBUSY)) != 0)) {
- if ((sidconf & BIT(AB8500_SIDFIRCONF_ENFIRSIDS)) == 0) {
- dev_err(component->dev, "%s: Sidetone busy while off!\n",
- __func__);
- status = -EPERM;
- } else {
- status = -EBUSY;
- }
- dev_dbg(component->dev, "%s: Exit\n", __func__);
- return status;
- }
-
- snd_soc_component_write(component, AB8500_SIDFIRADR, 0);
-
- for (param = 0; param < AB8500_SID_FIR_COEFFS; param++) {
- snd_soc_component_write(component, AB8500_SIDFIRCOEF1, 0);
- snd_soc_component_write(component, AB8500_SIDFIRCOEF2, 0);
- }
-
- snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
- BIT(AB8500_SIDFIRADR_FIRSIDSET),
- BIT(AB8500_SIDFIRADR_FIRSIDSET));
- snd_soc_component_update_bits(component, AB8500_SIDFIRADR,
- BIT(AB8500_SIDFIRADR_FIRSIDSET), 0);
-
- drvdata->sid_status = SID_FIR_CONFIGURED;
-
- dev_dbg(component->dev, "%s: Exit\n", __func__);
-
- return status;
-}
-
/*
* Controls - Non-DAPM ASoC
*/
@@ -1324,9 +1222,6 @@ static SOC_ENUM_SINGLE_DECL(soc_enum_bfifomast,
AB8500_FIFOCONF3, AB8500_FIFOCONF3_BFIFOMAST_SHIFT,
enum_slavemaster);
-/* Sidetone */
-static SOC_ENUM_SINGLE_EXT_DECL(soc_enum_sidstate, enum_sid_state);
-
/* ANC */
static struct snd_kcontrol_new ab8500_ctrls[] = {
@@ -1617,8 +1512,6 @@ static struct snd_kcontrol_new ab8500_ctrls[] = {
AB8500_ANC_WARP_DELAY_MIN, AB8500_ANC_WARP_DELAY_MAX, 0),
/* Sidetone */
- SOC_ENUM_EXT("Sidetone Status", soc_enum_sidstate,
- sid_status_control_get, sid_status_control_put),
SOC_SINGLE_STROBE("Sidetone Reset",
AB8500_SIDFIRADR, AB8500_SIDFIRADR_FIRSIDSET, 0),
};
@@ -2145,10 +2038,8 @@ static void ab8500_codec_of_probe(struct device *dev, struct device_node *np,
static int ab8500_codec_probe(struct snd_soc_component *component)
{
- struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
struct device *dev = component->dev;
struct device_node *np = dev->of_node;
- struct ab8500_codec_drvdata *drvdata = dev_get_drvdata(dev);
struct ab8500_codec_platform_data codec_pdata;
int status;
@@ -2181,10 +2072,6 @@ static int ab8500_codec_probe(struct snd_soc_component *component)
snd_soc_component_write(component, AB8500_SHORTCIRCONF,
BIT(AB8500_SHORTCIRCONF_HSZCDDIS));
- snd_soc_dapm_disable_pin(dapm, "ANC Configure Input");
-
- mutex_init(&drvdata->ctrl_lock);
-
return status;
}
@@ -2213,7 +2100,6 @@ static int ab8500_codec_driver_probe(struct platform_device *pdev)
GFP_KERNEL);
if (!drvdata)
return -ENOMEM;
- drvdata->sid_status = SID_UNCONFIGURED;
dev_set_drvdata(&pdev->dev, drvdata);
drvdata->regmap = devm_regmap_init(&pdev->dev, NULL, &pdev->dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 123/733] ASoC: ab8500: Skip missing DMIC GPIOs on AB8505
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (121 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 122/733] ASoC: ab8500: Remove the nonfunctional sidetone apply control Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 124/733] drm/pagemap: Prevent double migration of device pages Greg Kroah-Hartman
` (621 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 711178754287db3fd0f7accff3c2a7575f8873b7 ]
GPIO27, GPIO29 and GPIO31 provide the digital microphone clock
outputs on AB8500, but these GPIOs do not exist on AB8505. The shared
codec driver nevertheless accesses their direction register while
setting up every AB8505 codec.
Identify the parent MFD device and leave the nonexistent GPIOs
untouched on AB8505.
Fixes: 679d7abdc754 ("ASoC: codecs: Add AB8500 codec-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260831-ab8500-codec-fixes-v1-6-f85024e717e3@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/ab8500-codec.c | 31 +++++++++++++++++--------------
1 file changed, 17 insertions(+), 14 deletions(-)
diff --git a/sound/soc/codecs/ab8500-codec.c b/sound/soc/codecs/ab8500-codec.c
index 11142d15df450..e1a0e35836e6c 100644
--- a/sound/soc/codecs/ab8500-codec.c
+++ b/sound/soc/codecs/ab8500-codec.c
@@ -1540,6 +1540,8 @@ static int ab8500_audio_init_audioblock(struct snd_soc_component *component)
static int ab8500_audio_setup_mics(struct snd_soc_component *component,
struct amic_settings *amics)
{
+ struct device *dev = component->dev;
+ struct ab8500 *ab8500 = dev_get_drvdata(dev->parent);
struct snd_soc_dapm_context *dapm = snd_soc_component_to_dapm(component);
u8 value8;
unsigned int value;
@@ -1548,20 +1550,21 @@ static int ab8500_audio_setup_mics(struct snd_soc_component *component,
dev_dbg(component->dev, "%s: Enter.\n", __func__);
- /* Set DMic-clocks to outputs */
- status = abx500_get_register_interruptible(component->dev, AB8500_MISC,
- AB8500_GPIO_DIR4_REG,
- &value8);
- if (status < 0)
- return status;
- value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
- GPIO31_DIR_OUTPUT;
- status = abx500_set_register_interruptible(component->dev,
- AB8500_MISC,
- AB8500_GPIO_DIR4_REG,
- value);
- if (status < 0)
- return status;
+ /* Set DMic-clocks to outputs; these GPIOs do not exist on AB8505. */
+ if (!is_ab8505(ab8500)) {
+ status = abx500_get_register_interruptible(dev, AB8500_MISC,
+ AB8500_GPIO_DIR4_REG,
+ &value8);
+ if (status < 0)
+ return status;
+ value = value8 | GPIO27_DIR_OUTPUT | GPIO29_DIR_OUTPUT |
+ GPIO31_DIR_OUTPUT;
+ status = abx500_set_register_interruptible(dev, AB8500_MISC,
+ AB8500_GPIO_DIR4_REG,
+ value);
+ if (status < 0)
+ return status;
+ }
/* Attach regulators to AMic DAPM-paths */
dev_dbg(component->dev, "%s: Mic 1a regulator: %s\n", __func__,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 124/733] drm/pagemap: Prevent double migration of device pages
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (122 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 123/733] ASoC: ab8500: Skip missing DMIC GPIOs on AB8505 Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 125/733] drm/pagemap: Reset migration page count on eviction retry Greg Kroah-Hartman
` (620 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maarten Lankhorst, Maxime Ripard,
Matthew Brost, Thomas Zimmermann, David Airlie, Simona Vetter,
Thomas Hellström, Himal Prasad Ghimiray, Arvind Yadav,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arvind Yadav <arvind.yadav@intel.com>
[ Upstream commit c4126f1db36e6b2e1c79b0e30a8a2de91c568f4c ]
A device-private folio migrated to system memory by a CPU fault can
remain reachable through the raw-PFN eviction path until migration
finalization drops the source reference.
If eviction selects the same device-private folio during this window,
it can attempt to migrate the folio again. The second migration can leave
an uncharged folio on an LRU list, causing folio_lruvec_lock_irqsave() to
retry indefinitely and resulting in a soft lockup and RCU stall.
Mark successfully migrated device-private folios using a low bit of
their zone_device_data before migration finalization. Make both CPU-fault
and raw-PFN migration paths skip device-private folios carrying this
flag.
Mask the flag when retrieving the drm_pagemap_zdd pointer and preserve
it when a device-private folio is split. Keeping the state on the physical
folio also avoids depending on a virtual address that may change before a
fault occurs.
v2:
- Replace the retired-PFN XArray with an embedded bitmap. (Matthew Brost)
- Mark every base page covered by a migrated folio so retirement remains
valid if the folio is later split.
v3:
- Store the migrated state in a low bit of zone_device_data instead of
adding virtual-range and bitmap tracking to the ZDD. (Matthew Brost)
- Mask the flag when retrieving the ZDD and preserve it when splitting
a folio.
- Drop the pre-existing fixes already covered by Matthew Brost's series:
https://patchwork.freedesktop.org/series/171651/
v4:
- Advance by the folio size only for migration entries marked with
MIGRATE_PFN_COMPOUND. (Sashiko)
v5:
- Simplify ZDD flag updates and folio iteration. (Matthew Brost)
- Skip retired device-private folios in the CPU-fault path. (Matthew Brost)
- Preserve flag bits while taking a new ZDD reference for split folios.
v6:
- Restore MIGRATE_PFN_COMPOUND-aware stepping so non-compound migration
entries are processed one at a time. (Sashiko)
- Drop the pre-existing fixes already covered by Matthew Brost's series:
https://patchwork.freedesktop.org/series/171651/
The lockup was observed as:
[10109.860465] watchdog: BUG: soft lockup - CPU#9 stuck for 26s! [kworker/u65:5:6557]
[10109.860524] Tainted: [S]=CPU_OUT_OF_SPEC, [O]=OOT_MODULE
[10109.860524] Hardware name: ASUS System Product Name/PRIME Z790-P WIFI, BIOS 0812 02/24/2023
[10109.860525] Workqueue: xe_page_fault_work_queue xe_pagefault_queue_work [xe]
[10109.860644] RIP: 0010:_raw_spin_unlock_irqrestore+0x57/0x80
[10109.860655] Call Trace:
[10109.860655] <TASK>
[10109.860657] folio_lruvec_lock_irqsave+0x216/0x220
[10109.860661] ? __pfx_lru_add+0x10/0x10
[10109.860665] folio_batch_move_lru+0xc8/0x450
[10109.860670] ? lock_acquire+0xc4/0x2d0
[10109.860674] ? __folio_batch_add_and_move+0x60/0x2e0
[10109.860677] ? folio_migrate_mapping+0xa6/0x110
[10109.860679] ? folio_migrate_flags+0x13b/0x1b0
[10109.860681] ? __pfx_lru_add+0x10/0x10
[10109.860683] __folio_batch_add_and_move+0xe7/0x2e0
[10109.860685] ? dma_iova_try_alloc+0xb0/0x140
[10109.860689] folio_add_lru+0x64/0x80
[10109.860691] __migrate_device_finalize+0x12c/0x270
[10109.860695] migrate_device_finalize+0x10/0x20
[10109.860698] drm_pagemap_evict_to_ram+0x185/0x370 [drm_gpusvm_helper]
[10109.860704] ? drm_pagemap_evict_to_ram+0x96/0x370 [drm_gpusvm_helper]
[10109.860709] xe_svm_bo_evict+0x15/0x20 [xe]
[10109.860819] ? xe_svm_bo_evict+0x15/0x20 [xe]
[10109.860921] xe_bo_move+0x107e/0x1570 [xe]
[10109.860992] ? xe_ttm_tt_create+0x168/0x340 [xe]
[10109.861059] ? __up_read+0x98/0x2b0
[10109.861061] ? lock_is_held_type+0xa3/0x130
[10109.861067] ttm_bo_handle_move_mem+0xe8/0x1e0 [ttm]
[10109.861075] ttm_bo_evict+0x141/0x1c0 [ttm]
[10109.861081] ttm_bo_evict_cb+0x9f/0x100 [ttm]
[10109.861086] ttm_lru_walk_for_evict+0x84/0x190 [ttm]
[10109.861091] ? xe_ttm_vram_mgr_new+0x258/0x3a0 [xe]
[10109.861198] ttm_bo_alloc_resource+0x219/0x750 [ttm]
[10109.861203] ? ttm_bo_alloc_resource+0xa9/0x750 [ttm]
[10109.861208] ? lock_acquire+0xc4/0x2d0
[10109.861214] ttm_bo_validate+0x94/0x1c0 [ttm]
[10109.861218] ? ww_mutex_trylock+0x19d/0x3d0
[10109.861219] ? _raw_write_unlock+0x22/0x50
[10109.861223] ttm_bo_init_reserved+0x17d/0x1f0 [ttm]
[10109.861228] xe_bo_init_locked+0x20a/0x620 [xe]
[10109.861294] ? __pfx_xe_ttm_bo_destroy+0x10/0x10 [xe]
[10109.861359] ? mark_held_locks+0x46/0x90
[10109.861361] ? __create_object+0x68/0xc0
[10109.861366] __xe_bo_create_locked+0x384/0xa20 [xe]
[10109.861432] ? lock_acquire+0xc4/0x2d0
[10109.861434] ? xe_drm_pagemap_populate_mm+0xd3/0x340 [xe]
[10109.861542] xe_bo_create_locked+0x23/0x40 [xe]
[10109.861609] xe_drm_pagemap_populate_mm+0x12e/0x340 [xe]
[10109.861707] ? __lock_acquire+0x43e/0x2930
[10109.861716] drm_pagemap_populate_mm+0x74/0xe0 [drm_gpusvm_helper]
[10109.861720] xe_svm_alloc_vram+0xb5/0x2c0 [xe]
[10109.861817] ? seqcount_lockdep_reader_access.constprop.0+0x9f/0xc0
[10109.861819] ? ktime_get+0x23/0x130
[10109.861821] ? trace_hardirqs_on+0x22/0xe0
[10109.861823] ? seqcount_lockdep_reader_access.constprop.0+0x9f/0xc0
[10109.861826] __xe_svm_handle_pagefault+0x77d/0xbf0 [xe]
[10109.861924] ? rwsem_down_write_slowpath+0x43a/0x9a0
[10109.861926] ? _raw_spin_unlock_irq+0x27/0x70
[10109.861928] ? rwsem_down_write_slowpath+0x43a/0x9a0
[10109.861929] ? trace_hardirqs_on+0x22/0xe0
[10109.861931] ? _raw_spin_unlock_irq+0x27/0x70
[10109.861933] ? rwsem_down_write_slowpath+0x459/0x9a0
[10109.861937] xe_svm_handle_pagefault+0x3d/0xb0 [xe]
[10109.862030] xe_pagefault_queue_work+0x1a9/0x520 [xe]
[10109.862122] process_one_work+0x239/0x730
[10109.862127] worker_thread+0x200/0x3f0
[10109.862130] ? __pfx_worker_thread+0x10/0x10
[10109.862132] kthread+0x10d/0x150
[10109.862133] ? __pfx_kthread+0x10/0x10
[10109.862135] ret_from_fork+0x3bd/0x470
[10109.862138] ? __pfx_kthread+0x10/0x10
[10109.862140] ret_from_fork_asm+0x1a/0x30
[10109.862146] </TASK>
Fixes: 99624bdff867 ("drm/gpusvm: Add support for GPU Shared Virtual Memory")
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Assisted-by: Claude:claude-opus-4-8
Suggested-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20260810092845.2776097-1-arvind.yadav@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_pagemap.c | 127 ++++++++++++++++++++++++++++++++--
include/drm/drm_pagemap.h | 8 ++-
2 files changed, 129 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index 05eb7254028f7..72ca5a48d4a66 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -1195,12 +1195,117 @@ void drm_pagemap_put(struct drm_pagemap *dpagemap)
}
EXPORT_SYMBOL(drm_pagemap_put);
+/**
+ * drm_pagemap_page_get_flags() - Read flags from a device-private folio
+ * @page: Pointer to a page of the device-private folio
+ *
+ * Return: The DRM_PAGEMAP_ZDD_FLAG_* bits encoded in zone_device_data.
+ */
+static unsigned long drm_pagemap_page_get_flags(struct page *page)
+{
+ struct folio *folio = page_folio(page);
+
+ return (unsigned long)folio_zone_device_data(folio) &
+ DRM_PAGEMAP_ZDD_FLAG_MASK;
+}
+
+/**
+ * drm_pagemap_page_set_flags() - Set flags on a device-private folio
+ * @page: Pointer to a page of the device-private folio
+ * @flags: DRM_PAGEMAP_ZDD_FLAG_* bits to set
+ *
+ * Preserve any flags already encoded alongside the ZDD pointer.
+ */
+static void drm_pagemap_page_set_flags(struct page *page,
+ unsigned long flags)
+{
+ struct folio *folio = page_folio(page);
+ unsigned long old;
+
+ if (WARN_ON_ONCE(flags & ~DRM_PAGEMAP_ZDD_FLAG_MASK))
+ return;
+
+ old = (unsigned long)folio_zone_device_data(folio);
+ folio_set_zone_device_data(folio, (void *)(old | flags));
+}
+
+/**
+ * drm_pagemap_retire_migrated_pages() - Record migrated device-private folios
+ * @src_pfns: source array after migrate_vma_pages() or migrate_device_pages()
+ * @npages: number of entries in @src_pfns
+ *
+ * Flag device-private folios successfully migrated to RAM before finalize
+ * unlocks the sources. The migrated state is stored in the physical folio, so
+ * it survives later folio splits and subsequent migrations can skip it.
+ */
+static void drm_pagemap_retire_migrated_pages(unsigned long *src_pfns,
+ unsigned long npages)
+{
+ unsigned long i = 0;
+
+ while (i < npages) {
+ struct page *page = migrate_pfn_to_page(src_pfns[i]);
+ unsigned long nr = 1;
+
+ if (!page) {
+ i++;
+ continue;
+ }
+
+ if (src_pfns[i] & MIGRATE_PFN_COMPOUND)
+ nr = folio_nr_pages(page_folio(page));
+
+ if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
+ is_device_private_page(page))
+ drm_pagemap_page_set_flags(page,
+ DRM_PAGEMAP_ZDD_FLAG_MIGRATED);
+
+ i += nr;
+ }
+}
+
+/**
+ * drm_pagemap_skip_retired_pages() - Skip retired device-private folios
+ * @src_pfns: MIGRATE_PFN-encoded source array
+ * @npages: number of entries in @src_pfns
+ *
+ * Skip source folios already migrated to RAM, identified by the migrated flag
+ * stored in the physical folio's zone_device_data.
+ */
+static void drm_pagemap_skip_retired_pages(unsigned long *src_pfns,
+ unsigned long npages)
+{
+ unsigned long i = 0;
+
+ while (i < npages) {
+ struct page *page = migrate_pfn_to_page(src_pfns[i]);
+ unsigned long nr = 1;
+
+ if (!page) {
+ i++;
+ continue;
+ }
+
+ if (src_pfns[i] & MIGRATE_PFN_COMPOUND)
+ nr = folio_nr_pages(page_folio(page));
+
+ if ((src_pfns[i] & MIGRATE_PFN_MIGRATE) &&
+ is_device_private_page(page) &&
+ (drm_pagemap_page_get_flags(page) &
+ DRM_PAGEMAP_ZDD_FLAG_MIGRATED))
+ src_pfns[i] &= ~MIGRATE_PFN_MIGRATE;
+
+ i += nr;
+ }
+}
+
/**
* drm_pagemap_evict_to_ram() - Evict GPU SVM range to RAM
* @devmem_allocation: Pointer to the device memory allocation
*
- * Similar to __drm_pagemap_migrate_to_ram but does not require mmap lock and
- * migration done via migrate_device_* functions.
+ * Similar to __drm_pagemap_migrate_to_ram(), but uses the
+ * migrate_device_* helpers and does not require the mmap lock.
+ * Device-private PFNs already migrated to RAM by either path are skipped.
*
* Return: 0 on success, negative error code on failure.
*/
@@ -1241,6 +1346,8 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
if (err)
goto err_free;
+ drm_pagemap_skip_retired_pages(src, npages);
+
err = drm_pagemap_migrate_populate_ram_pfn(NULL, NULL, npages, &mpages,
src, dst, 0);
if (err || !mpages)
@@ -1263,6 +1370,7 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
if (err)
drm_pagemap_migration_unlock_put_pages(npages, dst);
migrate_device_pages(src, dst, npages);
+ drm_pagemap_retire_migrated_pages(src, npages);
migrate_device_finalize(src, dst, npages);
drm_pagemap_migrate_unmap_pages(devmem_allocation->dev, pagemap_addr, dst, npages,
DMA_FROM_DEVICE, &state);
@@ -1360,13 +1468,15 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
if (!migrate.cpages)
goto err_free;
+ drm_pagemap_skip_retired_pages(migrate.src, npages);
+
ops = zdd->devmem_allocation->ops;
dev = zdd->devmem_allocation->dev;
err = drm_pagemap_migrate_populate_ram_pfn(vas, page, npages, &mpages,
migrate.src, migrate.dst,
start);
- if (err)
+ if (err || !mpages)
goto err_finalize;
err = drm_pagemap_migrate_map_system_pages(dev, pagemap_addr,
@@ -1386,6 +1496,7 @@ static int __drm_pagemap_migrate_to_ram(struct vm_area_struct *vas,
if (err)
drm_pagemap_migration_unlock_put_pages(npages, migrate.dst);
migrate_vma_pages(&migrate);
+ drm_pagemap_retire_migrated_pages(migrate.src, npages);
migrate_vma_finalize(&migrate);
if (dev)
drm_pagemap_migrate_unmap_pages(dev, pagemap_addr, migrate.dst,
@@ -1438,13 +1549,19 @@ static vm_fault_t drm_pagemap_migrate_to_ram(struct vm_fault *vmf)
static void drm_pagemap_folio_split(struct folio *orig_folio, struct folio *new_folio)
{
struct drm_pagemap_zdd *zdd;
+ unsigned long orig_data, new_data;
if (!new_folio)
return;
new_folio->pgmap = orig_folio->pgmap;
- zdd = folio_zone_device_data(orig_folio);
- folio_set_zone_device_data(new_folio, drm_pagemap_zdd_get(zdd));
+
+ orig_data = (unsigned long)folio_zone_device_data(orig_folio);
+ zdd = (struct drm_pagemap_zdd *)(orig_data & ~DRM_PAGEMAP_ZDD_FLAG_MASK);
+
+ new_data = (unsigned long)drm_pagemap_zdd_get(zdd);
+ new_data |= orig_data & DRM_PAGEMAP_ZDD_FLAG_MASK;
+ folio_set_zone_device_data(new_folio, (void *)new_data);
}
static const struct dev_pagemap_ops drm_pagemap_pagemap_ops = {
diff --git a/include/drm/drm_pagemap.h b/include/drm/drm_pagemap.h
index 95eb4b66b0577..ebbd3b0ddf367 100644
--- a/include/drm/drm_pagemap.h
+++ b/include/drm/drm_pagemap.h
@@ -2,6 +2,7 @@
#ifndef _DRM_PAGEMAP_H_
#define _DRM_PAGEMAP_H_
+#include <linux/bits.h>
#include <linux/dma-direction.h>
#include <linux/hmm.h>
#include <linux/memremap.h>
@@ -339,6 +340,9 @@ struct drm_pagemap_migrate_details {
#if IS_ENABLED(CONFIG_ZONE_DEVICE)
+#define DRM_PAGEMAP_ZDD_FLAG_MIGRATED BIT(0)
+#define DRM_PAGEMAP_ZDD_FLAG_MASK DRM_PAGEMAP_ZDD_FLAG_MIGRATED
+
int drm_pagemap_migrate_to_devmem(struct drm_pagemap_devmem *devmem_allocation,
struct mm_struct *mm,
unsigned long start, unsigned long end,
@@ -373,7 +377,9 @@ static inline struct drm_pagemap_zdd *drm_pagemap_page_zone_device_data(struct p
{
struct folio *folio = page_folio(page);
- return folio_zone_device_data(folio);
+ return (struct drm_pagemap_zdd *)
+ ((unsigned long)folio_zone_device_data(folio) &
+ ~DRM_PAGEMAP_ZDD_FLAG_MASK);
}
#else
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 125/733] drm/pagemap: Reset migration page count on eviction retry
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (123 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 124/733] drm/pagemap: Prevent double migration of device pages Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 126/733] net: ethernet: oa_tc6: Handle the OA TC6 SPI protected mode Greg Kroah-Hartman
` (619 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Matthew Brost, Thomas Hellström,
Himal Prasad Ghimiray, Maarten Lankhorst, Maxime Ripard,
Thomas Zimmermann, David Airlie, Simona Vetter, Arvind Yadav,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arvind Yadav <arvind.yadav@intel.com>
[ Upstream commit 8eae39cd0adf28ba81a46090b10484cf402c0ac8 ]
drm_pagemap_evict_to_ram() may retry eviction, but mpages retains
the count from the previous attempt. A retry can therefore continue
to the copy path even when no RAM pages were populated.
Reset mpages at the retry label so it reflects only the current
attempt.
Fixes: 99624bdff867 ("drm/gpusvm: Add support for GPU Shared Virtual Memory")
Cc: Matthew Brost <matthew.brost@intel.com>
Cc: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Cc: Himal Prasad Ghimiray <himal.prasad.ghimiray@intel.com>
Cc: Maarten Lankhorst <maarten.lankhorst@linux.intel.com>
Cc: Maxime Ripard <mripard@kernel.org>
Cc: Thomas Zimmermann <tzimmermann@suse.de>
Cc: David Airlie <airlied@gmail.com>
Cc: Simona Vetter <simona@ffwll.ch>
Signed-off-by: Arvind Yadav <arvind.yadav@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Signed-off-by: Matthew Brost <matthew.brost@intel.com>
Link: https://patch.msgid.link/20260728090304.1264759-1-arvind.yadav@intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/drm_pagemap.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/gpu/drm/drm_pagemap.c b/drivers/gpu/drm/drm_pagemap.c
index 72ca5a48d4a66..89e1ddff84dd2 100644
--- a/drivers/gpu/drm/drm_pagemap.c
+++ b/drivers/gpu/drm/drm_pagemap.c
@@ -1313,7 +1313,7 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
{
const struct drm_pagemap_devmem_ops *ops = devmem_allocation->ops;
struct drm_pagemap_iova_state state = {};
- unsigned long npages, mpages = 0;
+ unsigned long npages, mpages;
struct page **pages;
unsigned long *src, *dst;
struct drm_pagemap_addr *pagemap_addr;
@@ -1324,6 +1324,7 @@ int drm_pagemap_evict_to_ram(struct drm_pagemap_devmem *devmem_allocation)
npages = devmem_allocation->size >> PAGE_SHIFT;
retry:
+ mpages = 0;
if (!mmget_not_zero(devmem_allocation->mm))
return -EFAULT;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 126/733] net: ethernet: oa_tc6: Handle the OA TC6 SPI protected mode
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (124 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 125/733] drm/pagemap: Reset migration page count on eviction retry Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 127/733] net: ethernet: oa_tc6: Export standard defined registers Greg Kroah-Hartman
` (618 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Ciprian Regus, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ciprian Regus <ciprian.regus@analog.com>
[ Upstream commit 7d0e4c4b8c85d8ea2c77a90e1f7a7f74ce531e52 ]
Implement the OA TC6 standard defined protected mode for control (register
access) transactions. In addition to the current register access formats
the oa_tc6 driver handles, 1's complement values of the data field
are included (by both the host and the MACPHY) in the SPI transfer frames.
This feature acts as an integrity check.
Control write transactions look like this:
|<- 32 bits ->|<--- data_size --->|<- 32 bits ->|
MOSI: | ctrl header | reg write data | ignored |
MISO: | (discard) | echoed ctrl hdr | echoed data |
data_size (LEN = number of registers to read in a sequence):
Unprotected: 32 x (LEN + 1) bits
Protected: 2 x 32 x (LEN + 1) bits
Control read transaction:
|<- 32 bits ->|<--- 32 bits --> |<- data_size ->|
MOSI: | ctrl header | ignored ... |
MISO: | (discard) | echoed ctrl hdr | reg read data |
data_size (LEN = number of registers to read in a sequence):
Unprotected: 32 x (LEN + 1) bits
Protected: 2 x 32 x (LEN + 1) bits
Register data format ("reg write data" and "reg read data"):
Unprotected:
| W1 (normal) | W2 (normal) | ... | Wx (normal) |
Protected:
| W1 (normal) | W1 (complement) | ... | Wx (normal) | Wx (complement)|
The protected mode state can be read from the bit 5 of CONFIG0 (0x4)
register, and this setting is usually only configured during the
MACPHY's reset (depending on the device it can be done by setting the
state of a pin). We can read the protected mode configuration before any
other register access and since the SPI transfer is initially sized for an
unprotected read, the MACPHY's complement words are never clocked out
and no checking is required. The data transactions (Ethernet frames)
remain unchanged.
Signed-off-by: Ciprian Regus <ciprian.regus@analog.com>
Link: https://patch.msgid.link/20260708-adin1140-driver-v5-2-4aca7b51a58b@analog.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: 5443d9c4f55d ("net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 93 ++++++++++++++++++++++++++++-------
1 file changed, 76 insertions(+), 17 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 0727d53345a33..8b96558834960 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -25,6 +25,7 @@
#define OA_TC6_REG_CONFIG0 0x0004
#define CONFIG0_SYNC BIT(15)
#define CONFIG0_ZARFE_ENABLE BIT(12)
+#define CONFIG0_PROTE BIT(5)
/* Status Register #0 */
#define OA_TC6_REG_STATUS0 0x0008
@@ -90,14 +91,17 @@
#define OA_TC6_PHY_C45_AUTO_NEG_MMS5 5 /* MMD 7 */
#define OA_TC6_PHY_C45_POWER_UNIT_MMS6 6 /* MMD 13 */
+#define OA_TC6_CTRL_PROT_REPLY_SIZE 4
#define OA_TC6_CTRL_HEADER_SIZE 4
#define OA_TC6_CTRL_REG_VALUE_SIZE 4
#define OA_TC6_CTRL_IGNORED_SIZE 4
#define OA_TC6_CTRL_MAX_REGISTERS 128
-#define OA_TC6_CTRL_SPI_BUF_SIZE (OA_TC6_CTRL_HEADER_SIZE +\
- (OA_TC6_CTRL_MAX_REGISTERS *\
- OA_TC6_CTRL_REG_VALUE_SIZE) +\
- OA_TC6_CTRL_IGNORED_SIZE)
+#define OA_TC6_CTRL_SPI_BUF_SIZE (OA_TC6_CTRL_HEADER_SIZE +\
+ (OA_TC6_CTRL_MAX_REGISTERS *\
+ (OA_TC6_CTRL_REG_VALUE_SIZE +\
+ OA_TC6_CTRL_PROT_REPLY_SIZE)) +\
+ OA_TC6_CTRL_IGNORED_SIZE)
+
#define OA_TC6_CHUNK_PAYLOAD_SIZE 64
#define OA_TC6_DATA_HEADER_SIZE 4
#define OA_TC6_CHUNK_SIZE (OA_TC6_DATA_HEADER_SIZE +\
@@ -130,6 +134,7 @@ struct oa_tc6 {
bool rx_buf_overflow;
bool int_flag;
bool disable_traffic;
+ bool prot_ctrl;
};
enum oa_tc6_header_type {
@@ -213,25 +218,36 @@ static void oa_tc6_update_ctrl_write_data(struct oa_tc6 *tc6, u32 value[],
{
__be32 *tx_buf = tc6->spi_ctrl_tx_buf + OA_TC6_CTRL_HEADER_SIZE;
- for (int i = 0; i < length; i++)
+ for (int i = 0; i < length; i++) {
*tx_buf++ = cpu_to_be32(value[i]);
+ if (tc6->prot_ctrl)
+ *tx_buf++ = cpu_to_be32(~value[i]);
+ }
}
-static u16 oa_tc6_calculate_ctrl_buf_size(u8 length)
+static u16 oa_tc6_calculate_ctrl_buf_size(u8 length, bool ctrl_prot)
{
+ u32 reply_size = OA_TC6_CTRL_REG_VALUE_SIZE;
+
+ if (ctrl_prot)
+ reply_size += OA_TC6_CTRL_PROT_REPLY_SIZE;
+
/* Control command consists 4 bytes header + 4 bytes register value for
- * each register + 4 bytes ignored value.
+ * each register (+ 4 bytes for the register value complement in case
+ * protected mode is used) + 4 bytes ignored value.
*/
- return OA_TC6_CTRL_HEADER_SIZE + OA_TC6_CTRL_REG_VALUE_SIZE * length +
+ return OA_TC6_CTRL_HEADER_SIZE + reply_size * length +
OA_TC6_CTRL_IGNORED_SIZE;
}
static void oa_tc6_prepare_ctrl_spi_buf(struct oa_tc6 *tc6, u32 address,
u32 value[], u8 length,
- enum oa_tc6_register_op reg_op)
+ enum oa_tc6_register_op reg_op,
+ u16 buf_size)
{
__be32 *tx_buf = tc6->spi_ctrl_tx_buf;
+ memset(tx_buf, 0, buf_size);
*tx_buf = oa_tc6_prepare_ctrl_header(address, length, reg_op);
if (reg_op == OA_TC6_CTRL_REG_WRITE)
@@ -254,10 +270,12 @@ static int oa_tc6_check_ctrl_write_reply(struct oa_tc6 *tc6, u8 size)
return 0;
}
-static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size)
+static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 length)
{
- u32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE;
- u32 *tx_buf = tc6->spi_ctrl_tx_buf;
+ __be32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE;
+ __be32 *tx_buf = tc6->spi_ctrl_tx_buf;
+ u32 complement;
+ u32 reply;
/* The echoed control read header must match with the one that was
* transmitted.
@@ -265,6 +283,20 @@ static int oa_tc6_check_ctrl_read_reply(struct oa_tc6 *tc6, u8 size)
if (*tx_buf != *rx_buf)
return -EPROTO;
+ if (tc6->prot_ctrl) {
+ /* Skip past the echoed header to the value/complement pairs */
+ rx_buf += 1;
+ for (int i = 0; i < length; i++) {
+ reply = be32_to_cpu(rx_buf[0]);
+ complement = be32_to_cpu(rx_buf[1]);
+
+ if (complement != ~reply)
+ return -EPROTO;
+
+ rx_buf += 2;
+ }
+ }
+
return 0;
}
@@ -274,8 +306,13 @@ static void oa_tc6_copy_ctrl_read_data(struct oa_tc6 *tc6, u32 value[],
__be32 *rx_buf = tc6->spi_ctrl_rx_buf + OA_TC6_CTRL_IGNORED_SIZE +
OA_TC6_CTRL_HEADER_SIZE;
- for (int i = 0; i < length; i++)
+ for (int i = 0; i < length; i++) {
value[i] = be32_to_cpu(*rx_buf++);
+
+ /* skip complement word */
+ if (tc6->prot_ctrl)
+ rx_buf++;
+ }
}
static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[],
@@ -284,10 +321,10 @@ static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[],
u16 size;
int ret;
- /* Prepare control command and copy to SPI control buffer */
- oa_tc6_prepare_ctrl_spi_buf(tc6, address, value, length, reg_op);
+ size = oa_tc6_calculate_ctrl_buf_size(length, tc6->prot_ctrl);
- size = oa_tc6_calculate_ctrl_buf_size(length);
+ /* Prepare control command and copy to SPI control buffer */
+ oa_tc6_prepare_ctrl_spi_buf(tc6, address, value, length, reg_op, size);
/* Perform SPI transfer */
ret = oa_tc6_spi_transfer(tc6, OA_TC6_CTRL_HEADER, size);
@@ -302,7 +339,7 @@ static int oa_tc6_perform_ctrl(struct oa_tc6 *tc6, u32 address, u32 value[],
return oa_tc6_check_ctrl_write_reply(tc6, size);
/* Check echoed/received control read command reply for errors */
- ret = oa_tc6_check_ctrl_read_reply(tc6, size);
+ ret = oa_tc6_check_ctrl_read_reply(tc6, length);
if (ret)
return ret;
@@ -1272,6 +1309,20 @@ netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(oa_tc6_start_xmit);
+static int oa_tc6_check_ctrl_protection(struct oa_tc6 *tc6)
+{
+ u32 regval;
+ int ret;
+
+ ret = oa_tc6_read_register(tc6, OA_TC6_REG_CONFIG0, ®val);
+ if (ret)
+ return ret;
+
+ tc6->prot_ctrl = FIELD_GET(CONFIG0_PROTE, regval);
+
+ return 0;
+}
+
/**
* oa_tc6_init - allocates and initializes oa_tc6 structure.
* @spi: device with which data will be exchanged.
@@ -1324,6 +1375,14 @@ struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev)
if (!tc6->spi_data_rx_buf)
return NULL;
+ /* Check the PROTE bit status so that we can reset the device */
+ ret = oa_tc6_check_ctrl_protection(tc6);
+ if (ret) {
+ dev_err(&tc6->spi->dev,
+ "Failed to check the protection mode: %d\n", ret);
+ return NULL;
+ }
+
ret = oa_tc6_sw_reset_macphy(tc6);
if (ret) {
dev_err(&tc6->spi->dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 127/733] net: ethernet: oa_tc6: Export standard defined registers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (125 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 126/733] net: ethernet: oa_tc6: Handle the OA TC6 SPI protected mode Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 128/733] net: ethernet: oa_tc6: Add the OA_TC6_ prefix to standard registers Greg Kroah-Hartman
` (617 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Lunn, Ciprian Regus,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ciprian Regus <ciprian.regus@analog.com>
[ Upstream commit 9210d402bdf54240b8aec9815b2f9aad360fcb42 ]
Move defines for standard Open Alliance TC6 register addresses and
subfields in the oa_tc6's header. As such, other ethernet drivers
that rely on oa_tc6 can use them directly.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Ciprian Regus <ciprian.regus@analog.com>
Link: https://patch.msgid.link/20260708-adin1140-driver-v5-5-4aca7b51a58b@analog.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: 5443d9c4f55d ("net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 50 -----------------------------------
include/linux/oa_tc6.h | 50 +++++++++++++++++++++++++++++++++++
2 files changed, 50 insertions(+), 50 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 8b96558834960..88fc8456bd64e 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -12,47 +12,6 @@
#include <linux/phy.h>
#include <linux/oa_tc6.h>
-/* OPEN Alliance TC6 registers */
-/* Standard Capabilities Register */
-#define OA_TC6_REG_STDCAP 0x0002
-#define STDCAP_DIRECT_PHY_REG_ACCESS BIT(8)
-
-/* Reset Control and Status Register */
-#define OA_TC6_REG_RESET 0x0003
-#define RESET_SWRESET BIT(0) /* Software Reset */
-
-/* Configuration Register #0 */
-#define OA_TC6_REG_CONFIG0 0x0004
-#define CONFIG0_SYNC BIT(15)
-#define CONFIG0_ZARFE_ENABLE BIT(12)
-#define CONFIG0_PROTE BIT(5)
-
-/* Status Register #0 */
-#define OA_TC6_REG_STATUS0 0x0008
-#define STATUS0_RESETC BIT(6) /* Reset Complete */
-#define STATUS0_HEADER_ERROR BIT(5)
-#define STATUS0_LOSS_OF_FRAME_ERROR BIT(4)
-#define STATUS0_RX_BUFFER_OVERFLOW_ERROR BIT(3)
-#define STATUS0_TX_PROTOCOL_ERROR BIT(0)
-
-/* Buffer Status Register */
-#define OA_TC6_REG_BUFFER_STATUS 0x000B
-#define BUFFER_STATUS_TX_CREDITS_AVAILABLE GENMASK(15, 8)
-#define BUFFER_STATUS_RX_CHUNKS_AVAILABLE GENMASK(7, 0)
-
-/* Interrupt Mask Register #0 */
-#define OA_TC6_REG_INT_MASK0 0x000C
-#define INT_MASK0_HEADER_ERR_MASK BIT(5)
-#define INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4)
-#define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3)
-#define INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0)
-#define INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \
- GENMASK(12, 7))
-
-/* PHY Clause 22 registers base address and mask */
-#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00
-#define OA_TC6_PHY_STD_REG_ADDR_MASK 0x1F
-
/* Control command header */
#define OA_TC6_CTRL_HEADER_DATA_NOT_CTRL BIT(31)
#define OA_TC6_CTRL_HEADER_WRITE_NOT_READ BIT(29)
@@ -82,15 +41,6 @@
#define OA_TC6_DATA_FOOTER_END_BYTE_OFFSET GENMASK(13, 8)
#define OA_TC6_DATA_FOOTER_TX_CREDITS GENMASK(5, 1)
-/* PHY – Clause 45 registers memory map selector (MMS) as per table 6 in the
- * OPEN Alliance specification.
- */
-#define OA_TC6_PHY_C45_PCS_MMS2 2 /* MMD 3 */
-#define OA_TC6_PHY_C45_PMA_PMD_MMS3 3 /* MMD 1 */
-#define OA_TC6_PHY_C45_VS_PLCA_MMS4 4 /* MMD 31 */
-#define OA_TC6_PHY_C45_AUTO_NEG_MMS5 5 /* MMD 7 */
-#define OA_TC6_PHY_C45_POWER_UNIT_MMS6 6 /* MMD 13 */
-
#define OA_TC6_CTRL_PROT_REPLY_SIZE 4
#define OA_TC6_CTRL_HEADER_SIZE 4
#define OA_TC6_CTRL_REG_VALUE_SIZE 4
diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
index 15f58e3c56c74..97c6ed0bf34df 100644
--- a/include/linux/oa_tc6.h
+++ b/include/linux/oa_tc6.h
@@ -10,6 +10,56 @@
#include <linux/etherdevice.h>
#include <linux/spi/spi.h>
+/* OPEN Alliance TC6 registers */
+/* Standard Capabilities Register */
+#define OA_TC6_REG_STDCAP 0x0002
+#define STDCAP_DIRECT_PHY_REG_ACCESS BIT(8)
+
+/* Reset Control and Status Register */
+#define OA_TC6_REG_RESET 0x0003
+#define RESET_SWRESET BIT(0) /* Software Reset */
+
+/* Configuration Register #0 */
+#define OA_TC6_REG_CONFIG0 0x0004
+#define CONFIG0_SYNC BIT(15)
+#define CONFIG0_ZARFE_ENABLE BIT(12)
+#define CONFIG0_PROTE BIT(5)
+
+/* Status Register #0 */
+#define OA_TC6_REG_STATUS0 0x0008
+#define STATUS0_RESETC BIT(6) /* Reset Complete */
+#define STATUS0_HEADER_ERROR BIT(5)
+#define STATUS0_LOSS_OF_FRAME_ERROR BIT(4)
+#define STATUS0_RX_BUFFER_OVERFLOW_ERROR BIT(3)
+#define STATUS0_TX_PROTOCOL_ERROR BIT(0)
+
+/* Buffer Status Register */
+#define OA_TC6_REG_BUFFER_STATUS 0x000B
+#define BUFFER_STATUS_TX_CREDITS_AVAILABLE GENMASK(15, 8)
+#define BUFFER_STATUS_RX_CHUNKS_AVAILABLE GENMASK(7, 0)
+
+/* Interrupt Mask Register #0 */
+#define OA_TC6_REG_INT_MASK0 0x000C
+#define INT_MASK0_HEADER_ERR_MASK BIT(5)
+#define INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4)
+#define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3)
+#define INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0)
+#define INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \
+ GENMASK(12, 7))
+
+/* PHY Clause 22 registers base address and mask */
+#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00
+#define OA_TC6_PHY_STD_REG_ADDR_MASK 0x1F
+
+/* PHY – Clause 45 registers memory map selector (MMS) as per table 6 in the
+ * OPEN Alliance specification.
+ */
+#define OA_TC6_PHY_C45_PCS_MMS2 2 /* MMD 3 */
+#define OA_TC6_PHY_C45_PMA_PMD_MMS3 3 /* MMD 1 */
+#define OA_TC6_PHY_C45_VS_PLCA_MMS4 4 /* MMD 31 */
+#define OA_TC6_PHY_C45_AUTO_NEG_MMS5 5 /* MMD 7 */
+#define OA_TC6_PHY_C45_POWER_UNIT_MMS6 6 /* MMD 13 */
+
struct oa_tc6;
struct oa_tc6 *oa_tc6_init(struct spi_device *spi, struct net_device *netdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 128/733] net: ethernet: oa_tc6: Add the OA_TC6_ prefix to standard registers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (126 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 127/733] net: ethernet: oa_tc6: Export standard defined registers Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 129/733] net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances Greg Kroah-Hartman
` (616 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Lunn, Ciprian Regus,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ciprian Regus <ciprian.regus@analog.com>
[ Upstream commit 31bc75f17c1f5ff989fa896aae3e4e411d9b0b7a ]
The OA TC6 standard registers are currently exported in a header file.
Add the OA_TC6_ prefix to the register address and subfield mask macros
to avoid future naming conflicts.
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Ciprian Regus <ciprian.regus@analog.com>
Link: https://patch.msgid.link/20260708-adin1140-driver-v5-6-4aca7b51a58b@analog.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Stable-dep-of: 5443d9c4f55d ("net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 37 ++++++++++++++++----------------
include/linux/oa_tc6.h | 40 +++++++++++++++++------------------
2 files changed, 39 insertions(+), 38 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index 88fc8456bd64e..fb219542e90d3 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -395,7 +395,7 @@ static int oa_tc6_check_phy_reg_direct_access_capability(struct oa_tc6 *tc6)
if (ret)
return ret;
- if (!(regval & STDCAP_DIRECT_PHY_REG_ACCESS))
+ if (!(regval & OA_TC6_STDCAP_DIRECT_PHY_REG_ACCESS))
return -ENODEV;
return 0;
@@ -588,7 +588,7 @@ static int oa_tc6_read_status0(struct oa_tc6 *tc6)
static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
{
- u32 regval = RESET_SWRESET;
+ u32 regval = OA_TC6_RESET_SWRESET;
int ret;
ret = oa_tc6_write_register(tc6, OA_TC6_REG_RESET, regval);
@@ -597,7 +597,7 @@ static int oa_tc6_sw_reset_macphy(struct oa_tc6 *tc6)
/* Poll for soft reset complete for every 1ms until 1s timeout */
ret = readx_poll_timeout(oa_tc6_read_status0, tc6, regval,
- regval & STATUS0_RESETC,
+ regval & OA_TC6_STATUS0_RESETC,
STATUS0_RESETC_POLL_DELAY,
STATUS0_RESETC_POLL_TIMEOUT);
if (ret)
@@ -616,10 +616,10 @@ static int oa_tc6_unmask_macphy_error_interrupts(struct oa_tc6 *tc6)
if (ret)
return ret;
- regval &= ~(INT_MASK0_TX_PROTOCOL_ERR_MASK |
- INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
- INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
- INT_MASK0_HEADER_ERR_MASK);
+ regval &= ~(OA_TC6_INT_MASK0_TX_PROTOCOL_ERR_MASK |
+ OA_TC6_INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK |
+ OA_TC6_INT_MASK0_LOSS_OF_FRAME_ERR_MASK |
+ OA_TC6_INT_MASK0_HEADER_ERR_MASK);
return oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
}
@@ -634,7 +634,7 @@ static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)
return ret;
/* Enable configuration synchronization for data transfer */
- value |= CONFIG0_SYNC;
+ value |= OA_TC6_CONFIG0_SYNC;
return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value);
}
@@ -679,7 +679,7 @@ static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
*/
static void oa_tc6_disable_traffic(struct oa_tc6 *tc6)
{
- u32 regval = INT_MASK0_ALL_INTERRUPTS;
+ u32 regval = OA_TC6_INT_MASK0_ALL_INTERRUPTS;
tc6->disable_traffic = true;
oa_tc6_free_pending_skbs(tc6);
@@ -709,25 +709,25 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
return ret;
}
- if (FIELD_GET(STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
+ if (FIELD_GET(OA_TC6_STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
tc6->rx_buf_overflow = true;
oa_tc6_cleanup_ongoing_rx_skb(tc6);
net_err_ratelimited("%s: Receive buffer overflow error\n",
tc6->netdev->name);
return -EAGAIN;
}
- if (FIELD_GET(STATUS0_TX_PROTOCOL_ERROR, value)) {
+ if (FIELD_GET(OA_TC6_STATUS0_TX_PROTOCOL_ERROR, value)) {
netdev_err(tc6->netdev, "Transmit protocol error\n");
return -ENODEV;
}
/* TODO: Currently loss of frame and header errors are treated as
* non-recoverable errors. They will be handled in the next version.
*/
- if (FIELD_GET(STATUS0_LOSS_OF_FRAME_ERROR, value)) {
+ if (FIELD_GET(OA_TC6_STATUS0_LOSS_OF_FRAME_ERROR, value)) {
netdev_err(tc6->netdev, "Loss of frame error\n");
return -ENODEV;
}
- if (FIELD_GET(STATUS0_HEADER_ERROR, value)) {
+ if (FIELD_GET(OA_TC6_STATUS0_HEADER_ERROR, value)) {
netdev_err(tc6->netdev, "Header error\n");
return -ENODEV;
}
@@ -1174,9 +1174,10 @@ static int oa_tc6_update_buffer_status_from_register(struct oa_tc6 *tc6)
if (ret)
return ret;
- tc6->tx_credits = FIELD_GET(BUFFER_STATUS_TX_CREDITS_AVAILABLE, value);
- tc6->rx_chunks_available = FIELD_GET(BUFFER_STATUS_RX_CHUNKS_AVAILABLE,
- value);
+ tc6->tx_credits = FIELD_GET(OA_TC6_BUFFER_STATUS_TX_CREDITS_AVAILABLE,
+ value);
+ tc6->rx_chunks_available =
+ FIELD_GET(OA_TC6_BUFFER_STATUS_RX_CHUNKS_AVAILABLE, value);
return 0;
}
@@ -1220,7 +1221,7 @@ int oa_tc6_zero_align_receive_frame_enable(struct oa_tc6 *tc6)
return ret;
/* Set Zero-Align Receive Frame Enable */
- regval |= CONFIG0_ZARFE_ENABLE;
+ regval |= OA_TC6_CONFIG0_ZARFE_ENABLE;
return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, regval);
}
@@ -1268,7 +1269,7 @@ static int oa_tc6_check_ctrl_protection(struct oa_tc6 *tc6)
if (ret)
return ret;
- tc6->prot_ctrl = FIELD_GET(CONFIG0_PROTE, regval);
+ tc6->prot_ctrl = FIELD_GET(OA_TC6_CONFIG0_PROTE, regval);
return 0;
}
diff --git a/include/linux/oa_tc6.h b/include/linux/oa_tc6.h
index 97c6ed0bf34df..71cffcb041b1c 100644
--- a/include/linux/oa_tc6.h
+++ b/include/linux/oa_tc6.h
@@ -13,39 +13,39 @@
/* OPEN Alliance TC6 registers */
/* Standard Capabilities Register */
#define OA_TC6_REG_STDCAP 0x0002
-#define STDCAP_DIRECT_PHY_REG_ACCESS BIT(8)
+#define OA_TC6_STDCAP_DIRECT_PHY_REG_ACCESS BIT(8)
/* Reset Control and Status Register */
#define OA_TC6_REG_RESET 0x0003
-#define RESET_SWRESET BIT(0) /* Software Reset */
+#define OA_TC6_RESET_SWRESET BIT(0) /* Software Reset */
/* Configuration Register #0 */
#define OA_TC6_REG_CONFIG0 0x0004
-#define CONFIG0_SYNC BIT(15)
-#define CONFIG0_ZARFE_ENABLE BIT(12)
-#define CONFIG0_PROTE BIT(5)
+#define OA_TC6_CONFIG0_SYNC BIT(15)
+#define OA_TC6_CONFIG0_ZARFE_ENABLE BIT(12)
+#define OA_TC6_CONFIG0_PROTE BIT(5)
/* Status Register #0 */
#define OA_TC6_REG_STATUS0 0x0008
-#define STATUS0_RESETC BIT(6) /* Reset Complete */
-#define STATUS0_HEADER_ERROR BIT(5)
-#define STATUS0_LOSS_OF_FRAME_ERROR BIT(4)
-#define STATUS0_RX_BUFFER_OVERFLOW_ERROR BIT(3)
-#define STATUS0_TX_PROTOCOL_ERROR BIT(0)
+#define OA_TC6_STATUS0_RESETC BIT(6) /* Reset Complete */
+#define OA_TC6_STATUS0_HEADER_ERROR BIT(5)
+#define OA_TC6_STATUS0_LOSS_OF_FRAME_ERROR BIT(4)
+#define OA_TC6_STATUS0_RX_BUFFER_OVERFLOW_ERROR BIT(3)
+#define OA_TC6_STATUS0_TX_PROTOCOL_ERROR BIT(0)
/* Buffer Status Register */
-#define OA_TC6_REG_BUFFER_STATUS 0x000B
-#define BUFFER_STATUS_TX_CREDITS_AVAILABLE GENMASK(15, 8)
-#define BUFFER_STATUS_RX_CHUNKS_AVAILABLE GENMASK(7, 0)
+#define OA_TC6_REG_BUFFER_STATUS 0x000B
+#define OA_TC6_BUFFER_STATUS_TX_CREDITS_AVAILABLE GENMASK(15, 8)
+#define OA_TC6_BUFFER_STATUS_RX_CHUNKS_AVAILABLE GENMASK(7, 0)
/* Interrupt Mask Register #0 */
-#define OA_TC6_REG_INT_MASK0 0x000C
-#define INT_MASK0_HEADER_ERR_MASK BIT(5)
-#define INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4)
-#define INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3)
-#define INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0)
-#define INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \
- GENMASK(12, 7))
+#define OA_TC6_REG_INT_MASK0 0x000C
+#define OA_TC6_INT_MASK0_HEADER_ERR_MASK BIT(5)
+#define OA_TC6_INT_MASK0_LOSS_OF_FRAME_ERR_MASK BIT(4)
+#define OA_TC6_INT_MASK0_RX_BUFFER_OVERFLOW_ERR_MASK BIT(3)
+#define OA_TC6_INT_MASK0_TX_PROTOCOL_ERR_MASK BIT(0)
+#define OA_TC6_INT_MASK0_ALL_INTERRUPTS (GENMASK(5, 0) | \
+ GENMASK(12, 7))
/* PHY Clause 22 registers base address and mask */
#define OA_TC6_PHY_STD_REG_ADDR_BASE 0xFF00
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 129/733] net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (127 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 128/733] net: ethernet: oa_tc6: Add the OA_TC6_ prefix to standard registers Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 130/733] net: ethernet: oa_tc6: Improve the error recovery Greg Kroah-Hartman
` (615 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Selvamani Rajagopal, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
[ Upstream commit 5443d9c4f55d46634b95432e1e8a40b824019bbb ]
Threaded IRQ uses waiting_tx_skb. Transmit path also uses this pointer
without any mutual exclusion protection. As a result, it might leak skb
buffer, particularly if threaded IRQ sets disable_traffic true after
start_xmit already checked and found that disable_traffic being false,
if they happen to run on different cores.
On fatal error, where disable_traffic is set, transmit function drops the
packet and return NETDEV_TX_OK. Due to this change, skb_linearize call
is moved up to the beginning of the transmit function.
Since skb buffer may be freed from different contexts, dev_kfree_skb_any
is used to free skb buffer now, replacing one of the kfree_skb call.
oa_tc6_exit disables the irq before setting disable_traffic true.
Fixes: b542d13fab0f ("net: ethernet: oa_tc6: Interrupt is active low, level triggered.")
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Link: https://patch.msgid.link/20260824-fix-race-condition-and-crash-v7-1-4323279b18f2@onsemi.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 109 ++++++++++++++++++++++++----------
1 file changed, 76 insertions(+), 33 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index fb219542e90d3..d283e81358e65 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -639,6 +639,26 @@ static int oa_tc6_enable_data_transfer(struct oa_tc6 *tc6)
return oa_tc6_write_register(tc6, OA_TC6_REG_CONFIG0, value);
}
+/* Called when a frame that is meant to be transmitted, is dropped. */
+static void oa_tc6_drop_tx_skb(struct oa_tc6 *tc6, struct sk_buff *skb)
+{
+ if (skb) {
+ tc6->netdev->stats.tx_dropped++;
+ dev_kfree_skb_any(skb);
+ }
+}
+
+static struct sk_buff *oa_tc6_detach_waiting_tx_skb(struct oa_tc6 *tc6)
+{
+ struct sk_buff *skb;
+
+ lockdep_assert_held(&tc6->tx_skb_lock);
+ skb = tc6->waiting_tx_skb;
+ tc6->waiting_tx_skb = NULL;
+
+ return skb;
+}
+
static void oa_tc6_cleanup_ongoing_rx_skb(struct oa_tc6 *tc6)
{
if (tc6->rx_skb) {
@@ -650,26 +670,30 @@ static void oa_tc6_cleanup_ongoing_rx_skb(struct oa_tc6 *tc6)
static void oa_tc6_cleanup_ongoing_tx_skb(struct oa_tc6 *tc6)
{
- if (tc6->ongoing_tx_skb) {
- tc6->netdev->stats.tx_dropped++;
- kfree_skb(tc6->ongoing_tx_skb);
- tc6->ongoing_tx_skb = NULL;
- }
+ oa_tc6_drop_tx_skb(tc6, tc6->ongoing_tx_skb);
+ tc6->ongoing_tx_skb = NULL;
}
static void oa_tc6_cleanup_waiting_tx_skb(struct oa_tc6 *tc6)
{
- if (tc6->waiting_tx_skb) {
- tc6->netdev->stats.tx_dropped++;
- kfree_skb(tc6->waiting_tx_skb);
- tc6->waiting_tx_skb = NULL;
- }
+ struct sk_buff *skb;
+
+ spin_lock_bh(&tc6->tx_skb_lock);
+ skb = oa_tc6_detach_waiting_tx_skb(tc6);
+ spin_unlock_bh(&tc6->tx_skb_lock);
+
+ oa_tc6_drop_tx_skb(tc6, skb);
}
-static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
+static void oa_tc6_free_ongoing_skbs(struct oa_tc6 *tc6)
{
oa_tc6_cleanup_ongoing_tx_skb(tc6);
oa_tc6_cleanup_ongoing_rx_skb(tc6);
+}
+
+static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
+{
+ oa_tc6_free_ongoing_skbs(tc6);
oa_tc6_cleanup_waiting_tx_skb(tc6);
}
@@ -680,9 +704,15 @@ static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
static void oa_tc6_disable_traffic(struct oa_tc6 *tc6)
{
u32 regval = OA_TC6_INT_MASK0_ALL_INTERRUPTS;
+ struct sk_buff *skb;
+ spin_lock_bh(&tc6->tx_skb_lock);
tc6->disable_traffic = true;
- oa_tc6_free_pending_skbs(tc6);
+ skb = oa_tc6_detach_waiting_tx_skb(tc6);
+ spin_unlock_bh(&tc6->tx_skb_lock);
+
+ oa_tc6_drop_tx_skb(tc6, skb);
+ oa_tc6_free_ongoing_skbs(tc6);
oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
oa_tc6_read_register(tc6, OA_TC6_REG_STATUS0, ®val);
oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, regval);
@@ -1123,8 +1153,7 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
if (ret == -EAGAIN)
continue;
- oa_tc6_cleanup_ongoing_tx_skb(tc6);
- oa_tc6_cleanup_ongoing_rx_skb(tc6);
+ oa_tc6_free_ongoing_skbs(tc6);
netdev_err(tc6->netdev, "Device error: %d\n", ret);
return ret;
}
@@ -1146,15 +1175,20 @@ static irqreturn_t oa_tc6_macphy_threaded_irq(int irq, void *data)
* no need to attempt spi transfer, once it fails. Pending skbs
* are already freed.
*/
- if (!tc6->disable_traffic) {
- while (tc6->int_flag ||
- (tc6->waiting_tx_skb && tc6->tx_credits)) {
- ret = oa_tc6_try_spi_transfer(tc6);
- if (ret) {
- disable_irq_nosync(tc6->spi->irq);
- oa_tc6_disable_traffic(tc6);
- break;
- }
+ spin_lock_bh(&tc6->tx_skb_lock);
+ if (tc6->disable_traffic) {
+ spin_unlock_bh(&tc6->tx_skb_lock);
+ return IRQ_HANDLED;
+ }
+ spin_unlock_bh(&tc6->tx_skb_lock);
+
+ while (tc6->int_flag ||
+ (tc6->waiting_tx_skb && tc6->tx_credits)) {
+ ret = oa_tc6_try_spi_transfer(tc6);
+ if (ret) {
+ disable_irq_nosync(tc6->spi->irq);
+ oa_tc6_disable_traffic(tc6);
+ break;
}
}
@@ -1233,23 +1267,30 @@ EXPORT_SYMBOL_GPL(oa_tc6_zero_align_receive_frame_enable);
* @tc6: oa_tc6 struct.
* @skb: socket buffer in which the ethernet frame is stored.
*
- * Return: NETDEV_TX_OK if the transmit ethernet frame skb added in the tx_skb_q
- * otherwise returns NETDEV_TX_BUSY.
+ * Return: NETDEV_TX_OK either on successful queueing of the packet for
+ * transmission, or on packet getting dropped. Packet can be dropped due to
+ * failure in linearizing the buffer or disable_traffic is set due to
+ * earlier fatal error. Returns NETDEV_TX_BUSY when there is no room
+ * to queue the packet.
*/
netdev_tx_t oa_tc6_start_xmit(struct oa_tc6 *tc6, struct sk_buff *skb)
{
- if (tc6->disable_traffic || tc6->waiting_tx_skb) {
- netif_stop_queue(tc6->netdev);
- return NETDEV_TX_BUSY;
- }
-
if (skb_linearize(skb)) {
- dev_kfree_skb_any(skb);
- tc6->netdev->stats.tx_dropped++;
+ oa_tc6_drop_tx_skb(tc6, skb);
return NETDEV_TX_OK;
}
spin_lock_bh(&tc6->tx_skb_lock);
+ if (tc6->waiting_tx_skb) {
+ netif_stop_queue(tc6->netdev);
+ spin_unlock_bh(&tc6->tx_skb_lock);
+ return NETDEV_TX_BUSY;
+ }
+ if (tc6->disable_traffic) {
+ spin_unlock_bh(&tc6->tx_skb_lock);
+ oa_tc6_drop_tx_skb(tc6, skb);
+ return NETDEV_TX_OK;
+ }
tc6->waiting_tx_skb = skb;
spin_unlock_bh(&tc6->tx_skb_lock);
@@ -1403,8 +1444,10 @@ EXPORT_SYMBOL_GPL(oa_tc6_init);
*/
void oa_tc6_exit(struct oa_tc6 *tc6)
{
- tc6->disable_traffic = true;
disable_irq(tc6->spi->irq);
+ spin_lock_bh(&tc6->tx_skb_lock);
+ tc6->disable_traffic = true;
+ spin_unlock_bh(&tc6->tx_skb_lock);
oa_tc6_phy_exit(tc6);
oa_tc6_free_pending_skbs(tc6);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 130/733] net: ethernet: oa_tc6: Improve the error recovery
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (128 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 129/733] net: ethernet: oa_tc6: Protect skb pointer used by two different kernel instances Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 131/733] net: ethernet: oa_tc6: Disable tx queues on fatal error Greg Kroah-Hartman
` (614 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Selvamani Rajagopal, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
[ Upstream commit 172c974113bffe5723b80b1acac17593bb50513c ]
When oversubscribed traffic causes lot of buffer overflow errors,
probably due to loss of data chunks, driver fails to find a
data chunk with end_valid bit set, before it runs out of sk buffer
space. As a result, assert is seen during skb_put.
Now, check is made if skb buffer has enough tailroom for the
incoming data before accepting. If there is no room, current
frame is abandoned and it will start looking for a data chunk
with start_valid bit, that is a new frame.
SK buffer allocation error is considered as recoverable error.
rx_buf_overflow flag is too specific and no longer the only
condition this flag is used for. Therefore it is renamed as
wait_until_start_valid. This is more appropriate as this flag
is used to look for the next data chunk with SV bit set, after
failures like buffer overflow, buffer allocation failure, skb pointer
validity besides buffer overflow error.
Not writing to status0 if it reads 0.
Fixes: d70a0d8f2f2d ("net: ethernet: oa_tc6: implement receive path to receive rx ethernet frames")
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Link: https://patch.msgid.link/20260824-fix-race-condition-and-crash-v7-2-4323279b18f2@onsemi.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 143 +++++++++++++++++++++++++---------
1 file changed, 108 insertions(+), 35 deletions(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index d283e81358e65..c60e0f37b7c5e 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -81,7 +81,7 @@ struct oa_tc6 {
u16 spi_data_tx_buf_offset;
u16 tx_credits;
u8 rx_chunks_available;
- bool rx_buf_overflow;
+ bool wait_until_start_valid;
bool int_flag;
bool disable_traffic;
bool prot_ctrl;
@@ -697,6 +697,12 @@ static void oa_tc6_free_pending_skbs(struct oa_tc6 *tc6)
oa_tc6_cleanup_waiting_tx_skb(tc6);
}
+static void oa_tc6_look_for_new_frame(struct oa_tc6 *tc6)
+{
+ tc6->wait_until_start_valid = true;
+ oa_tc6_cleanup_ongoing_rx_skb(tc6);
+}
+
/* If the failure is at SPI interface level, masking and clearing
* the interrupt of the device won't work. Since SPI interrupt is
* disabled, it should stop the repeated interrupts.
@@ -731,6 +737,13 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
return ret;
}
+ /* This function is called for each chunk received in a given SPI
+ * transaction. In case, extended status bit is set in more than
+ * one chunk, skip the write, if status0 is already cleared.
+ */
+ if (!value)
+ return 0;
+
/* Clear the error interrupts status */
ret = oa_tc6_write_register(tc6, OA_TC6_REG_STATUS0, value);
if (ret) {
@@ -740,8 +753,7 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
}
if (FIELD_GET(OA_TC6_STATUS0_RX_BUFFER_OVERFLOW_ERROR, value)) {
- tc6->rx_buf_overflow = true;
- oa_tc6_cleanup_ongoing_rx_skb(tc6);
+ oa_tc6_look_for_new_frame(tc6);
net_err_ratelimited("%s: Receive buffer overflow error\n",
tc6->netdev->name);
return -EAGAIN;
@@ -767,6 +779,8 @@ static int oa_tc6_process_extended_status(struct oa_tc6 *tc6)
static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
{
+ int ret = 0;
+
/* Process rx chunk footer for the following,
* 1. tx credits
* 2. errors if any from MAC-PHY
@@ -777,9 +791,11 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
footer);
if (FIELD_GET(OA_TC6_DATA_FOOTER_EXTENDED_STS, footer)) {
- int ret = oa_tc6_process_extended_status(tc6);
-
- if (ret)
+ ret = oa_tc6_process_extended_status(tc6);
+ /* EAGAIN error is recoverable. Move on to check
+ * HEADER and SYNC errors before returning.
+ */
+ if (ret && ret != -EAGAIN)
return ret;
}
@@ -797,7 +813,7 @@ static int oa_tc6_process_rx_chunk_footer(struct oa_tc6 *tc6, u32 footer)
return -ENODEV;
}
- return 0;
+ return ret;
}
static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6)
@@ -822,13 +838,35 @@ static void oa_tc6_submit_rx_skb(struct oa_tc6 *tc6)
tc6->rx_skb = NULL;
}
-static void oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
+/* On oversubscribed traffic condition, particularly with overwhelming rx
+ * buffer overflow errors, there could be data chunk loss. If tail + length
+ * goes beyond end pointer, that is an indication that the data chunk with
+ * end_valid bit is lost. Time to look for a data chunk with start_valid bit.
+ *
+ * If rx_skb is NULL, it is time to start looking for data chunk with
+ * start_bit.
+ */
+static int oa_tc6_update_rx_skb(struct oa_tc6 *tc6, u8 *payload, u8 length)
{
+ if (!tc6->rx_skb ||
+ skb_tailroom(tc6->rx_skb) < length) {
+ oa_tc6_look_for_new_frame(tc6);
+ return -EAGAIN;
+ }
+
memcpy(skb_put(tc6->rx_skb, length), payload, length);
+ return 0;
}
+/* On overwhelming rx buffer overflow errors, due to data chunk loss, it is
+ * possible that we get two data chunks with start_valid bit set, without
+ * end_valid bit set in between. In this case, rx_skb would have a valid
+ * buffer pointer. We should release, if a valid pointer is found before
+ * allocating a new one.
+ */
static int oa_tc6_allocate_rx_skb(struct oa_tc6 *tc6)
{
+ oa_tc6_cleanup_ongoing_rx_skb(tc6);
tc6->rx_skb = netdev_alloc_skb_ip_align(tc6->netdev, tc6->netdev->mtu +
ETH_HLEN + ETH_FCS_LEN);
if (!tc6->rx_skb) {
@@ -848,7 +886,9 @@ static int oa_tc6_prcs_complete_rx_frame(struct oa_tc6 *tc6, u8 *payload,
if (ret)
return ret;
- oa_tc6_update_rx_skb(tc6, payload, size);
+ ret = oa_tc6_update_rx_skb(tc6, payload, size);
+ if (ret)
+ return ret;
oa_tc6_submit_rx_skb(tc6);
@@ -863,22 +903,24 @@ static int oa_tc6_prcs_rx_frame_start(struct oa_tc6 *tc6, u8 *payload, u16 size)
if (ret)
return ret;
- oa_tc6_update_rx_skb(tc6, payload, size);
-
- return 0;
+ return oa_tc6_update_rx_skb(tc6, payload, size);
}
-static void oa_tc6_prcs_rx_frame_end(struct oa_tc6 *tc6, u8 *payload, u16 size)
+static int oa_tc6_prcs_rx_frame_end(struct oa_tc6 *tc6, u8 *payload, u16 size)
{
- oa_tc6_update_rx_skb(tc6, payload, size);
+ int ret;
- oa_tc6_submit_rx_skb(tc6);
+ ret = oa_tc6_update_rx_skb(tc6, payload, size);
+ if (!ret)
+ oa_tc6_submit_rx_skb(tc6);
+ return ret;
}
-static void oa_tc6_prcs_ongoing_rx_frame(struct oa_tc6 *tc6, u8 *payload,
- u32 footer)
+static int oa_tc6_prcs_ongoing_rx_frame(struct oa_tc6 *tc6, u8 *payload,
+ u32 footer)
{
- oa_tc6_update_rx_skb(tc6, payload, OA_TC6_CHUNK_PAYLOAD_SIZE);
+ return oa_tc6_update_rx_skb(tc6, payload,
+ OA_TC6_CHUNK_PAYLOAD_SIZE);
}
static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
@@ -893,10 +935,10 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
u16 size;
/* Restart the new rx frame after receiving rx buffer overflow error */
- if (start_valid && tc6->rx_buf_overflow)
- tc6->rx_buf_overflow = false;
+ if (start_valid && tc6->wait_until_start_valid)
+ tc6->wait_until_start_valid = false;
- if (tc6->rx_buf_overflow)
+ if (tc6->wait_until_start_valid)
return 0;
/* Process the chunk with complete rx frame */
@@ -918,8 +960,7 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
/* Process the chunk with only rx frame end */
if (end_valid && !start_valid) {
size = end_byte_offset + 1;
- oa_tc6_prcs_rx_frame_end(tc6, data, size);
- return 0;
+ return oa_tc6_prcs_rx_frame_end(tc6, data, size);
}
/* Process the chunk with previous rx frame end and next rx frame
@@ -933,6 +974,15 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
if (tc6->rx_skb) {
size = end_byte_offset + 1;
oa_tc6_prcs_rx_frame_end(tc6, data, size);
+
+ /* Return value from oa_tc6_prcs_rx_frame_end is not
+ * checked. If it returned an error, it is to make
+ * the code to look for new frame. At this stage,
+ * code below is going to process a new frame. So,
+ * error condition is set to false, in case it is
+ * set before proceeding.
+ */
+ tc6->wait_until_start_valid = false;
}
size = OA_TC6_CHUNK_PAYLOAD_SIZE - start_byte_offset;
return oa_tc6_prcs_rx_frame_start(tc6,
@@ -941,9 +991,7 @@ static int oa_tc6_prcs_rx_chunk_payload(struct oa_tc6 *tc6, u8 *data,
}
/* Process the chunk with ongoing rx frame data */
- oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer);
-
- return 0;
+ return oa_tc6_prcs_ongoing_rx_frame(tc6, data, footer);
}
static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offset)
@@ -959,8 +1007,9 @@ static u32 oa_tc6_get_rx_chunk_footer(struct oa_tc6 *tc6, u16 footer_offset)
static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length)
{
u16 no_of_rx_chunks = length / OA_TC6_CHUNK_SIZE;
+ bool retry = false;
+ int ret = 0;
u32 footer;
- int ret;
/* All the rx chunks in the receive SPI data buffer are examined here */
for (int i = 0; i < no_of_rx_chunks; i++) {
@@ -969,8 +1018,11 @@ static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length)
OA_TC6_CHUNK_PAYLOAD_SIZE);
ret = oa_tc6_process_rx_chunk_footer(tc6, footer);
- if (ret)
- return ret;
+ if (ret) {
+ if (ret != -EAGAIN)
+ return ret;
+ retry = true;
+ }
/* If there is a data valid chunks then process it for the
* information needed to determine the validity and the location
@@ -982,12 +1034,35 @@ static int oa_tc6_process_spi_data_rx_buf(struct oa_tc6 *tc6, u16 length)
ret = oa_tc6_prcs_rx_chunk_payload(tc6, payload,
footer);
- if (ret)
- return ret;
+ if (ret) {
+ if (ret != -ENOMEM && ret != -EAGAIN)
+ return ret;
+ retry = true;
+ }
}
}
- return 0;
+ /* Not bailing out on recoverable error codes, -EAGAIN and
+ * -ENOMEM. If subsequent loop iterations, if any, succeeds,
+ * error code would be overwritten. retry flag helps to
+ * make the caller to continue and retry. Since recovery
+ * action for -ENOMEM and -EAGAIN are same, we are returning
+ * one of the error codes, that is -EAGAIN.
+ *
+ * Successful recovery depends on how small the frames are,
+ * how many chunks, among the received chunks triggered the
+ * error, whether data is intact even with error conditions.
+ * As a result, there is no single, best method to recover
+ * most data when error conditions hit. We do our best by
+ * processing all the chunks with good "footer header" and
+ * "data valid" bit set.
+ */
+ if (retry) {
+ ret = -EAGAIN;
+ oa_tc6_look_for_new_frame(tc6);
+ }
+
+ return ret;
}
static __be32 oa_tc6_prepare_data_header(bool data_valid, bool start_valid,
@@ -1149,10 +1224,8 @@ static int oa_tc6_try_spi_transfer(struct oa_tc6 *tc6)
}
ret = oa_tc6_process_spi_data_rx_buf(tc6, spi_len);
- if (ret) {
- if (ret == -EAGAIN)
- continue;
+ if (ret && ret != -EAGAIN) {
oa_tc6_free_ongoing_skbs(tc6);
netdev_err(tc6->netdev, "Device error: %d\n", ret);
return ret;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 131/733] net: ethernet: oa_tc6: Disable tx queues on fatal error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (129 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 130/733] net: ethernet: oa_tc6: Improve the error recovery Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 132/733] net: ethernet: oa_tc6: Fix for the wrong data type Greg Kroah-Hartman
` (613 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Selvamani Rajagopal, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
[ Upstream commit 349c366365876b7f67120827a0deb44899f59303 ]
Previously, TX queue interface was stopped when
disable_traffic flag was set, which would indicate fatal
error. It is more appropriate to disable the queue as,
unless driver is unloaded and reloaded, there is no recovery
after disable_traffic is set.
Queues may be re-enabled inadvertently by other layers.
Intention of disable_traffic is only to stop the traffic
from flowing on fatal error.
Fixes: b542d13fab0f ("net: ethernet: oa_tc6: Interrupt is active low, level triggered.")
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Link: https://patch.msgid.link/20260824-fix-race-condition-and-crash-v7-3-4323279b18f2@onsemi.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index c60e0f37b7c5e..bc468cd86a140 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -717,6 +717,10 @@ static void oa_tc6_disable_traffic(struct oa_tc6 *tc6)
skb = oa_tc6_detach_waiting_tx_skb(tc6);
spin_unlock_bh(&tc6->tx_skb_lock);
+ /* disable_traffic, when set, is a point of no return to
+ * working state. Keeping the TX queues disabled.
+ */
+ netif_tx_disable(tc6->netdev);
oa_tc6_drop_tx_skb(tc6, skb);
oa_tc6_free_ongoing_skbs(tc6);
oa_tc6_write_register(tc6, OA_TC6_REG_INT_MASK0, regval);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 132/733] net: ethernet: oa_tc6: Fix for the wrong data type
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (130 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 131/733] net: ethernet: oa_tc6: Disable tx queues on fatal error Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 133/733] net/sched: cls_u32: fix duplicate handle when node ID pool is exhausted Greg Kroah-Hartman
` (612 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Selvamani Rajagopal, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
[ Upstream commit 3cc2aa96b97184abd6fc106aac626ddf14389813 ]
Inadvertently bool data type is used where int is supposed to
be used. This might turn a negative error code into true or
false and sign of the return code would be lost.
Fixes: 8f9bf857e43b ("net: ethernet: oa_tc6: implement internal PHY initialization")
Signed-off-by: Selvamani Rajagopal <Selvamani.Rajagopal@onsemi.com>
Link: https://patch.msgid.link/20260824-fix-race-condition-and-crash-v7-4-4323279b18f2@onsemi.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/oa_tc6.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/oa_tc6.c b/drivers/net/ethernet/oa_tc6.c
index bc468cd86a140..f552165e503e1 100644
--- a/drivers/net/ethernet/oa_tc6.c
+++ b/drivers/net/ethernet/oa_tc6.c
@@ -410,7 +410,7 @@ static int oa_tc6_mdiobus_read(struct mii_bus *bus, int addr, int regnum)
{
struct oa_tc6 *tc6 = bus->priv;
u32 regval;
- bool ret;
+ int ret;
ret = oa_tc6_read_register(tc6, OA_TC6_PHY_STD_REG_ADDR_BASE |
(regnum & OA_TC6_PHY_STD_REG_ADDR_MASK),
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 133/733] net/sched: cls_u32: fix duplicate handle when node ID pool is exhausted
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (131 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 132/733] net: ethernet: oa_tc6: Fix for the wrong data type Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 134/733] rust: samples: add missing newlines in rust_print_main Greg Kroah-Hartman
` (611 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, vega, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit d7e7e98d23f42a92d9ab7e36302bd96bd9b33b5f ]
gen_new_kid() falls back to returning max (htid | 0xFFF) when both
idr_alloc_u32() ranges are full, instead of reporting an error.
u32_change() trusts that value and inserts a new knode with a handle
that is already live in the hash table, breaking handle uniqueness
within the table's node ID space.
The handle was never reserved in ht->handle_idr, so every later error
path that does idr_remove(&ht->handle_idr, handle) removes the
reservation of a different, live knode, which is then reused — one
failed add compounds into further duplicates.
The 4095 limit is per (table, bucket) — ht->handle_idr is per hash
table and the range is derived from htid (bucketid), so a table with
divisor 256 can legitimately hold 256*4095 knodes.
The sibling helper gen_new_htid() has the same silent in-band failure:
it returns 0 when the tp_c handle pool (1..0x7FF) is full, and
u32_init() publishes the root hash table with handle 0 without
checking. Two root tables with handle 0 alias in u32_lookup_ht(),
allowing cross-tcf_proto knode add/lookup/delete. Add the same
exhaustion check that the divisor path already has.
Return an error so u32_change() fails with ENOSPC/ENOMEM when the
node ID space is exhausted, and so u32_init() fails with -ENOMEM
when the hash table ID space is exhausted. The extack message
distinguishes pool exhaustion (-ENOSPC) from a transient allocation
failure (-ENOMEM).
Conditions to recreate the bug:
- CONFIG_NET_SCHED=y, CONFIG_CLS_U32=y (or =m with module loaded)
- Create a clsact qdisc on a device, then add 4095 u32 filters with
auto-generated handles to fill the node ID space for the root hash
table (single bucket). The 4096th auto-handle filter add triggers
the duplicate handle (fh 800::fff reused). Reachable at Level 2
(unshare -Urn, namespace-local CAP_NET_ADMIN).
- For gen_new_htid: create 2047 u32 proto entries on the same block
to fill the tp_c handle pool, then create one more. The root table
gets handle 0 and aliases with other handle-0 root tables.
Fixes: 7801db8aec95 ("net_sched: avoid generating same handle for u32 filters")
Reported-by: vega@nebusec.ai
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260825081052.133898-1-jhs@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_u32.c | 32 ++++++++++++++++++++++++++------
1 file changed, 26 insertions(+), 6 deletions(-)
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index ac6d0fa5a40e3..a3e65c8cf29ef 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -370,6 +370,10 @@ static int u32_init(struct tcf_proto *tp)
refcount_set(&root_ht->refcnt, 1);
root_ht->handle = tp_c ? gen_new_htid(tp_c, root_ht) : id2handle(0);
+ if (root_ht->handle == 0) {
+ kfree(root_ht);
+ return -ENOMEM;
+ }
root_ht->prio = tp->prio;
root_ht->is_root = true;
idr_init(&root_ht->handle_idr);
@@ -695,21 +699,33 @@ static int u32_delete(struct tcf_proto *tp, void *arg, bool *last,
return ret;
}
-static u32 gen_new_kid(struct tc_u_hnode *ht, u32 htid)
+static u32 gen_new_kid(struct tc_u_hnode *ht, u32 htid, int *err)
{
u32 index = htid | 0x800;
u32 max = htid | 0xFFF;
+ *err = 0;
+
if (idr_alloc_u32(&ht->handle_idr, NULL, &index, max, GFP_KERNEL)) {
index = htid + 1;
- if (idr_alloc_u32(&ht->handle_idr, NULL, &index, max,
- GFP_KERNEL))
- index = max;
+ *err = idr_alloc_u32(&ht->handle_idr, NULL, &index, max,
+ GFP_KERNEL);
+ if (*err)
+ return 0;
}
return index;
}
+static int u32_kid_extack(int err, struct netlink_ext_ack *extack)
+{
+ if (err == -ENOSPC)
+ NL_SET_ERR_MSG_MOD(extack, "Hash table node ID pool exhausted");
+ else
+ NL_SET_ERR_MSG_MOD(extack, "Failed to allocate node ID");
+ return err;
+}
+
static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
[TCA_U32_CLASSID] = { .type = NLA_U32 },
[TCA_U32_HASH] = { .type = NLA_U32 },
@@ -1079,7 +1095,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
* handle which is used to uniquely identify the match entry.
*/
if (!TC_U32_NODE(handle)) {
- handle = gen_new_kid(ht, htid);
+ handle = gen_new_kid(ht, htid, &err);
+ if (err)
+ return u32_kid_extack(err, extack);
} else {
handle = htid | TC_U32_NODE(handle);
err = idr_alloc_u32(&ht->handle_idr, NULL, &handle,
@@ -1091,7 +1109,9 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
/* The user did not give us a handle; lets just generate one
* from the table's pool of nodeids.
*/
- handle = gen_new_kid(ht, htid);
+ handle = gen_new_kid(ht, htid, &err);
+ if (err)
+ return u32_kid_extack(err, extack);
}
if (tb[TCA_U32_SEL] == NULL) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 134/733] rust: samples: add missing newlines in rust_print_main
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (132 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 133/733] net/sched: cls_u32: fix duplicate handle when node ID pool is exhausted Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 135/733] igmp: convert struct ip_sf_list to RCU Greg Kroah-Hartman
` (610 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miguel Ojeda, Mehmet Koseoglu,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mehmet Koseoglu <mehmet.mkoseoglu@gmail.com>
[ Upstream commit e510334fbaeaa016ac76d80b4c5f47611c5f7860 ]
Calls to `pr_info!` in `arc_print` are missing trailing newlines, which
are expected as the `pr_*!` documentation shows.
Add the missing `\n` to all four formatting strings.
Fixes: f431c5c581fa ("samples: rust: print: Add sample code for Arc printing")
Fixes: 47cb6bf7860c ("rust: use derive(CoercePointee) on rustc >= 1.84.0")
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Link: https://github.com/Rust-for-Linux/linux/issues/1139
Signed-off-by: Mehmet Koseoglu <mehmet.mkoseoglu@gmail.com>
Link: https://patch.msgid.link/20260828015148.221737-2-mehmet.mkoseoglu@gmail.com
[ Reworded to fix the description of the missing-newline behavior. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
samples/rust/rust_print_main.rs | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/samples/rust/rust_print_main.rs b/samples/rust/rust_print_main.rs
index 682207c81fc2b..01729e87d6b5a 100644
--- a/samples/rust/rust_print_main.rs
+++ b/samples/rust/rust_print_main.rs
@@ -23,10 +23,10 @@ fn arc_print() -> Result {
let b = UniqueArc::new("hello, world", GFP_KERNEL)?;
// Prints the value of data in `a`.
- pr_info!("{}", a);
+ pr_info!("{}\n", a);
// Uses ":?" to print debug fmt of `b`.
- pr_info!("{:?}", b);
+ pr_info!("{:?}\n", b);
let a: Arc<&str> = b.into();
let c = a.clone();
@@ -42,7 +42,7 @@ fn arc_print() -> Result {
use kernel::fmt::Display;
fn arc_dyn_print(arc: &Arc<dyn Display>) {
- pr_info!("Arc<dyn Display> says {arc}");
+ pr_info!("Arc<dyn Display> says {arc}\n");
}
let a_i32_display: Arc<dyn Display> = Arc::new(42i32, GFP_KERNEL)?;
@@ -53,7 +53,7 @@ fn arc_dyn_print(arc: &Arc<dyn Display>) {
}
// Pretty-prints the debug formatting with lower-case hexadecimal integers.
- pr_info!("{:#x?}", a);
+ pr_info!("{:#x?}\n", a);
Ok(())
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 135/733] igmp: convert struct ip_sf_list to RCU
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (133 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 134/733] rust: samples: add missing newlines in rust_print_main Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 136/733] ppp: ppp_async: simplify tty disc_data access Greg Kroah-Hartman
` (609 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+3d99fb01bcd740f2fc1e,
Eric Dumazet, Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 2987ee196c88dbde0463dc87d5fb209c684e34a2 ]
Commit 23d2b94043ca ("igmp: Add ip_mc_list lock in ip_check_mc_rcu")
added spin_lock_bh(&im->lock) to ip_check_mc_rcu() to prevent a
use-after-free while iterating im->sources during concurrent deletions.
However, ip_check_mc_rcu() is called from RCU read-side critical
sections in packet receive and route lookup fast paths (e.g.
__mkroute_output(), ip_route_input_rcu(), and __udp4_lib_rcv()).
When igmpv3_send_cr() or igmpv3_send_report() holds &pmc->lock and
calls add_grec() -> igmpv3_newpack() -> ip_route_output_ports(),
an XFRM policy matching a multicast destination triggers
xfrm_tmpl_resolve_one() -> xfrm4_get_saddr() -> __mkroute_output() ->
ip_check_mc_rcu(). This attempts to acquire &im->lock while &pmc->lock
is already held on the same CPU, triggering a lockdep recursive locking
warning / deadlock.
Fix this by converting IPv4 struct ip_sf_list to RCU, mirroring the
IPv6 implementation in net/ipv6/mcast.c:
1. Add struct rcu_head to struct ip_sf_list and annotate sf_next,
sources, and tomb as __rcu pointers.
2. Use rcu_assign_pointer() and kfree_rcu() for list updates and
deletions.
3. Remove spin_lock_bh(&im->lock) from ip_check_mc_rcu() and traverse
im->sources locklessly with for_each_psf_rcu(), reading and writing
counter fields with READ_ONCE() and WRITE_ONCE().
Note: RCU conversion of /proc/net/mcfilter will be done in a
separate patch.
Fixes: 23d2b94043ca ("igmp: Add ip_mc_list lock in ip_check_mc_rcu")
Reported-by: syzbot+3d99fb01bcd740f2fc1e@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=3d99fb01bcd740f2fc1e
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260827160656.903003-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/igmp.h | 7 +-
net/ipv4/igmp.c | 210 +++++++++++++++++++++++++++----------------
2 files changed, 135 insertions(+), 82 deletions(-)
diff --git a/include/linux/igmp.h b/include/linux/igmp.h
index 3a2d35a9f3078..a0cf0398519fd 100644
--- a/include/linux/igmp.h
+++ b/include/linux/igmp.h
@@ -57,20 +57,21 @@ struct ip_mc_socklist {
};
struct ip_sf_list {
- struct ip_sf_list *sf_next;
+ struct ip_sf_list __rcu *sf_next;
unsigned long sf_count[2]; /* include/exclude counts */
__be32 sf_inaddr;
unsigned char sf_gsresp; /* include in g & s response? */
unsigned char sf_oldin; /* change state */
unsigned char sf_crcount; /* retrans. left to send */
+ struct rcu_head rcu;
};
struct ip_mc_list {
struct in_device *interface;
__be32 multiaddr;
unsigned int sfmode;
- struct ip_sf_list *sources;
- struct ip_sf_list *tomb;
+ struct ip_sf_list __rcu *sources;
+ struct ip_sf_list __rcu *tomb;
unsigned long sfcount[2];
union {
struct ip_mc_list *next;
diff --git a/net/ipv4/igmp.c b/net/ipv4/igmp.c
index bb2d4441a4929..0a5b7ded23be2 100644
--- a/net/ipv4/igmp.c
+++ b/net/ipv4/igmp.c
@@ -188,6 +188,10 @@ static void ip_ma_put(struct ip_mc_list *im)
}
}
+#define pmc_dereference(e, pmc) \
+ rcu_dereference_protected(e, lockdep_is_held(&(pmc)->lock) || \
+ lockdep_is_held(&(pmc)->interface->mc_tomb_lock))
+
#define for_each_pmc_rcu(in_dev, pmc) \
for (pmc = rcu_dereference(in_dev->mc_list); \
pmc != NULL; \
@@ -198,13 +202,28 @@ static void ip_ma_put(struct ip_mc_list *im)
pmc != NULL; \
pmc = rtnl_dereference(pmc->next_rcu))
+#define for_each_psf_mclock(pmc, psf) \
+ for (psf = pmc_dereference((pmc)->sources, pmc); \
+ psf; \
+ psf = pmc_dereference(psf->sf_next, pmc))
+
+#define for_each_psf_rcu(im, psf) \
+ for (psf = rcu_dereference((im)->sources); \
+ psf; \
+ psf = rcu_dereference(psf->sf_next))
+
+#define for_each_psf_tomb(pmc, psf) \
+ for (psf = pmc_dereference((pmc)->tomb, pmc); \
+ psf; \
+ psf = pmc_dereference(psf->sf_next, pmc))
+
static void ip_sf_list_clear_all(struct ip_sf_list *psf)
{
struct ip_sf_list *next;
while (psf) {
- next = psf->sf_next;
- kfree(psf);
+ next = rcu_dereference_protected(psf->sf_next, 1);
+ kfree_rcu(psf, rcu);
psf = next;
}
}
@@ -349,7 +368,7 @@ igmp_scount(struct ip_mc_list *pmc, int type, int gdeleted, int sdeleted)
struct ip_sf_list *psf;
int scount = 0;
- for (psf = pmc->sources; psf; psf = psf->sf_next) {
+ for_each_psf_mclock(pmc, psf) {
if (!is_in(pmc, psf, type, gdeleted, sdeleted))
continue;
scount++;
@@ -494,7 +513,8 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
struct net *net = dev_net(dev);
struct igmpv3_report *pih;
struct igmpv3_grec *pgr = NULL;
- struct ip_sf_list *psf, *psf_next, *psf_prev, **psf_list;
+ struct ip_sf_list *psf, *psf_next, *psf_prev;
+ struct ip_sf_list __rcu **psf_list;
int scount, stotal, first, isquery, truncate;
unsigned int mtu;
@@ -517,7 +537,7 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
psf_list = sdeleted ? &pmc->tomb : &pmc->sources;
- if (!*psf_list)
+ if (!rcu_access_pointer(*psf_list))
goto empty_source;
pih = skb ? igmpv3_report_hdr(skb) : NULL;
@@ -533,10 +553,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
}
first = 1;
psf_prev = NULL;
- for (psf = *psf_list; psf; psf = psf_next) {
+ for (psf = pmc_dereference(*psf_list, pmc);
+ psf;
+ psf = psf_next) {
__be32 *psrc;
- psf_next = psf->sf_next;
+ psf_next = pmc_dereference(psf->sf_next, pmc);
if (!is_in(pmc, psf, type, gdeleted, sdeleted)) {
psf_prev = psf;
@@ -583,10 +605,12 @@ static struct sk_buff *add_grec(struct sk_buff *skb, struct ip_mc_list *pmc,
psf->sf_crcount--;
if ((sdeleted || gdeleted) && psf->sf_crcount == 0) {
if (psf_prev)
- psf_prev->sf_next = psf->sf_next;
+ rcu_assign_pointer(psf_prev->sf_next,
+ psf_next);
else
- *psf_list = psf->sf_next;
- kfree(psf);
+ rcu_assign_pointer(*psf_list,
+ psf_next);
+ kfree_rcu(psf, rcu);
continue;
}
}
@@ -655,28 +679,29 @@ static int igmpv3_send_report(struct in_device *in_dev, struct ip_mc_list *pmc)
/*
* remove zero-count source records from a source filter list
*/
-static void igmpv3_clear_zeros(struct ip_sf_list **ppsf)
+static void igmpv3_clear_zeros(struct ip_sf_list __rcu **ppsf)
{
struct ip_sf_list *psf_prev, *psf_next, *psf;
psf_prev = NULL;
- for (psf = *ppsf; psf; psf = psf_next) {
- psf_next = psf->sf_next;
+ for (psf = rcu_dereference_protected(*ppsf, 1); psf; psf = psf_next) {
+ psf_next = rcu_dereference_protected(psf->sf_next, 1);
if (psf->sf_crcount == 0) {
if (psf_prev)
- psf_prev->sf_next = psf->sf_next;
+ rcu_assign_pointer(psf_prev->sf_next, psf_next);
else
- *ppsf = psf->sf_next;
- kfree(psf);
- } else
+ rcu_assign_pointer(*ppsf, psf_next);
+ kfree_rcu(psf, rcu);
+ } else {
psf_prev = psf;
+ }
}
}
static void kfree_pmc(struct ip_mc_list *pmc)
{
- ip_sf_list_clear_all(pmc->sources);
- ip_sf_list_clear_all(pmc->tomb);
+ ip_sf_list_clear_all(rcu_dereference_protected(pmc->sources, 1));
+ ip_sf_list_clear_all(rcu_dereference_protected(pmc->tomb, 1));
kfree(pmc);
}
@@ -710,7 +735,8 @@ static void igmpv3_send_cr(struct in_device *in_dev)
igmpv3_clear_zeros(&pmc->sources);
}
}
- if (pmc->crcount == 0 && !pmc->tomb && !pmc->sources) {
+ if (pmc->crcount == 0 && !rcu_access_pointer(pmc->tomb) &&
+ !rcu_access_pointer(pmc->sources)) {
if (pmc_prev)
pmc_prev->next = pmc_next;
else
@@ -896,7 +922,7 @@ static int igmp_xmarksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
int i, scount;
scount = 0;
- for (psf = pmc->sources; psf; psf = psf->sf_next) {
+ for_each_psf_mclock(pmc, psf) {
if (scount == nsrcs)
break;
for (i = 0; i < nsrcs; i++) {
@@ -927,7 +953,7 @@ static int igmp_marksources(struct ip_mc_list *pmc, int nsrcs, __be32 *srcs)
/* mark INCLUDE-mode sources */
scount = 0;
- for (psf = pmc->sources; psf; psf = psf->sf_next) {
+ for_each_psf_mclock(pmc, psf) {
if (scount == nsrcs)
break;
for (i = 0; i < nsrcs; i++)
@@ -1228,11 +1254,12 @@ static void igmpv3_add_delrec(struct in_device *in_dev, struct ip_mc_list *im,
if (pmc->sfmode == MCAST_INCLUDE) {
struct ip_sf_list *psf;
+ for_each_psf_mclock(im, psf)
+ psf->sf_crcount = pmc->crcount;
pmc->tomb = im->tomb;
pmc->sources = im->sources;
- im->tomb = im->sources = NULL;
- for (psf = pmc->sources; psf; psf = psf->sf_next)
- psf->sf_crcount = pmc->crcount;
+ RCU_INIT_POINTER(im->tomb, NULL);
+ RCU_INIT_POINTER(im->sources, NULL);
}
spin_unlock_bh(&im->lock);
@@ -1271,9 +1298,18 @@ static void igmpv3_del_delrec(struct in_device *in_dev, struct ip_mc_list *im)
if (pmc) {
im->interface = pmc->interface;
if (im->sfmode == MCAST_INCLUDE) {
- swap(im->tomb, pmc->tomb);
- swap(im->sources, pmc->sources);
- for (psf = im->sources; psf; psf = psf->sf_next)
+ struct ip_sf_list *sources, *tomb;
+
+ tomb = rcu_replace_pointer(im->tomb,
+ rcu_dereference_protected(pmc->tomb, 1),
+ lockdep_is_held(&im->lock));
+ rcu_assign_pointer(pmc->tomb, tomb);
+
+ sources = rcu_replace_pointer(im->sources,
+ rcu_dereference_protected(pmc->sources, 1),
+ lockdep_is_held(&im->lock));
+ rcu_assign_pointer(pmc->sources, sources);
+ for_each_psf_mclock(im, psf)
psf->sf_crcount = in_dev->mr_qrv ?:
READ_ONCE(net->ipv4.sysctl_igmp_qrv);
} else {
@@ -1310,8 +1346,8 @@ static void igmpv3_clear_delrec(struct in_device *in_dev)
struct ip_sf_list *psf;
spin_lock_bh(&pmc->lock);
- psf = pmc->tomb;
- pmc->tomb = NULL;
+ psf = pmc_dereference(pmc->tomb, pmc);
+ RCU_INIT_POINTER(pmc->tomb, NULL);
spin_unlock_bh(&pmc->lock);
ip_sf_list_clear_all(psf);
}
@@ -1988,7 +2024,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
int rv = 0;
psf_prev = NULL;
- for (psf = pmc->sources; psf; psf = psf->sf_next) {
+ for_each_psf_mclock(pmc, psf) {
if (psf->sf_inaddr == *psfsrc)
break;
psf_prev = psf;
@@ -1997,7 +2033,7 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
/* source filter not found, or count wrong => bug */
return -ESRCH;
}
- psf->sf_count[sfmode]--;
+ WRITE_ONCE(psf->sf_count[sfmode], psf->sf_count[sfmode] - 1);
if (psf->sf_count[sfmode] == 0) {
ip_rt_multicast_event(pmc->interface);
}
@@ -2009,19 +2045,28 @@ static int ip_mc_del1_src(struct ip_mc_list *pmc, int sfmode,
/* no more filters for this source */
if (psf_prev)
- psf_prev->sf_next = psf->sf_next;
+ rcu_assign_pointer(psf_prev->sf_next,
+ pmc_dereference(psf->sf_next, pmc));
else
- pmc->sources = psf->sf_next;
+ rcu_assign_pointer(pmc->sources,
+ pmc_dereference(psf->sf_next, pmc));
#ifdef CONFIG_IP_MULTICAST
if (psf->sf_oldin &&
!IGMP_V1_SEEN(in_dev) && !IGMP_V2_SEEN(in_dev)) {
- psf->sf_crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
- psf->sf_next = pmc->tomb;
- pmc->tomb = psf;
- rv = 1;
- } else
+ struct ip_sf_list *dpsf = kmalloc_obj(*dpsf, GFP_ATOMIC);
+
+ if (dpsf) {
+ *dpsf = *psf;
+ dpsf->sf_crcount = in_dev->mr_qrv ?:
+ READ_ONCE(net->ipv4.sysctl_igmp_qrv);
+ rcu_assign_pointer(dpsf->sf_next,
+ pmc_dereference(pmc->tomb, pmc));
+ rcu_assign_pointer(pmc->tomb, dpsf);
+ rv = 1;
+ }
+ }
#endif
- kfree(psf);
+ kfree_rcu(psf, rcu);
}
return rv;
}
@@ -2058,7 +2103,7 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
err = -EINVAL;
if (!pmc->sfcount[sfmode])
goto out_unlock;
- pmc->sfcount[sfmode]--;
+ WRITE_ONCE(pmc->sfcount[sfmode], pmc->sfcount[sfmode] - 1);
}
err = 0;
for (i = 0; i < sfcount; i++) {
@@ -2081,7 +2126,7 @@ static int ip_mc_del_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
#ifdef CONFIG_IP_MULTICAST
pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount);
- for (psf = pmc->sources; psf; psf = psf->sf_next)
+ for_each_psf_mclock(pmc, psf)
psf->sf_crcount = 0;
igmp_ifc_event(pmc->interface);
} else if (sf_setstate(pmc) || changerec) {
@@ -2102,7 +2147,7 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
struct ip_sf_list *psf, *psf_prev;
psf_prev = NULL;
- for (psf = pmc->sources; psf; psf = psf->sf_next) {
+ for_each_psf_mclock(pmc, psf) {
if (psf->sf_inaddr == *psfsrc)
break;
psf_prev = psf;
@@ -2112,12 +2157,12 @@ static int ip_mc_add1_src(struct ip_mc_list *pmc, int sfmode,
if (!psf)
return -ENOBUFS;
psf->sf_inaddr = *psfsrc;
- if (psf_prev) {
- psf_prev->sf_next = psf;
- } else
- pmc->sources = psf;
+ if (psf_prev)
+ rcu_assign_pointer(psf_prev->sf_next, psf);
+ else
+ rcu_assign_pointer(pmc->sources, psf);
}
- psf->sf_count[sfmode]++;
+ WRITE_ONCE(psf->sf_count[sfmode], psf->sf_count[sfmode] + 1);
if (psf->sf_count[sfmode] == 1) {
ip_rt_multicast_event(pmc->interface);
}
@@ -2130,13 +2175,15 @@ static void sf_markstate(struct ip_mc_list *pmc)
struct ip_sf_list *psf;
int mca_xcount = pmc->sfcount[MCAST_EXCLUDE];
- for (psf = pmc->sources; psf; psf = psf->sf_next)
+ for_each_psf_mclock(pmc, psf) {
if (pmc->sfcount[MCAST_EXCLUDE]) {
psf->sf_oldin = mca_xcount ==
psf->sf_count[MCAST_EXCLUDE] &&
!psf->sf_count[MCAST_INCLUDE];
- } else
+ } else {
psf->sf_oldin = psf->sf_count[MCAST_INCLUDE] != 0;
+ }
+ }
}
static int sf_setstate(struct ip_mc_list *pmc)
@@ -2147,27 +2194,31 @@ static int sf_setstate(struct ip_mc_list *pmc)
int new_in, rv;
rv = 0;
- for (psf = pmc->sources; psf; psf = psf->sf_next) {
+ for_each_psf_mclock(pmc, psf) {
if (pmc->sfcount[MCAST_EXCLUDE]) {
new_in = mca_xcount == psf->sf_count[MCAST_EXCLUDE] &&
!psf->sf_count[MCAST_INCLUDE];
- } else
+ } else {
new_in = psf->sf_count[MCAST_INCLUDE] != 0;
+ }
if (new_in) {
if (!psf->sf_oldin) {
struct ip_sf_list *prev = NULL;
- for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next) {
+ for_each_psf_tomb(pmc, dpsf) {
if (dpsf->sf_inaddr == psf->sf_inaddr)
break;
prev = dpsf;
}
if (dpsf) {
+ struct ip_sf_list *dpsf_next;
+
+ dpsf_next = pmc_dereference(dpsf->sf_next, pmc);
if (prev)
- prev->sf_next = dpsf->sf_next;
+ rcu_assign_pointer(prev->sf_next, dpsf_next);
else
- pmc->tomb = dpsf->sf_next;
- kfree(dpsf);
+ rcu_assign_pointer(pmc->tomb, dpsf_next);
+ kfree_rcu(dpsf, rcu);
}
psf->sf_crcount = qrv;
rv++;
@@ -2179,17 +2230,19 @@ static int sf_setstate(struct ip_mc_list *pmc)
* add or update "delete" records if an active filter
* is now inactive
*/
- for (dpsf = pmc->tomb; dpsf; dpsf = dpsf->sf_next)
+ for_each_psf_tomb(pmc, dpsf) {
if (dpsf->sf_inaddr == psf->sf_inaddr)
break;
+ }
if (!dpsf) {
dpsf = kmalloc_obj(*dpsf, GFP_ATOMIC);
if (!dpsf)
continue;
*dpsf = *psf;
/* pmc->lock held by callers */
- dpsf->sf_next = pmc->tomb;
- pmc->tomb = dpsf;
+ rcu_assign_pointer(dpsf->sf_next,
+ pmc_dereference(pmc->tomb, pmc));
+ rcu_assign_pointer(pmc->tomb, dpsf);
}
dpsf->sf_crcount = qrv;
rv++;
@@ -2229,7 +2282,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
#endif
isexclude = pmc->sfmode == MCAST_EXCLUDE;
if (!delta)
- pmc->sfcount[sfmode]++;
+ WRITE_ONCE(pmc->sfcount[sfmode], pmc->sfcount[sfmode] + 1);
err = 0;
for (i = 0; i < sfcount; i++) {
err = ip_mc_add1_src(pmc, sfmode, &psfsrc[i]);
@@ -2240,7 +2293,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
int j;
if (!delta)
- pmc->sfcount[sfmode]--;
+ WRITE_ONCE(pmc->sfcount[sfmode], pmc->sfcount[sfmode] - 1);
for (j = 0; j < i; j++)
(void) ip_mc_del1_src(pmc, sfmode, &psfsrc[j]);
} else if (isexclude != (pmc->sfcount[MCAST_EXCLUDE] != 0)) {
@@ -2260,7 +2313,7 @@ static int ip_mc_add_src(struct in_device *in_dev, __be32 *pmca, int sfmode,
pmc->crcount = in_dev->mr_qrv ?: READ_ONCE(net->ipv4.sysctl_igmp_qrv);
WRITE_ONCE(in_dev->mr_ifc_count, pmc->crcount);
- for (psf = pmc->sources; psf; psf = psf->sf_next)
+ for_each_psf_mclock(pmc, psf)
psf->sf_crcount = 0;
igmp_ifc_event(in_dev);
} else if (sf_setstate(pmc)) {
@@ -2276,13 +2329,13 @@ static void ip_mc_clear_src(struct ip_mc_list *pmc)
struct ip_sf_list *tomb, *sources;
spin_lock_bh(&pmc->lock);
- tomb = pmc->tomb;
- pmc->tomb = NULL;
- sources = pmc->sources;
- pmc->sources = NULL;
+ tomb = pmc_dereference(pmc->tomb, pmc);
+ RCU_INIT_POINTER(pmc->tomb, NULL);
+ sources = pmc_dereference(pmc->sources, pmc);
+ RCU_INIT_POINTER(pmc->sources, NULL);
pmc->sfmode = MCAST_EXCLUDE;
- pmc->sfcount[MCAST_INCLUDE] = 0;
- pmc->sfcount[MCAST_EXCLUDE] = 1;
+ WRITE_ONCE(pmc->sfcount[MCAST_INCLUDE], 0);
+ WRITE_ONCE(pmc->sfcount[MCAST_EXCLUDE], 1);
spin_unlock_bh(&pmc->lock);
ip_sf_list_clear_all(tomb);
@@ -2864,20 +2917,19 @@ int ip_check_mc_rcu(struct in_device *in_dev, __be32 mc_addr, __be32 src_addr, u
rv = 1;
} else if (im) {
if (src_addr) {
- spin_lock_bh(&im->lock);
- for (psf = im->sources; psf; psf = psf->sf_next) {
+ for_each_psf_rcu(im, psf) {
if (psf->sf_inaddr == src_addr)
break;
}
if (psf)
- rv = psf->sf_count[MCAST_INCLUDE] ||
- psf->sf_count[MCAST_EXCLUDE] !=
- im->sfcount[MCAST_EXCLUDE];
+ rv = READ_ONCE(psf->sf_count[MCAST_INCLUDE]) ||
+ READ_ONCE(psf->sf_count[MCAST_EXCLUDE]) !=
+ READ_ONCE(im->sfcount[MCAST_EXCLUDE]);
else
- rv = im->sfcount[MCAST_EXCLUDE] != 0;
- spin_unlock_bh(&im->lock);
- } else
+ rv = READ_ONCE(im->sfcount[MCAST_EXCLUDE]) != 0;
+ } else {
rv = 1; /* unspecified source; tentatively allow */
+ }
}
return rv;
}
@@ -3041,7 +3093,7 @@ static inline struct ip_sf_list *igmp_mcf_get_first(struct seq_file *seq)
im = rcu_dereference(idev->mc_list);
if (likely(im)) {
spin_lock_bh(&im->lock);
- psf = im->sources;
+ psf = pmc_dereference(im->sources, im);
if (likely(psf)) {
state->im = im;
state->idev = idev;
@@ -3057,7 +3109,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
{
struct igmp_mcf_iter_state *state = igmp_mcf_seq_private(seq);
- psf = psf->sf_next;
+ psf = pmc_dereference(psf->sf_next, state->im);
while (!psf) {
spin_unlock_bh(&state->im->lock);
state->im = state->im->next;
@@ -3073,7 +3125,7 @@ static struct ip_sf_list *igmp_mcf_get_next(struct seq_file *seq, struct ip_sf_l
state->im = rcu_dereference(state->idev->mc_list);
}
spin_lock_bh(&state->im->lock);
- psf = state->im->sources;
+ psf = pmc_dereference(state->im->sources, state->im);
}
out:
return psf;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 136/733] ppp: ppp_async: simplify tty disc_data access
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (134 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 135/733] igmp: convert struct ip_sf_list to RCU Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 137/733] ppp: ppp_synctty: " Greg Kroah-Hartman
` (608 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+8e808eb853386f575d86,
Qingfang Deng, Eric Dumazet, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <qingfang.deng@linux.dev>
[ Upstream commit 9feb069e5ed03582fbf6272539f1caa2a17dc6d5 ]
tty_ldisc_hangup() invokes the hangup callback while holding only a read
lock on tty->ldisc_sem, so it can run concurrently with other line
discipline callbacks. This currently forces async PPP to maintain
separate lifetime protection around tty->disc_data.
Line discipline close is called under the write lock during hangup
processing. Remove the hangup callback and rely on close for teardown,
as done for SLIP by commit 23c53269f2ba ("slip: remove slip_hangup() to
fix use-after-free in slip_receive_buf()"). This serializes teardown
with all other line discipline operations.
disc_data_lock, refcount and completion are redundant with that
serialization. Remove them and access tty->disc_data directly.
This also eliminates a lockdep warning reported by syzbot. The warning
does not indicate a real deadlock because the write side runs only in
process context with hardirqs disabled.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+8e808eb853386f575d86@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/0000000000002fbad30611e25849@google.com/
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260828073245.126804-1-qingfang.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ppp/ppp_async.c | 82 ++++---------------------------------
1 file changed, 7 insertions(+), 75 deletions(-)
diff --git a/drivers/net/ppp/ppp_async.c b/drivers/net/ppp/ppp_async.c
index a5db4f78b5fc8..6664686b1e041 100644
--- a/drivers/net/ppp/ppp_async.c
+++ b/drivers/net/ppp/ppp_async.c
@@ -65,8 +65,6 @@ struct asyncppp {
struct tasklet_struct tsk;
- refcount_t refcnt;
- struct completion dead;
struct ppp_channel chan; /* interface to generic ppp layer */
unsigned char obuf[OBUFSIZE];
};
@@ -116,38 +114,6 @@ static const struct ppp_channel_ops async_ops = {
* Routines implementing the PPP line discipline.
*/
-/*
- * We have a potential race on dereferencing tty->disc_data,
- * because the tty layer provides no locking at all - thus one
- * cpu could be running ppp_asynctty_receive while another
- * calls ppp_asynctty_close, which zeroes tty->disc_data and
- * frees the memory that ppp_asynctty_receive is using. The best
- * way to fix this is to use a rwlock in the tty struct, but for now
- * we use a single global rwlock for all ttys in ppp line discipline.
- *
- * FIXME: this is no longer true. The _close path for the ldisc is
- * now guaranteed to be sane.
- */
-static DEFINE_RWLOCK(disc_data_lock);
-
-static struct asyncppp *ap_get(struct tty_struct *tty)
-{
- struct asyncppp *ap;
-
- read_lock(&disc_data_lock);
- ap = tty->disc_data;
- if (ap != NULL)
- refcount_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
- return ap;
-}
-
-static void ap_put(struct asyncppp *ap)
-{
- if (refcount_dec_and_test(&ap->refcnt))
- complete(&ap->dead);
-}
-
/*
* Called when a tty is put into PPP line discipline. Called in process
* context.
@@ -182,9 +148,6 @@ ppp_asynctty_open(struct tty_struct *tty)
skb_queue_head_init(&ap->rqueue);
tasklet_setup(&ap->tsk, ppp_async_process);
- refcount_set(&ap->refcnt, 1);
- init_completion(&ap->dead);
-
ap->chan.private = ap;
ap->chan.ops = &async_ops;
ap->chan.mtu = PPP_MRU;
@@ -205,34 +168,18 @@ ppp_asynctty_open(struct tty_struct *tty)
}
/*
- * Called when the tty is put into another line discipline
- * or it hangs up. We have to wait for any cpu currently
- * executing in any of the other ppp_asynctty_* routines to
- * finish before we can call ppp_unregister_channel and free
- * the asyncppp struct. This routine must be called from
- * process context, not interrupt or softirq context.
+ * Called when the tty is put into another line discipline or it hangs up.
+ * This call is serialized against other ldisc functions.
*/
static void
ppp_asynctty_close(struct tty_struct *tty)
{
- struct asyncppp *ap;
+ struct asyncppp *ap = tty->disc_data;
- write_lock_irq(&disc_data_lock);
- ap = tty->disc_data;
- tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
if (!ap)
return;
- /*
- * We have now ensured that nobody can start using ap from now
- * on, but we have to wait for all existing users to finish.
- * Note that ppp_unregister_channel ensures that no calls to
- * our channel ops (i.e. ppp_async_send/ioctl) are in progress
- * by the time it returns.
- */
- if (!refcount_dec_and_test(&ap->refcnt))
- wait_for_completion(&ap->dead);
+ tty->disc_data = NULL;
tasklet_kill(&ap->tsk);
ppp_unregister_channel(&ap->chan);
@@ -242,17 +189,6 @@ ppp_asynctty_close(struct tty_struct *tty)
kfree(ap);
}
-/*
- * Called on tty hangup in process context.
- *
- * Wait for I/O to driver to complete and unregister PPP channel.
- * This is already done by the close routine, so just call that.
- */
-static void ppp_asynctty_hangup(struct tty_struct *tty)
-{
- ppp_asynctty_close(tty);
-}
-
/*
* Read does nothing - no data is ever available this way.
* Pppd reads and writes packets via /dev/ppp instead.
@@ -283,7 +219,7 @@ ppp_asynctty_write(struct tty_struct *tty, struct file *file, const u8 *buf,
static int
ppp_asynctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
{
- struct asyncppp *ap = ap_get(tty);
+ struct asyncppp *ap = tty->disc_data;
int err, val;
int __user *p = (int __user *)arg;
@@ -324,7 +260,6 @@ ppp_asynctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
err = tty_mode_ioctl(tty, cmd, arg);
}
- ap_put(ap);
return err;
}
@@ -333,7 +268,7 @@ static void
ppp_asynctty_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags,
size_t count)
{
- struct asyncppp *ap = ap_get(tty);
+ struct asyncppp *ap = tty->disc_data;
unsigned long flags;
if (!ap)
@@ -343,21 +278,19 @@ ppp_asynctty_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags,
spin_unlock_irqrestore(&ap->recv_lock, flags);
if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
- ap_put(ap);
tty_unthrottle(tty);
}
static void
ppp_asynctty_wakeup(struct tty_struct *tty)
{
- struct asyncppp *ap = ap_get(tty);
+ struct asyncppp *ap = tty->disc_data;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
if (!ap)
return;
set_bit(XMIT_WAKEUP, &ap->xmit_flags);
tasklet_schedule(&ap->tsk);
- ap_put(ap);
}
@@ -367,7 +300,6 @@ static struct tty_ldisc_ops ppp_ldisc = {
.name = "ppp",
.open = ppp_asynctty_open,
.close = ppp_asynctty_close,
- .hangup = ppp_asynctty_hangup,
.read = ppp_asynctty_read,
.write = ppp_asynctty_write,
.ioctl = ppp_asynctty_ioctl,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 137/733] ppp: ppp_synctty: simplify tty disc_data access
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (135 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 136/733] ppp: ppp_async: simplify tty disc_data access Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 138/733] klp-build: Fix wrong index in funcs cleanup error path Greg Kroah-Hartman
` (607 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+b503105c2410c3433459,
Qingfang Deng, Eric Dumazet, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <qingfang.deng@linux.dev>
[ Upstream commit d8d4d1cf40d541a5d7cc3b15d57e42d0815c7d53 ]
Apply the same simplification as the preceding ppp_async change.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: syzbot+b503105c2410c3433459@syzkaller.appspotmail.com
Closes: https://syzbot.org/bug?extid=b503105c2410c3433459
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260828073245.126804-2-qingfang.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ppp/ppp_synctty.c | 83 +++--------------------------------
1 file changed, 7 insertions(+), 76 deletions(-)
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c
index b7f243b416f82..0208e752ef1eb 100644
--- a/drivers/net/ppp/ppp_synctty.c
+++ b/drivers/net/ppp/ppp_synctty.c
@@ -38,11 +38,9 @@
#include <linux/ppp-ioctl.h>
#include <linux/ppp_channel.h>
#include <linux/spinlock.h>
-#include <linux/completion.h>
#include <linux/init.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
-#include <linux/refcount.h>
#include <linux/unaligned.h>
#include <linux/uaccess.h>
@@ -69,8 +67,6 @@ struct syncppp {
struct tasklet_struct tsk;
- refcount_t refcnt;
- struct completion dead_cmp;
struct ppp_channel chan; /* interface to generic ppp layer */
};
@@ -118,37 +114,6 @@ ppp_print_buffer (const char *name, const __u8 *buf, int count)
* Routines implementing the synchronous PPP line discipline.
*/
-/*
- * We have a potential race on dereferencing tty->disc_data,
- * because the tty layer provides no locking at all - thus one
- * cpu could be running ppp_synctty_receive while another
- * calls ppp_synctty_close, which zeroes tty->disc_data and
- * frees the memory that ppp_synctty_receive is using. The best
- * way to fix this is to use a rwlock in the tty struct, but for now
- * we use a single global rwlock for all ttys in ppp line discipline.
- *
- * FIXME: Fixed in tty_io nowadays.
- */
-static DEFINE_RWLOCK(disc_data_lock);
-
-static struct syncppp *sp_get(struct tty_struct *tty)
-{
- struct syncppp *ap;
-
- read_lock(&disc_data_lock);
- ap = tty->disc_data;
- if (ap != NULL)
- refcount_inc(&ap->refcnt);
- read_unlock(&disc_data_lock);
- return ap;
-}
-
-static void sp_put(struct syncppp *ap)
-{
- if (refcount_dec_and_test(&ap->refcnt))
- complete(&ap->dead_cmp);
-}
-
/*
* Called when a tty is put into sync-PPP line discipline.
*/
@@ -179,9 +144,6 @@ ppp_sync_open(struct tty_struct *tty)
skb_queue_head_init(&ap->rqueue);
tasklet_setup(&ap->tsk, ppp_sync_process);
- refcount_set(&ap->refcnt, 1);
- init_completion(&ap->dead_cmp);
-
ap->chan.private = ap;
ap->chan.ops = &sync_ops;
ap->chan.mtu = PPP_MRU;
@@ -203,34 +165,18 @@ ppp_sync_open(struct tty_struct *tty)
}
/*
- * Called when the tty is put into another line discipline
- * or it hangs up. We have to wait for any cpu currently
- * executing in any of the other ppp_synctty_* routines to
- * finish before we can call ppp_unregister_channel and free
- * the syncppp struct. This routine must be called from
- * process context, not interrupt or softirq context.
+ * Called when the tty is put into another line discipline or it hangs up.
+ * This call is serialized against other ldisc functions.
*/
static void
ppp_sync_close(struct tty_struct *tty)
{
- struct syncppp *ap;
+ struct syncppp *ap = tty->disc_data;
- write_lock_irq(&disc_data_lock);
- ap = tty->disc_data;
- tty->disc_data = NULL;
- write_unlock_irq(&disc_data_lock);
if (!ap)
return;
- /*
- * We have now ensured that nobody can start using ap from now
- * on, but we have to wait for all existing users to finish.
- * Note that ppp_unregister_channel ensures that no calls to
- * our channel ops (i.e. ppp_sync_send/ioctl) are in progress
- * by the time it returns.
- */
- if (!refcount_dec_and_test(&ap->refcnt))
- wait_for_completion(&ap->dead_cmp);
+ tty->disc_data = NULL;
tasklet_kill(&ap->tsk);
ppp_unregister_channel(&ap->chan);
@@ -239,17 +185,6 @@ ppp_sync_close(struct tty_struct *tty)
kfree(ap);
}
-/*
- * Called on tty hangup in process context.
- *
- * Wait for I/O to driver to complete and unregister PPP channel.
- * This is already done by the close routine, so just call that.
- */
-static void ppp_sync_hangup(struct tty_struct *tty)
-{
- ppp_sync_close(tty);
-}
-
/*
* Read does nothing - no data is ever available this way.
* Pppd reads and writes packets via /dev/ppp instead.
@@ -275,7 +210,7 @@ ppp_sync_write(struct tty_struct *tty, struct file *file, const u8 *buf,
static int
ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
{
- struct syncppp *ap = sp_get(tty);
+ struct syncppp *ap = tty->disc_data;
int __user *p = (int __user *)arg;
int err, val;
@@ -316,7 +251,6 @@ ppp_synctty_ioctl(struct tty_struct *tty, unsigned int cmd, unsigned long arg)
break;
}
- sp_put(ap);
return err;
}
@@ -325,7 +259,7 @@ static void
ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags,
size_t count)
{
- struct syncppp *ap = sp_get(tty);
+ struct syncppp *ap = tty->disc_data;
unsigned long flags;
if (!ap)
@@ -335,21 +269,19 @@ ppp_sync_receive(struct tty_struct *tty, const u8 *buf, const u8 *cflags,
spin_unlock_irqrestore(&ap->recv_lock, flags);
if (!skb_queue_empty(&ap->rqueue))
tasklet_schedule(&ap->tsk);
- sp_put(ap);
tty_unthrottle(tty);
}
static void
ppp_sync_wakeup(struct tty_struct *tty)
{
- struct syncppp *ap = sp_get(tty);
+ struct syncppp *ap = tty->disc_data;
clear_bit(TTY_DO_WRITE_WAKEUP, &tty->flags);
if (!ap)
return;
set_bit(XMIT_WAKEUP, &ap->xmit_flags);
tasklet_schedule(&ap->tsk);
- sp_put(ap);
}
@@ -359,7 +291,6 @@ static struct tty_ldisc_ops ppp_sync_ldisc = {
.name = "pppsync",
.open = ppp_sync_open,
.close = ppp_sync_close,
- .hangup = ppp_sync_hangup,
.read = ppp_sync_read,
.write = ppp_sync_write,
.ioctl = ppp_synctty_ioctl,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 138/733] klp-build: Fix wrong index in funcs cleanup error path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (136 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 137/733] ppp: ppp_synctty: " Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 139/733] objtool/klp: Fix checksums for constant pool references Greg Kroah-Hartman
` (606 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yafang Shao, Song Liu, Petr Mladek,
Miroslav Benes, Josh Poimboeuf, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yafang Shao <laoar.shao@gmail.com>
[ Upstream commit 4825ef699cda4c6f2f0586b17a5e225560481da6 ]
In the object allocation loop, when kzalloc() for funcs fails, the
cleanup loop uses `objs[i].funcs` instead of `objs[j].funcs`. Since
`objs[i].funcs` is still NULL at that point, it repeatedly calls
kfree(NULL) and leaks all previously allocated funcs arrays.
Fixes: 59adee07b568 ("livepatch/klp-build: Add stub init code for livepatch modules")
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Acked-by: Song Liu <song@kernel.org>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Acked-by: Miroslav Benes <mbenes@suse.cz>
Link: https://patch.msgid.link/20260816090442.18128-2-laoar.shao@gmail.com
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
scripts/livepatch/init.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/livepatch/init.c b/scripts/livepatch/init.c
index f14d8c8fb35fa..16aff8f736eb6 100644
--- a/scripts/livepatch/init.c
+++ b/scripts/livepatch/init.c
@@ -51,7 +51,7 @@ static int __init livepatch_mod_init(void)
if (!funcs) {
ret = -ENOMEM;
for (int j = 0; j < i; j++)
- kfree(objs[i].funcs);
+ kfree(objs[j].funcs);
goto err_free_objs;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 139/733] objtool/klp: Fix checksums for constant pool references
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (137 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 138/733] klp-build: Fix wrong index in funcs cleanup error path Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 140/733] ipv6: mcast: fix RCU list diversion in ip6_mc_del1_src() Greg Kroah-Hartman
` (605 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Josh Poimboeuf, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf <jpoimboe@kernel.org>
[ Upstream commit ac323c9467092479dc1e5bc138c9abbe015b0069 ]
Adding a line of code to __link_shadow_page() with a literal string
causes a false positive changed function with GCC:
arch/x86/kvm/kvm.ko.o: changed function: kvm_tdp_mmu_map_private_pfn
While the patch only touched __link_shadow_page(), the string addition
triggered a rename of .LC64 -> .LC65 in kvm_tdp_mmu_map_private_pfn()
even though the underlying referenced constant data didn't change.
So for .LC* symbols, the suffix is arbitrary but the data isn't. Add
the underlying data to the checksum calculation rather than the symbol
name.
Clang also uses .LC* symbols, but also uses anonymous data. Both
compilers put this data in .rodata.cst<num> sections.
Fixes: 0d83da43b1e1 ("objtool/klp: Add --checksum option to generate per-function checksums")
Link: https://patch.msgid.link/f3a9e74ceebc6475ce94bcfe985401140857814a.1787939301.git.jpoimboe@kernel.org
Signed-off-by: Josh Poimboeuf <jpoimboe@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/objtool/klp-checksum.c | 21 +++++++++++++++++++++
1 file changed, 21 insertions(+)
diff --git a/tools/objtool/klp-checksum.c b/tools/objtool/klp-checksum.c
index b8e47f28997e9..ebe25f9c5260a 100644
--- a/tools/objtool/klp-checksum.c
+++ b/tools/objtool/klp-checksum.c
@@ -54,6 +54,19 @@ static int checksum_debug_init(struct objtool_file *file)
return 0;
}
+/*
+ * Detect a reference to anonymous constant pool data which the compiler places
+ * in .rodata.cst<num> and which either has an .LC<num> symbol associated with
+ * it or (with Clang) no symbol at all. These are typically initializers for
+ * local function stack data, so they're considered part of the function rather
+ * than data per se.
+ */
+static bool is_anonymous_const_data(struct symbol *sym)
+{
+ return strstarts(sym->sec->name, ".rodata.cst") &&
+ (is_sec_sym(sym) || strstarts(sym->name, ".LC"));
+}
+
static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
struct instruction *insn)
{
@@ -129,6 +142,14 @@ static void checksum_update_insn(struct objtool_file *file, struct symbol *func,
goto alts;
}
+ if (is_anonymous_const_data(sym)) {
+ void *cst;
+
+ cst = sym->sec->data->d_buf + sym->offset + offset;
+ __checksum_update_insn(func, insn, cst, sym->sec->sh.sh_entsize);
+ goto alts;
+ }
+
if (is_sec_sym(sym)) {
sym = find_symbol_containing(reloc->sym->sec, offset);
if (!sym)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 140/733] ipv6: mcast: fix RCU list diversion in ip6_mc_del1_src()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (138 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 139/733] objtool/klp: Fix checksums for constant pool references Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 141/733] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
` (604 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Taehee Yoo,
Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 93b49239840b91313adbd77b8b52993eff2d08c1 ]
When removing a source filter whose count reaches zero, ip6_mc_del1_src()
unlinks psf from pmc->mca_sources. If the filter was previously active,
the code moved psf directly into pmc->mca_tomb by updating psf->sf_next.
Because pmc->mca_sources is traversed locklessly under RCU (e.g. by
ipv6_chk_mcast_addr()), mutating psf->sf_next before a grace period
elapses diverts concurrent readers to the tombstone list. Consequently,
readers miss remaining active sources in pmc->mca_sources and improperly
examine deleted tombstone entries.
Fix this by allocating a new tombstone node for pmc->mca_tomb (as done
in sf_setstate()) and retiring the original psf via kfree_rcu().
Fixes: 4b200e398953 ("mld: convert ip6_sf_list to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/mcast.c | 18 +++++++++++-------
1 file changed, 11 insertions(+), 7 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 4d2b9377ba2de..54acc9d4cae03 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2350,14 +2350,18 @@ static int ip6_mc_del1_src(struct ifmcaddr6 *pmc, int sfmode,
if (psf->sf_oldin && !(pmc->mca_flags & MAF_NOREPORT) &&
!mld_in_v1_mode(idev)) {
- psf->sf_crcount = idev->mc_qrv;
- rcu_assign_pointer(psf->sf_next,
- mc_dereference(pmc->mca_tomb, idev));
- rcu_assign_pointer(pmc->mca_tomb, psf);
- rv = 1;
- } else {
- kfree_rcu(psf, rcu);
+ struct ip6_sf_list *dpsf = kmalloc_obj(*dpsf);
+
+ if (dpsf) {
+ *dpsf = *psf;
+ dpsf->sf_crcount = idev->mc_qrv;
+ rcu_assign_pointer(dpsf->sf_next,
+ mc_dereference(pmc->mca_tomb, idev));
+ rcu_assign_pointer(pmc->mca_tomb, dpsf);
+ rv = 1;
+ }
}
+ kfree_rcu(psf, rcu);
}
return rv;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 141/733] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (139 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 140/733] ipv6: mcast: fix RCU list diversion in ip6_mc_del1_src() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 142/733] ipv6: mcast: fix delay calculation in igmp6_join_group() Greg Kroah-Hartman
` (603 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Taehee Yoo,
Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit c073d1b070f171d206b19c98d71739a97f15b3f1 ]
pmc->sflist is read locklessly under rcu_read_lock() by
inet6_mc_check() during packet reception in the UDP and RAW
multicast receive paths.
ip6_mc_source() mutated psl->sl_addr and psl->sl_count in-place
when adding or removing a source filter. Additionally, when expanding
the filter buffer, newpsl was published via rcu_assign_pointer()
before writing the new source into the array.
Because 16-byte struct in6_addr writes are not atomic and array
shifting is not synchronized with RCU readers, concurrent readers in
inet6_mc_check() could read torn IPv6 addresses or observe
duplicated/missed source entries.
Fix this by switching ip6_mc_source() to copy-on-write RCU updates:
allocate and fully populate newpsl before publishing it via
rcu_assign_pointer(), and reclaim the old filter via kfree_rcu(),
matching ip6_mc_msfilter().
Also remove the now unused IP6_SFBLOCK macro.
Fixes: 882ba1f73c06 ("mld: convert ipv6_mc_socklist->sflist to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-3-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/if_inet6.h | 2 -
net/ipv6/mcast.c | 98 ++++++++++++++++++++++++------------------
2 files changed, 56 insertions(+), 44 deletions(-)
diff --git a/include/net/if_inet6.h b/include/net/if_inet6.h
index 238ad3349456a..795fb41b45f5d 100644
--- a/include/net/if_inet6.h
+++ b/include/net/if_inet6.h
@@ -88,8 +88,6 @@ struct ip6_sf_socklist {
struct in6_addr sl_addr[] __counted_by(sl_max);
};
-#define IP6_SFBLOCK 10 /* allocate this many at once */
-
struct ipv6_mc_socklist {
struct in6_addr addr;
int ifindex;
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 54acc9d4cae03..3ff7c1c1bf4f8 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -355,12 +355,12 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
{
struct ipv6_pinfo *inet6 = inet6_sk(sk);
struct in6_addr *source, *group;
+ struct ip6_sf_socklist *newpsl, *psl;
struct net *net = sock_net(sk);
struct ipv6_mc_socklist *pmc;
- struct ip6_sf_socklist *psl;
struct inet6_dev *idev;
int leavegroup = 0;
- int i, j, rv;
+ int i, j;
int err;
source = &((struct sockaddr_in6 *)&pgsr->gsr_source)->sin6_addr;
@@ -409,13 +409,11 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
if (!add) {
if (!psl)
goto done; /* err = -EADDRNOTAVAIL */
- rv = !0;
for (i = 0; i < psl->sl_count; i++) {
- rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
- if (rv == 0)
+ if (ipv6_addr_equal(&psl->sl_addr[i], source))
break;
}
- if (rv) /* source not found */
+ if (i == psl->sl_count) /* source not found */
goto done; /* err = -EADDRNOTAVAIL */
/* special case - (INCLUDE, empty) == LEAVE_GROUP */
@@ -424,58 +422,74 @@ int ip6_mc_source(int add, int omode, struct sock *sk,
goto done;
}
+ atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+ &sk->sk_omem_alloc);
+
+ if (psl->sl_count == 1) {
+ newpsl = NULL;
+ } else {
+ newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr,
+ psl->sl_count - 1),
+ GFP_KERNEL);
+ if (!newpsl) {
+ atomic_add(struct_size(psl, sl_addr, psl->sl_max),
+ &sk->sk_omem_alloc);
+ err = -ENOBUFS;
+ goto done;
+ }
+ newpsl->sl_max = psl->sl_count - 1;
+ newpsl->sl_count = psl->sl_count - 1;
+ for (j = 0; j < i; j++)
+ newpsl->sl_addr[j] = psl->sl_addr[j];
+ for (j = i + 1; j < psl->sl_count; j++)
+ newpsl->sl_addr[j - 1] = psl->sl_addr[j];
+ }
+
/* update the interface filter */
ip6_mc_del_src(idev, group, omode, 1, source, 1);
- for (j = i+1; j < psl->sl_count; j++)
- psl->sl_addr[j-1] = psl->sl_addr[j];
- psl->sl_count--;
+ rcu_assign_pointer(pmc->sflist, newpsl);
+ kfree_rcu(psl, rcu);
err = 0;
goto done;
}
/* else, add a new source to the filter */
- if (psl && psl->sl_count >= sysctl_mld_max_msf) {
+ if (psl && psl->sl_count >= READ_ONCE(sysctl_mld_max_msf)) {
err = -ENOBUFS;
goto done;
}
- if (!psl || psl->sl_count == psl->sl_max) {
- struct ip6_sf_socklist *newpsl;
- int count = IP6_SFBLOCK;
-
- if (psl)
- count += psl->sl_max;
- newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, count),
- GFP_KERNEL);
- if (!newpsl) {
- err = -ENOBUFS;
- goto done;
- }
- newpsl->sl_max = count;
- newpsl->sl_count = count - IP6_SFBLOCK;
- if (psl) {
- for (i = 0; i < psl->sl_count; i++)
- newpsl->sl_addr[i] = psl->sl_addr[i];
- atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
- &sk->sk_omem_alloc);
+ if (psl) {
+ for (i = 0; i < psl->sl_count; i++) {
+ if (ipv6_addr_equal(&psl->sl_addr[i], source))
+ goto done; /* err = -EADDRNOTAVAIL */
}
- rcu_assign_pointer(pmc->sflist, newpsl);
- kfree_rcu(psl, rcu);
- psl = newpsl;
}
- rv = 1; /* > 0 for insert logic below if sl_count is 0 */
- for (i = 0; i < psl->sl_count; i++) {
- rv = !ipv6_addr_equal(&psl->sl_addr[i], source);
- if (rv == 0) /* There is an error in the address. */
- goto done;
+
+ i = psl ? psl->sl_count + 1 : 1;
+ newpsl = sock_kmalloc(sk, struct_size(newpsl, sl_addr, i),
+ GFP_KERNEL);
+ if (!newpsl) {
+ err = -ENOBUFS;
+ goto done;
}
- for (j = psl->sl_count-1; j >= i; j--)
- psl->sl_addr[j+1] = psl->sl_addr[j];
- psl->sl_addr[i] = *source;
- psl->sl_count++;
- err = 0;
+ newpsl->sl_max = i;
+ newpsl->sl_count = i;
+ if (psl) {
+ for (j = 0; j < psl->sl_count; j++)
+ newpsl->sl_addr[j] = psl->sl_addr[j];
+ }
+ newpsl->sl_addr[i - 1] = *source;
+
/* update the interface list */
ip6_mc_add_src(idev, group, omode, 1, source, 1);
+
+ if (psl)
+ atomic_sub(struct_size(psl, sl_addr, psl->sl_max),
+ &sk->sk_omem_alloc);
+ rcu_assign_pointer(pmc->sflist, newpsl);
+ kfree_rcu(psl, rcu);
+ err = 0;
done:
mutex_unlock(&idev->mc_lock);
in6_dev_put(idev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 142/733] ipv6: mcast: fix delay calculation in igmp6_join_group()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (140 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 141/733] ipv6: mcast: use copy-on-write RCU updates in ip6_mc_source() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 143/733] ipv6: mcast: use rcu_assign_pointer() for __rcu list updates Greg Kroah-Hartman
` (602 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Taehee Yoo,
Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 75fa9caeb8aaba19c2463dee0b0a1e09d39c04af ]
When joining a multicast group, if a report work is already pending
(e.g. scheduled by a query or a previous join), igmp6_join_group()
cancels the delayed work and recalculates the delay:
if (cancel_delayed_work(&ma->mca_work)) {
refcount_dec(&ma->mca_refcnt);
delay = ma->mca_work.timer.expires - jiffies;
}
Unlike igmp6_group_queried(), igmp6_join_group() did not check
if delay >= interval. This leads to two issues:
1. If the timer has already expired (timer.expires <= jiffies), the
stale expiry is reused by mod_delayed_work(), causing the second
unsolicited report to fire on the very next tick without a
randomized delay.
2. If the timer was originally armed by a query with a large
maximum response delay, delay could exceed
unsolicited_report_interval(ma->idev).
Fix this by initializing delay to unsolicited_report_interval(ma->idev)
and re-randomizing it with get_random_u32_below(interval) when
delay >= interval, mirroring the logic in igmp6_group_queried().
Fixes: 2d9a93b4902b ("mld: convert from timer to delayed work")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Link: https://patch.msgid.link/20260828084531.1826790-4-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/mcast.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 3ff7c1c1bf4f8..62c9a1c08b9a2 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -2638,7 +2638,7 @@ static void ip6_mc_clear_src(struct ifmcaddr6 *pmc)
static void igmp6_join_group(struct ifmcaddr6 *ma)
{
- unsigned long delay;
+ unsigned long delay, interval;
mc_assert_locked(ma->idev);
@@ -2647,13 +2647,17 @@ static void igmp6_join_group(struct ifmcaddr6 *ma)
igmp6_send(&ma->mca_addr, ma->idev->dev, ICMPV6_MGM_REPORT);
- delay = get_random_u32_below(unsolicited_report_interval(ma->idev));
+ interval = unsolicited_report_interval(ma->idev);
+ delay = interval;
if (cancel_delayed_work(&ma->mca_work)) {
refcount_dec(&ma->mca_refcnt);
delay = ma->mca_work.timer.expires - jiffies;
}
+ if (delay >= interval)
+ delay = get_random_u32_below(interval);
+
if (!mod_delayed_work(mld_wq, &ma->mca_work, delay))
refcount_inc(&ma->mca_refcnt);
WRITE_ONCE(ma->mca_flags, ma->mca_flags |
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 143/733] ipv6: mcast: use rcu_assign_pointer() for __rcu list updates
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (141 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 142/733] ipv6: mcast: fix delay calculation in igmp6_join_group() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 144/733] ipv6: mcast: use jiffies_delta_to_clock_t() in igmp6_mc_seq_show() Greg Kroah-Hartman
` (601 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Taehee Yoo,
Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 0c8f56c583c3250408367880c98e4d6fbc929315 ]
Several places in net/ipv6/mcast.c update RCU-protected lists
(np->ipv6_mc_list, idev->mc_list, idev->mc_tomb) using direct pointer
assignments instead of rcu_assign_pointer():
1. In __ipv6_dev_mc_dec(), unlinking a group from idev->mc_list did:
*map = ma->next;
without rcu_assign_pointer() while concurrent readers traverse
idev->mc_list locklessly under rcu_read_lock().
2. In ipv6_sock_mc_drop() and __ipv6_sock_mc_close(), unlinking a group
from np->ipv6_mc_list directly assigned *lnk = mc_lst->next and
np->ipv6_mc_list = mc_lst->next without rcu_assign_pointer(), racing
with lockless readers in inet6_mc_check().
3. In __ipv6_sock_mc_join(), mc_lst->next was initialized to
np->ipv6_mc_list via raw assignment before publishing mc_lst.
4. In mld_del_delrec() and __ipv6_dev_mc_inc(), __rcu source pointers
passed into rcu_assign_pointer() lacked explicit dereference helpers.
Fix these by consistently using rcu_assign_pointer() along with
mc_dereference() / sock_dereference().
Fixes: 456b61bca8ee ("ipv6: mcast: RCU conversion")
Fixes: 88e2ca308094 ("mld: convert ifmcaddr6 to RCU")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Taehee Yoo <ap420073@gmail.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-5-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/mcast.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index 62c9a1c08b9a2..d5db3b449cd08 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -240,7 +240,8 @@ static int __ipv6_sock_mc_join(struct sock *sk, int ifindex,
return err;
}
- mc_lst->next = np->ipv6_mc_list;
+ rcu_assign_pointer(mc_lst->next,
+ sock_dereference(np->ipv6_mc_list, sk));
rcu_assign_pointer(np->ipv6_mc_list, mc_lst);
return 0;
@@ -300,7 +301,8 @@ int ipv6_sock_mc_drop(struct sock *sk, int ifindex, const struct in6_addr *addr)
lnk = &mc_lst->next) {
if ((ifindex == 0 || mc_lst->ifindex == ifindex) &&
ipv6_addr_equal(&mc_lst->addr, addr)) {
- *lnk = mc_lst->next;
+ rcu_assign_pointer(*lnk,
+ sock_dereference(mc_lst->next, sk));
__ipv6_sock_mc_drop(sk, mc_lst);
return 0;
}
@@ -333,7 +335,8 @@ void __ipv6_sock_mc_close(struct sock *sk)
struct ipv6_mc_socklist *mc_lst;
while ((mc_lst = sock_dereference(np->ipv6_mc_list, sk)) != NULL) {
- np->ipv6_mc_list = mc_lst->next;
+ rcu_assign_pointer(np->ipv6_mc_list,
+ sock_dereference(mc_lst->next, sk));
__ipv6_sock_mc_drop(sk, mc_lst);
}
}
@@ -798,9 +801,11 @@ static void mld_del_delrec(struct inet6_dev *idev, struct ifmcaddr6 *im)
if (!pmc)
return;
if (pmc_prev)
- rcu_assign_pointer(pmc_prev->next, pmc->next);
+ rcu_assign_pointer(pmc_prev->next,
+ mc_dereference(pmc->next, idev));
else
- rcu_assign_pointer(idev->mc_tomb, pmc->next);
+ rcu_assign_pointer(idev->mc_tomb,
+ mc_dereference(pmc->next, idev));
im->idev = pmc->idev;
if (im->mca_sfmode == MCAST_INCLUDE) {
@@ -979,7 +984,7 @@ static int __ipv6_dev_mc_inc(struct net_device *dev,
return -ENOMEM;
}
- rcu_assign_pointer(mc->next, idev->mc_list);
+ rcu_assign_pointer(mc->next, mc_dereference(idev->mc_list, idev));
rcu_assign_pointer(idev->mc_list, mc);
mld_del_delrec(idev, mc);
@@ -1013,7 +1018,8 @@ int __ipv6_dev_mc_dec(struct inet6_dev *idev, const struct in6_addr *addr)
WRITE_ONCE(ma->mca_users, new_users);
if (new_users == 0) {
- *map = ma->next;
+ rcu_assign_pointer(*map,
+ mc_dereference(ma->next, idev));
igmp6_group_dropped(ma);
inet6_ifmcaddr_notify(idev->dev, ma,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 144/733] ipv6: mcast: use jiffies_delta_to_clock_t() in igmp6_mc_seq_show()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (142 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 143/733] ipv6: mcast: use rcu_assign_pointer() for __rcu list updates Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 145/733] ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit Greg Kroah-Hartman
` (600 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Ido Schimmel,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit b4cf4a092a7bdaa62acca39c28f386b6d1674968 ]
If a multicast group timer has expired but the delayed work has
not yet run to clear MAF_TIMER_RUNNING, expires - jiffies produces
a negative value.
Because unsigned arithmetic was used with jiffies_to_clock_t(),
expires - jiffies underflows to a huge value and reports invalid
timer durations in /proc/net/igmp6.
Use jiffies_delta_to_clock_t() with a signed long delta to properly
cap expired deltas to 0, matching IPv4 igmp_mc_seq_show() and commit
a399a8053164 ("time: jiffies_delta_to_clock_t() helper to the rescue").
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828084531.1826790-6-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/mcast.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/mcast.c b/net/ipv6/mcast.c
index d5db3b449cd08..fad53a5cdfffb 100644
--- a/net/ipv6/mcast.c
+++ b/net/ipv6/mcast.c
@@ -3028,7 +3028,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
struct ifmcaddr6 *im = (struct ifmcaddr6 *)v;
struct igmp6_mc_iter_state *state = igmp6_mc_seq_private(seq);
unsigned int mca_flags = READ_ONCE(im->mca_flags);
- unsigned long expires = READ_ONCE(im->mca_work.timer.expires);
+ long delta = READ_ONCE(im->mca_work.timer.expires) - jiffies;
seq_printf(seq,
"%-4d %-15s %pi6 %5d %08X %ld\n",
@@ -3036,7 +3036,7 @@ static int igmp6_mc_seq_show(struct seq_file *seq, void *v)
&im->mca_addr,
READ_ONCE(im->mca_users), mca_flags,
(mca_flags & MAF_TIMER_RUNNING) ?
- jiffies_to_clock_t(expires - jiffies) : 0);
+ jiffies_delta_to_clock_t(delta) : 0);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 145/733] ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (143 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 144/733] ipv6: mcast: use jiffies_delta_to_clock_t() in igmp6_mc_seq_show() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 146/733] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Greg Kroah-Hartman
` (599 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shuangpeng Bai, Davide Caratti,
Eric Dumazet, Ido Schimmel, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 97cc84dad1d7f68a36b71b69b361d88482707673 ]
Shuangpeng Bai reported a KASAN slab-use-after-free in
ip6gre_tunnel_xmit().
The precise KASAN bug was caused by ip6_tnl_xmit() consuming the
skb during headroom expansion and returning an error, while
ip6gre_tunnel_xmit() still held the stale pointer and called
skb_tunnel_info_txcheck(skb) at tx_err. That specific bug was fixed by
commit 87f21b59ddc6 ("ip6_tunnel: use skb_cow_head() in ip6_tnl_xmit()").
However, calling skb_tunnel_info_txcheck(skb) at the tx_err label
after the transmission attempt remains problematic:
Downstream helpers like ip6_tnl_xmit() call skb_scrub_packet(),
which drops the skb's metadata_dst before transmission. If an error
occurs later during transmit, inspecting skb at tx_err sees a scrubbed
dst and misclassifies tx_errors vs tx_dropped.
Commit e5f7e211b6aa ("ip6gre: avoid tx_error when sending MLD/DAD on
external tunnels") already handled this correctly in
ip6erspan_tunnel_xmit() by checking and caching tun_info before
transmit.
Align ip6gre_tunnel_xmit() with ip6erspan_tunnel_xmit() by caching
tun_info before xmit and checking it at tx_err.
Fixes: e5f7e211b6aa ("ip6gre: avoid tx_error when sending MLD/DAD on external tunnels")
Reported-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Closes: https://lore.kernel.org/netdev/20260819062224.3197349-1-shuangpeng.kernel@gmail.com/
Cc: Davide Caratti <dcaratti@redhat.com>
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828103731.1951815-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ip6_gre.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 200d0ba1a40e7..678678fcb5da3 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -878,6 +878,7 @@ static int ip6gre_xmit_other(struct sk_buff *skb, struct net_device *dev)
static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
struct net_device *dev)
{
+ struct ip_tunnel_info *tun_info = NULL;
struct ip6_tnl *t = netdev_priv(dev);
__be16 payload_protocol;
int ret;
@@ -888,6 +889,9 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
if (!ip6_tnl_xmit_ctl(t, &t->parms.laddr, &t->parms.raddr))
goto tx_err;
+ if (t->parms.collect_md)
+ tun_info = skb_tunnel_info_txcheck(skb);
+
payload_protocol = skb_protocol(skb, true);
switch (payload_protocol) {
case htons(ETH_P_IP):
@@ -907,7 +911,7 @@ static netdev_tx_t ip6gre_tunnel_xmit(struct sk_buff *skb,
return NETDEV_TX_OK;
tx_err:
- if (!t->parms.collect_md || !IS_ERR(skb_tunnel_info_txcheck(skb)))
+ if (!IS_ERR(tun_info))
DEV_STATS_INC(dev, tx_errors);
DEV_STATS_INC(dev, tx_dropped);
kfree_skb(skb);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 146/733] tipc: fix NULL deref in tipc_named_node_up() on empty publication list
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (144 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 145/733] ip6_gre: check tunnel info before xmit in ip6gre_tunnel_xmit Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 147/733] tipc: Dont send random pad bytes in RESET/ACTIVATE messages Greg Kroah-Hartman
` (598 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi, Tung Nguyen,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tung Nguyen <tung.quang.nguyen@est.tech>
[ Upstream commit b3b76e9f4f2476f1135b2ba7743a821db4a0df4b ]
User-space applications can bind a large number of service addresses to
one or more sockets. Each binding of a local-scope service address inserts
one entry (publication) into the TIPC name table. If the number of these
publications exceeds TIPC_MAX_PUBL (65535), protocol service types
(such as node state and link state) are no longer inserted into the name
table. This causes two issues:
1. User-space applications subscribing to node or link up/down events
stop receiving notifications.
2. A NULL pointer dereference can occur:
BUG: kernel NULL pointer dereference, address: 00000000000000d0
...
CPU: 0 UID: 0 PID: 0 Comm: swapper/0 Not tainted 7.2.0-rc4-default+ #5 PREEMPT(full)
...
RIP: 0010:tipc_named_node_up (./include/linux/skbuff.h:2251 net/tipc/name_distr.c:195 net/tipc/name_distr.c:221)
...
Call Trace:
<IRQ>
tipc_node_write_unlock (net/tipc/node.c:428)
tipc_rcv (net/tipc/node.c:934 net/tipc/node.c:2189)
tipc_udp_recv (net/tipc/udp_media.c:389)
Thread 1 (tipc_net_finalize) | Thread 2 (named_distribute)
-----------------------------|-----------------------------
| ...
| list_for_each_entry(publ, pls, binding_node) {
| ...
| __skb_queue_tail(list, skb);
| ...
| }
| ...
| hdr = buf_msg(skb_peek_tail(list));
... |
tipc_nametbl_publish(); |
If 'tipc_nametbl_publish()' (Thread 1) fails because the number of
local publications reaches TIPC_MAX_PUBL, list (Thread 2) will be empty. As a
result, NULL is passed to 'buf_msg()', leading to a NULL pointer dereference.
Fix these issues by allowing protocol service types (node state, link state,
and topology server) to be inserted into the name table unconditionally.
This ensures that users subscribing to these types always receive
notifications. In addition, the maximum number of local user publications is
reduced to (TIPC_MAX_PUBL - 1). This ensures that the maximum bulk size
calculated in tipc_link_set_queue_limits() remains valid.
Fixes: a5e7ac5ce134 ("tipc: fix regression bug where node events are not being generated")
Reported-by: Xiang Mei <xmei5@asu.edu>
Tested-by: Weiming Shi <bestswngs@gmail.com>
Signed-off-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20260827111418.164957-1-tung.quang.nguyen@est.tech
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/tipc/name_table.c | 30 ++++++++++++++++++++++++++----
1 file changed, 26 insertions(+), 4 deletions(-)
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 253c72d1366eb..6fda36ab17669 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -763,21 +763,40 @@ struct publication *tipc_nametbl_publish(struct net *net, struct tipc_uaddr *ua,
struct tipc_socket_addr *sk, u32 key)
{
struct name_table *nt = tipc_name_table(net);
+ u32 max_user_pub = TIPC_MAX_PUBL - 1;
struct tipc_net *tn = tipc_net(net);
struct publication *p = NULL;
struct sk_buff *skb = NULL;
+ bool protocol_type = false;
u32 rc_dests;
+ if (ua->sr.type == TIPC_NODE_STATE || ua->sr.type == TIPC_LINK_STATE ||
+ ua->sr.type == TIPC_TOP_SRV)
+ protocol_type = true;
+
spin_lock_bh(&tn->nametbl_lock);
+ if (protocol_type)
+ goto insert;
- if (nt->local_publ_count >= TIPC_MAX_PUBL) {
- pr_warn("Bind failed, max limit %u reached\n", TIPC_MAX_PUBL);
+ /* Reserve one entry for node state service type because it has cluster
+ * scope and it is distributed in bulk. So, the maximum number of user's
+ * publications is (TIPC_MAX_PUBL - 1).
+ */
+ if (nt->local_publ_count >= max_user_pub) {
+ pr_warn("Bind failed, max limit %u reached\n", max_user_pub);
goto exit;
}
+insert:
p = tipc_nametbl_insert_publ(net, ua, sk, key);
if (p) {
- nt->local_publ_count++;
+ /* Not count node state, link state and topology server types
+ * so that maximum nt->local_publ_count does not prevent
+ * protocol service types from being inserted into the name
+ * table.
+ */
+ if (!protocol_type)
+ nt->local_publ_count++;
skb = tipc_named_publish(net, p);
}
rc_dests = nt->rc_dests;
@@ -810,7 +829,10 @@ void tipc_nametbl_withdraw(struct net *net, struct tipc_uaddr *ua,
p = tipc_nametbl_remove_publ(net, ua, sk, key);
if (p) {
- nt->local_publ_count--;
+ if (p->sr.type != TIPC_NODE_STATE &&
+ p->sr.type != TIPC_LINK_STATE &&
+ p->sr.type != TIPC_TOP_SRV)
+ nt->local_publ_count--;
skb = tipc_named_withdraw(net, p);
list_del_init(&p->binding_sock);
kfree_rcu(p, rcu);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 147/733] tipc: Dont send random pad bytes in RESET/ACTIVATE messages
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (145 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 146/733] tipc: fix NULL deref in tipc_named_node_up() on empty publication list Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 148/733] ipv6: sr: restore network header before routing and forwarding Greg Kroah-Hartman
` (597 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Laight, Tung Nguyen,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Laight <david.laight.linux@gmail.com>
[ Upstream commit 81c600c26302a27852ed8b19c5f2f647ea3555c9 ]
The interface name is passed in a fixed length (TIPC_MAX_IF_NAME) buffer.
Replace the strcpy(data, l->if_name) with memcpy() so that the
pad bytes are actually written (l->if_name[] is zero padded)
rather than sending random bytes from the skb to the remote system.
Replace two other strcpy() with strscpy().
Fixes: e74a386d70c7 ("tipc: remove pre-allocated message header in link struct")
Signed-off-by: David Laight <david.laight.linux@gmail.com>
Reviewed-by: Tung Nguyen <tung.quang.nguyen@est.tech>
Link: https://patch.msgid.link/20260829115813.188600-1-david.laight.linux@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/tipc/link.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 49dfc098d89b2..6427c69f89294 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -504,7 +504,7 @@ bool tipc_link_create(struct net *net, char *if_name, int bearer_id,
snprintf(l->name, sizeof(l->name), "%s:%s-%s:unknown",
self_str, if_name, peer_str);
- strcpy(l->if_name, if_name);
+ strscpy(l->if_name, if_name);
l->addr = peer;
l->peer_caps = peer_caps;
l->net = net;
@@ -574,7 +574,7 @@ bool tipc_link_bc_create(struct net *net, u32 ownnode, u32 peer, u8 *peer_id,
snprintf(l->name, sizeof(l->name), "%s:%s", tipc_bclink_name,
peer_str);
} else {
- strcpy(l->name, tipc_bclink_name);
+ strscpy(l->name, tipc_bclink_name);
}
trace_tipc_link_reset(l, TIPC_DUMP_ALL, "bclink created!");
tipc_link_reset(l);
@@ -1898,7 +1898,7 @@ static void tipc_link_build_proto_msg(struct tipc_link *l, int mtyp, bool probe,
msg_set_dest_session(hdr, l->peer_session);
}
msg_set_max_pkt(hdr, l->advertised_mtu);
- strcpy(data, l->if_name);
+ memcpy(data, l->if_name, TIPC_MAX_IF_NAME);
msg_set_size(hdr, INT_H_SIZE + TIPC_MAX_IF_NAME);
skb_trim(skb, INT_H_SIZE + TIPC_MAX_IF_NAME);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 148/733] ipv6: sr: restore network header before routing and forwarding
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (146 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 147/733] tipc: Dont send random pad bytes in RESET/ACTIVATE messages Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 149/733] af_packet: Dont cast tpacket_hdr.tp_len to int in tpacket_parse_header() Greg Kroah-Hartman
` (596 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Jun Yang,
Fourie Zhang, Eric Dumazet, Ido Schimmel, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 975b5b067f525a1b1338c4a3bee1c46545801518 ]
ipv6_srh_rcv() runs with skb->data at the Segment Routing Header (SRH)
while skb_network_header() points at the IPv6 header.
When segments_left > 0, ipv6_srh_rcv() previously restored the skb->data
position by pushing sizeof(struct ipv6hdr), assuming the SRH immediately
followed the fixed IPv6 header. If another extension header (such as a
Hop-by-Hop options header) precedes the SRH, skb_network_offset()
remained negative.
This led to two problems:
1. During ip6_route_input(), fib6_rules_early_flow_dissect() invokes
__skb_flow_dissect() which passes the negative skb_network_offset()
to flow dissection, breaking BPF and C flow dissector logic.
2. If forwarded via ip6_forward() or redirected via act_mirred, downstream
handlers (like sch_fragment() or neighbour output) pass the negative
offset as an unsigned length, triggering OOB memcpy or buffer overflows.
Fix this by pushing -skb_network_offset(skb) before routing, ensuring
skb_network_offset(skb) is 0 for route lookup / flow dissection as well as
downstream forwarding. On the loopback path, pull skb_transport_offset(skb)
to restore skb->data to the SRH before looping back.
Fixes: 1ababeba4a21 ("ipv6: implement dataplane support for rthdr type 4 (Segment Routing Header)")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Reported-by: Jun Yang <junvyyang@tencent.com>
Reported-by: Fourie Zhang <fouriezhang@tencent.com>
Closes: https://lore.kernel.org/netdev/20260817104128.22681-1-juny24602@gmail.com/
Closes: https://lore.kernel.org/netdev/20260827092345.2301937-1-fouriezhang@tencent.com/
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260828141727.2372570-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/exthdrs.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/ipv6/exthdrs.c b/net/ipv6/exthdrs.c
index 51941ad656a36..09a4552f7f08a 100644
--- a/net/ipv6/exthdrs.c
+++ b/net/ipv6/exthdrs.c
@@ -445,7 +445,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb, struct inet6_dev *idev)
hdr->segments_left--;
addr = hdr->segments + hdr->segments_left;
- skb_push(skb, sizeof(struct ipv6hdr));
+ skb_push(skb, -skb_network_offset(skb));
if (skb->ip_summed == CHECKSUM_COMPLETE)
seg6_update_csum(skb);
@@ -469,7 +469,7 @@ static int ipv6_srh_rcv(struct sk_buff *skb, struct inet6_dev *idev)
}
ipv6_hdr(skb)->hop_limit--;
- skb_pull(skb, sizeof(struct ipv6hdr));
+ skb_pull(skb, skb_transport_offset(skb));
goto looped_back;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 149/733] af_packet: Dont cast tpacket_hdr.tp_len to int in tpacket_parse_header().
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (147 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 148/733] ipv6: sr: restore network header before routing and forwarding Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 150/733] staging: fbtft: make dirty_lock IRQ-safe Greg Kroah-Hartman
` (595 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+73df3f89e1e13089e466,
Kuniyuki Iwashima, Eric Dumazet, Willem de Bruijn, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 73e594c19b4f815d8343461cec7074c4713bbde7 ]
syzbot reported BUG() in sock_sendmsg_nosec(). [0]
The problem is that tpacket_parse_header() casts user-provided
tpacket_hdr.tp_len, which is u32, to int.
If the length is larger than INT_MAX, the following condition
in tpacket_parse_header() passes,
if (unlikely(tp_len > size_max))
and any negative value can be returned to the caller, up to
sock_sendmsg_nosec().
The repro set tpacket_hdr.tp_len to 0xfffffdef, which is cast
to -EIOCBQUEUED (-529), triggering BUG() in sock_sendmsg_nosec().
*(uint64_t*)0x200000000008 = 0xfffffdef;
...
syscall(__NR_write, /*fd=*/r[0], /*buf=*/0x200000000000ul, /*count=*/1ul);
Let's define the local tp_len as u32 in tpacket_parse_header().
[0]:
kernel BUG at net/socket.c:803!
Oops: invalid opcode: 0000 [#1] SMP KASAN PTI
CPU: 0 UID: 0 PID: 5628 Comm: syz-executor176 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
RIP: 0010:sock_sendmsg_nosec+0x145/0x180 net/socket.c:803
Code: 06 67 48 0f b9 3a eb 95 e8 e8 3a 22 f8 48 89 df 4c 89 f6 4c 89 e2 4d 89 fb 2e e8 32 a5 5c 16 e9 51 ff ff ff e8 cc 3a 22 f8 90 <0f> 0b e8 c4 3a 22 f8 48 83 c3 18 48 89 d8 48 c1 e8 03 42 80 3c 28
RSP: 0018:ffffc90003aefb48 EFLAGS: 00010293
RAX: ffffffff89a578d4 RBX: ffff8880764c67c0 RCX: ffff88807fb23e80
RDX: 0000000000000000 RSI: 00000000fffffdef RDI: 00000000fffffdef
RBP: 00000000fffffdef R08: ffffc90003aef747 R09: 1ffff9200075dee8
R10: dffffc0000000000 R11: fffff5200075dee9 R12: 0000000000000001
R13: dffffc0000000000 R14: ffffc90003aefbc0 R15: ffffffff8aac4310
FS: 000055559101b400(0000) GS:ffff888124ce0000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000000210 CR3: 0000000073dca000 CR4: 00000000003526f0
Call Trace:
<TASK>
__sock_sendmsg net/socket.c:815 [inline]
sock_write_iter+0x2de/0x3e0 net/socket.c:1266
new_sync_write fs/read_write.c:595 [inline]
vfs_write+0x612/0xba0 fs/read_write.c:687
ksys_write+0x150/0x270 fs/read_write.c:739
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7f173130ecb9
Code: c0 79 93 eb d5 48 8d 7c 1d 00 eb 99 0f 1f 44 00 00 48 89 f8 48 89 f7 48 89 d6 48 89 ca 4d 89 c2 4d 89 c8 4c 8b 4c 24 08 0f 05 <48> 3d 01 f0 ff ff 73 01 c3 48 c7 c1 d8 ff ff ff f7 d8 64 89 01 48
RSP: 002b:00007ffd67e44248 EFLAGS: 00000246 ORIG_RAX: 0000000000000001
RAX: ffffffffffffffda RBX: 0000200000000000 RCX: 00007f173130ecb9
RDX: 0000000000000001 RSI: 0000200000000000 RDI: 0000000000000003
RBP: 0000000000000001 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 00007ffd67e44388
R13: 0000000000000002 R14: 00002000000000c0 R15: 0000000000000002
</TASK>
Fixes: 69e3c75f4d54 ("net: TX_RING and packet mmap")
Reported-by: syzbot+73df3f89e1e13089e466@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a946ffa.1d9ded08.62e62.0123.GAE@google.com/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260830180915.260225-1-kuniyu@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/packet/af_packet.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/net/packet/af_packet.c b/net/packet/af_packet.c
index b22cda3221363..76bde7906d494 100644
--- a/net/packet/af_packet.c
+++ b/net/packet/af_packet.c
@@ -2675,7 +2675,8 @@ static int tpacket_parse_header(struct packet_sock *po, void *frame,
int size_max, void **data)
{
union tpacket_uhdr ph;
- int tp_len, off;
+ u32 tp_len;
+ int off;
ph.raw = frame;
@@ -2695,7 +2696,7 @@ static int tpacket_parse_header(struct packet_sock *po, void *frame,
break;
}
if (unlikely(tp_len > size_max)) {
- pr_err("packet size is too long (%d > %d)\n", tp_len, size_max);
+ pr_err("packet size is too long (%u > %d)\n", tp_len, size_max);
return -EMSGSIZE;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 150/733] staging: fbtft: make dirty_lock IRQ-safe
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (148 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 149/733] af_packet: Dont cast tpacket_hdr.tp_len to int in tpacket_parse_header() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 151/733] net: bonding: annotate lockless writes with WRITE_ONCE() Greg Kroah-Hartman
` (594 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Hui Su, Nam Cao, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit f576944a59f31bcffff121117ebf452c5dd162b7 ]
fbtft_mkdirty() can be reached from the fbcon rendering path while
processing printk() in hardirq context. Meanwhile, dirty_lock is also
taken by fbtft_deferred_io() in workqueue context with local interrupts
enabled.
Lockdep reports a possible IRQ lock inversion involving dirty_lock and
console_owner. A hardirq can interrupt a CPU holding dirty_lock and
enter the console rendering path, which can attempt to acquire
dirty_lock again.
The following lockdep report was observed on an RK3566 system with
CONFIG_PROVE_LOCKING enabled:
WARNING: possible irq lock inversion dependency detected
swapper/2/0 just changed the state of lock:
(console_owner){-...}-{0:0}
but this lock took another, HARDIRQ-unsafe lock in the past:
(&par->dirty_lock){+.+.}-{2:2}
CPU0 CPU1
---- ----
lock(&par->dirty_lock);
local_irq_disable();
lock(console_owner);
lock(&par->dirty_lock);
<Interrupt>
lock(console_owner);
*** DEADLOCK ***
Use spin_lock_irqsave() for fbtft_mkdirty() and spin_lock_irq() for
fbtft_deferred_io(). They only access the dirty line range, so the
IRQ-off regions remain short.
Fixes: c296d5f9957c ("staging: fbtft: core support")
Signed-off-by: Hui Su <sh_def@163.com>
Link: https://lore.kernel.org/lkml/20260804173712.176017-1-sh_def@163.com/
Reviewed-by: Nam Cao <namcao@linutronix.de>
Link: https://patch.msgid.link/20260807150953.2811933-3-sh_def@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/staging/fbtft/fbtft-core.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/drivers/staging/fbtft/fbtft-core.c b/drivers/staging/fbtft/fbtft-core.c
index ca0c38221c16b..7925d974de801 100644
--- a/drivers/staging/fbtft/fbtft-core.c
+++ b/drivers/staging/fbtft/fbtft-core.c
@@ -298,14 +298,15 @@ static void fbtft_mkdirty(struct fb_info *info, int y, int height)
{
struct fbtft_par *par = info->par;
struct fb_deferred_io *fbdefio = info->fbdefio;
+ unsigned long flags;
/* Mark display lines/area as dirty */
- spin_lock(&par->dirty_lock);
+ spin_lock_irqsave(&par->dirty_lock, flags);
if (y < par->dirty_lines_start)
par->dirty_lines_start = y;
if (y + height - 1 > par->dirty_lines_end)
par->dirty_lines_end = y + height - 1;
- spin_unlock(&par->dirty_lock);
+ spin_unlock_irqrestore(&par->dirty_lock, flags);
/* Schedule deferred_io to update display (no-op if already on queue)*/
schedule_delayed_work(&info->deferred_work, fbdefio->delay);
@@ -318,13 +319,13 @@ static void fbtft_deferred_io(struct fb_info *info, struct list_head *pagereflis
struct fb_deferred_io_pageref *pageref;
unsigned int y_low = 0, y_high = 0;
- spin_lock(&par->dirty_lock);
+ spin_lock_irq(&par->dirty_lock);
dirty_lines_start = par->dirty_lines_start;
dirty_lines_end = par->dirty_lines_end;
/* set display line markers as clean */
par->dirty_lines_start = par->info->var.yres - 1;
par->dirty_lines_end = 0;
- spin_unlock(&par->dirty_lock);
+ spin_unlock_irq(&par->dirty_lock);
/* Mark display lines as dirty */
list_for_each_entry(pageref, pagereflist, list) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 151/733] net: bonding: annotate lockless writes with WRITE_ONCE()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (149 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 150/733] staging: fbtft: make dirty_lock IRQ-safe Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 152/733] ALSA: hda: restore MFG widget enumeration after core split Greg Kroah-Hartman
` (593 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jay Vosburgh,
Xuanqiang Luo, Hangbin Liu, Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit bc93419130bb70fabf6561e197054caae85c160c ]
Several fields in bonding are read locklessly using READ_ONCE()
(or ACCESS_ONCE() previously) but have corresponding writes that
do not use WRITE_ONCE().
Add WRITE_ONCE() annotations to:
- bond->send_peer_notif decrements in bond_peer_notify_may_events()
and reset in bond_close().
- bond->slave_cnt increments and decrements in bond_enslave() and
__bond_release_one().
- bond->recv_probe updates in bond_open(), bond_option_arp_interval_set()
and rlb_initialize().
- slaves->count decrement in bond_skip_slave().
Fixes: 4d97480b1806 ("bonding: use local function pointer of bond->recv_probe in bond_handle_frame")
Fixes: 9a72c2da690d ("bonding: fix div by zero while enslaving and transmitting")
Fixes: ee6377147409 ("bonding: Simplify the xmit function for modes that use xmit_hash")
Fixes: 429208aab9db ("net: bonding: add the READ_ONCE/WRITE_ONCE for outside lock accessing")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Cc: Jay Vosburgh <jv@jvosburgh.net>
Reviewed-by: Xuanqiang Luo<luoxuanqiang@kylinos.cn>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260831081027.3209554-1-edumazet@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_alb.c | 2 +-
drivers/net/bonding/bond_main.c | 14 +++++++-------
drivers/net/bonding/bond_options.c | 4 ++--
3 files changed, 10 insertions(+), 10 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 839f7482dc182..d2fb67a47cf99 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -875,7 +875,7 @@ static int rlb_initialize(struct bonding *bond)
spin_unlock_bh(&bond->mode_lock);
/* register to receive ARPs */
- bond->recv_probe = rlb_arp_recv;
+ WRITE_ONCE(bond->recv_probe, rlb_arp_recv);
return 0;
}
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 522eab060f9ed..909ecec0de4d6 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -1245,7 +1245,7 @@ static void bond_peer_notify_may_events(struct bonding *bond, bool force)
}
if (notified || force)
- bond->send_peer_notif--;
+ WRITE_ONCE(bond->send_peer_notif, bond->send_peer_notif - 1);
}
/**
@@ -2284,7 +2284,7 @@ int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev,
}
}
- bond->slave_cnt++;
+ WRITE_ONCE(bond->slave_cnt, bond->slave_cnt + 1);
netdev_compute_master_upper_features(bond->dev, true);
bond_set_carrier(bond);
@@ -2533,7 +2533,7 @@ static int __bond_release_one(struct net_device *bond_dev,
unblock_netpoll_tx();
synchronize_rcu();
- bond->slave_cnt--;
+ WRITE_ONCE(bond->slave_cnt, bond->slave_cnt - 1);
if (!bond_has_slaves(bond)) {
call_netdevice_notifiers(NETDEV_CHANGEADDR, bond->dev);
@@ -4385,13 +4385,13 @@ static int bond_open(struct net_device *bond_dev)
if (bond->params.arp_interval) { /* arp interval, in milliseconds. */
queue_delayed_work(bond->wq, &bond->arp_work, 0);
- bond->recv_probe = bond_rcv_validate;
+ WRITE_ONCE(bond->recv_probe, bond_rcv_validate);
}
if (BOND_MODE(bond) == BOND_MODE_8023AD) {
queue_delayed_work(bond->wq, &bond->ad_work, 0);
/* register to receive LACPDUs */
- bond->recv_probe = bond_3ad_lacpdu_recv;
+ WRITE_ONCE(bond->recv_probe, bond_3ad_lacpdu_recv);
bond_3ad_initiate_agg_selection(bond, 1);
bond_for_each_slave(bond, slave, iter)
@@ -4413,7 +4413,7 @@ static int bond_close(struct net_device *bond_dev)
struct slave *slave;
bond_work_cancel_all(bond);
- bond->send_peer_notif = 0;
+ WRITE_ONCE(bond->send_peer_notif, 0);
WRITE_ONCE(bond->recv_probe, NULL);
/* Wait for any in-flight RX handlers */
@@ -5124,7 +5124,7 @@ static void bond_skip_slave(struct bond_up_slave *slaves,
if (skipslave == slaves->arr[idx]) {
slaves->arr[idx] =
slaves->arr[slaves->count - 1];
- slaves->count--;
+ WRITE_ONCE(slaves->count, slaves->count - 1);
break;
}
}
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index e590c8dee86e1..d8cdbfca1bb16 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -1147,11 +1147,11 @@ static int bond_option_arp_interval_set(struct bonding *bond,
*/
if (!newval->value) {
if (bond->params.arp_validate)
- bond->recv_probe = NULL;
+ WRITE_ONCE(bond->recv_probe, NULL);
cancel_delayed_work_sync(&bond->arp_work);
} else {
/* arp_validate can be set only in active-backup mode */
- bond->recv_probe = bond_rcv_validate;
+ WRITE_ONCE(bond->recv_probe, bond_rcv_validate);
cancel_delayed_work_sync(&bond->mii_work);
queue_delayed_work(bond->wq, &bond->arp_work, 0);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 152/733] ALSA: hda: restore MFG widget enumeration after core split
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (150 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 151/733] net: bonding: annotate lockless writes with WRITE_ONCE() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 153/733] s390/boot: Fix physical memory search range Greg Kroah-Hartman
` (592 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xu Rao, Takashi Iwai, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <raoxu@uniontech.com>
[ Upstream commit 32d7226e6105c257ef7b3d0ec819f11a81f53b6d ]
Before commit 7639a06c23c7 ("ALSA: hda - Move a part of hda_codec stuff
into hdac_device"), widget enumeration selected the function group with
codec->afg ? codec->afg : codec->mfg
and read subordinate nodes from that group.
The core split moved this logic into snd_hdac_refresh_widgets(), but
hard-coded codec->afg there. For an MFG-only codec, codec->afg is zero,
so the Root Node is queried and codec->start_nid/num_nodes are populated
from the function-group range instead of the MFG's subordinate nodes.
Restore the pre-split AFG-or-MFG selection.
Fixes: 7639a06c23c7 ("ALSA: hda - Move a part of hda_codec stuff into hdac_device")
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Link: https://patch.msgid.link/44809B8FF80DCCA2+20260901034024.2407783-1-raoxu@uniontech.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/core/device.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/sound/hda/core/device.c b/sound/hda/core/device.c
index 160c8d0453b0e..ebaa106d0f018 100644
--- a/sound/hda/core/device.c
+++ b/sound/hda/core/device.c
@@ -404,6 +404,7 @@ static void setup_fg_nodes(struct hdac_device *codec)
*/
int snd_hdac_refresh_widgets(struct hdac_device *codec)
{
+ hda_nid_t fg = codec->afg ? codec->afg : codec->mfg;
hda_nid_t start_nid;
int nums, err = 0;
@@ -412,10 +413,10 @@ int snd_hdac_refresh_widgets(struct hdac_device *codec)
* widgets array.
*/
guard(mutex)(&codec->widget_lock);
- nums = snd_hdac_get_sub_nodes(codec, codec->afg, &start_nid);
+ nums = snd_hdac_get_sub_nodes(codec, fg, &start_nid);
if (!start_nid || nums <= 0 || nums >= 0xff) {
dev_err(&codec->dev, "cannot read sub nodes for FG 0x%02x\n",
- codec->afg);
+ fg);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 153/733] s390/boot: Fix physical memory search range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (151 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 152/733] ALSA: hda: restore MFG widget enumeration after core split Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 154/733] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
` (591 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Vasily Gorbik,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit a0c798ed4103316c23938bdf625af364fbd38016 ]
search_mem_end() calculates the number of 1MB blocks with a signed int
literal. CONFIG_MAX_PHYSMEM_BITS values of 51 and above either overflow
the signed int or shift beyond its width. This produces an invalid search
range when the binary-search memory detection fallback is used.
Use an unsigned long literal so the full supported physical address range
is represented.
Fixes: 54c57795e848 ("s390/mem_detect: replace tprot loop with binary search")
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/boot/physmem_info.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/s390/boot/physmem_info.c b/arch/s390/boot/physmem_info.c
index 1f2ca5435838e..0ebb2174713f2 100644
--- a/arch/s390/boot/physmem_info.c
+++ b/arch/s390/boot/physmem_info.c
@@ -141,7 +141,7 @@ static int tprot(unsigned long addr)
static unsigned long search_mem_end(void)
{
- unsigned long range = 1 << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
+ unsigned long range = 1UL << (MAX_PHYSMEM_BITS - 20); /* in 1MB blocks */
unsigned long offset = 0;
unsigned long pivot;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 154/733] s390/boot: Avoid IPL parameter append past command line
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (152 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 153/733] s390/boot: Fix physical memory search range Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 155/733] ASoC: fsl_micfil: balance mclk enable/disable Greg Kroah-Hartman
` (590 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Vasily Gorbik,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasily Gorbik <gor@linux.ibm.com>
[ Upstream commit d76181dfabdaa720703167393704efacba343442 ]
A command line may occupy all but the terminating byte of
COMMAND_LINE_SIZE. In that case append_ipl_block_parm() passes a zero size
to the IPL parameter conversion helpers and points the destination one
byte past early_command_line. The helpers subtract one from the unsigned
size and write the converted parameter outside the command line buffer.
Convert the IPL parameter in the command line parsing buffer first. A
parameter beginning with '=' can then replace the existing command line
regardless of its length, while other parameters are appended only when
space remains.
Fixes: 5ecb2da660ab ("s390: support command lines longer than 896 bytes")
Reviewed-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/boot/ipl_parm.c | 26 ++++++++++++--------------
1 file changed, 12 insertions(+), 14 deletions(-)
diff --git a/arch/s390/boot/ipl_parm.c b/arch/s390/boot/ipl_parm.c
index 6bc950b92be76..59eabf4a2de05 100644
--- a/arch/s390/boot/ipl_parm.c
+++ b/arch/s390/boot/ipl_parm.c
@@ -23,6 +23,7 @@ struct parmarea parmarea __section(".parmarea") = {
};
char __bootdata(early_command_line)[COMMAND_LINE_SIZE];
+static char command_line_buf[COMMAND_LINE_SIZE];
unsigned int __bootdata_preserved(zlib_dfltcc_support) = ZLIB_DFLTCC_FULL;
struct ipl_parameter_block __bootdata_preserved(ipl_block);
@@ -135,31 +136,29 @@ static size_t ipl_block_get_ascii_scpdata(char *dest, size_t size,
static void append_ipl_block_parm(void)
{
- char *parm, *delim;
- size_t len, rc = 0;
+ size_t len, extra = 0;
+ char *delim;
len = strlen(early_command_line);
-
- delim = early_command_line + len; /* '\0' character position */
- parm = early_command_line + len + 1; /* append right after '\0' */
+ delim = early_command_line + len; /* '\0' character position */
switch (ipl_block.pb0_hdr.pbt) {
case IPL_PBT_CCW:
- rc = ipl_block_get_ascii_vmparm(
- parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+ extra = ipl_block_get_ascii_vmparm(command_line_buf, sizeof(command_line_buf), &ipl_block);
break;
case IPL_PBT_FCP:
case IPL_PBT_NVME:
case IPL_PBT_ECKD:
- rc = ipl_block_get_ascii_scpdata(
- parm, COMMAND_LINE_SIZE - len - 1, &ipl_block);
+ extra = ipl_block_get_ascii_scpdata(command_line_buf, sizeof(command_line_buf), &ipl_block);
break;
}
- if (rc) {
- if (*parm == '=')
- memmove(early_command_line, parm + 1, rc);
- else
+ if (extra) {
+ if (command_line_buf[0] == '=') {
+ memmove(early_command_line, command_line_buf + 1, extra);
+ } else if (len < COMMAND_LINE_SIZE - 2) {
*delim = ' '; /* replace '\0' with space */
+ sized_strscpy(delim + 1, command_line_buf, COMMAND_LINE_SIZE - len - 1);
+ }
}
}
@@ -245,7 +244,6 @@ static void modify_fac_list(char *str)
check_cleared_facilities();
}
-static char command_line_buf[COMMAND_LINE_SIZE];
void parse_boot_command_line(void)
{
char *param, *val;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 155/733] ASoC: fsl_micfil: balance mclk enable/disable
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (153 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 154/733] s390/boot: Avoid IPL parameter append past command line Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 156/733] ASoC: amd: renoir: fix disable_pdm_interrupts() to clear mask bits Greg Kroah-Hartman
` (589 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ștefan Ghețu, Chancel Liu,
Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ștefan Ghețu <stefanghetu9@gmail.com>
[ Upstream commit d3dbccfe6afa7b9a6a7ed65cfaa76a47fa050a56 ]
hw_params() enables mclk unconditionally and hw_free() disables it
unconditionally, but the PCM core does not guarantee 1:1 pairing:
hw_free() can run without hw_params(), and hw_params() can be called
multiple times from the SETUP state. This triggers an "already
disabled" WARN() in the first case and leaks an enable reference in
the second, leaving the clock ungateable.
Guard both sides with the existing mclk_flag, as fsl_sai.c does with
mclk_streams.
Fixes: b47024dc624b ("ASoC: fsl_micfil: Add mclk enable flag")
Signed-off-by: Ștefan Ghețu <stefanghetu9@gmail.com>
Reviewed-by: Chancel Liu <chancel.liu@nxp.com>
Link: https://patch.msgid.link/20260830205106.11267-1-stefanghetu9@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/fsl/fsl_micfil.c | 21 +++++++++++++--------
1 file changed, 13 insertions(+), 8 deletions(-)
diff --git a/sound/soc/fsl/fsl_micfil.c b/sound/soc/fsl/fsl_micfil.c
index 60ac8eabab9da..5d8f0f76ab46f 100644
--- a/sound/soc/fsl/fsl_micfil.c
+++ b/sound/soc/fsl/fsl_micfil.c
@@ -953,12 +953,17 @@ static int fsl_micfil_reparent_rootclk(struct fsl_micfil *micfil, unsigned int s
/* Get root clock */
clk = micfil->mclk;
- /* Disable clock first, for it was enabled by pm_runtime */
+ /* Reparent root clock to the PLL matching this sample rate */
fsl_asoc_reparent_pll_clocks(dev, clk, micfil->pll8k_clk,
micfil->pll11k_clk, ratio);
- ret = clk_prepare_enable(clk);
- if (ret)
- return ret;
+
+ /* Enable only once; hw_params can be called multiple times */
+ if (!micfil->mclk_flag) {
+ ret = clk_prepare_enable(clk);
+ if (ret)
+ return ret;
+ micfil->mclk_flag = true;
+ }
return 0;
}
@@ -991,8 +996,6 @@ static int fsl_micfil_hw_params(struct snd_pcm_substream *substream,
if (ret)
return ret;
- micfil->mclk_flag = true;
-
/* floor(K * CLKDIV) */
switch (micfil->quality) {
case QUALITY_HIGH:
@@ -1068,8 +1071,10 @@ static int fsl_micfil_hw_free(struct snd_pcm_substream *substream,
{
struct fsl_micfil *micfil = snd_soc_dai_get_drvdata(dai);
- clk_disable_unprepare(micfil->mclk);
- micfil->mclk_flag = false;
+ if (micfil->mclk_flag) {
+ clk_disable_unprepare(micfil->mclk);
+ micfil->mclk_flag = false;
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 156/733] ASoC: amd: renoir: fix disable_pdm_interrupts() to clear mask bits
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (154 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 155/733] ASoC: fsl_micfil: balance mclk enable/disable Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 157/733] ASoC: amd: yc: fix memory leak in acp6x_pdm_dma_close() Greg Kroah-Hartman
` (588 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, wangdicheng, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: wangdicheng <wangdicheng@kylinos.cn>
[ Upstream commit 0c06c4ce0206290c9a934a1e7196aaa86adfe018 ]
disable_pdm_interrupts() uses |= ~PDM_DMA_INTR_MASK which sets all
bits except the PDM DMA interrupt bit instead of clearing only the
PDM DMA interrupt bit. Use &= ~PDM_DMA_INTR_MASK to clear only the
target bit.
Fixes: f621a3676d3f ("ASoC: amd: add ACP3x PDM platform driver")
Signed-off-by: wangdicheng <wangdicheng@kylinos.cn>
Link: https://patch.msgid.link/20260824063507.483784-1-wangdich9700@163.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/renoir/acp3x-pdm-dma.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/soc/amd/renoir/acp3x-pdm-dma.c b/sound/soc/amd/renoir/acp3x-pdm-dma.c
index e60e3821703cc..3f59b753243d5 100644
--- a/sound/soc/amd/renoir/acp3x-pdm-dma.c
+++ b/sound/soc/amd/renoir/acp3x-pdm-dma.c
@@ -104,7 +104,7 @@ static void disable_pdm_interrupts(void __iomem *acp_base)
u32 ext_int_ctrl;
ext_int_ctrl = rn_readl(acp_base + ACP_EXTERNAL_INTR_CNTL);
- ext_int_ctrl |= ~PDM_DMA_INTR_MASK;
+ ext_int_ctrl &= ~PDM_DMA_INTR_MASK;
rn_writel(ext_int_ctrl, acp_base + ACP_EXTERNAL_INTR_CNTL);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 157/733] ASoC: amd: yc: fix memory leak in acp6x_pdm_dma_close()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (155 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 156/733] ASoC: amd: renoir: fix disable_pdm_interrupts() to clear mask bits Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 158/733] block: save page offset gaps in cloned bio Greg Kroah-Hartman
` (587 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, wangdicheng, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: wangdicheng <wangdicheng@kylinos.cn>
[ Upstream commit 1b67e0d3b9691d7b6b74e18960ddd2be24f9dc9d ]
acp6x_pdm_dma_close() does not free the runtime->private_data buffer
allocated in acp6x_pdm_dma_open(). Add the missing kfree.
Fixes: 7610174a5bfe ("ASoC: amd: add acp6x pdm platform driver")
Signed-off-by: wangdicheng <wangdicheng@kylinos.cn>
Link: https://patch.msgid.link/20260824063507.483784-2-wangdich9700@163.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/amd/yc/acp6x-pdm-dma.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/sound/soc/amd/yc/acp6x-pdm-dma.c b/sound/soc/amd/yc/acp6x-pdm-dma.c
index 710db721ffa48..40c4d833f4ed3 100644
--- a/sound/soc/amd/yc/acp6x-pdm-dma.c
+++ b/sound/soc/amd/yc/acp6x-pdm-dma.c
@@ -275,9 +275,11 @@ static int acp6x_pdm_dma_close(struct snd_soc_component *component,
struct snd_pcm_substream *substream)
{
struct pdm_dev_data *adata = dev_get_drvdata(component->dev);
+ struct snd_pcm_runtime *runtime = substream->runtime;
acp6x_disable_pdm_interrupts(adata->acp6x_base);
adata->capture_stream = NULL;
+ kfree(runtime->private_data);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 158/733] block: save page offset gaps in cloned bio
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (156 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 157/733] ASoC: amd: yc: fix memory leak in acp6x_pdm_dma_close() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 159/733] ASoC: cs35l56: Request IRQ in cs35l56_common_probe() Greg Kroah-Hartman
` (586 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Auger, Eric Auger, Keith Busch,
Christoph Hellwig, Jens Axboe, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <kbusch@kernel.org>
[ Upstream commit 96c8ea3c5add7920b3c43840d1ea76b3354c8d2d ]
The cloned bio needs to inherit the accumulated gaps between vectors so
that we can know if this bio can subscribe to the iova coalescing
optimization.
When cloning for a split, the gap only applies to the front bio since
that's as far as has been processed. The remaining bio can reset its
gaps to 0 since it advanced past the checked vectors, and will start its
accounting from there on the next split check.
Fixes: 2f6b2565d43c ("block: accumulate memory segment gaps per bio")
Reported-by: Eric Auger <eauger@redhat.com>
Tested-by: Eric Auger <eric.auger@redhat.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/20260819154937.3903312-1-kbusch@meta.com
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
block/bio.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/block/bio.c b/block/bio.c
index 5018a6fc2f36b..bdcb60cb8d88f 100644
--- a/block/bio.c
+++ b/block/bio.c
@@ -859,6 +859,7 @@ static int __bio_clone(struct bio *bio, struct bio *bio_src, gfp_t gfp)
bio->bi_ioprio = bio_src->bi_ioprio;
bio->bi_write_hint = bio_src->bi_write_hint;
bio->bi_write_stream = bio_src->bi_write_stream;
+ bio->bi_bvec_gap_bit = bio_src->bi_bvec_gap_bit;
bio->bi_iter = bio_src->bi_iter;
if (bio->bi_bdev) {
@@ -1913,6 +1914,14 @@ struct bio *bio_split(struct bio *bio, int sectors,
bio_advance(bio, split->bi_iter.bi_size);
+ /*
+ * The gap bit is set when splitting to limits and only applies to the
+ * front bio that was split off. The remaining bio will calcualte its
+ * gap value when it is subsequently split to limits, so it is safe to
+ * re-initialize the value back to 0.
+ */
+ bio->bi_bvec_gap_bit = 0;
+
if (bio_flagged(bio, BIO_TRACE_COMPLETION))
bio_set_flag(split, BIO_TRACE_COMPLETION);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 159/733] ASoC: cs35l56: Request IRQ in cs35l56_common_probe()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (157 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 158/733] block: save page offset gaps in cloned bio Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 160/733] ASoC: cs35l56: Fix probe deadlock waiting for SoundWire enumeration Greg Kroah-Hartman
` (585 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
[ Upstream commit 888162dabf64128603b12ac2d23236cf2086b7ef ]
Call cs35l56_irq_request() in cs35l56_common_probe() instead of calling
it afterwards in the probe() for each bus type.
Calling cs35l56_irq_request() in each bus probe() is a legacy of dealing
with the oddities of the SoundWire framework. It's no longer serving any
useful purpose to do it outside of the main cs35l56_common_probe().
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260810104045.60701-2-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: 1d80a4792f1d ("ASoC: cs35l56: Fix probe deadlock waiting for SoundWire enumeration")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/cs35l56-i2c.c | 10 +---------
sound/soc/codecs/cs35l56-sdw.c | 6 +-----
sound/soc/codecs/cs35l56-spi.c | 10 +---------
sound/soc/codecs/cs35l56.c | 12 ++++++++++--
sound/soc/codecs/cs35l56.h | 2 +-
5 files changed, 14 insertions(+), 26 deletions(-)
diff --git a/sound/soc/codecs/cs35l56-i2c.c b/sound/soc/codecs/cs35l56-i2c.c
index 4f6ddf1c5a3f6..5e69ddbe342a1 100644
--- a/sound/soc/codecs/cs35l56-i2c.c
+++ b/sound/soc/codecs/cs35l56-i2c.c
@@ -51,15 +51,7 @@ static int cs35l56_i2c_probe(struct i2c_client *client)
return dev_err_probe(cs35l56->base.dev, ret, "Failed to allocate register map\n");
}
- ret = cs35l56_common_probe(cs35l56);
- if (ret != 0)
- return ret;
-
- ret = cs35l56_irq_request(&cs35l56->base, client->irq);
- if (ret < 0)
- cs35l56_remove(cs35l56);
-
- return ret;
+ return cs35l56_common_probe(cs35l56, client->irq);
}
static void cs35l56_i2c_remove(struct i2c_client *client)
diff --git a/sound/soc/codecs/cs35l56-sdw.c b/sound/soc/codecs/cs35l56-sdw.c
index 0a55b93b96f96..a3812ab4c0227 100644
--- a/sound/soc/codecs/cs35l56-sdw.c
+++ b/sound/soc/codecs/cs35l56-sdw.c
@@ -483,11 +483,7 @@ static int cs35l56_sdw_probe(struct sdw_slave *peripheral, const struct sdw_devi
/* Start in cache-only until device is enumerated */
regcache_cache_only(cs35l56->base.regmap, true);
- ret = cs35l56_common_probe(cs35l56);
- if (ret != 0)
- return ret;
-
- return 0;
+ return cs35l56_common_probe(cs35l56, -EINVAL);
}
static void cs35l56_sdw_remove(struct sdw_slave *peripheral)
diff --git a/sound/soc/codecs/cs35l56-spi.c b/sound/soc/codecs/cs35l56-spi.c
index b1eb924a5b6cc..21b18da9e73d1 100644
--- a/sound/soc/codecs/cs35l56-spi.c
+++ b/sound/soc/codecs/cs35l56-spi.c
@@ -40,15 +40,7 @@ static int cs35l56_spi_probe(struct spi_device *spi)
if (ret)
return ret;
- ret = cs35l56_common_probe(cs35l56);
- if (ret != 0)
- return ret;
-
- ret = cs35l56_irq_request(&cs35l56->base, spi->irq);
- if (ret < 0)
- cs35l56_remove(cs35l56);
-
- return ret;
+ return cs35l56_common_probe(cs35l56, spi->irq);
}
static void cs35l56_spi_remove(struct spi_device *spi)
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index 063ef7a70de03..a6364cdb15926 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1941,7 +1941,7 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
return ret;
}
-int cs35l56_common_probe(struct cs35l56_private *cs35l56)
+int cs35l56_common_probe(struct cs35l56_private *cs35l56, int irq)
{
int ret;
@@ -2018,16 +2018,24 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56)
goto err_remove_wm_adsp;
}
+ ret = cs35l56_irq_request(&cs35l56->base, irq);
+ if (ret)
+ goto err_remove_wm_adsp;
+
ret = snd_soc_register_component(cs35l56->base.dev,
&soc_component_dev_cs35l56,
cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
if (ret < 0) {
dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n");
- goto err_remove_wm_adsp;
+ goto err_free_irq;
}
return 0;
+err_free_irq:
+ if (cs35l56->base.irq)
+ devm_free_irq(cs35l56->base.dev, cs35l56->base.irq, &cs35l56->base);
+
err_remove_wm_adsp:
wm_adsp2_remove(&cs35l56->dsp);
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
index 9acd2e7e17c93..1ddee9ab6a876 100644
--- a/sound/soc/codecs/cs35l56.h
+++ b/sound/soc/codecs/cs35l56.h
@@ -78,7 +78,7 @@ int cs35l56_system_resume_early(struct device *dev);
int cs35l56_system_resume(struct device *dev);
irqreturn_t cs35l56_irq(int irq, void *data);
int cs35l56_irq_request(struct cs35l56_base *cs35l56_base, int irq);
-int cs35l56_common_probe(struct cs35l56_private *cs35l56);
+int cs35l56_common_probe(struct cs35l56_private *cs35l56, int irq);
int cs35l56_init(struct cs35l56_private *cs35l56);
void cs35l56_remove(struct cs35l56_private *cs35l56);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 160/733] ASoC: cs35l56: Fix probe deadlock waiting for SoundWire enumeration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (158 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 159/733] ASoC: cs35l56: Request IRQ in cs35l56_common_probe() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 161/733] drm/xe/oa: Remove sysfs entry on idr_alloc failure in xe_oa_add_config_ioctl() Greg Kroah-Hartman
` (584 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
[ Upstream commit 1d80a4792f1de236c157bcee2e5400fad4c66c65 ]
On SoundWire, don't call snd_soc_register_component() from driver probe().
Instead, queue a work item after first SoundWire attach to call
snd_soc_register_component(). This prevents a deadlock if
snd_soc_register_component() directly calls cs35l56_component_probe().
On SoundWire, the registers are not accessible during driver probe().
Drivers must return from their probe() and wait for the SoundWire core
to call their update_status() callback to report an ATTACHED status. The
cs35l56 driver handled this by calling snd_soc_register_component() from
driver probe() as usual, and cs35l56_component_probe() waited for
init_completion to be signalled. A SoundWire attach calls cs35l56_init()
which then signals init_completion.
This created a deadlock if this was the last component needed to complete
a card. In that case, snd_soc_register_component() directly called
cs35l56_component_probe() which led to this:
driver probe()
calls snd_soc_register_component()
calls cs35l56_component_probe()
waits for init_completion
In this case the driver probe() has not returned, so the SoundWire core
would not call update_status() and init_completion would not be signalled.
Fortunately, snd_soc_register_component() never returns -EPROBE_DEFER, so
it doesn't need to be called from a driver probe(). It can be deferred to
a work item. This work is queued after the first completed pass through
cs35l56_init(), so there is no need for it to wait for init_completion.
snd_soc_register_component() isn't called directly from cs35l56_init()
because cs35l56_init() runs in the SoundWire bus driver thread, and there
would be a risk of nested locking or lock inversion.
The work item is queued on a freezable workqueue to prevent a race between
the work item and system_suspend of another instance. If the workqueue
were not frozen it would be possible for the work item of one driver
instance to call snd_soc_register_component() which then calls
cs35l56_component_probe() of another instance while that instance is
already executing its system suspend functions.
The non-SoundWire case still calls snd_soc_register_component() from
cs35l56_common_probe() so that it is the last initialization action.
There's no need defer the call for I2S/SPI buses so we can also leave it
able to return errors during probe.
Fixes: 440c2d38950f7 ("ASoC: cs35l56: Wait for init_complete in cs35l56_component_probe()")
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260901122644.634494-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/cs35l56.c | 71 +++++++++++++++++++++++++++++++-------
sound/soc/codecs/cs35l56.h | 2 ++
2 files changed, 60 insertions(+), 13 deletions(-)
diff --git a/sound/soc/codecs/cs35l56.c b/sound/soc/codecs/cs35l56.c
index a6364cdb15926..80eb03eda5eb1 100644
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -1368,12 +1368,6 @@ static int _cs35l56_component_probe(struct snd_soc_component *component)
BUILD_BUG_ON(ARRAY_SIZE(cs35l56_tx_input_texts) != ARRAY_SIZE(cs35l56_tx_input_values));
- if (!wait_for_completion_timeout(&cs35l56->init_completion,
- msecs_to_jiffies(5000))) {
- dev_err(cs35l56->base.dev, "%s: init_completion timed out\n", __func__);
- return -ENODEV;
- }
-
cs35l56->dsp.part = kasprintf(GFP_KERNEL, "cs35l%02x", cs35l56->base.type);
if (!cs35l56->dsp.part)
return -ENOMEM;
@@ -1941,6 +1935,40 @@ static int cs35l56_try_get_broken_sdca_spkid_gpio(struct cs35l56_private *cs35l5
return ret;
}
+static int cs35l56_component_register(struct cs35l56_private *cs35l56)
+{
+ int ret;
+
+ ret = snd_soc_register_component(cs35l56->base.dev,
+ &soc_component_dev_cs35l56,
+ cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
+ if (ret < 0) {
+ dev_err(cs35l56->base.dev, "Register codec failed: %d\n", ret);
+ return ret;
+ }
+
+ cs35l56->component_registered = true;
+
+ return 0;
+}
+
+static void cs35l56_component_register_work(struct work_struct *work)
+{
+ struct cs35l56_private *cs35l56 = container_of(work,
+ struct cs35l56_private,
+ component_register_work);
+ int ret;
+
+ PM_RUNTIME_ACQUIRE_AUTOSUSPEND(cs35l56->base.dev, pm_err);
+ ret = PM_RUNTIME_ACQUIRE_ERR(&pm_err);
+ if (ret) {
+ dev_err(cs35l56->base.dev, "register_work failed to get pm_runtime: %d\n", ret);
+ return;
+ }
+
+ cs35l56_component_register(cs35l56);
+}
+
int cs35l56_common_probe(struct cs35l56_private *cs35l56, int irq)
{
int ret;
@@ -1949,6 +1977,7 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56, int irq)
mutex_init(&cs35l56->base.irq_lock);
cs35l56->base.cal_index = -1;
cs35l56->speaker_id = -ENOENT;
+ INIT_WORK(&cs35l56->component_register_work, cs35l56_component_register_work);
dev_set_drvdata(cs35l56->base.dev, cs35l56);
@@ -2022,12 +2051,17 @@ int cs35l56_common_probe(struct cs35l56_private *cs35l56, int irq)
if (ret)
goto err_remove_wm_adsp;
- ret = snd_soc_register_component(cs35l56->base.dev,
- &soc_component_dev_cs35l56,
- cs35l56_dai, ARRAY_SIZE(cs35l56_dai));
- if (ret < 0) {
- dev_err_probe(cs35l56->base.dev, ret, "Register codec failed\n");
- goto err_free_irq;
+ /*
+ * Defer calling snd_soc_register_component() on SoundWire to prevent
+ * a deadlock where it calls our component_probe(), which requires the
+ * SoundWire enumeration to complete, but because we are still in probe()
+ * the SoundWire core will not call the update_status() callback. At time
+ * of writing snd_soc_register_component() never returns EPROBE_DEFER.
+ */
+ if (!cs35l56->sdw_peripheral) {
+ ret = cs35l56_component_register(cs35l56);
+ if (ret < 0)
+ goto err_free_irq;
}
return 0;
@@ -2057,6 +2091,7 @@ EXPORT_SYMBOL_NS_GPL(cs35l56_common_probe, "SND_SOC_CS35L56_CORE");
int cs35l56_init(struct cs35l56_private *cs35l56)
{
+ bool first_time_init = !cs35l56->base.init_done;
int ret;
/*
@@ -2133,13 +2168,23 @@ int cs35l56_init(struct cs35l56_private *cs35l56)
cs35l56->base.init_done = true;
complete_all(&cs35l56->init_completion);
+ if (cs35l56->sdw_peripheral && first_time_init) {
+ /*
+ * Hardware now accessible, queue work to call
+ * snd_soc_register_component().
+ */
+ queue_work(system_freezable_wq, &cs35l56->component_register_work);
+ }
+
return 0;
}
EXPORT_SYMBOL_NS_GPL(cs35l56_init, "SND_SOC_CS35L56_CORE");
void cs35l56_remove(struct cs35l56_private *cs35l56)
{
- snd_soc_unregister_component(cs35l56->base.dev);
+ cancel_work_sync(&cs35l56->component_register_work);
+ if (cs35l56->component_registered)
+ snd_soc_unregister_component(cs35l56->base.dev);
cs35l56->base.init_done = false;
diff --git a/sound/soc/codecs/cs35l56.h b/sound/soc/codecs/cs35l56.h
index 1ddee9ab6a876..6adba4d2da1f8 100644
--- a/sound/soc/codecs/cs35l56.h
+++ b/sound/soc/codecs/cs35l56.h
@@ -32,6 +32,7 @@ struct sdw_slave;
struct cs35l56_private {
struct wm_adsp dsp; /* must be first member */
struct cs35l56_base base;
+ struct work_struct component_register_work;
struct work_struct dsp_work;
struct workqueue_struct *dsp_wq;
struct snd_soc_component *component;
@@ -43,6 +44,7 @@ struct cs35l56_private {
bool sdw_irq_no_unmask;
bool soft_resetting;
bool sdw_attached;
+ bool component_registered;
struct completion init_completion;
int speaker_id;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 161/733] drm/xe/oa: Remove sysfs entry on idr_alloc failure in xe_oa_add_config_ioctl()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (159 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 160/733] ASoC: cs35l56: Fix probe deadlock waiting for SoundWire enumeration Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 162/733] ALSA: dummy: Report a change when one capture switch channel moves Greg Kroah-Hartman
` (583 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Lu Yao, Rodrigo Vivi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lu Yao <yaolu@kylinos.cn>
[ Upstream commit 3663c8d1f31e65771bd73ee3259f35fd397f9933 ]
If idr_alloc() fails after create_dynamic_oa_sysfs_entry() has
succeeded, the error path frees the OA config without removing the
metrics sysfs group.
Remove the sysfs group before releasing the config, and fix up the
misleading error message copied from the sysfs creation failure path.
Fixes: cdf02fe1a94a ("drm/xe/oa/uapi: Add/remove OA config perf ops")
Signed-off-by: Lu Yao <yaolu@kylinos.cn>
Link: https://patch.msgid.link/20260831014218.28515-1-yaolu@kylinos.cn
Reviewed-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(cherry picked from commit 2c6fbda5fdde461d6dedb82a59285182720b8fef)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/xe/xe_oa.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/gpu/drm/xe/xe_oa.c b/drivers/gpu/drm/xe/xe_oa.c
index 18d990c5d4ec4..e5b0f3e2f3894 100644
--- a/drivers/gpu/drm/xe/xe_oa.c
+++ b/drivers/gpu/drm/xe/xe_oa.c
@@ -2431,9 +2431,9 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi
oa_config->id = idr_alloc(&oa->metrics_idr, oa_config, 1, 0, GFP_KERNEL);
if (oa_config->id < 0) {
- drm_dbg(&oa->xe->drm, "Failed to create sysfs entry for OA config\n");
+ drm_dbg(&oa->xe->drm, "Failed to allocate id for OA config\n");
err = oa_config->id;
- goto sysfs_err;
+ goto id_alloc_err;
}
id = oa_config->id;
@@ -2444,6 +2444,8 @@ int xe_oa_add_config_ioctl(struct drm_device *dev, u64 data, struct drm_file *fi
return id;
+id_alloc_err:
+ sysfs_remove_group(oa->metrics_kobj, &oa_config->sysfs_metric);
sysfs_err:
mutex_unlock(&oa->metrics_lock);
reg_err:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 162/733] ALSA: dummy: Report a change when one capture switch channel moves
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (160 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 161/733] drm/xe/oa: Remove sysfs entry on idr_alloc failure in xe_oa_add_config_ioctl() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 163/733] accel/amdxdna: refuse to flush an imported BO Greg Kroah-Hartman
` (582 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Takashi Iwai,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <sammiee5311@gmail.com>
[ Upstream commit 83162eeaf78c71ff6f6fa31dc95e3b6e90ee593f ]
The snd_dummy_capsrc_put() builds its change flag with &&, so it reports
a change only when both channels move at once. Writing a single channel
stores the new value and returns 0, the control core then sends no
SNDRV_CTL_EVENT_MASK_VALUE, and a second reader keeps showing the old
setting until it polls again.
The volume put a few lines above compares the same pair of channels with
||.
The mixer selftest already reports this. With snd-dummy loaded it fails
event_missing on all five capture switches:
# CD Capture Switch.1 orig 0 read 1, is_volatile 0
not ok 13 event_missing.Dummy.9
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Assisted-by: Claude:claude-opus-5
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Link: https://patch.msgid.link/20260901153921.3971-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/drivers/dummy.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/sound/drivers/dummy.c b/sound/drivers/dummy.c
index 41ceeafce824e..21eb0d76d6f8d 100644
--- a/sound/drivers/dummy.c
+++ b/sound/drivers/dummy.c
@@ -782,7 +782,7 @@ static int snd_dummy_capsrc_put(struct snd_kcontrol *kcontrol, struct snd_ctl_el
left = ucontrol->value.integer.value[0] & 1;
right = ucontrol->value.integer.value[1] & 1;
guard(spinlock_irq)(&dummy->mixer_lock);
- change = dummy->capture_source[addr][0] != left &&
+ change = dummy->capture_source[addr][0] != left ||
dummy->capture_source[addr][1] != right;
dummy->capture_source[addr][0] = left;
dummy->capture_source[addr][1] = right;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 163/733] accel/amdxdna: refuse to flush an imported BO
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (161 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 162/733] ALSA: dummy: Report a change when one capture switch channel moves Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 164/733] btrfs: detach failed sprout device from transaction update list Greg Kroah-Hartman
` (581 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König, Lizhi Hou,
Taimuraz Kaitmazov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taimuraz Kaitmazov <taimuraz@kaitmazov.com>
[ Upstream commit 0ba8e0f90039da68342febf613019f4a68d86620 ]
SYNC_BO clflushes an imported BO's scatterlist. An importer may not do
that: the memory belongs to the exporter, and dma-buf gives the importer
no interface to ask for maintenance on it. Refuse the request instead.
is_import_bo() is (obj)->attach, which covers more than foreign buffers.
A userptr BO arrives through a ubuf, and on a carveout device every share
BO and the device heap arrive through a cbuf, so SYNC_BO answers
-EOPNOTSUPP for those too, including the AMDXDNA_BO_DEV path that flushes
through its heap.
Only the ubuf case gives up maintenance it was getting: on a 64 MiB
userptr BO a 4 KiB sync and a full sync both cost 659 us, this arm having
ignored the range. amdxdna_cbuf_map() fills in only the DMA address and
length, so drm_clflush_sg() already walks zero pages on carveout memory.
Userspace maintains these through the mapping it already holds, as XRT's
buffer::sync() does unless it is told to sync through the driver.
Fixes: dbc8fd7a03cb ("accel/amdxdna: Add expandable device heap support")
Reported-by: Christian König <christian.koenig@amd.com>
Link: https://lore.kernel.org/dri-devel/a505f9e5-b416-43e9-934d-c5c29b8a70e9@amd.com/
Suggested-by: Lizhi Hou <lizhi.hou@amd.com>
Signed-off-by: Taimuraz Kaitmazov <taimuraz@kaitmazov.com>
Reviewed-by: Lizhi Hou <lizhi.hou@amd.com>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260819224458.257346-5-taimuraz@kaitmazov.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/accel/amdxdna/amdxdna_gem.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/accel/amdxdna/amdxdna_gem.c b/drivers/accel/amdxdna/amdxdna_gem.c
index 2a16de96e6a4e..219dacdfa527c 100644
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -1240,6 +1240,9 @@ static int amdxdna_flush_bo(struct amdxdna_gem_obj *abo, u64 offset, u64 size)
{
u64 end;
+ if (is_import_bo(abo))
+ return -EOPNOTSUPP;
+
if (offset >= abo->mem.size)
return -EINVAL;
@@ -1250,9 +1253,7 @@ static int amdxdna_flush_bo(struct amdxdna_gem_obj *abo, u64 offset, u64 size)
if (!size)
return 0;
- if (is_import_bo(abo))
- drm_clflush_sg(abo->base.sgt);
- else if (amdxdna_gem_vmap(abo))
+ if (amdxdna_gem_vmap(abo))
drm_clflush_virt_range(amdxdna_gem_vmap(abo) + offset, size);
else if (abo->base.pages)
drm_clflush_pages(abo->base.pages, abo->mem.size >> PAGE_SHIFT);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 164/733] btrfs: detach failed sprout device from transaction update list
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (162 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 163/733] accel/amdxdna: refuse to flush an imported BO Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 165/733] btrfs: restore active device pointers after failed sprout Greg Kroah-Hartman
` (580 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Guanghui Yang,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanghui Yang <3497809730@qq.com>
[ Upstream commit c93b3c43df561cd9f592cee20ae058b563f9e5b6 ]
When creating the first metadata chunk for a sprout filesystem,
create_chunk() adds the new device to the transaction dev_update_list
through device->post_commit_list.
If the subsequent system chunk creation fails, btrfs_init_new_device()
aborts the transaction and releases the device while post_commit_list is
still linked. This triggers a warning in btrfs_free_device() and leaves
the transaction list referencing freed memory.
Detach the device while holding chunk_mutex before releasing it.
Fixes: bbbf7243d62d ("btrfs: combine device update operations during transaction commit")
Assisted-by: Codex:gpt-5
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/volumes.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 6eab4cc73ce44..556d8a60a5ec9 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3071,6 +3071,8 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
btrfs_sysfs_remove_device(device);
mutex_lock(&fs_info->fs_devices->device_list_mutex);
mutex_lock(&fs_info->chunk_mutex);
+ if (!list_empty(&device->post_commit_list))
+ list_del_init(&device->post_commit_list);
list_del_rcu(&device->dev_list);
list_del(&device->dev_alloc_list);
fs_info->fs_devices->num_devices--;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 165/733] btrfs: restore active device pointers after failed sprout
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (163 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 164/733] btrfs: detach failed sprout device from transaction update list Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 166/733] bonding: alb: fix uninitialized transport header access in alb_determine_nd() Greg Kroah-Hartman
` (579 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Guanghui Yang,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guanghui Yang <3497809730@qq.com>
[ Upstream commit e0b54613aabeb8e9da597f23b90c6a03d0981986 ]
btrfs_init_new_device() switches latest_dev and possibly s_bdev from the
seed device to the new sprout device before creating the first writable
chunks.
If chunk creation or the subsequent sprout setup fails, the error path
releases the new device without switching those pointers back.
btrfs_show_devname() can then dereference the freed latest_dev and crash.
Restore the active device pointers to the latest seed device before
removing and releasing the failed sprout device.
Fixes: b7cb29e666fe ("btrfs: update latest_dev when we create a sprout device")
Assisted-by: Codex:gpt-5
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Guanghui Yang <3497809730@qq.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/volumes.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/fs/btrfs/volumes.c b/fs/btrfs/volumes.c
index 556d8a60a5ec9..b90cbd1e3ebe3 100644
--- a/fs/btrfs/volumes.c
+++ b/fs/btrfs/volumes.c
@@ -3070,6 +3070,8 @@ int btrfs_init_new_device(struct btrfs_fs_info *fs_info, const char *device_path
error_sysfs:
btrfs_sysfs_remove_device(device);
mutex_lock(&fs_info->fs_devices->device_list_mutex);
+ if (seeding_dev)
+ btrfs_assign_next_active_device(device, seed_devices->latest_dev);
mutex_lock(&fs_info->chunk_mutex);
if (!list_empty(&device->post_commit_list))
list_del_init(&device->post_commit_list);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 166/733] bonding: alb: fix uninitialized transport header access in alb_determine_nd()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (164 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 165/733] btrfs: restore active device pointers after failed sprout Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 167/733] perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ Greg Kroah-Hartman
` (578 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Joe Damato,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 70f3995830d3f1e79faa14eb0605914f778feca9 ]
alb_determine_nd() uses icmp6_hdr(skb) to inspect ICMPv6 headers.
However, in xmit paths (e.g. packets sent via AF_PACKET / raw sockets
or forwarded packets), skb->transport_header is not guaranteed to be
initialized. While pskb_network_may_pull() ensures the packet data is
linear starting from the network header, it does not set or adjust the
transport header offset.
Dereferencing icmp6_hdr(skb) can therefore access out-of-bounds memory.
Fetch the icmp6hdr directly after ipv6hdr following pskb_network_may_pull(),
and reload ipv6hdr in case pskb_may_pull() reallocated skb->head.
Also remove the unused bond argument from alb_determine_nd().
Fixes: 0da8aa00bfcf ("net: bonding: Add support for IPV6 ns/na to balance-alb/balance-tlb mode")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260831194626.119371-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_alb.c | 13 +++++++------
1 file changed, 7 insertions(+), 6 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index d2fb67a47cf99..654f051d00239 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1281,10 +1281,10 @@ static int alb_set_mac_address(struct bonding *bond, void *addr)
}
/* determine if the packet is NA or NS */
-static bool alb_determine_nd(struct sk_buff *skb, struct bonding *bond)
+static bool alb_determine_nd(struct sk_buff *skb)
{
- struct ipv6hdr *ip6hdr;
- struct icmp6hdr *hdr;
+ const struct ipv6hdr *ip6hdr;
+ const struct icmp6hdr *hdr;
if (!pskb_network_may_pull(skb, sizeof(*ip6hdr)))
return true;
@@ -1296,7 +1296,8 @@ static bool alb_determine_nd(struct sk_buff *skb, struct bonding *bond)
if (!pskb_network_may_pull(skb, sizeof(*ip6hdr) + sizeof(*hdr)))
return true;
- hdr = icmp6_hdr(skb);
+ ip6hdr = ipv6_hdr(skb);
+ hdr = (const struct icmp6hdr *)(ip6hdr + 1);
return hdr->icmp6_type == NDISC_NEIGHBOUR_ADVERTISEMENT ||
hdr->icmp6_type == NDISC_NEIGHBOUR_SOLICITATION;
}
@@ -1381,7 +1382,7 @@ struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
if (!is_multicast_ether_addr(eth_data->h_dest)) {
switch (skb->protocol) {
case htons(ETH_P_IPV6):
- if (alb_determine_nd(skb, bond))
+ if (alb_determine_nd(skb))
break;
fallthrough;
case htons(ETH_P_IP):
@@ -1467,7 +1468,7 @@ struct slave *bond_xmit_alb_slave_get(struct bonding *bond,
break;
}
- if (alb_determine_nd(skb, bond)) {
+ if (alb_determine_nd(skb)) {
do_tx_balance = false;
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 167/733] perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (165 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 166/733] bonding: alb: fix uninitialized transport header access in alb_determine_nd() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 168/733] scsi: mpt3sas: Avoid out-of-bounds cpumask_of_node() call in _base_assign_reply_queues() Greg Kroah-Hartman
` (577 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, Paul Walmsley,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
[ Upstream commit f643f520c4c6998fa27dce90dd3b3ff6414e0bae ]
The overflow IRQ handler dereferences cpu_hw_evt before the null check.
Move the check first. Defensive only; the cookie is valid on the normal
path today.
Fixes: a8625217a054 ("drivers/perf: riscv: Implement SBI PMU snapshot function")
Assisted-by: DeepSeek:deepseek-v3
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/fdd42c791752.v2.1786420235.git.liuxixin@kylinos.cn
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/perf/riscv_pmu_sbi.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/perf/riscv_pmu_sbi.c b/drivers/perf/riscv_pmu_sbi.c
index dfc886dee5ad0..f0dd9d2645b44 100644
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1050,11 +1050,13 @@ static irqreturn_t pmu_sbi_ovf_handler(int irq, void *dev)
u64 overflowed_ctrs = 0;
struct cpu_hw_events *cpu_hw_evt = dev;
u64 start_clock = sched_clock();
- struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
+ struct riscv_pmu_snapshot_data *sdata;
if (WARN_ON_ONCE(!cpu_hw_evt))
return IRQ_NONE;
+ sdata = cpu_hw_evt->snapshot_addr;
+
/* Firmware counter don't support overflow yet */
fidx = find_first_bit(cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS);
if (fidx == RISCV_MAX_COUNTERS) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 168/733] scsi: mpt3sas: Avoid out-of-bounds cpumask_of_node() call in _base_assign_reply_queues()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (166 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 167/733] perf: RISC-V: check cpu_hw_evt before dereference in overflow IRQ Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 169/733] sched/rt,dl: Skip migrate-disabled tasks when picking a push candidate Greg Kroah-Hartman
` (576 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Thumshirn, Ivy Lopez,
John Garry, Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivy Lopez <skunkolee@gmail.com>
[ Upstream commit e0d26fe176a8db6ccad4ab38c5bab29391c1946b ]
dev_to_node() can return NUMA_NO_NODE (-1) on systems without NUMA
topology information for the PCI device, such as single-socket boards
that don't expose device-to-node affinity. Passing -1 directly into
cpumask_of_node() indexes node_to_cpumask_map[-1], an out-of-bounds
array read caught by UBSAN:
UBSAN: array-index-out-of-bounds in arch/x86/include/asm/topology.h:72:28
index -1 is out of range for type 'cpumask *[1024]'
Fall back to cpu_online_mask when no NUMA node is available, rather than
assuming dev_to_node() always returns a valid node index.
Link: https://bugzilla.kernel.org/show_bug.cgi?id=221294
Suggested-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Fixes: 728bbc6cbff7 ("scsi: mpt3sas: Affinity high iops queues IRQs to local node")
Signed-off-by: Ivy Lopez <skunkolee@gmail.com>
Reviewed-by: John Garry <john.g.garry@oracle.com>
Link: https://patch.msgid.link/20260825190313.24013-1-skunkolee@gmail.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/scsi/mpt3sas/mpt3sas_base.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/scsi/mpt3sas/mpt3sas_base.c b/drivers/scsi/mpt3sas/mpt3sas_base.c
index 11bcb8440e1c8..ae2f7d9c281f9 100644
--- a/drivers/scsi/mpt3sas/mpt3sas_base.c
+++ b/drivers/scsi/mpt3sas/mpt3sas_base.c
@@ -3238,7 +3238,10 @@ _base_assign_reply_queues(struct MPT3SAS_ADAPTER *ioc)
* corresponding to high iops queues.
*/
if (ioc->high_iops_queues) {
- mask = cpumask_of_node(dev_to_node(&ioc->pdev->dev));
+ int node = dev_to_node(&ioc->pdev->dev);
+
+ mask = (node == NUMA_NO_NODE) ?
+ cpu_online_mask : cpumask_of_node(node);
for (index = 0; index < ioc->high_iops_queues;
index++) {
irq = pci_irq_vector(ioc->pdev, index);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 169/733] sched/rt,dl: Skip migrate-disabled tasks when picking a push candidate
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (167 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 168/733] scsi: mpt3sas: Avoid out-of-bounds cpumask_of_node() call in _base_assign_reply_queues() Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 170/733] sched/core: Skip rq->avg_idle update without a valid idle_stamp Greg Kroah-Hartman
` (575 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Seiji Nishikawa,
Peter Zijlstra (Intel), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seiji Nishikawa <snishika@redhat.com>
[ Upstream commit dae5c0292080dd7b9c7d784268dcf443f1f3d15e ]
A migrate_disable()'d RT task cannot be moved to another CPU, but the
scheduler still keeps such a task on that CPU's pushable list
(rq->rt.pushable_tasks) and still marks the runqueue RT-overloaded
(rq->rt.overloaded = 1). So the RT balancer keeps treating this CPU as
having a task to move away, and keeps trying to move the task, but the
push can never succeed. When the head is pinned, push_rt_task() does not
give up either. It falls back to pushing rq->curr instead, using the
per-CPU stopper, as added by commit a7c81556ec4d ("sched: Fix
migrate_disable() vs rt/dl balancing").
The CPU spends tens of milliseconds in this retry loop. The core is
isolated for real-time work, but during the loop nearly half of its time
is consumed by pushes that cannot succeed.
An ftrace capture of the affected CPU, with sched_switch enabled and
commit 94894c9c477e ("sched/rt: Skip currently executing CPU in
rto_next_cpu()") applied, shows where the CPU time went. Two SCHED_FIFO
tasks at equal priority shared the CPU, taskA migrate_disable()'d and
queued, taskB as rq->curr. In one 89 ms window, taskB got only 52 ms of
CPU. The other 37 ms went to the stopper thread.
The scheduler kept trying to push taskA, the pinned head of the pushable
list, fell back to pushing taskB instead, and woke the stopper 5204
times. Every one of those pushes failed and no task was moved. taskA
stayed runnable and queued the whole time, and never ran.
Pushing taskB fails on a re-check. find_lock_lowest_rq() drops the rq
lock to take the target rq lock, then checks again with
"task != pick_next_pushable_task(rq)".
The task being pushed is taskB, but the pick returns taskA, the head of
the pushable list. taskB is rq->curr, and set_next_task_rt() removes the
running task from that list, so taskB can never be the head. The check
expects a candidate taken from the pushable list, but the fallback
pushes rq->curr, which is never on that list. So the check fails every
time.
.--> push-IPI arrives
| |
| v
| pushable head = taskA -> pinned, cannot be pushed
| |
| v
| so push taskB instead -> wake migration/N, a stop-class
| | thread, so it preempts taskB
| v
| re-check compares taskB against the pushable head,
| which is still taskA -> give up
| |
| v
| nothing moved, taskA still queued, rq still overloaded
| |
'----------'
repeats every ~17 us, 5204 times, for 89 ms
The loop cannot stop itself. Every round leaves the runqueue
exactly as it was, so the next push-IPI does the same thing. In
the capture it ended only when taskB went to sleep on its own.
taskA was then picked locally and left the pushable list.
CPU time per task in the window, from sched_switch:
taskB 51.95 ms real work
migration/N 37.18 ms nothing moved
taskA 0.00 ms queued the whole time, never picked
idle 0.01 ms
Counts over the same window:
7667 push-IPIs handled on this CPU
17481 pick_next_pushable_task() returned taskA, still pinned
5204 find_lock_lowest_rq() gave up on the re-check
1 push that actually completed
0 migrations of taskA
The CPU times and the window length come from the standard
sched_switch tracepoint. The counts needed tracepoints added inside
the RT balancer for this investigation.
The self-IPI path is closed by the rto_next_cpu() fix above, and that
part works. But the runqueue is still marked overloaded, because the
pinned task is still advertised as pushable. Other CPUs now send the
push-IPIs during their own RT balancing, and the same loop runs again.
Closing the self-IPI path did not stop a pinned task from triggering
push balancing.
A pinned task should never have been returned as a push candidate in the
first place. A migrate_disable()'d task cannot be migrated, so it
belongs in the same skip that was added for on_cpu tasks by
commit e0ca8991b2de ("sched: Make class_schedulers avoid pushing
current, and get rid of proxy_tag_curr()"). Add is_migration_disabled()
to the skip condition in pick_next_pushable_task() and
pick_next_pushable_dl_task().
With the skip in place, if the pinned task is the only extra runnable
task the helpers return NULL, push_rt_task() and push_dl_task() give up
early, and no stopper is woken. The pinned task then runs locally once
curr yields. If a task that really can be migrated is queued behind the
pinned head, it is now picked and pushed for real.
This makes the fallback that pushes rq->curr unreachable when the
pushable head is migrate-disabled. Nothing is lost, because that path
was always stopped by the re-check described above. In the capture it
ran 5204 times and moved nothing.
Fixes: a7c81556ec4d ("sched: Fix migrate_disable() vs rt/dl balancing")
Signed-off-by: Seiji Nishikawa <snishika@redhat.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260830073746.2189355-1-snishika@redhat.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/deadline.c | 4 ++--
kernel/sched/rt.c | 4 ++--
2 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 857dbe3519a86..0663c00c41c04 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -3028,8 +3028,8 @@ static struct task_struct *pick_next_pushable_dl_task(struct rq *rq)
next_node = rb_first_cached(&rq->dl.pushable_dl_tasks_root);
while (next_node) {
i = __node_2_pdl(next_node);
- /* make sure task isn't on_cpu (possible with proxy-exec) */
- if (!task_on_cpu(rq, i)) {
+ /* skip tasks that cannot be migrated */
+ if (!task_on_cpu(rq, i) && !is_migration_disabled(i)) {
p = i;
break;
}
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index e6e5f8a2caafb..85303add726df 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1872,8 +1872,8 @@ static struct task_struct *pick_next_pushable_task(struct rq *rq)
return NULL;
plist_for_each_entry(i, head, pushable_tasks) {
- /* make sure task isn't on_cpu (possible with proxy-exec) */
- if (!task_on_cpu(rq, i)) {
+ /* skip tasks that cannot be migrated */
+ if (!task_on_cpu(rq, i) && !is_migration_disabled(i)) {
p = i;
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 170/733] sched/core: Skip rq->avg_idle update without a valid idle_stamp
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (168 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 169/733] sched/rt,dl: Skip migrate-disabled tasks when picking a push candidate Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:07 ` [PATCH 7.2 171/733] x86/itmt: Dont make ITMT enablement depend on debugfs Greg Kroah-Hartman
` (574 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shubhang Kaushik (Ampere),
Peter Zijlstra (Intel), K Prateek Nayak, Vincent Guittot,
John Stultz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shubhang Kaushik (Ampere) <sh@gentwo.org>
[ Upstream commit c6dcd97c8be75f052a1ca52cf79b03e7292962f1 ]
Commit 4b603f1551a73 ("sched: Update rq->avg_idle when a task is moved
to an idle CPU") moved rq->avg_idle accounting out of the wakeup path and
into put_prev_task_idle(), so that the idle interval is consumed whenever
the idle task is switched out.
The wakeup-side accounting that it replaced only updated rq->avg_idle
when rq->idle_stamp was non-zero. The new helper lost that validity
check and unconditionally computes:
rq_clock(rq) - rq->idle_stamp
If rq->idle_stamp is zero, this uses rq_clock(rq) as the sample. That is
not a valid idle duration and can immediately drive rq->avg_idle to its
clamp.
This can happen when sched_balance_newidle() returns before setting
rq->idle_stamp, for example when this_rq->ttwu_pending is set. In that
case the rq can switch to the idle task with idle_stamp still zero and
leave idle again when the pending wakeup is processed.
Other paths can also switch to the idle task without setting
rq->idle_stamp via newidle_balance(), for example find_proxy_task() or
force-idling.
Restore the idle_stamp validity check in update_rq_avg_idle() and skip
the rq->avg_idle update when there is no measured idle interval.
Fixes: 4b603f1551a73 ("sched: Update rq->avg_idle when a task is moved to an idle CPU")
Signed-off-by: Shubhang Kaushik (Ampere) <sh@gentwo.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Reviewed-by: Vincent Guittot <vincent.guittot@linaro.org>
Acked-by: John Stultz <jstultz@google.com>
Link: https://patch.msgid.link/20260807-master-v3-1-c328354efed3@gentwo.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/core.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index 87caa1290fad6..d0992ecda4c72 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -3743,11 +3743,17 @@ static inline void ttwu_do_wakeup(struct task_struct *p)
void update_rq_avg_idle(struct rq *rq)
{
- u64 delta = rq_clock(rq) - rq->idle_stamp;
- u64 max = 2*rq->max_idle_balance_cost;
+ u64 idle_stamp = rq->idle_stamp;
+ u64 delta, max;
+
+ if (!idle_stamp)
+ return;
+
+ delta = rq_clock(rq) - idle_stamp;
update_avg(&rq->avg_idle, delta);
+ max = 2 * rq->max_idle_balance_cost;
if (rq->avg_idle > max)
rq->avg_idle = max;
rq->idle_stamp = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 171/733] x86/itmt: Dont make ITMT enablement depend on debugfs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (169 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 170/733] sched/core: Skip rq->avg_idle update without a valid idle_stamp Greg Kroah-Hartman
@ 2026-09-17 15:07 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 172/733] perf/core: Skip empty AUX records with only format flags Greg Kroah-Hartman
` (573 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:07 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Klaus Kusche, Mario Limonciello,
Peter Zijlstra (Intel), Tim Chen, K Prateek Nayak, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <mario.limonciello@amd.com>
[ Upstream commit eaece4849991d62fcd6f46637c55dcce00e25d70 ]
sched_set_itmt_support() treats debugfs file creation failures as fatal.
When CONFIG_DEBUG_FS is disabled, debugfs stubs return ERR_PTR(-ENODEV),
causing ITMT to be silently disabled.
debugfs is a debug-only facility; its return values should be ignored.
Drop the fatal error handling and enable ITMT unconditionally.
Fixes: d04013a4b21b ("x86/itmt: Move the "sched_itmt_enabled" sysctl to debugfs")
Reported-by: Klaus Kusche <klaus.kusche@computerix.info>
Signed-off-by: Mario Limonciello <mario.limonciello@amd.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: Tim Chen <tim.c.chen@linux.intel.com>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://patch.msgid.link/20260831053836.1881864-1-mario.limonciello@amd.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/kernel/itmt.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/arch/x86/kernel/itmt.c b/arch/x86/kernel/itmt.c
index 243a769fdd97b..85ebde361d6ae 100644
--- a/arch/x86/kernel/itmt.c
+++ b/arch/x86/kernel/itmt.c
@@ -110,18 +110,14 @@ int sched_set_itmt_support(void)
arch_debugfs_dir,
&sysctl_sched_itmt_enabled,
&dfs_sched_itmt_fops);
- if (IS_ERR_OR_NULL(dfs_sched_itmt)) {
+ if (IS_ERR(dfs_sched_itmt))
dfs_sched_itmt = NULL;
- return -ENOMEM;
- }
dfs_sched_core_prio = debugfs_create_file("sched_core_priority", 0644,
arch_debugfs_dir, NULL,
&sched_core_priority_fops);
- if (IS_ERR_OR_NULL(dfs_sched_core_prio)) {
+ if (IS_ERR(dfs_sched_core_prio))
dfs_sched_core_prio = NULL;
- return -ENOMEM;
- }
sched_itmt_capable = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 172/733] perf/core: Skip empty AUX records with only format flags
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (170 preceding siblings ...)
2026-09-17 15:07 ` [PATCH 7.2 171/733] x86/itmt: Dont make ITMT enablement depend on debugfs Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 173/733] locking/lockdep: Invalidate stale class_cache entries for zapped classes Greg Kroah-Hartman
` (572 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tamas Petz, Leo Yan,
Peter Zijlstra (Intel), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leo Yan <leo.yan@arm.com>
[ Upstream commit 8a7f5b5e860b5c113ca99acd5b1e9074f5c5af3c ]
perf_aux_output_end() emits a PERF_RECORD_AUX when the recorded size is
nonzero or when any flag other than PERF_AUX_FLAG_OVERWRITE is set.
PMU format flags describe how an AUX payload is encoded. TRBE driver
sets PERF_AUX_FLAG_CORESIGHT_FORMAT_RAW for raw trace buffers, causing
an AUX record to be emitted even when no trace data.
This is noticeable when tracing a task with strace. Ptrace stops
repeatedly end empty AUX transactions, producing many zero-sized
PERF_RECORD_AUX records. For example:
perf record -e cs_etm//u -m,128M -- strace ls
perf script -D 2>&1 |
awk '/PERF_RECORD_AUX offset/ {
for (i = 1; i <= NF; i++)
if ($i == "size:" && $(i + 1) == "0")
count++
}
END { print count }'
165
This recording contains 165 zero-sized AUX records which provide no
useful information to userspace.
Ignore PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK, together with
PERF_AUX_FLAG_OVERWRITE, when deciding whether an empty AUX record is
useful. Zero-sized records carrying TRUNCATED, PARTIAL or COLLISION
are still emitted.
Fixes: 547b60988e63 ("perf: aux: Add flags for the buffer format")
Reported-by: Tamas Petz <tamas.petz@arm.com>
Signed-off-by: Leo Yan <leo.yan@arm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260825-perf_core_fix_zero_aux_records-v1-1-23b95e8d5df3@arm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/events/ring_buffer.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
diff --git a/kernel/events/ring_buffer.c b/kernel/events/ring_buffer.c
index 9fe92161715e0..1b1ffe0533e58 100644
--- a/kernel/events/ring_buffer.c
+++ b/kernel/events/ring_buffer.c
@@ -509,7 +509,10 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
/*
* Only send RECORD_AUX if we have something useful to communicate
*
- * Note: the OVERWRITE records by themselves are not considered
+ * PMU_FORMAT bits identify the PMU type rather than an AUX event
+ * has occurred, so ignore them for zero-sized records.
+ *
+ * The OVERWRITE records by themselves are not considered
* useful, as they don't communicate any *new* information,
* aside from the short-lived offset, that becomes history at
* the next event sched-in and therefore isn't useful.
@@ -518,7 +521,9 @@ void perf_aux_output_end(struct perf_output_handle *handle, unsigned long size)
* offset. So, from now on we don't output AUX records that
* have *only* OVERWRITE flag set.
*/
- if (size || (handle->aux_flags & ~(u64)PERF_AUX_FLAG_OVERWRITE))
+ if (size ||
+ (handle->aux_flags & ~(u64)(PERF_AUX_FLAG_PMU_FORMAT_TYPE_MASK |
+ PERF_AUX_FLAG_OVERWRITE)))
perf_event_aux_event(handle->event, aux_head, size,
handle->aux_flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 173/733] locking/lockdep: Invalidate stale class_cache entries for zapped classes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (171 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 172/733] perf/core: Skip empty AUX records with only format flags Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 174/733] octeontx2-af: Fix limiting SRIOV VF count logic Greg Kroah-Hartman
` (571 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+2d770620059281e225a4,
Eric Dumazet, Peter Zijlstra (Intel), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 02c6be7d675b21d81f0ba3a524346850a8c0e3bf ]
syzbot reported a lockdep splat hitting DEBUG_LOCKS_WARN_ON(1) in
hlock_class() due to an invalid class_idx:
WARNING: kernel/locking/lockdep.c:238 at __lock_acquire+0x382/0x2cf0 kernel/locking/lockdep.c:5203
Workqueue: wg-crypt-wg0 wg_packet_tx_worker
RIP: 0010:hlock_class kernel/locking/lockdep.c:238 [inline]
RIP: 0010:check_wait_context kernel/locking/lockdep.c:4870 [inline]
RIP: 0010:__lock_acquire+0x389/0x2cf0 kernel/locking/lockdep.c:5203
Call Trace:
<IRQ>
lock_acquire+0x106/0x350 kernel/locking/lockdep.c:5886
_raw_spin_lock+0x2e/0x40 kernel/locking/spinlock.c:173
tcp_tsq_handler+0x29/0x200 net/ipv4/tcp_output.c:1291
tcp_tsq_workfn+0x384/0x410 net/ipv4/tcp_output.c:1325
...
When a lock class is zapped (e.g. during module unload or key
unregistration), zap_class() clears the class's bit in
lock_classes_in_use and removes it from the class hash table.
However, existing lockdep_map instances embedded in data structures
may still retain a pointer to the zapped class in their class_cache[]
array.
When __lock_acquire() subsequently runs on such a lock, it finds
lock->class_cache[subclass] != NULL, skipping register_lock_class()
and assigning hlock->class_idx to the index of the zapped class. When
check_wait_context() or hlock_class() inspects the held_lock, it finds
!test_bit(class_idx, lock_classes_in_use) and warns. Furthermore, if
the zapped slot is subsequently re-allocated to an unrelated lock key,
the stale class_cache entry would erroneously match the unrelated
class (ABA issue).
Add lock_class_cache_is_valid() to validate that the cached class is
within lock_classes bounds, still allocated in lock_classes_in_use
(using uninstrumented arch_test_bit() in __always_inline context so it
is safe in noinstr contexts like match_held_lock()), and that
class->key matches the expected subkey (taking lockdep_set_subclass()
overrides into account). Also use READ_ONCE()/WRITE_ONCE() when
accessing class_cache[]. If the entry is invalid or stale, fall back
to register_lock_class() / look_up_lock_class().
Fixes: a0b0fd53e1e6 ("locking/lockdep: Free lock classes that are no longer in use")
Closes: https://lore.kernel.org/netdev/6a8c66dc.4d75e56a.c9a88.0050.GAE@google.com/T/#u
Reported-by: syzbot+2d770620059281e225a4@syzkaller.appspotmail.com
Assisted-by: Gemini:gemini-3.1-pro
Signed-off-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260824155129.676096-1-edumazet@google.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/locking/lockdep.c | 50 +++++++++++++++++++++++++++++++++-------
1 file changed, 42 insertions(+), 8 deletions(-)
diff --git a/kernel/locking/lockdep.c b/kernel/locking/lockdep.c
index e0de811148242..06f025abe8875 100644
--- a/kernel/locking/lockdep.c
+++ b/kernel/locking/lockdep.c
@@ -947,6 +947,34 @@ look_up_lock_class(const struct lockdep_map *lock, unsigned int subclass)
return NULL;
}
+static __always_inline bool lock_class_cache_is_valid(const struct lockdep_map *lock,
+ const struct lock_class *class,
+ unsigned int subclass)
+{
+ unsigned int class_subclass;
+
+ if (!class)
+ return false;
+
+ if (unlikely(class < lock_classes || class >= lock_classes + MAX_LOCKDEP_KEYS))
+ return false;
+
+ if (unlikely(!arch_test_bit(class - lock_classes, lock_classes_in_use)))
+ return false;
+
+ if (unlikely(!lock->key))
+ return false;
+
+ class_subclass = subclass ? subclass : class->subclass;
+ if (unlikely(class_subclass >= MAX_LOCKDEP_SUBCLASSES))
+ return false;
+
+ if (unlikely(READ_ONCE(class->key) != lock->key->subkeys + class_subclass))
+ return false;
+
+ return true;
+}
+
/*
* Static locks do not have their class-keys yet - for them the key is
* the lock object itself. If the lock is in the per cpu area, the
@@ -1379,9 +1407,9 @@ register_lock_class(struct lockdep_map *lock, unsigned int subclass, int force)
out_set_class_cache:
if (!subclass || force)
- lock->class_cache[0] = class;
+ WRITE_ONCE(lock->class_cache[0], class);
else if (subclass < NR_LOCKDEP_CACHING_CLASSES)
- lock->class_cache[subclass] = class;
+ WRITE_ONCE(lock->class_cache[subclass], class);
/*
* Hash collision, did we smoke some? We found a class with a matching
@@ -4941,7 +4969,7 @@ void lockdep_init_map_type(struct lockdep_map *lock, const char *name,
int i;
for (i = 0; i < NR_LOCKDEP_CACHING_CLASSES; i++)
- lock->class_cache[i] = NULL;
+ WRITE_ONCE(lock->class_cache[i], NULL);
#ifdef CONFIG_LOCK_STAT
lock->cpu = raw_smp_processor_id();
@@ -5006,12 +5034,15 @@ EXPORT_SYMBOL_GPL(__lockdep_no_track__);
void lockdep_set_lock_cmp_fn(struct lockdep_map *lock, lock_cmp_fn cmp_fn,
lock_print_fn print_fn)
{
- struct lock_class *class = lock->class_cache[0];
+ struct lock_class *class = READ_ONCE(lock->class_cache[0]);
unsigned long flags;
raw_local_irq_save(flags);
lockdep_recursion_inc();
+ if (!lock_class_cache_is_valid(lock, class, 0))
+ class = NULL;
+
if (!class)
class = register_lock_class(lock, 0, 0);
@@ -5103,8 +5134,11 @@ static int __lock_acquire(struct lockdep_map *lock, unsigned int subclass,
if (DEBUG_LOCKS_WARN_ON(subclass >= MAX_LOCKDEP_SUBCLASSES))
return 0;
- if (subclass < NR_LOCKDEP_CACHING_CLASSES)
- class = lock->class_cache[subclass];
+ if (subclass < NR_LOCKDEP_CACHING_CLASSES) {
+ class = READ_ONCE(lock->class_cache[subclass]);
+ if (!lock_class_cache_is_valid(lock, class, subclass))
+ class = NULL;
+ }
/*
* Not cached?
*/
@@ -5307,9 +5341,9 @@ static noinstr int match_held_lock(const struct held_lock *hlock,
return 1;
if (hlock->references) {
- const struct lock_class *class = lock->class_cache[0];
+ const struct lock_class *class = READ_ONCE(lock->class_cache[0]);
- if (!class)
+ if (!lock_class_cache_is_valid(lock, class, 0))
class = look_up_lock_class(lock, 0);
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 174/733] octeontx2-af: Fix limiting SRIOV VF count logic
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (172 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 173/733] locking/lockdep: Invalidate stale class_cache entries for zapped classes Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 175/733] ksmbd: fix sparc build with atomic work state Greg Kroah-Hartman
` (570 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sunil Goutham, Nitin Shetty J,
David S. Miller, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunil Goutham <sgoutham@marvell.com>
[ Upstream commit f695390ea63941a9e412bf1f3afe65ab245fc681 ]
When RVU PF0/AF's VFs are SDP instead of LBK, limiting the VF count
based on the LBK channel count is incorrect.
Apply LBK channel-based VF limits only when the VF device ID matches
the LBK RVU AFVF device.
Fixes: 9bd6caf33567 ("octeontx2-af: Enable sriov on AF to create VFs")
Signed-off-by: Sunil Goutham <sgoutham@marvell.com>
Signed-off-by: Nitin Shetty J <nshettyj@marvell.com>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/marvell/octeontx2/af/rvu.c | 33 +++++++++++--------
1 file changed, 19 insertions(+), 14 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
index 74c041ab5280a..937b085582b5f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu.c
@@ -3468,6 +3468,8 @@ int rvu_get_num_lbk_chans(void)
return ret;
}
+#define PCI_DEVID_OCTEONTX2_RVU_AFVF 0xA0F8
+
static int rvu_enable_sriov(struct rvu *rvu)
{
struct pci_dev *pdev = rvu->pdev;
@@ -3486,24 +3488,27 @@ static int rvu_enable_sriov(struct rvu *rvu)
return 0;
pci_read_config_word(pdev, pos + PCI_SRIOV_VF_DID, &rvu->vf_devid);
- chans = rvu_get_num_lbk_chans();
- if (chans < 0)
- return chans;
-
vfs = pci_sriov_get_totalvfs(pdev);
-
- /* Limit VFs in case we have more VFs than LBK channels available. */
- if (vfs > chans)
- vfs = chans;
-
if (!vfs)
return 0;
- /* LBK channel number 63 is used for switching packets between
- * CGX mapped VFs. Hence limit LBK pairs till 62 only.
- */
- if (vfs > 62)
- vfs = 62;
+ if (rvu->vf_devid == PCI_DEVID_OCTEONTX2_RVU_AFVF) {
+ chans = rvu_get_num_lbk_chans();
+ if (chans < 0)
+ return chans;
+
+ /* The last LBK channel is reserved for switching packets between
+ * CGX mapped VFs. Also, since LBK VFs work in pairs, limit VF
+ * count to available LBK channels minus 2.
+ */
+ vfs = min(vfs, chans - 2);
+
+ if (vfs <= 0) {
+ dev_warn(&pdev->dev,
+ "Skipping SRIOV enablement, not enough LBK channels available\n");
+ return 0;
+ }
+ }
/* Save VFs number for reference in VF interrupts handlers.
* Since interrupts might start arriving during SRIOV enablement
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 175/733] ksmbd: fix sparc build with atomic work state
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (173 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 174/733] octeontx2-af: Fix limiting SRIOV VF count logic Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 176/733] ALSA: ump: do not touch legacy_rmidi before it exists Greg Kroah-Hartman
` (569 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Namjae Jeon,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <linkinjeon@kernel.org>
[ Upstream commit 636abbe7a66d80e179011a31754d55001cd44f63 ]
Use an unsigned int for the work state so xchg() uses a supported
4-byte operation on sparc.
Fixes: d12168084c8c ("ksmbd: safely drain sessions during logoff")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609021157.8f7Wx34I-lkp@intel.com/
Signed-off-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/smb/server/ksmbd_work.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/smb/server/ksmbd_work.h b/fs/smb/server/ksmbd_work.h
index 5f1d3ebab4fb5..0844aa929f55d 100644
--- a/fs/smb/server/ksmbd_work.h
+++ b/fs/smb/server/ksmbd_work.h
@@ -82,7 +82,7 @@ struct ksmbd_work {
/* Contiguous SMB2 compression transform owned by this work item. */
void *compress_buf;
- unsigned char state;
+ unsigned int state;
/* No response for cancelled request */
bool send_no_response:1;
/* Request is encrypted */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 176/733] ALSA: ump: do not touch legacy_rmidi before it exists
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (174 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 175/733] ksmbd: fix sparc build with atomic work state Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 177/733] printk/nbcon: Change nbcon_irq_work to IRQ_WORK_LAZY Greg Kroah-Hartman
` (568 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Qingyu Zhang, Takashi Iwai,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingyu Zhang <usupergate@gmail.com>
[ Upstream commit adeee7187694719890aaffdc14b7e89cfd736f1d ]
snd_ump_parse_endpoint() sets ump->parsed on every exit, including
error, before the caller attaches the legacy rawmidi device.
ump_handle_ep_name_msg() then treats parsed as "legacy_rmidi is live"
and calls ump_legacy_set_rawmidi_name(), which snprintf()s into
ump->legacy_rmidi->name. If a UMP packet arrives in that window
(IRQ path from snd_ump_receive), legacy_rmidi is still NULL
(KASAN null-ptr-deref in snprintf).
Guard the legacy helpers. parsed only means endpoint info was
parsed, not that legacy_rmidi exists.
Fixes: 37e0e14128e0 ("ALSA: ump: Support UMP Endpoint and Function Block parsing")
Signed-off-by: Qingyu Zhang <usupergate@gmail.com>
Link: https://patch.msgid.link/20260902073918.880245-1-usupergate@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/core/ump.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/sound/core/ump.c b/sound/core/ump.c
index 632c13baf21e1..a85d1006e7a51 100644
--- a/sound/core/ump.c
+++ b/sound/core/ump.c
@@ -1333,6 +1333,8 @@ static void update_legacy_names(struct snd_ump_endpoint *ump)
{
struct snd_rawmidi *rmidi = ump->legacy_rmidi;
+ if (!rmidi)
+ return;
update_legacy_substreams(ump, rmidi, SNDRV_RAWMIDI_STREAM_INPUT);
update_legacy_substreams(ump, rmidi, SNDRV_RAWMIDI_STREAM_OUTPUT);
}
@@ -1341,6 +1343,8 @@ static void ump_legacy_set_rawmidi_name(struct snd_ump_endpoint *ump)
{
struct snd_rawmidi *rmidi = ump->legacy_rmidi;
+ if (!rmidi)
+ return;
snprintf(rmidi->name, sizeof(rmidi->name), "%.68s (MIDI 1.0)",
ump->core.name);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 177/733] printk/nbcon: Change nbcon_irq_work to IRQ_WORK_LAZY
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (175 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 176/733] ALSA: ump: do not touch legacy_rmidi before it exists Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 178/733] platform/x86: x86-android-tablets: hold device reference for secondary fwnode teardown Greg Kroah-Hartman
` (567 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Ogness,
Sebastian Andrzej Siewior, Petr Mladek, Jon Hunter, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Ogness <john.ogness@linutronix.de>
[ Upstream commit 560f4deda32785e260056200f8bb911c475c5b88 ]
Change the nbcon_irq_work to be IRQ_WORK_LAZY, thus not raising
an IRQ upon irq_work queuing. The irq_work is then handled on the
next kernel tick. This additional delay is acceptable because
nbcon_irq_work is only responsible for non-emergency deferred
printing, which is delayed anyway. This has the benefit of not
needing to raise an IRQ for each printk() call.
On a side note, the Tegra20 and Tegra30 platforms can hang if an
irq_work IRQ is raised while entering cpuidle states. This problem
was reproducible by calling printk() while entering cpuidle. So
this change also provides a workaround for these platforms (as long
as they are not running tickless).
Link: https://lore.kernel.org/lkml/f3757a75-0ba1-4558-bf57-f19ab7e59a4c@nvidia.com
Fixes: 76f258bf3f2a ("printk: nbcon: Introduce printer kthreads")
Signed-off-by: John Ogness <john.ogness@linutronix.de>
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Reviewed-by: Petr Mladek <pmladek@suse.com>
Tested-by: Jon Hunter <jonathanh@nvidia.com>
Link: https://patch.msgid.link/20260901093245.344455-3-john.ogness@linutronix.de
Signed-off-by: Petr Mladek <pmladek@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/printk/nbcon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/printk/nbcon.c b/kernel/printk/nbcon.c
index a5921a84a80ed..ad79e30afd647 100644
--- a/kernel/printk/nbcon.c
+++ b/kernel/printk/nbcon.c
@@ -1782,7 +1782,7 @@ bool nbcon_alloc(struct console *con)
}
rcuwait_init(&con->rcuwait);
- init_irq_work(&con->irq_work, nbcon_irq_work);
+ con->irq_work = IRQ_WORK_INIT_LAZY(nbcon_irq_work);
atomic_long_set(&ACCESS_PRIVATE(con, nbcon_prev_seq), -1UL);
nbcon_state_set(con, &state);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 178/733] platform/x86: x86-android-tablets: hold device reference for secondary fwnode teardown
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (176 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 177/733] printk/nbcon: Change nbcon_irq_work to IRQ_WORK_LAZY Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 179/733] ASoC: ux500: Fix MSP stream lifecycle handling Greg Kroah-Hartman
` (566 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dmitry Torokhov, Hans de Goede,
Andy Shevchenko, Linus Walleij, Ilpo Järvinen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <dmitry.torokhov@gmail.com>
[ Upstream commit 144113b0a70fa18033a747ee5db6803308f7688c ]
In gpio_secondary_fwnode_init(), acpi_bus_find_device_by_name() returns a
device reference, but the local dev variable is declared with
__free(put_device), dropping the reference at the end of each iteration.
Meanwhile, devm_add_action_or_reset() saves the dev pointer for
gpio_secondary_unset() without incrementing its reference count, which
could lead to a use-after-free during driver teardown if the device is
released in the interim.
Acquire an explicit device reference with get_device() when registering
the devres action, and drop it with put_device() inside
gpio_secondary_unset().
Fixes: 1448c2d2ca5c ("platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips")
Assisted-by: LLM
Signed-off-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Tested-by: Hans de Goede <johannes.goede@oss.qualcomm.com> # Yoga tab 2 1380, yt3
Reviewed-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@intel.com>
Reviewed-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260830-x86-android-lenovo-swnode-v1-2-066a91acb4ba@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/x86-android-tablets/core.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
index 5db794d65eb5f..722c0ae4ecd12 100644
--- a/drivers/platform/x86/x86-android-tablets/core.c
+++ b/drivers/platform/x86/x86-android-tablets/core.c
@@ -367,6 +367,7 @@ static void gpio_secondary_unset(void *data)
struct device *dev = data;
set_secondary_fwnode(dev, NULL);
+ put_device(dev);
}
static void gpio_secondary_unregister_node_group(void *data)
@@ -409,7 +410,7 @@ static int gpio_secondary_fwnode_init(struct device *parent)
set_secondary_fwnode(dev, fwnode);
- ret = devm_add_action_or_reset(parent, gpio_secondary_unset, dev);
+ ret = devm_add_action_or_reset(parent, gpio_secondary_unset, get_device(dev));
if (ret)
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 179/733] ASoC: ux500: Fix MSP stream lifecycle handling
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (177 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 178/733] platform/x86: x86-android-tablets: hold device reference for secondary fwnode teardown Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 180/733] ASoC: ux500: Propagate MSP setup errors Greg Kroah-Hartman
` (565 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit c37ba8fe00f264eee2fd18b0bff7c5f188136c51 ]
The trigger stop path drops the direction busy flag even though ALSA
still owns the stream until shutdown. A later trigger cannot reliably
restart it, shutdown may leave the block configured, and a second
stream may overwrite shared duplex configuration.
Keep configured and running directions as separate state. Program
shared settings only for the first direction, require a compatible
configuration for the other half of a duplex stream, and enable the
frame generator only while a provider stream is running. Also fix the
RX-disable direction test and preserve the other direction multichannel
setup.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-1-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 8 +-
sound/soc/ux500/ux500_msp_i2s.c | 183 ++++++++++++++++++++++++--------
sound/soc/ux500/ux500_msp_i2s.h | 4 +
3 files changed, 149 insertions(+), 46 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 7798957c6504d..7d65408989340 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -34,8 +34,10 @@ static int setup_pcm_multichan(struct snd_soc_dai *dai,
if (drvdata->slots > 1) {
msp_config->multichannel_configured = 1;
- multi->tx_multichannel_enable = true;
- multi->rx_multichannel_enable = true;
+ multi->tx_multichannel_enable =
+ msp_config->direction & MSP_DIR_TX;
+ multi->rx_multichannel_enable =
+ msp_config->direction & MSP_DIR_RX;
multi->rx_comparison_enable_mode = MSP_COMPARISON_DISABLED;
multi->tx_channel_0_enable = drvdata->tx_mask;
@@ -192,6 +194,7 @@ static int setup_clocking(struct snd_soc_dai *dai,
case SND_SOC_DAIFMT_BC_FC:
dev_dbg(dai->dev, "%s: Codec is master.\n", __func__);
+ msp_config->clock_provider = false;
msp_config->iodelay = 0x20;
msp_config->rx_fsync_sel = 0;
msp_config->tx_fsync_sel = 1 << TFSSEL_SHIFT;
@@ -204,6 +207,7 @@ static int setup_clocking(struct snd_soc_dai *dai,
case SND_SOC_DAIFMT_BP_FP:
dev_dbg(dai->dev, "%s: Codec is slave.\n", __func__);
+ msp_config->clock_provider = true;
msp_config->tx_clk_sel = TX_CLK_SEL_SRG;
msp_config->tx_fsync_sel = TX_SYNC_SRG_PROG;
msp_config->rx_clk_sel = RX_CLK_SEL_SRG;
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index fbfeefa418ca7..ec6f0874294ae 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -344,20 +344,27 @@ static int configure_multichannel(struct ux500_msp *msp,
return 0;
}
-static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
+static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config,
+ bool first)
{
- int status = 0;
- u32 reg_val_DMACR, reg_val_GCR;
+ int status;
+ u32 reg_val_DMACR;
/* Configure msp with protocol dependent settings */
- configure_protocol(msp, config);
- setup_bitclk(msp, config);
+ status = configure_protocol(msp, config);
+ if (status)
+ return status;
+
+ if (first && config->clock_provider) {
+ status = setup_bitclk(msp, config);
+ if (status)
+ return status;
+ }
+
if (config->multichannel_configured == 1) {
status = configure_multichannel(msp, config);
if (status)
- dev_warn(msp->dev,
- "%s: WARN: configure_multichannel failed (%d)!\n",
- __func__, status);
+ return status;
}
reg_val_DMACR = readl(msp->registers + MSP_DMACR);
@@ -369,11 +376,7 @@ static int enable_msp(struct ux500_msp *msp, struct ux500_msp_config *config)
writel(config->iodelay, msp->registers + MSP_IODLY);
- /* Enable frame generation logic */
- reg_val_GCR = readl(msp->registers + MSP_GCR);
- writel(reg_val_GCR | FRAME_GEN_ENABLE, msp->registers + MSP_GCR);
-
- return status;
+ return 0;
}
static void flush_fifo_rx(struct ux500_msp *msp)
@@ -411,12 +414,36 @@ static void flush_fifo_tx(struct ux500_msp *msp)
writel(reg_val_GCR, msp->registers + MSP_GCR);
}
+static bool ux500_msp_config_compatible(struct ux500_msp *msp,
+ struct ux500_msp_config *config)
+{
+ struct ux500_msp_config *active = &msp->config;
+
+ return active->f_inputclk == config->f_inputclk &&
+ active->tx_clk_sel == config->tx_clk_sel &&
+ active->rx_clk_sel == config->rx_clk_sel &&
+ active->srg_clk_sel == config->srg_clk_sel &&
+ active->rx_fsync_pol == config->rx_fsync_pol &&
+ active->tx_fsync_pol == config->tx_fsync_pol &&
+ active->rx_fsync_sel == config->rx_fsync_sel &&
+ active->tx_fsync_sel == config->tx_fsync_sel &&
+ active->default_protdesc == config->default_protdesc &&
+ active->protocol == config->protocol &&
+ active->frame_freq == config->frame_freq &&
+ active->data_size == config->data_size &&
+ active->def_elem_len == config->def_elem_len &&
+ active->clock_provider == config->clock_provider &&
+ !memcmp(&active->protdesc, &config->protdesc,
+ sizeof(active->protdesc));
+}
+
int ux500_msp_i2s_open(struct ux500_msp *msp,
struct ux500_msp_config *config)
{
u32 old_reg, new_reg, mask;
int res;
unsigned int tx_sel, rx_sel, tx_busy, rx_busy;
+ bool first;
if (in_interrupt()) {
dev_err(msp->dev,
@@ -444,40 +471,66 @@ int ux500_msp_i2s_open(struct ux500_msp *msp,
return -EBUSY;
}
- msp->dir_busy |= (tx_sel ? MSP_DIR_TX : 0) | (rx_sel ? MSP_DIR_RX : 0);
-
- /* First do the global config register */
- mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
- TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
- RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK | SRG_CLK_SEL_MASK |
- LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
-
- new_reg = (config->tx_clk_sel | config->rx_clk_sel |
- config->rx_fsync_pol | config->tx_fsync_pol |
- config->rx_fsync_sel | config->tx_fsync_sel |
- config->rx_fifo_config | config->tx_fifo_config |
- config->srg_clk_sel | config->loopback_enable |
- config->tx_data_enable);
+ first = !msp->dir_busy;
+ if (!first && !ux500_msp_config_compatible(msp, config)) {
+ dev_err(msp->dev, "%s: Incompatible duplex configuration\n",
+ __func__);
+ return -EBUSY;
+ }
- old_reg = readl(msp->registers + MSP_GCR);
- old_reg &= ~mask;
- new_reg |= old_reg;
- writel(new_reg, msp->registers + MSP_GCR);
+ if (first) {
+ /* First do the global config register */
+ mask = RX_CLK_SEL_MASK | TX_CLK_SEL_MASK | RX_FSYNC_MASK |
+ TX_FSYNC_MASK | RX_SYNC_SEL_MASK | TX_SYNC_SEL_MASK |
+ RX_FIFO_ENABLE_MASK | TX_FIFO_ENABLE_MASK |
+ SRG_CLK_SEL_MASK | LOOPBACK_MASK | TX_EXTRA_DELAY_MASK;
+
+ new_reg = config->tx_clk_sel | config->rx_clk_sel |
+ config->rx_fsync_pol | config->tx_fsync_pol |
+ config->rx_fsync_sel | config->tx_fsync_sel |
+ config->rx_fifo_config | config->tx_fifo_config |
+ config->srg_clk_sel | config->loopback_enable |
+ config->tx_data_enable;
+
+ old_reg = readl(msp->registers + MSP_GCR);
+ old_reg &= ~mask;
+ new_reg |= old_reg;
+ writel(new_reg, msp->registers + MSP_GCR);
+ }
- res = enable_msp(msp, config);
+ res = enable_msp(msp, config, first);
if (res < 0) {
dev_err(msp->dev, "%s: ERROR: enable_msp failed (%d)!\n",
__func__, res);
- return -EBUSY;
+ if (tx_sel)
+ writel(0, msp->registers + MSP_TCF);
+ if (rx_sel)
+ writel(0, msp->registers + MSP_RCF);
+ if (first) {
+ writel(0, msp->registers + MSP_GCR);
+ writel(0, msp->registers + MSP_DMACR);
+ writel(0, msp->registers + MSP_SRG);
+ writel(0, msp->registers + MSP_MCR);
+ }
+ return res;
+ }
+
+ msp->dir_busy |= config->direction;
+ if (first) {
+ msp->config = *config;
+ msp->clock_provider = config->clock_provider;
}
if (config->loopback_enable & 0x80)
msp->loopback_enable = 1;
/* Flush FIFOs */
- flush_fifo_tx(msp);
- flush_fifo_rx(msp);
+ if (tx_sel)
+ flush_fifo_tx(msp);
+ if (rx_sel)
+ flush_fifo_rx(msp);
- msp->msp_state = MSP_STATE_CONFIGURED;
+ if (!msp->dir_running)
+ msp->msp_state = MSP_STATE_CONFIGURED;
return 0;
}
@@ -494,7 +547,6 @@ static void disable_msp_rx(struct ux500_msp *msp)
~(RX_SERVICE_INT | RX_OVERRUN_ERROR_INT),
msp->registers + MSP_IMSC);
- msp->dir_busy &= ~MSP_DIR_RX;
}
static void disable_msp_tx(struct ux500_msp *msp)
@@ -510,7 +562,6 @@ static void disable_msp_tx(struct ux500_msp *msp)
~(TX_SERVICE_INT | TX_UNDERRUN_ERR_INT),
msp->registers + MSP_IMSC);
- msp->dir_busy &= ~MSP_DIR_TX;
}
static int disable_msp(struct ux500_msp *msp, unsigned int dir)
@@ -520,7 +571,7 @@ static int disable_msp(struct ux500_msp *msp, unsigned int dir)
reg_val_GCR = readl(msp->registers + MSP_GCR);
disable_tx = dir & MSP_DIR_TX;
- disable_rx = dir & MSP_DIR_TX;
+ disable_rx = dir & MSP_DIR_RX;
if (disable_tx && disable_rx) {
reg_val_GCR = readl(msp->registers + MSP_GCR);
writel(reg_val_GCR | LOOPBACK_MASK,
@@ -553,7 +604,15 @@ static int disable_msp(struct ux500_msp *msp, unsigned int dir)
int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
{
- u32 reg_val_GCR, enable_bit;
+ u32 reg_val_DMACR, reg_val_GCR, dma_enable_bit, enable_bit;
+ unsigned int dir;
+
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ dir = MSP_DIR_TX;
+ else if (direction == SNDRV_PCM_STREAM_CAPTURE)
+ dir = MSP_DIR_RX;
+ else
+ return -EINVAL;
if (msp->msp_state == MSP_STATE_IDLE) {
dev_err(msp->dev, "%s: ERROR: MSP is not configured!\n",
@@ -565,21 +624,44 @@ int ux500_msp_i2s_trigger(struct ux500_msp *msp, int cmd, int direction)
case SNDRV_PCM_TRIGGER_START:
case SNDRV_PCM_TRIGGER_RESUME:
case SNDRV_PCM_TRIGGER_PAUSE_RELEASE:
- if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
enable_bit = TX_ENABLE;
- else
+ dma_enable_bit = TX_DMA_ENABLE;
+ } else {
enable_bit = RX_ENABLE;
+ dma_enable_bit = RX_DMA_ENABLE;
+ }
+ if (!(msp->dir_busy & dir))
+ return -EINVAL;
+ reg_val_DMACR = readl(msp->registers + MSP_DMACR);
+ writel(reg_val_DMACR | dma_enable_bit,
+ msp->registers + MSP_DMACR);
reg_val_GCR = readl(msp->registers + MSP_GCR);
+ if (msp->clock_provider)
+ enable_bit |= FRAME_GEN_ENABLE;
writel(reg_val_GCR | enable_bit, msp->registers + MSP_GCR);
+ msp->dir_running |= dir;
+ msp->msp_state = MSP_STATE_RUNNING;
break;
case SNDRV_PCM_TRIGGER_STOP:
case SNDRV_PCM_TRIGGER_SUSPEND:
case SNDRV_PCM_TRIGGER_PAUSE_PUSH:
- if (direction == SNDRV_PCM_STREAM_PLAYBACK)
+ if (!(msp->dir_busy & dir))
+ return -EINVAL;
+ if (direction == SNDRV_PCM_STREAM_PLAYBACK) {
disable_msp_tx(msp);
- else
+ msp->dir_running &= ~MSP_DIR_TX;
+ } else {
disable_msp_rx(msp);
+ msp->dir_running &= ~MSP_DIR_RX;
+ }
+ if (!msp->dir_running) {
+ reg_val_GCR = readl(msp->registers + MSP_GCR);
+ writel(reg_val_GCR & ~FRAME_GEN_ENABLE,
+ msp->registers + MSP_GCR);
+ msp->msp_state = MSP_STATE_CONFIGURED;
+ }
break;
default:
return -EINVAL;
@@ -594,7 +676,18 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
dev_dbg(msp->dev, "%s: Enter (dir = 0x%01x).\n", __func__, dir);
+ if (!dir || dir & ~(MSP_DIR_TX | MSP_DIR_RX) ||
+ (msp->dir_busy & dir) != dir)
+ return -EINVAL;
+
status = disable_msp(msp, dir);
+ msp->dir_busy &= ~dir;
+ msp->dir_running &= ~dir;
+ if (msp->dir_busy && !msp->dir_running) {
+ writel(readl(msp->registers + MSP_GCR) & ~FRAME_GEN_ENABLE,
+ msp->registers + MSP_GCR);
+ msp->msp_state = MSP_STATE_CONFIGURED;
+ }
if (msp->dir_busy == 0) {
/* disable sample rate and frame generators */
msp->msp_state = MSP_STATE_IDLE;
@@ -618,6 +711,8 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
writel(0, msp->registers + MSP_RCE1);
writel(0, msp->registers + MSP_RCE2);
writel(0, msp->registers + MSP_RCE3);
+ memset(&msp->config, 0, sizeof(msp->config));
+ msp->clock_provider = false;
}
return status;
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 69d4ebc409fc1..d75a0974369a5 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -460,6 +460,7 @@ struct ux500_msp_config {
enum msp_data_size data_size;
unsigned int def_elem_len;
unsigned int iodelay;
+ bool clock_provider;
};
struct ux500_msp {
@@ -470,8 +471,11 @@ struct ux500_msp {
enum msp_state msp_state;
int def_elem_len;
unsigned int dir_busy;
+ unsigned int dir_running;
int loopback_enable;
unsigned int f_bitclk;
+ bool clock_provider;
+ struct ux500_msp_config config;
};
int ux500_msp_i2s_init_msp(struct platform_device *pdev,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 180/733] ASoC: ux500: Propagate MSP setup errors
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (178 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 179/733] ASoC: ux500: Fix MSP stream lifecycle handling Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 181/733] ASoC: ux500: Correct MSP frame and bit clock setup Greg Kroah-Hartman
` (564 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 3415421a2b0bc4e32bb5a9df24ed7863512d47a7 ]
The prepare callback continues with a partly initialized configuration
when format setup fails. Probe likewise tests the allocated pointer
instead of the return value, so an MMIO resource or mapping failure can
be ignored after allocation succeeds.
Return configuration failures from prepare and test the MSP
initialization result directly.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-2-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 7d65408989340..32d751fc1e784 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -468,7 +468,9 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (rate = %d).\n", __func__,
dai->id, snd_pcm_stream_str(substream), runtime->rate);
- setup_msp_config(substream, dai, &msp_config);
+ ret = setup_msp_config(substream, dai, &msp_config);
+ if (ret)
+ return ret;
ret = ux500_msp_i2s_open(drvdata->msp, &msp_config);
if (ret < 0) {
@@ -764,7 +766,7 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
}
ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp);
- if (!drvdata->msp) {
+ if (ret) {
dev_err(&pdev->dev,
"%s: ERROR: Failed to init MSP-struct (%d)!",
__func__, ret);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 181/733] ASoC: ux500: Correct MSP frame and bit clock setup
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (179 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 180/733] ASoC: ux500: Propagate MSP setup errors Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 182/733] ASoC: ux500: Validate MSP DAI configuration Greg Kroah-Hartman
` (563 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 94c18cea657c48680e4ee20b635b6c01f3eb352e ]
FRPER plus one is the number of bit clocks in a frame. It must follow
the configured slot count and width. The legacy rate-dependent
constants produce malformed frames; notably, a 16-slot, 16-bit frame
is programmed as 278 rather than 256 clocks.
Derive the frame period from the TDM geometry and use the real
functional clock rate. Validate that the requested bit clock has an
exact, representable divider, program SCKDIV as divider minus one, and
report the resulting bit clock using that same divisor.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-3-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 75 +++++++--------------------------
sound/soc/ux500/ux500_msp_dai.h | 11 -----
sound/soc/ux500/ux500_msp_i2s.c | 54 ++++++++++++++----------
sound/soc/ux500/ux500_msp_i2s.h | 2 -
4 files changed, 46 insertions(+), 96 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 32d751fc1e784..0a9cc7e769fe3 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -59,72 +59,21 @@ static int setup_pcm_multichan(struct snd_soc_dai *dai,
return 0;
}
-static int setup_frameper(struct snd_soc_dai *dai, unsigned int rate,
- struct msp_protdesc *prot_desc)
+static void setup_frameper(struct snd_soc_dai *dai,
+ struct msp_protdesc *prot_desc)
{
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
- switch (drvdata->slots) {
- case 1:
- switch (rate) {
- case 8000:
- prot_desc->frame_period =
- FRAME_PER_SINGLE_SLOT_8_KHZ;
- break;
-
- case 16000:
- prot_desc->frame_period =
- FRAME_PER_SINGLE_SLOT_16_KHZ;
- break;
-
- case 44100:
- prot_desc->frame_period =
- FRAME_PER_SINGLE_SLOT_44_1_KHZ;
- break;
-
- case 48000:
- prot_desc->frame_period =
- FRAME_PER_SINGLE_SLOT_48_KHZ;
- break;
-
- default:
- dev_err(dai->dev,
- "%s: Error: Unsupported sample-rate (freq = %d)!\n",
- __func__, rate);
- return -EINVAL;
- }
- break;
-
- case 2:
- prot_desc->frame_period = FRAME_PER_2_SLOTS;
- break;
-
- case 8:
- prot_desc->frame_period = FRAME_PER_8_SLOTS;
- break;
-
- case 16:
- prot_desc->frame_period = FRAME_PER_16_SLOTS;
- break;
- default:
- dev_err(dai->dev,
- "%s: Error: Unsupported slot-count (slots = %d)!\n",
- __func__, drvdata->slots);
- return -EINVAL;
- }
-
- prot_desc->clocks_per_frame =
- prot_desc->frame_period+1;
+ prot_desc->clocks_per_frame = drvdata->slots * drvdata->slot_width;
+ prot_desc->frame_period = prot_desc->clocks_per_frame - 1;
dev_dbg(dai->dev, "%s: Clocks per frame: %u\n",
__func__,
prot_desc->clocks_per_frame);
-
- return 0;
}
-static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate,
- struct msp_protdesc *prot_desc)
+static int setup_pcm_framing(struct snd_soc_dai *dai,
+ struct msp_protdesc *prot_desc)
{
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
@@ -165,7 +114,9 @@ static int setup_pcm_framing(struct snd_soc_dai *dai, unsigned int rate,
prot_desc->tx_elem_len_2 = MSP_ELEM_LEN_16;
prot_desc->rx_elem_len_2 = MSP_ELEM_LEN_16;
- return setup_frameper(dai, rate, prot_desc);
+ setup_frameper(dai, prot_desc);
+
+ return 0;
}
static int setup_clocking(struct snd_soc_dai *dai,
@@ -366,7 +317,7 @@ static int setup_msp_config(struct snd_pcm_substream *substream,
if (ret < 0)
return ret;
- ret = setup_pcm_framing(dai, runtime->rate, prot_desc);
+ ret = setup_pcm_framing(dai, prot_desc);
if (ret < 0)
return ret;
@@ -735,7 +686,6 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
drvdata->tx_mask = 0x01;
drvdata->rx_mask = 0x01;
drvdata->slot_width = 16;
- drvdata->master_clk = MSP_INPUT_FREQ_APB;
drvdata->reg_vape = devm_regulator_get(&pdev->dev, "v-ape");
if (IS_ERR(drvdata->reg_vape)) {
@@ -764,6 +714,11 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
__func__, ret);
return ret;
}
+ drvdata->master_clk = clk_get_rate(drvdata->clk);
+ if (!drvdata->master_clk) {
+ dev_err(&pdev->dev, "MSP clock has no rate\n");
+ return -EINVAL;
+ }
ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp);
if (ret) {
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 30bf708381961..19058c238420e 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -22,17 +22,6 @@
#define UX500_I2S_FORMATS (SNDRV_PCM_FMTBIT_S16_LE)
-#define FRAME_PER_SINGLE_SLOT_8_KHZ 31
-#define FRAME_PER_SINGLE_SLOT_16_KHZ 124
-#define FRAME_PER_SINGLE_SLOT_44_1_KHZ 63
-#define FRAME_PER_SINGLE_SLOT_48_KHZ 49
-#define FRAME_PER_2_SLOTS 31
-#define FRAME_PER_8_SLOTS 138
-#define FRAME_PER_16_SLOTS 277
-
-#define UX500_MSP_INTERNAL_CLOCK_FREQ 40000000
-#define UX500_MSP1_INTERNAL_CLOCK_FREQ UX500_MSP_INTERNAL_CLOCK_FREQ
-
#define UX500_MSP_MIN_CHANNELS 1
#define UX500_MSP_MAX_CHANNELS 8
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index ec6f0874294ae..ef41de92d8e76 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -212,35 +212,20 @@ static int configure_protocol(struct ux500_msp *msp,
static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
{
+ struct msp_protdesc *protdesc;
+ u64 desired_bitclk;
+ unsigned int bitclk;
u32 reg_val_GCR;
- u32 frame_per = 0;
- u32 sck_div = 0;
- u32 frame_width = 0;
- u32 temp_reg = 0;
- struct msp_protdesc *protdesc = NULL;
+ u32 sck_div;
+ u32 temp_reg;
reg_val_GCR = readl(msp->registers + MSP_GCR);
writel(reg_val_GCR & ~SRG_ENABLE, msp->registers + MSP_GCR);
- if (config->default_protdesc)
- protdesc =
- (struct msp_protdesc *)&prot_descs[config->protocol];
- else
- protdesc = (struct msp_protdesc *)&config->protdesc;
-
switch (config->protocol) {
case MSP_PCM_PROTOCOL:
case MSP_PCM_COMPAND_PROTOCOL:
- frame_width = protdesc->frame_width;
- sck_div = config->f_inputclk / (config->frame_freq *
- (protdesc->clocks_per_frame));
- frame_per = protdesc->frame_period;
- break;
case MSP_I2S_PROTOCOL:
- frame_width = protdesc->frame_width;
- sck_div = config->f_inputclk / (config->frame_freq *
- (protdesc->clocks_per_frame));
- frame_per = protdesc->frame_period;
break;
default:
dev_err(msp->dev, "%s: ERROR: Unknown protocol (%d)!\n",
@@ -249,12 +234,35 @@ static int setup_bitclk(struct ux500_msp *msp, struct ux500_msp_config *config)
return -EINVAL;
}
+ if (config->default_protdesc)
+ protdesc = (struct msp_protdesc *)&prot_descs[config->protocol];
+ else
+ protdesc = &config->protdesc;
+
+ if (!config->frame_freq || !protdesc->clocks_per_frame)
+ return -EINVAL;
+
+ desired_bitclk = (u64)config->frame_freq * protdesc->clocks_per_frame;
+ if (desired_bitclk > config->f_inputclk)
+ return -EINVAL;
+ bitclk = desired_bitclk;
+ if (config->f_inputclk % bitclk) {
+ dev_err(msp->dev,
+ "Input clock %u cannot generate bit clock %u\n",
+ config->f_inputclk, bitclk);
+ return -EINVAL;
+ }
+
+ sck_div = config->f_inputclk / bitclk;
+ if (!sck_div || sck_div > SCK_DIV_MASK + 1)
+ return -EINVAL;
+
temp_reg = (sck_div - 1) & SCK_DIV_MASK;
- temp_reg |= FRAME_WIDTH_BITS(frame_width);
- temp_reg |= FRAME_PERIOD_BITS(frame_per);
+ temp_reg |= FRAME_WIDTH_BITS(protdesc->frame_width);
+ temp_reg |= FRAME_PERIOD_BITS(protdesc->frame_period);
writel(temp_reg, msp->registers + MSP_SRG);
- msp->f_bitclk = (config->f_inputclk)/(sck_div + 1);
+ msp->f_bitclk = config->f_inputclk / sck_div;
/* Enable bit-clock */
udelay(100);
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index d75a0974369a5..80085dde50793 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -12,8 +12,6 @@
#include <linux/platform_device.h>
-#define MSP_INPUT_FREQ_APB 48000000
-
/*** Stereo mode. Used for APB data accesses as 16 bits accesses (mono),
* 32 bits accesses (stereo).
***/
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 182/733] ASoC: ux500: Validate MSP DAI configuration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (180 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 181/733] ASoC: ux500: Correct MSP frame and bit clock setup Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 183/733] mfd: db8500-prcmu: Fold dbx500 header into db8500 Greg Kroah-Hartman
` (562 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 9ccbacf5a0120964fc1ffacb8151e3347bee9287 ]
Installing channel constraints from hw_params is too late to affect the
parameters being committed. The driver consequently accepts channel
counts which disagree with the I2S or TDM setup. It also silently
truncates out-of-range slot masks and accepts inverted bit clock formats
which prepare then rejects.
Validate the selected channel count directly, reject invalid masks
before changing cached TDM state, and implement all four standard clock
and frame inversion combinations. Use the requested format in
validation diagnostics.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-4-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 41 ++++++++++++++++++++++-----------
sound/soc/ux500/ux500_msp_i2s.c | 7 ++++--
sound/soc/ux500/ux500_msp_i2s.h | 1 +
3 files changed, 33 insertions(+), 16 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 0a9cc7e769fe3..599de5de23dde 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -130,7 +130,16 @@ static int setup_clocking(struct snd_soc_dai *dai,
case SND_SOC_DAIFMT_NB_IF:
msp_config->tx_fsync_pol ^= 1 << TFSPOL_SHIFT;
msp_config->rx_fsync_pol ^= 1 << RFSPOL_SHIFT;
+ break;
+
+ case SND_SOC_DAIFMT_IB_NF:
+ msp_config->bclk_inverted = true;
+ break;
+ case SND_SOC_DAIFMT_IB_IF:
+ msp_config->bclk_inverted = true;
+ msp_config->tx_fsync_pol ^= 1 << TFSPOL_SHIFT;
+ msp_config->rx_fsync_pol ^= 1 << RFSPOL_SHIFT;
break;
default:
@@ -453,7 +462,6 @@ static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
unsigned int mask, slots_active;
- struct snd_pcm_runtime *runtime = substream->runtime;
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n",
@@ -461,9 +469,8 @@ static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
switch (drvdata->fmt & SND_SOC_DAIFMT_FORMAT_MASK) {
case SND_SOC_DAIFMT_I2S:
- snd_pcm_hw_constraint_minmax(runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- 1, 2);
+ if (params_channels(params) < 1 || params_channels(params) > 2)
+ return -EINVAL;
break;
case SND_SOC_DAIFMT_DSP_B:
@@ -475,9 +482,8 @@ static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
slots_active = hweight32(mask);
dev_dbg(dai->dev, "TDM-slots active: %d", slots_active);
- snd_pcm_hw_constraint_single(runtime,
- SNDRV_PCM_HW_PARAM_CHANNELS,
- slots_active);
+ if (!slots_active || params_channels(params) != slots_active)
+ return -EINVAL;
break;
default:
@@ -510,20 +516,21 @@ static int ux500_msp_dai_set_dai_fmt(struct snd_soc_dai *dai,
default:
dev_err(dai->dev,
"%s: Error: Unsupported protocol/master (fmt = 0x%x)!\n",
- __func__, drvdata->fmt);
+ __func__, fmt);
return -EINVAL;
}
switch (fmt & SND_SOC_DAIFMT_INV_MASK) {
case SND_SOC_DAIFMT_NB_NF:
case SND_SOC_DAIFMT_NB_IF:
+ case SND_SOC_DAIFMT_IB_NF:
case SND_SOC_DAIFMT_IB_IF:
break;
default:
dev_err(dai->dev,
"%s: Error: Unsupported inversion (fmt = 0x%x)!\n",
- __func__, drvdata->fmt);
+ __func__, fmt);
return -EINVAL;
}
@@ -557,17 +564,23 @@ static int ux500_msp_dai_set_tdm_slot(struct snd_soc_dai *dai,
__func__, slots);
return -EINVAL;
}
- drvdata->slots = slots;
- if (!(slot_width == 16)) {
+ if (slot_width != 16) {
dev_err(dai->dev, "%s: Error: Unsupported slot-width (%d)!\n",
__func__, slot_width);
return -EINVAL;
}
- drvdata->slot_width = slot_width;
- drvdata->tx_mask = tx_mask & cap;
- drvdata->rx_mask = rx_mask & cap;
+ if ((tx_mask | rx_mask) & ~cap) {
+ dev_err(dai->dev, "%s: Slot mask exceeds %d slots\n",
+ __func__, slots);
+ return -EINVAL;
+ }
+
+ drvdata->slots = slots;
+ drvdata->slot_width = slot_width;
+ drvdata->tx_mask = tx_mask;
+ drvdata->rx_mask = rx_mask;
return 0;
}
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index ef41de92d8e76..bc77174e00707 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -201,10 +201,12 @@ static int configure_protocol(struct ux500_msp *msp,
/* The code below should not be separated. */
temp_reg = readl(msp->registers + MSP_GCR) & ~TX_CLK_POL_RISING;
- temp_reg |= MSP_TX_CLKPOL_BIT(~protdesc->tx_clk_pol);
+ temp_reg |= MSP_TX_CLKPOL_BIT(!protdesc->tx_clk_pol ^
+ config->bclk_inverted);
writel(temp_reg, msp->registers + MSP_GCR);
temp_reg = readl(msp->registers + MSP_GCR) & ~RX_CLK_POL_RISING;
- temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol);
+ temp_reg |= MSP_RX_CLKPOL_BIT(protdesc->rx_clk_pol ^
+ config->bclk_inverted);
writel(temp_reg, msp->registers + MSP_GCR);
return 0;
@@ -441,6 +443,7 @@ static bool ux500_msp_config_compatible(struct ux500_msp *msp,
active->data_size == config->data_size &&
active->def_elem_len == config->def_elem_len &&
active->clock_provider == config->clock_provider &&
+ active->bclk_inverted == config->bclk_inverted &&
!memcmp(&active->protdesc, &config->protdesc,
sizeof(active->protdesc));
}
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 80085dde50793..17b5c37a7e5d5 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -459,6 +459,7 @@ struct ux500_msp_config {
unsigned int def_elem_len;
unsigned int iodelay;
bool clock_provider;
+ bool bclk_inverted;
};
struct ux500_msp {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 183/733] mfd: db8500-prcmu: Fold dbx500 header into db8500
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (181 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 182/733] ASoC: ux500: Validate MSP DAI configuration Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 184/733] ASoC: ux500: Deassert the MSP reset during probe Greg Kroah-Hartman
` (561 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Linus Walleij,
Brian Masney, Guenter Roeck, Mark Brown, Lee Jones, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit b8bc38bcecb77880a802d0430862b023c0aa7392 ]
Move the DBx500 PRCMU definitions into the DB8500 PRCMU
header and delete the wrapper header.
Convert users of simple PRCMU wrappers to call the DB8500 helpers
directly.
The dbx500-prcmu.h header was the result of an earlier attempt to
abstract several DBx5x SoC PRCMU units to use the same abstract
header. They are deleted from the kernel and this is not just
causing maintenance burden and build errors.
The stub code is using -ENOSYS in a way checkpatch complains about
so replace these with -EINVAL while we're at it.
Assisted-by: Codex:gpt-5-5
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202606180825.vUSQntkJ-lkp@intel.com/
Signed-off-by: Linus Walleij <linusw@kernel.org>
Acked-by: Brian Masney <bmasney@redhat.com>
Acked-by: Guenter Roeck <linux@roeck-us.net>
Acked-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/oe-kbuild-all/202606180825.vUSQntkJ-lkp@intel.com/
Link: https://patch.msgid.link/20260619-mfd-prcmu-merge-headers-v1-1-8ea0ee23b4d6@kernel.org
Signed-off-by: Lee Jones <lee@kernel.org>
Stable-dep-of: 66ec63e7a90b ("ASoC: ux500: Deassert the MSP reset during probe")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm/mach-ux500/cpu-db8500.c | 6 +-
drivers/clk/ux500/clk-prcmu.c | 20 +-
drivers/clk/ux500/u8500_of_clk.c | 2 +-
drivers/cpuidle/cpuidle-ux500.c | 6 +-
drivers/mfd/ab8500-core.c | 2 +-
drivers/mfd/db8500-prcmu.c | 6 +-
drivers/regulator/db8500-prcmu.c | 12 +-
drivers/thermal/db8500_thermal.c | 10 +-
drivers/watchdog/db8500_wdt.c | 22 +-
include/linux/mfd/db8500-prcmu.h | 252 +++++++++++++-
include/linux/mfd/dbx500-prcmu.h | 575 -------------------------------
sound/soc/ux500/ux500_msp_dai.c | 2 +-
12 files changed, 294 insertions(+), 621 deletions(-)
delete mode 100644 include/linux/mfd/dbx500-prcmu.h
diff --git a/arch/arm/mach-ux500/cpu-db8500.c b/arch/arm/mach-ux500/cpu-db8500.c
index b1a70f203372b..0d7530fb6ad07 100644
--- a/arch/arm/mach-ux500/cpu-db8500.c
+++ b/arch/arm/mach-ux500/cpu-db8500.c
@@ -12,7 +12,7 @@
#include <linux/irq.h>
#include <linux/irqchip.h>
#include <linux/irqchip/arm-gic.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/platform_data/arm-ux500-pm.h>
#include <linux/platform_device.h>
#include <linux/io.h>
@@ -81,7 +81,7 @@ static void __init ux500_init_irq(void)
struct resource r;
irqchip_init();
- prcmu_early_init();
+ db8500_prcmu_early_init();
np = of_find_compatible_node(NULL, NULL, "stericsson,db8500-prcmu");
of_address_to_resource(np, 0, &r);
of_node_put(np);
@@ -101,7 +101,7 @@ static void ux500_restart(enum reboot_mode mode, const char *cmd)
local_irq_disable();
local_fiq_disable();
- prcmu_system_reset(0);
+ db8500_prcmu_system_reset(0);
}
static const struct of_device_id u8500_local_bus_nodes[] = {
diff --git a/drivers/clk/ux500/clk-prcmu.c b/drivers/clk/ux500/clk-prcmu.c
index ddc86551bf574..ac96c46bd1bbf 100644
--- a/drivers/clk/ux500/clk-prcmu.c
+++ b/drivers/clk/ux500/clk-prcmu.c
@@ -7,7 +7,7 @@
*/
#include <linux/clk-provider.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/slab.h>
#include <linux/io.h>
#include <linux/err.h>
@@ -35,13 +35,13 @@ static int clk_prcmu_prepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- return prcmu_request_clock(clk->cg_sel, true);
+ return db8500_prcmu_request_clock(clk->cg_sel, true);
}
static void clk_prcmu_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false))
+ if (db8500_prcmu_request_clock(clk->cg_sel, false))
pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
clk_hw_get_name(hw));
}
@@ -86,7 +86,7 @@ static int clk_prcmu_opp_prepare(struct clk_hw *hw)
clk->opp_requested = 1;
}
- err = prcmu_request_clock(clk->cg_sel, true);
+ err = db8500_prcmu_request_clock(clk->cg_sel, true);
if (err) {
prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP,
(char *)clk_hw_get_name(hw));
@@ -101,7 +101,7 @@ static void clk_prcmu_opp_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false)) {
+ if (db8500_prcmu_request_clock(clk->cg_sel, false)) {
pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
clk_hw_get_name(hw));
return;
@@ -120,7 +120,7 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
struct clk_prcmu *clk = to_clk_prcmu(hw);
if (!clk->opp_requested) {
- err = prcmu_request_ape_opp_100_voltage(true);
+ err = db8500_prcmu_request_ape_opp_100_voltage(true);
if (err) {
pr_err("clk_prcmu: %s fail req APE OPP VOLT for %s.\n",
__func__, clk_hw_get_name(hw));
@@ -129,9 +129,9 @@ static int clk_prcmu_opp_volt_prepare(struct clk_hw *hw)
clk->opp_requested = 1;
}
- err = prcmu_request_clock(clk->cg_sel, true);
+ err = db8500_prcmu_request_clock(clk->cg_sel, true);
if (err) {
- prcmu_request_ape_opp_100_voltage(false);
+ db8500_prcmu_request_ape_opp_100_voltage(false);
clk->opp_requested = 0;
return err;
}
@@ -143,14 +143,14 @@ static void clk_prcmu_opp_volt_unprepare(struct clk_hw *hw)
{
struct clk_prcmu *clk = to_clk_prcmu(hw);
- if (prcmu_request_clock(clk->cg_sel, false)) {
+ if (db8500_prcmu_request_clock(clk->cg_sel, false)) {
pr_err("clk_prcmu: %s failed to disable %s.\n", __func__,
clk_hw_get_name(hw));
return;
}
if (clk->opp_requested) {
- prcmu_request_ape_opp_100_voltage(false);
+ db8500_prcmu_request_ape_opp_100_voltage(false);
clk->opp_requested = 0;
}
}
diff --git a/drivers/clk/ux500/u8500_of_clk.c b/drivers/clk/ux500/u8500_of_clk.c
index 6f78808387b10..d2499815226f0 100644
--- a/drivers/clk/ux500/u8500_of_clk.c
+++ b/drivers/clk/ux500/u8500_of_clk.c
@@ -9,7 +9,7 @@
#include <linux/of.h>
#include <linux/of_address.h>
#include <linux/clk-provider.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include "clk.h"
#include "prcc.h"
diff --git a/drivers/cpuidle/cpuidle-ux500.c b/drivers/cpuidle/cpuidle-ux500.c
index f7d778580e9be..6d6c52c0bcc2d 100644
--- a/drivers/cpuidle/cpuidle-ux500.c
+++ b/drivers/cpuidle/cpuidle-ux500.c
@@ -11,7 +11,7 @@
#include <linux/spinlock.h>
#include <linux/atomic.h>
#include <linux/smp.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/platform_data/arm-ux500-pm.h>
#include <linux/platform_device.h>
@@ -66,7 +66,7 @@ static inline int ux500_enter_idle(struct cpuidle_device *dev,
/* Go to the retention state, the prcmu will wait for the
* cpu to go WFI and this is what happens after exiting this
* 'master' critical section */
- if (prcmu_set_power_state(PRCMU_AP_IDLE, true, true))
+ if (db8500_prcmu_set_power_state(PRCMU_AP_IDLE, true, true))
goto out;
/* When we switch to retention, the prcmu is in charge
@@ -109,7 +109,7 @@ static struct cpuidle_driver ux500_idle_driver = {
static int dbx500_cpuidle_probe(struct platform_device *pdev)
{
/* Configure wake up reasons */
- prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
+ db8500_prcmu_enable_wakeups(PRCMU_WAKEUP(ARM) | PRCMU_WAKEUP(RTC) |
PRCMU_WAKEUP(ABB));
return cpuidle_register(&ux500_idle_driver, NULL);
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index f0bc0b5a6f4ad..86fa99022cb35 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -19,7 +19,7 @@
#include <linux/mfd/core.h>
#include <linux/mfd/abx500.h>
#include <linux/mfd/abx500/ab8500.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/of.h>
/*
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 21e68a382b114..6672c55f2ebcc 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -32,7 +32,7 @@
#include <linux/platform_device.h>
#include <linux/uaccess.h>
#include <linux/mfd/core.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/mfd/abx500/ab8500.h>
#include <linux/regulator/db8500-prcmu.h>
#include <linux/regulator/machine.h>
@@ -2285,7 +2285,7 @@ void db8500_prcmu_system_reset(u16 reset_code)
/**
* db8500_prcmu_get_reset_code - Retrieve SW reset reason code
*
- * Retrieves the reset reason code stored by prcmu_system_reset() before
+ * Retrieves the reset reason code stored by db8500_prcmu_system_reset() before
* last restart.
*/
u16 db8500_prcmu_get_reset_code(void)
@@ -3041,7 +3041,7 @@ static int db8500_prcmu_probe(struct platform_device *pdev)
db8500_irq_init(np);
- prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
+ db8500_prcmu_config_esram0_deep_sleep(ESRAM0_DEEP_SLEEP_STATE_RET);
err = mfd_add_devices(&pdev->dev, 0, common_prcmu_devs,
ARRAY_SIZE(common_prcmu_devs), NULL, 0, db8500_irq_domain);
diff --git a/drivers/regulator/db8500-prcmu.c b/drivers/regulator/db8500-prcmu.c
index 1ec2e1348891d..751fe36580faf 100644
--- a/drivers/regulator/db8500-prcmu.c
+++ b/drivers/regulator/db8500-prcmu.c
@@ -13,7 +13,7 @@
#include <linux/err.h>
#include <linux/spinlock.h>
#include <linux/platform_device.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/regulator/driver.h>
#include <linux/regulator/machine.h>
#include <linux/regulator/db8500-prcmu.h>
@@ -93,13 +93,13 @@ static int enable_epod(u16 epod_id, bool ramret)
if (ramret) {
if (!epod_on[epod_id]) {
- ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
+ ret = db8500_prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
if (ret < 0)
return ret;
}
epod_ramret[epod_id] = true;
} else {
- ret = prcmu_set_epod(epod_id, EPOD_STATE_ON);
+ ret = db8500_prcmu_set_epod(epod_id, EPOD_STATE_ON);
if (ret < 0)
return ret;
epod_on[epod_id] = true;
@@ -114,18 +114,18 @@ static int disable_epod(u16 epod_id, bool ramret)
if (ramret) {
if (!epod_on[epod_id]) {
- ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
+ ret = db8500_prcmu_set_epod(epod_id, EPOD_STATE_OFF);
if (ret < 0)
return ret;
}
epod_ramret[epod_id] = false;
} else {
if (epod_ramret[epod_id]) {
- ret = prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
+ ret = db8500_prcmu_set_epod(epod_id, EPOD_STATE_RAMRET);
if (ret < 0)
return ret;
} else {
- ret = prcmu_set_epod(epod_id, EPOD_STATE_OFF);
+ ret = db8500_prcmu_set_epod(epod_id, EPOD_STATE_OFF);
if (ret < 0)
return ret;
}
diff --git a/drivers/thermal/db8500_thermal.c b/drivers/thermal/db8500_thermal.c
index 576f88b6a1b35..cf1706569e6d7 100644
--- a/drivers/thermal/db8500_thermal.c
+++ b/drivers/thermal/db8500_thermal.c
@@ -10,7 +10,7 @@
#include <linux/cpu_cooling.h>
#include <linux/interrupt.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <linux/module.h>
#include <linux/of.h>
#include <linux/platform_device.h>
@@ -82,7 +82,7 @@ static void db8500_thermal_update_config(struct db8500_thermal_zone *th,
unsigned long next_low,
unsigned long next_high)
{
- prcmu_stop_temp_sense();
+ db8500_prcmu_stop_temp_sense();
th->cur_index = idx;
th->interpolated_temp = (next_low + next_high)/2;
@@ -91,8 +91,8 @@ static void db8500_thermal_update_config(struct db8500_thermal_zone *th,
* The PRCMU accept absolute temperatures in celsius so divide
* down the millicelsius with 1000
*/
- prcmu_config_hotmon((u8)(next_low/1000), (u8)(next_high/1000));
- prcmu_start_temp_sense(PRCMU_DEFAULT_MEASURE_TIME);
+ db8500_prcmu_config_hotmon((u8)(next_low / 1000), (u8)(next_high / 1000));
+ db8500_prcmu_start_temp_sense(PRCMU_DEFAULT_MEASURE_TIME);
}
static irqreturn_t prcmu_low_irq_handler(int irq, void *irq_data)
@@ -204,7 +204,7 @@ static int db8500_thermal_probe(struct platform_device *pdev)
static int db8500_thermal_suspend(struct platform_device *pdev,
pm_message_t state)
{
- prcmu_stop_temp_sense();
+ db8500_prcmu_stop_temp_sense();
return 0;
}
diff --git a/drivers/watchdog/db8500_wdt.c b/drivers/watchdog/db8500_wdt.c
index 97148ac0aa54a..70ccea13288d8 100644
--- a/drivers/watchdog/db8500_wdt.c
+++ b/drivers/watchdog/db8500_wdt.c
@@ -16,7 +16,7 @@
#include <linux/watchdog.h>
#include <linux/platform_device.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#define WATCHDOG_TIMEOUT 600 /* 10 minutes */
@@ -37,24 +37,24 @@ MODULE_PARM_DESC(nowayout,
static int db8500_wdt_start(struct watchdog_device *wdd)
{
- return prcmu_enable_a9wdog(PRCMU_WDOG_ALL);
+ return db8500_prcmu_enable_a9wdog(PRCMU_WDOG_ALL);
}
static int db8500_wdt_stop(struct watchdog_device *wdd)
{
- return prcmu_disable_a9wdog(PRCMU_WDOG_ALL);
+ return db8500_prcmu_disable_a9wdog(PRCMU_WDOG_ALL);
}
static int db8500_wdt_keepalive(struct watchdog_device *wdd)
{
- return prcmu_kick_a9wdog(PRCMU_WDOG_ALL);
+ return db8500_prcmu_kick_a9wdog(PRCMU_WDOG_ALL);
}
static int db8500_wdt_set_timeout(struct watchdog_device *wdd,
unsigned int timeout)
{
db8500_wdt_stop(wdd);
- prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
+ db8500_prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
db8500_wdt_start(wdd);
return 0;
@@ -91,10 +91,10 @@ static int db8500_wdt_probe(struct platform_device *pdev)
watchdog_set_nowayout(&db8500_wdt, nowayout);
/* disable auto off on sleep */
- prcmu_config_a9wdog(PRCMU_WDOG_CPU1, false);
+ db8500_prcmu_config_a9wdog(PRCMU_WDOG_CPU1, false);
/* set HW initial value */
- prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
+ db8500_prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
ret = devm_watchdog_register_device(dev, &db8500_wdt);
if (ret)
@@ -110,9 +110,9 @@ static int db8500_wdt_suspend(struct platform_device *pdev,
{
if (watchdog_active(&db8500_wdt)) {
db8500_wdt_stop(&db8500_wdt);
- prcmu_config_a9wdog(PRCMU_WDOG_CPU1, true);
+ db8500_prcmu_config_a9wdog(PRCMU_WDOG_CPU1, true);
- prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
+ db8500_prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
db8500_wdt_start(&db8500_wdt);
}
return 0;
@@ -122,9 +122,9 @@ static int db8500_wdt_resume(struct platform_device *pdev)
{
if (watchdog_active(&db8500_wdt)) {
db8500_wdt_stop(&db8500_wdt);
- prcmu_config_a9wdog(PRCMU_WDOG_CPU1, false);
+ db8500_prcmu_config_a9wdog(PRCMU_WDOG_CPU1, false);
- prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
+ db8500_prcmu_load_a9wdog(PRCMU_WDOG_ALL, timeout * 1000);
db8500_wdt_start(&db8500_wdt);
}
return 0;
diff --git a/include/linux/mfd/db8500-prcmu.h b/include/linux/mfd/db8500-prcmu.h
index a62de3d155edc..c939c9a1170a0 100644
--- a/include/linux/mfd/db8500-prcmu.h
+++ b/include/linux/mfd/db8500-prcmu.h
@@ -12,6 +12,9 @@
#include <linux/interrupt.h>
#include <linux/bitops.h>
+#include <linux/err.h>
+
+#include <dt-bindings/mfd/dbx500-prcmu.h> /* For clock identifiers */
/*
* Registers
@@ -24,6 +27,38 @@
#define DB8500_PRCM_DSI_SW_RESET_DSI1_SW_RESETN BIT(1)
#define DB8500_PRCM_DSI_SW_RESET_DSI2_SW_RESETN BIT(2)
+/* Offset for the firmware version within the TCPM */
+#define DB8500_PRCMU_FW_VERSION_OFFSET 0xA4
+
+#define DB8500_PRCMU_LEGACY_OFFSET 0xDD4
+
+/*
+ * CLKOUT sources
+ */
+#define PRCMU_CLKSRC_CLK38M 0x00
+#define PRCMU_CLKSRC_ACLK 0x01
+#define PRCMU_CLKSRC_SYSCLK 0x02
+#define PRCMU_CLKSRC_LCDCLK 0x03
+#define PRCMU_CLKSRC_SDMMCCLK 0x04
+#define PRCMU_CLKSRC_TVCLK 0x05
+#define PRCMU_CLKSRC_TIMCLK 0x06
+#define PRCMU_CLKSRC_CLK009 0x07
+/* These are only valid for CLKOUT1: */
+#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40
+#define PRCMU_CLKSRC_I2CCLK 0x41
+#define PRCMU_CLKSRC_MSP02CLK 0x42
+#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43
+#define PRCMU_CLKSRC_HSIRXCLK 0x44
+#define PRCMU_CLKSRC_HSITXCLK 0x45
+#define PRCMU_CLKSRC_ARMCLKFIX 0x46
+#define PRCMU_CLKSRC_HDMICLK 0x47
+
+/*
+ * Definitions for controlling ESRAM0 in deep sleep.
+ */
+#define ESRAM0_DEEP_SLEEP_STATE_OFF 1
+#define ESRAM0_DEEP_SLEEP_STATE_RET 2
+
/* This portion previously known as <mach/prcmu-fw-defs_v1.h> */
/**
@@ -451,10 +486,173 @@ enum prcmu_power_status {
PRCMU_ARMPENDINGIT_ER = 0x93,
};
+/* PRCMU Wakeup defines */
+enum prcmu_wakeup_index {
+ PRCMU_WAKEUP_INDEX_RTC,
+ PRCMU_WAKEUP_INDEX_RTT0,
+ PRCMU_WAKEUP_INDEX_RTT1,
+ PRCMU_WAKEUP_INDEX_HSI0,
+ PRCMU_WAKEUP_INDEX_HSI1,
+ PRCMU_WAKEUP_INDEX_USB,
+ PRCMU_WAKEUP_INDEX_ABB,
+ PRCMU_WAKEUP_INDEX_ABB_FIFO,
+ PRCMU_WAKEUP_INDEX_ARM,
+ PRCMU_WAKEUP_INDEX_CD_IRQ,
+ NUM_PRCMU_WAKEUP_INDICES
+};
+
+#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name))
+
+/**
+ * enum prcmu_wdog_id - PRCMU watchdog IDs
+ * @PRCMU_WDOG_ALL: use all timers
+ * @PRCMU_WDOG_CPU1: use first CPU timer only
+ * @PRCMU_WDOG_CPU2: use second CPU timer conly
+ */
+enum prcmu_wdog_id {
+ PRCMU_WDOG_ALL = 0x00,
+ PRCMU_WDOG_CPU1 = 0x01,
+ PRCMU_WDOG_CPU2 = 0x02,
+};
+
+/**
+ * enum ape_opp - APE OPP states definition
+ * @APE_OPP_INIT:
+ * @APE_NO_CHANGE: The APE operating point is unchanged
+ * @APE_100_OPP: The new APE operating point is ape100opp
+ * @APE_50_OPP: 50%
+ * @APE_50_PARTLY_25_OPP: 50%, except some clocks at 25%.
+ */
+enum ape_opp {
+ APE_OPP_INIT = 0x00,
+ APE_NO_CHANGE = 0x01,
+ APE_100_OPP = 0x02,
+ APE_50_OPP = 0x03,
+ APE_50_PARTLY_25_OPP = 0xFF,
+};
+
+/**
+ * enum arm_opp - ARM OPP states definition
+ * @ARM_OPP_INIT:
+ * @ARM_NO_CHANGE: The ARM operating point is unchanged
+ * @ARM_100_OPP: The new ARM operating point is arm100opp
+ * @ARM_50_OPP: The new ARM operating point is arm50opp
+ * @ARM_MAX_OPP: Operating point is "max" (more than 100)
+ * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100
+ * @ARM_EXTCLK: The new ARM operating point is armExtClk
+ */
+enum arm_opp {
+ ARM_OPP_INIT = 0x00,
+ ARM_NO_CHANGE = 0x01,
+ ARM_100_OPP = 0x02,
+ ARM_50_OPP = 0x03,
+ ARM_MAX_OPP = 0x04,
+ ARM_MAX_FREQ100OPP = 0x05,
+ ARM_EXTCLK = 0x07
+};
+
+/**
+ * enum ddr_opp - DDR OPP states definition
+ * @DDR_100_OPP: The new DDR operating point is ddr100opp
+ * @DDR_50_OPP: The new DDR operating point is ddr50opp
+ * @DDR_25_OPP: The new DDR operating point is ddr25opp
+ */
+enum ddr_opp {
+ DDR_100_OPP = 0x00,
+ DDR_50_OPP = 0x01,
+ DDR_25_OPP = 0x02,
+};
+
+/**
+ * enum ddr_pwrst - DDR power states definition
+ * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged
+ * @DDR_PWR_STATE_ON:
+ * @DDR_PWR_STATE_OFFLOWLAT:
+ * @DDR_PWR_STATE_OFFHIGHLAT:
+ */
+enum ddr_pwrst {
+ DDR_PWR_STATE_UNCHANGED = 0x00,
+ DDR_PWR_STATE_ON = 0x01,
+ DDR_PWR_STATE_OFFLOWLAT = 0x02,
+ DDR_PWR_STATE_OFFHIGHLAT = 0x03
+};
+
/*
* Definitions for autonomous power management configuration.
*/
+/* EPOD (power domain) IDs */
+
+/*
+ * DB8500 EPODs
+ * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP
+ * - EPOD_ID_SVAPIPE: power domain for SVA pipe
+ * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP
+ * - EPOD_ID_SIAPIPE: power domain for SIA pipe
+ * - EPOD_ID_SGA: power domain for SGA
+ * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE
+ * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2
+ * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4
+ * - NUM_EPOD_ID: number of power domains
+ *
+ * TODO: These should be prefixed.
+ */
+#define EPOD_ID_SVAMMDSP 0
+#define EPOD_ID_SVAPIPE 1
+#define EPOD_ID_SIAMMDSP 2
+#define EPOD_ID_SIAPIPE 3
+#define EPOD_ID_SGA 4
+#define EPOD_ID_B2R2_MCDE 5
+#define EPOD_ID_ESRAM12 6
+#define EPOD_ID_ESRAM34 7
+#define NUM_EPOD_ID 8
+
+/*
+ * state definition for EPOD (power domain)
+ * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged
+ * - EPOD_STATE_OFF: The EPOD is switched off
+ * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in
+ * retention
+ * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off
+ * - EPOD_STATE_ON: Same as above, but with clock enabled
+ */
+#define EPOD_STATE_NO_CHANGE 0x00
+#define EPOD_STATE_OFF 0x01
+#define EPOD_STATE_RAMRET 0x02
+#define EPOD_STATE_ON_CLK_OFF 0x03
+#define EPOD_STATE_ON 0x04
+
+#define PRCMU_FW_PROJECT_U8500 2
+#define PRCMU_FW_PROJECT_U8400 3
+#define PRCMU_FW_PROJECT_U9500 4 /* Customer specific */
+#define PRCMU_FW_PROJECT_U8500_MBB 5
+#define PRCMU_FW_PROJECT_U8500_C1 6
+#define PRCMU_FW_PROJECT_U8500_C2 7
+#define PRCMU_FW_PROJECT_U8500_C3 8
+#define PRCMU_FW_PROJECT_U8500_C4 9
+#define PRCMU_FW_PROJECT_U9500_MBL 10
+#define PRCMU_FW_PROJECT_U8500_SSG1 11 /* Samsung specific */
+#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */
+#define PRCMU_FW_PROJECT_U8520 13
+#define PRCMU_FW_PROJECT_U8420 14
+#define PRCMU_FW_PROJECT_U8500_SSG2 15 /* Samsung specific */
+#define PRCMU_FW_PROJECT_U8420_SYSCLK 17
+#define PRCMU_FW_PROJECT_A9420 20
+/* [32..63] 9540 and derivatives */
+#define PRCMU_FW_PROJECT_U9540 32
+/* [64..95] 8540 and derivatives */
+#define PRCMU_FW_PROJECT_L8540 64
+/* [96..126] 8580 and derivatives */
+#define PRCMU_FW_PROJECT_L8580 96
+
+#define PRCMU_FW_PROJECT_NAME_LEN 20
+
+/* PRCMU QoS APE OPP class */
+#define PRCMU_QOS_APE_OPP 1
+#define PRCMU_QOS_DDR_OPP 2
+#define PRCMU_QOS_ARM_OPP 3
+#define PRCMU_QOS_DEFAULT_VALUE -1
+
#define PRCMU_AUTO_PM_OFF 0
#define PRCMU_AUTO_PM_ON 1
@@ -469,6 +667,14 @@ enum prcmu_auto_pm_policy {
PRCMU_AUTO_PM_POLICY_DSP_CLK_OFF_HWP_CLK_OFF,
};
+struct prcmu_fw_version {
+ u32 project; /* Notice, project shifted with 8 on ux540 */
+ u8 api_version;
+ u8 func_version;
+ u8 errata;
+ char project_name[PRCMU_FW_PROJECT_NAME_LEN];
+};
+
/**
* struct prcmu_auto_pm_config - Autonomous power management configuration.
* @sia_auto_pm_enable: SIA autonomous pm enable. (PRCMU_AUTO_PM_{OFF,ON})
@@ -501,6 +707,9 @@ void prcmu_configure_auto_pm(struct prcmu_auto_pm_config *sleep,
bool prcmu_is_auto_pm_enabled(void);
int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
+unsigned long prcmu_clock_rate(u8 clock);
+long prcmu_round_clock_rate(u8 clock, unsigned long rate);
+int prcmu_set_clock_rate(u8 clock, unsigned long rate);
int prcmu_set_clock_divider(u8 clock, u8 divider);
int db8500_prcmu_config_hotdog(u8 threshold);
int db8500_prcmu_config_hotmon(u8 low, u8 high);
@@ -508,6 +717,8 @@ int db8500_prcmu_start_temp_sense(u16 cycles32k);
int db8500_prcmu_stop_temp_sense(void);
int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
+int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value,
+ u8 *mask, u8 size);
int prcmu_ac_wake_req(void);
void prcmu_ac_sleep_req(void);
@@ -610,6 +821,21 @@ static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
return 0;
}
+static inline unsigned long prcmu_clock_rate(u8 clock)
+{
+ return 0;
+}
+
+static inline long prcmu_round_clock_rate(u8 clock, unsigned long rate)
+{
+ return 0;
+}
+
+static inline int prcmu_set_clock_rate(u8 clock, unsigned long rate)
+{
+ return 0;
+}
+
static inline int prcmu_set_clock_divider(u8 clock, u8 divider)
{
return 0;
@@ -637,12 +863,18 @@ static inline int db8500_prcmu_stop_temp_sense(void)
static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
{
- return -ENOSYS;
+ return -EINVAL;
}
static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
{
- return -ENOSYS;
+ return -EINVAL;
+}
+
+static inline int prcmu_abb_write_masked(u8 slave, u8 reg,
+ u8 *value, u8 *mask, u8 size)
+{
+ return -EINVAL;
}
static inline int prcmu_ac_wake_req(void)
@@ -745,4 +977,20 @@ static inline void db8500_prcmu_write_masked(unsigned int reg, u32 mask,
#endif /* !CONFIG_MFD_DB8500_PRCMU */
+static inline int prcmu_qos_add_requirement(int prcmu_qos_class,
+ char *name, s32 value)
+{
+ return 0;
+}
+
+static inline int prcmu_qos_update_requirement(int prcmu_qos_class,
+ char *name, s32 new_value)
+{
+ return 0;
+}
+
+static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name)
+{
+}
+
#endif /* __MFD_DB8500_PRCMU_H */
diff --git a/include/linux/mfd/dbx500-prcmu.h b/include/linux/mfd/dbx500-prcmu.h
deleted file mode 100644
index 828362b7860c6..0000000000000
--- a/include/linux/mfd/dbx500-prcmu.h
+++ /dev/null
@@ -1,575 +0,0 @@
-/* SPDX-License-Identifier: GPL-2.0-only */
-/*
- * Copyright (C) ST Ericsson SA 2011
- *
- * STE Ux500 PRCMU API
- */
-#ifndef __MACH_PRCMU_H
-#define __MACH_PRCMU_H
-
-#include <linux/interrupt.h>
-#include <linux/notifier.h>
-#include <linux/err.h>
-
-#include <dt-bindings/mfd/dbx500-prcmu.h> /* For clock identifiers */
-
-/* Offset for the firmware version within the TCPM */
-#define DB8500_PRCMU_FW_VERSION_OFFSET 0xA4
-#define DBX540_PRCMU_FW_VERSION_OFFSET 0xA8
-
-/* PRCMU Wakeup defines */
-enum prcmu_wakeup_index {
- PRCMU_WAKEUP_INDEX_RTC,
- PRCMU_WAKEUP_INDEX_RTT0,
- PRCMU_WAKEUP_INDEX_RTT1,
- PRCMU_WAKEUP_INDEX_HSI0,
- PRCMU_WAKEUP_INDEX_HSI1,
- PRCMU_WAKEUP_INDEX_USB,
- PRCMU_WAKEUP_INDEX_ABB,
- PRCMU_WAKEUP_INDEX_ABB_FIFO,
- PRCMU_WAKEUP_INDEX_ARM,
- PRCMU_WAKEUP_INDEX_CD_IRQ,
- NUM_PRCMU_WAKEUP_INDICES
-};
-#define PRCMU_WAKEUP(_name) (BIT(PRCMU_WAKEUP_INDEX_##_name))
-
-/* EPOD (power domain) IDs */
-
-/*
- * DB8500 EPODs
- * - EPOD_ID_SVAMMDSP: power domain for SVA MMDSP
- * - EPOD_ID_SVAPIPE: power domain for SVA pipe
- * - EPOD_ID_SIAMMDSP: power domain for SIA MMDSP
- * - EPOD_ID_SIAPIPE: power domain for SIA pipe
- * - EPOD_ID_SGA: power domain for SGA
- * - EPOD_ID_B2R2_MCDE: power domain for B2R2 and MCDE
- * - EPOD_ID_ESRAM12: power domain for ESRAM 1 and 2
- * - EPOD_ID_ESRAM34: power domain for ESRAM 3 and 4
- * - NUM_EPOD_ID: number of power domains
- *
- * TODO: These should be prefixed.
- */
-#define EPOD_ID_SVAMMDSP 0
-#define EPOD_ID_SVAPIPE 1
-#define EPOD_ID_SIAMMDSP 2
-#define EPOD_ID_SIAPIPE 3
-#define EPOD_ID_SGA 4
-#define EPOD_ID_B2R2_MCDE 5
-#define EPOD_ID_ESRAM12 6
-#define EPOD_ID_ESRAM34 7
-#define NUM_EPOD_ID 8
-
-/*
- * state definition for EPOD (power domain)
- * - EPOD_STATE_NO_CHANGE: The EPOD should remain unchanged
- * - EPOD_STATE_OFF: The EPOD is switched off
- * - EPOD_STATE_RAMRET: The EPOD is switched off with its internal RAM in
- * retention
- * - EPOD_STATE_ON_CLK_OFF: The EPOD is switched on, clock is still off
- * - EPOD_STATE_ON: Same as above, but with clock enabled
- */
-#define EPOD_STATE_NO_CHANGE 0x00
-#define EPOD_STATE_OFF 0x01
-#define EPOD_STATE_RAMRET 0x02
-#define EPOD_STATE_ON_CLK_OFF 0x03
-#define EPOD_STATE_ON 0x04
-
-/*
- * CLKOUT sources
- */
-#define PRCMU_CLKSRC_CLK38M 0x00
-#define PRCMU_CLKSRC_ACLK 0x01
-#define PRCMU_CLKSRC_SYSCLK 0x02
-#define PRCMU_CLKSRC_LCDCLK 0x03
-#define PRCMU_CLKSRC_SDMMCCLK 0x04
-#define PRCMU_CLKSRC_TVCLK 0x05
-#define PRCMU_CLKSRC_TIMCLK 0x06
-#define PRCMU_CLKSRC_CLK009 0x07
-/* These are only valid for CLKOUT1: */
-#define PRCMU_CLKSRC_SIAMMDSPCLK 0x40
-#define PRCMU_CLKSRC_I2CCLK 0x41
-#define PRCMU_CLKSRC_MSP02CLK 0x42
-#define PRCMU_CLKSRC_ARMPLL_OBSCLK 0x43
-#define PRCMU_CLKSRC_HSIRXCLK 0x44
-#define PRCMU_CLKSRC_HSITXCLK 0x45
-#define PRCMU_CLKSRC_ARMCLKFIX 0x46
-#define PRCMU_CLKSRC_HDMICLK 0x47
-
-/**
- * enum prcmu_wdog_id - PRCMU watchdog IDs
- * @PRCMU_WDOG_ALL: use all timers
- * @PRCMU_WDOG_CPU1: use first CPU timer only
- * @PRCMU_WDOG_CPU2: use second CPU timer conly
- */
-enum prcmu_wdog_id {
- PRCMU_WDOG_ALL = 0x00,
- PRCMU_WDOG_CPU1 = 0x01,
- PRCMU_WDOG_CPU2 = 0x02,
-};
-
-/**
- * enum ape_opp - APE OPP states definition
- * @APE_OPP_INIT:
- * @APE_NO_CHANGE: The APE operating point is unchanged
- * @APE_100_OPP: The new APE operating point is ape100opp
- * @APE_50_OPP: 50%
- * @APE_50_PARTLY_25_OPP: 50%, except some clocks at 25%.
- */
-enum ape_opp {
- APE_OPP_INIT = 0x00,
- APE_NO_CHANGE = 0x01,
- APE_100_OPP = 0x02,
- APE_50_OPP = 0x03,
- APE_50_PARTLY_25_OPP = 0xFF,
-};
-
-/**
- * enum arm_opp - ARM OPP states definition
- * @ARM_OPP_INIT:
- * @ARM_NO_CHANGE: The ARM operating point is unchanged
- * @ARM_100_OPP: The new ARM operating point is arm100opp
- * @ARM_50_OPP: The new ARM operating point is arm50opp
- * @ARM_MAX_OPP: Operating point is "max" (more than 100)
- * @ARM_MAX_FREQ100OPP: Set max opp if available, else 100
- * @ARM_EXTCLK: The new ARM operating point is armExtClk
- */
-enum arm_opp {
- ARM_OPP_INIT = 0x00,
- ARM_NO_CHANGE = 0x01,
- ARM_100_OPP = 0x02,
- ARM_50_OPP = 0x03,
- ARM_MAX_OPP = 0x04,
- ARM_MAX_FREQ100OPP = 0x05,
- ARM_EXTCLK = 0x07
-};
-
-/**
- * enum ddr_opp - DDR OPP states definition
- * @DDR_100_OPP: The new DDR operating point is ddr100opp
- * @DDR_50_OPP: The new DDR operating point is ddr50opp
- * @DDR_25_OPP: The new DDR operating point is ddr25opp
- */
-enum ddr_opp {
- DDR_100_OPP = 0x00,
- DDR_50_OPP = 0x01,
- DDR_25_OPP = 0x02,
-};
-
-/*
- * Definitions for controlling ESRAM0 in deep sleep.
- */
-#define ESRAM0_DEEP_SLEEP_STATE_OFF 1
-#define ESRAM0_DEEP_SLEEP_STATE_RET 2
-
-/**
- * enum ddr_pwrst - DDR power states definition
- * @DDR_PWR_STATE_UNCHANGED: SDRAM and DDR controller state is unchanged
- * @DDR_PWR_STATE_ON:
- * @DDR_PWR_STATE_OFFLOWLAT:
- * @DDR_PWR_STATE_OFFHIGHLAT:
- */
-enum ddr_pwrst {
- DDR_PWR_STATE_UNCHANGED = 0x00,
- DDR_PWR_STATE_ON = 0x01,
- DDR_PWR_STATE_OFFLOWLAT = 0x02,
- DDR_PWR_STATE_OFFHIGHLAT = 0x03
-};
-
-#define DB8500_PRCMU_LEGACY_OFFSET 0xDD4
-
-#define PRCMU_FW_PROJECT_U8500 2
-#define PRCMU_FW_PROJECT_U8400 3
-#define PRCMU_FW_PROJECT_U9500 4 /* Customer specific */
-#define PRCMU_FW_PROJECT_U8500_MBB 5
-#define PRCMU_FW_PROJECT_U8500_C1 6
-#define PRCMU_FW_PROJECT_U8500_C2 7
-#define PRCMU_FW_PROJECT_U8500_C3 8
-#define PRCMU_FW_PROJECT_U8500_C4 9
-#define PRCMU_FW_PROJECT_U9500_MBL 10
-#define PRCMU_FW_PROJECT_U8500_SSG1 11 /* Samsung specific */
-#define PRCMU_FW_PROJECT_U8500_MBL2 12 /* Customer specific */
-#define PRCMU_FW_PROJECT_U8520 13
-#define PRCMU_FW_PROJECT_U8420 14
-#define PRCMU_FW_PROJECT_U8500_SSG2 15 /* Samsung specific */
-#define PRCMU_FW_PROJECT_U8420_SYSCLK 17
-#define PRCMU_FW_PROJECT_A9420 20
-/* [32..63] 9540 and derivatives */
-#define PRCMU_FW_PROJECT_U9540 32
-/* [64..95] 8540 and derivatives */
-#define PRCMU_FW_PROJECT_L8540 64
-/* [96..126] 8580 and derivatives */
-#define PRCMU_FW_PROJECT_L8580 96
-
-#define PRCMU_FW_PROJECT_NAME_LEN 20
-struct prcmu_fw_version {
- u32 project; /* Notice, project shifted with 8 on ux540 */
- u8 api_version;
- u8 func_version;
- u8 errata;
- char project_name[PRCMU_FW_PROJECT_NAME_LEN];
-};
-
-#include <linux/mfd/db8500-prcmu.h>
-
-#if defined(CONFIG_UX500_SOC_DB8500)
-
-static inline void __init prcmu_early_init(void)
-{
- db8500_prcmu_early_init();
-}
-
-static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
- bool keep_ap_pll)
-{
- return db8500_prcmu_set_power_state(state, keep_ulp_clk,
- keep_ap_pll);
-}
-
-static inline u8 prcmu_get_power_state_result(void)
-{
- return db8500_prcmu_get_power_state_result();
-}
-
-static inline int prcmu_set_epod(u16 epod_id, u8 epod_state)
-{
- return db8500_prcmu_set_epod(epod_id, epod_state);
-}
-
-static inline void prcmu_enable_wakeups(u32 wakeups)
-{
- db8500_prcmu_enable_wakeups(wakeups);
-}
-
-static inline void prcmu_disable_wakeups(void)
-{
- prcmu_enable_wakeups(0);
-}
-
-static inline void prcmu_config_abb_event_readout(u32 abb_events)
-{
- db8500_prcmu_config_abb_event_readout(abb_events);
-}
-
-static inline void prcmu_get_abb_event_buffer(void __iomem **buf)
-{
- db8500_prcmu_get_abb_event_buffer(buf);
-}
-
-int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size);
-int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size);
-int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, u8 *mask, u8 size);
-
-int prcmu_config_clkout(u8 clkout, u8 source, u8 div);
-
-static inline int prcmu_request_clock(u8 clock, bool enable)
-{
- return db8500_prcmu_request_clock(clock, enable);
-}
-
-unsigned long prcmu_clock_rate(u8 clock);
-long prcmu_round_clock_rate(u8 clock, unsigned long rate);
-int prcmu_set_clock_rate(u8 clock, unsigned long rate);
-
-static inline int prcmu_get_ddr_opp(void)
-{
- return db8500_prcmu_get_ddr_opp();
-}
-
-static inline int prcmu_set_arm_opp(u8 opp)
-{
- return db8500_prcmu_set_arm_opp(opp);
-}
-
-static inline int prcmu_get_arm_opp(void)
-{
- return db8500_prcmu_get_arm_opp();
-}
-
-static inline int prcmu_set_ape_opp(u8 opp)
-{
- return db8500_prcmu_set_ape_opp(opp);
-}
-
-static inline int prcmu_get_ape_opp(void)
-{
- return db8500_prcmu_get_ape_opp();
-}
-
-static inline int prcmu_request_ape_opp_100_voltage(bool enable)
-{
- return db8500_prcmu_request_ape_opp_100_voltage(enable);
-}
-
-static inline void prcmu_system_reset(u16 reset_code)
-{
- db8500_prcmu_system_reset(reset_code);
-}
-
-static inline u16 prcmu_get_reset_code(void)
-{
- return db8500_prcmu_get_reset_code();
-}
-
-int prcmu_ac_wake_req(void);
-void prcmu_ac_sleep_req(void);
-static inline void prcmu_modem_reset(void)
-{
- db8500_prcmu_modem_reset();
-}
-
-static inline bool prcmu_is_ac_wake_requested(void)
-{
- return db8500_prcmu_is_ac_wake_requested();
-}
-
-static inline int prcmu_config_esram0_deep_sleep(u8 state)
-{
- return db8500_prcmu_config_esram0_deep_sleep(state);
-}
-
-static inline int prcmu_config_hotdog(u8 threshold)
-{
- return db8500_prcmu_config_hotdog(threshold);
-}
-
-static inline int prcmu_config_hotmon(u8 low, u8 high)
-{
- return db8500_prcmu_config_hotmon(low, high);
-}
-
-static inline int prcmu_start_temp_sense(u16 cycles32k)
-{
- return db8500_prcmu_start_temp_sense(cycles32k);
-}
-
-static inline int prcmu_stop_temp_sense(void)
-{
- return db8500_prcmu_stop_temp_sense();
-}
-
-static inline u32 prcmu_read(unsigned int reg)
-{
- return db8500_prcmu_read(reg);
-}
-
-static inline void prcmu_write(unsigned int reg, u32 value)
-{
- db8500_prcmu_write(reg, value);
-}
-
-static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value)
-{
- db8500_prcmu_write_masked(reg, mask, value);
-}
-
-static inline int prcmu_enable_a9wdog(u8 id)
-{
- return db8500_prcmu_enable_a9wdog(id);
-}
-
-static inline int prcmu_disable_a9wdog(u8 id)
-{
- return db8500_prcmu_disable_a9wdog(id);
-}
-
-static inline int prcmu_kick_a9wdog(u8 id)
-{
- return db8500_prcmu_kick_a9wdog(id);
-}
-
-static inline int prcmu_load_a9wdog(u8 id, u32 timeout)
-{
- return db8500_prcmu_load_a9wdog(id, timeout);
-}
-
-static inline int prcmu_config_a9wdog(u8 num, bool sleep_auto_off)
-{
- return db8500_prcmu_config_a9wdog(num, sleep_auto_off);
-}
-#else
-
-static inline void prcmu_early_init(void) {}
-
-static inline int prcmu_set_power_state(u8 state, bool keep_ulp_clk,
- bool keep_ap_pll)
-{
- return 0;
-}
-
-static inline int prcmu_set_epod(u16 epod_id, u8 epod_state)
-{
- return 0;
-}
-
-static inline void prcmu_enable_wakeups(u32 wakeups) {}
-
-static inline void prcmu_disable_wakeups(void) {}
-
-static inline int prcmu_abb_read(u8 slave, u8 reg, u8 *value, u8 size)
-{
- return -ENOSYS;
-}
-
-static inline int prcmu_abb_write(u8 slave, u8 reg, u8 *value, u8 size)
-{
- return -ENOSYS;
-}
-
-static inline int prcmu_abb_write_masked(u8 slave, u8 reg, u8 *value, u8 *mask,
- u8 size)
-{
- return -ENOSYS;
-}
-
-static inline int prcmu_config_clkout(u8 clkout, u8 source, u8 div)
-{
- return 0;
-}
-
-static inline int prcmu_request_clock(u8 clock, bool enable)
-{
- return 0;
-}
-
-static inline long prcmu_round_clock_rate(u8 clock, unsigned long rate)
-{
- return 0;
-}
-
-static inline int prcmu_set_clock_rate(u8 clock, unsigned long rate)
-{
- return 0;
-}
-
-static inline unsigned long prcmu_clock_rate(u8 clock)
-{
- return 0;
-}
-
-static inline int prcmu_set_ape_opp(u8 opp)
-{
- return 0;
-}
-
-static inline int prcmu_get_ape_opp(void)
-{
- return APE_100_OPP;
-}
-
-static inline int prcmu_request_ape_opp_100_voltage(bool enable)
-{
- return 0;
-}
-
-static inline int prcmu_set_arm_opp(u8 opp)
-{
- return 0;
-}
-
-static inline int prcmu_get_arm_opp(void)
-{
- return ARM_100_OPP;
-}
-
-static inline int prcmu_get_ddr_opp(void)
-{
- return DDR_100_OPP;
-}
-
-static inline void prcmu_system_reset(u16 reset_code) {}
-
-static inline u16 prcmu_get_reset_code(void)
-{
- return 0;
-}
-
-static inline int prcmu_ac_wake_req(void)
-{
- return 0;
-}
-
-static inline void prcmu_ac_sleep_req(void) {}
-
-static inline void prcmu_modem_reset(void) {}
-
-static inline bool prcmu_is_ac_wake_requested(void)
-{
- return false;
-}
-
-static inline int prcmu_config_esram0_deep_sleep(u8 state)
-{
- return 0;
-}
-
-static inline void prcmu_config_abb_event_readout(u32 abb_events) {}
-
-static inline void prcmu_get_abb_event_buffer(void __iomem **buf)
-{
- *buf = NULL;
-}
-
-static inline int prcmu_config_hotdog(u8 threshold)
-{
- return 0;
-}
-
-static inline int prcmu_config_hotmon(u8 low, u8 high)
-{
- return 0;
-}
-
-static inline int prcmu_start_temp_sense(u16 cycles32k)
-{
- return 0;
-}
-
-static inline int prcmu_stop_temp_sense(void)
-{
- return 0;
-}
-
-static inline u32 prcmu_read(unsigned int reg)
-{
- return 0;
-}
-
-static inline void prcmu_write(unsigned int reg, u32 value) {}
-
-static inline void prcmu_write_masked(unsigned int reg, u32 mask, u32 value) {}
-
-#endif
-
-static inline void prcmu_set(unsigned int reg, u32 bits)
-{
- prcmu_write_masked(reg, bits, bits);
-}
-
-static inline void prcmu_clear(unsigned int reg, u32 bits)
-{
- prcmu_write_masked(reg, bits, 0);
-}
-
-/* PRCMU QoS APE OPP class */
-#define PRCMU_QOS_APE_OPP 1
-#define PRCMU_QOS_DDR_OPP 2
-#define PRCMU_QOS_ARM_OPP 3
-#define PRCMU_QOS_DEFAULT_VALUE -1
-
-static inline int prcmu_qos_add_requirement(int prcmu_qos_class,
- char *name, s32 value)
-{
- return 0;
-}
-
-static inline int prcmu_qos_update_requirement(int prcmu_qos_class,
- char *name, s32 new_value)
-{
- return 0;
-}
-
-static inline void prcmu_qos_remove_requirement(int prcmu_qos_class, char *name)
-{
-}
-
-#endif /* __MACH_PRCMU_H */
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 599de5de23dde..78278927cc53a 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -14,7 +14,7 @@
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
-#include <linux/mfd/dbx500-prcmu.h>
+#include <linux/mfd/db8500-prcmu.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 184/733] ASoC: ux500: Deassert the MSP reset during probe
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (182 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 183/733] mfd: db8500-prcmu: Fold dbx500 header into db8500 Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 185/733] ASoC: ux500: Request the MSP MMIO resource Greg Kroah-Hartman
` (560 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 66ec63e7a90bedc56aa050fbe437964008c3d584 ]
The devicetree has described each MSP reset line since the PRCC reset
controller was added, but the driver never acquires or deasserts it. The
block can consequently remain inaccessible when firmware has left it in
reset.
Acquire the reset exclusively and keep it deasserted for the lifetime of
the bound device.
Fixes: 95f04048325c ("ARM: dts: ux500: Add reset lines to IP blocks")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-5-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 78278927cc53a..b3de115d829a7 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -14,6 +14,7 @@
#include <linux/clk.h>
#include <linux/of.h>
#include <linux/regulator/consumer.h>
+#include <linux/reset.h>
#include <linux/mfd/db8500-prcmu.h>
#include <sound/soc.h>
@@ -686,6 +687,7 @@ static const struct snd_soc_component_driver ux500_msp_component = {
static int ux500_msp_drv_probe(struct platform_device *pdev)
{
struct ux500_msp_i2s_drvdata *drvdata;
+ struct reset_control *reset;
int ret = 0;
drvdata = devm_kzalloc(&pdev->dev,
@@ -733,6 +735,11 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
return -EINVAL;
}
+ reset = devm_reset_control_get_exclusive_deasserted(&pdev->dev, NULL);
+ if (IS_ERR(reset))
+ return dev_err_probe(&pdev->dev, PTR_ERR(reset),
+ "Failed to deassert MSP reset\n");
+
ret = ux500_msp_i2s_init_msp(pdev, &drvdata->msp);
if (ret) {
dev_err(&pdev->dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 185/733] ASoC: ux500: Request the MSP MMIO resource
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (183 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 184/733] ASoC: ux500: Deassert the MSP reset during probe Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 186/733] ASoC: ux500: Remove obsolete PRCMU QoS calls Greg Kroah-Hartman
` (559 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 4fb67925f33ad789e9e00903a73306ed40f7ae32 ]
A bare devm_ioremap() neither reserves the register range nor preserves
the platform resource error. This permits another driver to claim the
same range and reports every mapping failure as an allocation failure.
Use the managed platform resource helper, retaining the resolved
resource only to derive the DMA register address.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-6-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_i2s.c | 18 ++++--------------
1 file changed, 4 insertions(+), 14 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index bc77174e00707..43dc9b3aa4ef5 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -733,7 +733,7 @@ int ux500_msp_i2s_close(struct ux500_msp *msp, unsigned int dir)
int ux500_msp_i2s_init_msp(struct platform_device *pdev,
struct ux500_msp **msp_p)
{
- struct resource *res = NULL;
+ struct resource *res;
struct ux500_msp *msp;
*msp_p = devm_kzalloc(&pdev->dev, sizeof(struct ux500_msp), GFP_KERNEL);
@@ -743,20 +743,10 @@ int ux500_msp_i2s_init_msp(struct platform_device *pdev,
msp->dev = &pdev->dev;
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (res == NULL) {
- dev_err(&pdev->dev, "%s: ERROR: Unable to get resource!\n",
- __func__);
- return -ENOMEM;
- }
-
+ msp->registers = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
+ if (IS_ERR(msp->registers))
+ return PTR_ERR(msp->registers);
msp->tx_rx_addr = res->start + MSP_DR;
- msp->registers = devm_ioremap(&pdev->dev, res->start,
- resource_size(res));
- if (msp->registers == NULL) {
- dev_err(&pdev->dev, "%s: ERROR: ioremap failed!\n", __func__);
- return -ENOMEM;
- }
msp->msp_state = MSP_STATE_IDLE;
msp->loopback_enable = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 186/733] ASoC: ux500: Remove obsolete PRCMU QoS calls
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (184 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 185/733] ASoC: ux500: Request the MSP MMIO resource Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 187/733] ASoC: ux500: Allow repeated MSP prepare calls Greg Kroah-Hartman
` (558 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 7b819677b503667422b0b7bdb21853e0066f8606 ]
The DB8500 PRCMU QoS interface consists of unconditional inline stubs,
so the MSP calls and cached constraint state have no effect. Device
power and clocks are already represented by the regulator, power-domain
and common-clock frameworks.
Remove the dead calls and their private state instead of pretending to
change the APE operating point.
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-7-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Stable-dep-of: dc1a1b1e2206 ("ASoC: ux500: Allow repeated MSP prepare calls")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 26 --------------------------
sound/soc/ux500/ux500_msp_dai.h | 2 --
2 files changed, 28 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index b3de115d829a7..5b4b3126637e4 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -15,7 +15,6 @@
#include <linux/of.h>
#include <linux/regulator/consumer.h>
#include <linux/reset.h>
-#include <linux/mfd/db8500-prcmu.h>
#include <sound/soc.h>
#include <sound/soc-dai.h>
@@ -393,12 +392,6 @@ static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
snd_pcm_stream_str(substream));
- if (drvdata->vape_opp_constraint == 1) {
- prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
- "ux500_msp_i2s", 50);
- drvdata->vape_opp_constraint = 0;
- }
-
if (ux500_msp_i2s_close(drvdata->msp,
is_playback ? MSP_DIR_TX : MSP_DIR_RX)) {
dev_err(dai->dev,
@@ -440,21 +433,6 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
return ret;
}
- /* Set OPP-level */
- if ((drvdata->fmt & SND_SOC_DAIFMT_CLOCK_PROVIDER_MASK) &&
- (drvdata->msp->f_bitclk > 19200000)) {
- /* If the bit-clock is higher than 19.2MHz, Vape should be
- * run in 100% OPP. Only when bit-clock is used (MSP master)
- */
- prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
- "ux500-msp-i2s", 100);
- drvdata->vape_opp_constraint = 1;
- } else {
- prcmu_qos_update_requirement(PRCMU_QOS_APE_OPP,
- "ux500-msp-i2s", 50);
- drvdata->vape_opp_constraint = 0;
- }
-
return ret;
}
@@ -710,8 +688,6 @@ static int ux500_msp_drv_probe(struct platform_device *pdev)
__func__, ret);
return ret;
}
- prcmu_qos_add_requirement(PRCMU_QOS_APE_OPP, (char *)pdev->name, 50);
-
drvdata->pclk = devm_clk_get(&pdev->dev, "apb_pclk");
if (IS_ERR(drvdata->pclk)) {
ret = PTR_ERR(drvdata->pclk);
@@ -780,8 +756,6 @@ static void ux500_msp_drv_remove(struct platform_device *pdev)
snd_soc_unregister_component(&pdev->dev);
- prcmu_qos_remove_requirement(PRCMU_QOS_APE_OPP, "ux500_msp_i2s");
-
ux500_msp_i2s_cleanup_msp(pdev, drvdata->msp);
}
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index 19058c238420e..ad4ce69bfbf5c 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -46,8 +46,6 @@ struct ux500_msp_i2s_drvdata {
struct clk *clk;
struct clk *pclk;
- /* Regulators */
- int vape_opp_constraint;
};
int ux500_msp_dai_set_data_delay(struct snd_soc_dai *dai, int delay);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 187/733] ASoC: ux500: Allow repeated MSP prepare calls
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (185 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 186/733] ASoC: ux500: Remove obsolete PRCMU QoS calls Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 188/733] ASoC: ux500: Program the MSP FIFO watermarks Greg Kroah-Hartman
` (557 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit dc1a1b1e22066f01bb86a9b11ee998d4dc72db66 ]
ALSA can call the DAI prepare callback again after an XRUN without
first shutting down the stream. The MSP open helper rejects the second
call with -EBUSY because the direction remains configured.
Track successful playback and capture configurations at the DAI layer.
Make repeated prepare calls no-ops and only close directions which were
successfully prepared.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-8-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_dai.c | 28 +++++++++++++++++++++-------
sound/soc/ux500/ux500_msp_dai.h | 1 +
2 files changed, 22 insertions(+), 7 deletions(-)
diff --git a/sound/soc/ux500/ux500_msp_dai.c b/sound/soc/ux500/ux500_msp_dai.c
index 5b4b3126637e4..37c48cc70394e 100644
--- a/sound/soc/ux500/ux500_msp_dai.c
+++ b/sound/soc/ux500/ux500_msp_dai.c
@@ -388,15 +388,21 @@ static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
int ret;
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
bool is_playback = (substream->stream == SNDRV_PCM_STREAM_PLAYBACK);
+ unsigned int configured = is_playback ? PLAYBACK_CONFIGURED :
+ CAPTURE_CONFIGURED;
+ unsigned int dir = is_playback ? MSP_DIR_TX : MSP_DIR_RX;
dev_dbg(dai->dev, "%s: MSP %d (%s): Enter.\n", __func__, dai->id,
snd_pcm_stream_str(substream));
- if (ux500_msp_i2s_close(drvdata->msp,
- is_playback ? MSP_DIR_TX : MSP_DIR_RX)) {
- dev_err(dai->dev,
- "%s: Error: MSP %d (%s): Unable to close i2s.\n",
- __func__, dai->id, snd_pcm_stream_str(substream));
+ if (drvdata->configured & configured) {
+ if (ux500_msp_i2s_close(drvdata->msp, dir)) {
+ dev_err(dai->dev,
+ "%s: Error: MSP %d (%s): Unable to close i2s.\n",
+ __func__, dai->id,
+ snd_pcm_stream_str(substream));
+ }
+ drvdata->configured &= ~configured;
}
/* Disable and unprepare clocks */
@@ -414,14 +420,20 @@ static void ux500_msp_dai_shutdown(struct snd_pcm_substream *substream,
static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
struct snd_soc_dai *dai)
{
- int ret = 0;
struct ux500_msp_i2s_drvdata *drvdata = dev_get_drvdata(dai->dev);
struct snd_pcm_runtime *runtime = substream->runtime;
struct ux500_msp_config msp_config;
+ bool is_playback = substream->stream == SNDRV_PCM_STREAM_PLAYBACK;
+ unsigned int configured = is_playback ? PLAYBACK_CONFIGURED :
+ CAPTURE_CONFIGURED;
+ int ret;
dev_dbg(dai->dev, "%s: MSP %d (%s): Enter (rate = %d).\n", __func__,
dai->id, snd_pcm_stream_str(substream), runtime->rate);
+ if (drvdata->configured & configured)
+ return 0;
+
ret = setup_msp_config(substream, dai, &msp_config);
if (ret)
return ret;
@@ -433,7 +445,9 @@ static int ux500_msp_dai_prepare(struct snd_pcm_substream *substream,
return ret;
}
- return ret;
+ drvdata->configured |= configured;
+
+ return 0;
}
static int ux500_msp_dai_hw_params(struct snd_pcm_substream *substream,
diff --git a/sound/soc/ux500/ux500_msp_dai.h b/sound/soc/ux500/ux500_msp_dai.h
index ad4ce69bfbf5c..aae582030d959 100644
--- a/sound/soc/ux500/ux500_msp_dai.h
+++ b/sound/soc/ux500/ux500_msp_dai.h
@@ -36,6 +36,7 @@ struct ux500_msp_i2s_drvdata {
struct ux500_msp *msp;
struct regulator *reg_vape;
unsigned int fmt;
+ unsigned int configured;
unsigned int tx_mask;
unsigned int rx_mask;
int slots;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 188/733] ASoC: ux500: Program the MSP FIFO watermarks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (186 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 187/733] ASoC: ux500: Allow repeated MSP prepare calls Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 189/733] bpf: backtrack_insn(): Handle ld_{abs,ind} subprog exit edge Greg Kroah-Hartman
` (556 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 2519439b4b5f6ee95879b1a44fc373127291b1e4 ]
The DMA engine is configured for four-element bursts, but the MSP
driver never programs the FIFO watermark register and instead depends
on its previous or reset value. The DB8500 DMA request protocol requires
the peripheral watermark to match the DMA packet size.
Program four-element receive and transmit watermarks when configuring
the first direction, before enabling MSP DMA requests.
Fixes: 3592b7f69a54 ("ASoC: Ux500: Add MSP I2S-driver")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260902-ux500-msp-fixes-v2-9-4b60b002d55a@kernel.org
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/ux500/ux500_msp_i2s.c | 2 ++
sound/soc/ux500/ux500_msp_i2s.h | 5 +++++
2 files changed, 7 insertions(+)
diff --git a/sound/soc/ux500/ux500_msp_i2s.c b/sound/soc/ux500/ux500_msp_i2s.c
index 43dc9b3aa4ef5..683b485fb5708 100644
--- a/sound/soc/ux500/ux500_msp_i2s.c
+++ b/sound/soc/ux500/ux500_msp_i2s.c
@@ -507,6 +507,8 @@ int ux500_msp_i2s_open(struct ux500_msp *msp,
old_reg &= ~mask;
new_reg |= old_reg;
writel(new_reg, msp->registers + MSP_GCR);
+ writel(MSP_WMRK_TX_4_ELEMENTS | MSP_WMRK_RX_4_ELEMENTS,
+ msp->registers + MSP_WMRK);
}
res = enable_msp(msp, config, first);
diff --git a/sound/soc/ux500/ux500_msp_i2s.h b/sound/soc/ux500/ux500_msp_i2s.h
index 17b5c37a7e5d5..2bf2699bdc49f 100644
--- a/sound/soc/ux500/ux500_msp_i2s.h
+++ b/sound/soc/ux500/ux500_msp_i2s.h
@@ -62,6 +62,7 @@ enum msp_direction {
#define MSP_SRG 0x10
#define MSP_FLR 0x14
#define MSP_DMACR 0x18
+#define MSP_WMRK 0x1c
#define MSP_IMSC 0x20
#define MSP_RIS 0x24
@@ -228,6 +229,10 @@ enum msp_direction {
#define RDMAE_SHIFT 0
#define TDMAE_SHIFT 1
+/* FIFO watermark register */
+#define MSP_WMRK_RX_4_ELEMENTS BIT(0)
+#define MSP_WMRK_TX_4_ELEMENTS BIT(3)
+
/* Interrupt Register */
#define RX_SERVICE_INT BIT(0)
#define RX_OVERRUN_ERROR_INT BIT(1)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 189/733] bpf: backtrack_insn(): Handle ld_{abs,ind} subprog exit edge
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (187 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 188/733] ASoC: ux500: Program the MSP FIFO watermarks Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 190/733] bpf: backtracking shouldnt clear outer frame R1-R5 for callbacks Greg Kroah-Hartman
` (555 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Daniel Borkmann, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 387b1baefbb776e3f48dc2261e77a49213f470f7 ]
Nicholas Carlini reported a bug in precision backtracking mechanism
for BPF_LD | BPF_{IND,ABS} instructions. These instructions are
modelled as two branches:
- fallthrough;
- implicit exit from current subprogram.
The implicit exit case was not handled by the backtrack_insn()
function. When backtracking such a path backtrack_insn() did not
call bt_subprog_enter(), which meant that backtracking continued
manipulating precision marks in a caller frame, while looking at
instructions in a callee frame.
This lead to segmentation faults during verification (see the
selftest), or unsound state pruning.
Fixes: ee861486e377 ("bpf: Fix ld_{abs,ind} failure path analysis in subprogs")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Daniel Borkmann <daniel@iogearbox.net>
Acked-by: Daniel Borkmann <daniel@iogearbox.net>
Link: https://lore.kernel.org/bpf/20260901-bug-016-backtrack-ld-abs-v1-1-59368f1be435@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/backtrack.c | 25 +++++++++++++++++++------
1 file changed, 19 insertions(+), 6 deletions(-)
diff --git a/kernel/bpf/backtrack.c b/kernel/bpf/backtrack.c
index 2e4ae0ef08609..ac7341f003b02 100644
--- a/kernel/bpf/backtrack.c
+++ b/kernel/bpf/backtrack.c
@@ -583,16 +583,29 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
*/
}
} else if (class == BPF_LD) {
- if (!bt_is_reg_set(bt, dreg))
- return 0;
- bt_clear_reg(bt, dreg);
/* It's ld_imm64 or ld_abs or ld_ind.
* For ld_imm64 no further tracking of precision
* into parent is necessary
*/
- if (mode == BPF_IND || mode == BPF_ABS)
- /* to be analyzed */
- return -ENOTSUPP;
+ if (mode == BPF_IMM) {
+ bt_clear_reg(bt, dreg);
+ return 0;
+ }
+ /*
+ * BPF_{IND,ABS} are modelled as two branches:
+ * - fallthrough;
+ * - implicit subprogram exit.
+ * It is necessary to switch current frame if
+ * implicit subprogram exit branch is backtracked.
+ */
+ if (mode == BPF_IND || mode == BPF_ABS) {
+ if (bt_is_reg_set(bt, dreg))
+ return -ENOTSUPP;
+ if (subseq_idx != idx + 1)
+ if (bt_subprog_enter(bt))
+ return -EFAULT;
+ return 0;
+ }
}
/* Propagate precision marks to linked registers, to account for
* registers marked as precise in this function.
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 190/733] bpf: backtracking shouldnt clear outer frame R1-R5 for callbacks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (188 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 189/733] bpf: backtrack_insn(): Handle ld_{abs,ind} subprog exit edge Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 191/733] btrfs: scrub: report the failing sectors address, not the stripe base Greg Kroah-Hartman
` (554 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit e3e4f66cc4b72333d0886ae2673c360248987889 ]
When processing calls to bpf_loop() verifier marks R1 (and R4) as
precise. R1 tracks loop iterations number and because of the
'callback_depth < R1' mechanics in check_helper_call() must be marked
precise. However, precision propagation for R1 was broken,
when bpf_loop() call was verified on a second iteration.
Consider the following verification trace:
- main: bpf_loop(nr_loops, callback ...)
- callback: BPF_EXIT
- main: bpf_loop(nr_loops, callback ...)
- ...
While the first visit of the call to bpf_loop() propagated R1
precision as expected, the second call to mark_chain_precision() in
the check_helper_call() set R1, but it was immediately reset when
backtrack_insn() processed preceding BPF_EXIT in the loop deleted in
this patch.
Because of that, the second visit of the call to bpf_loop() injected
checkpoint with R1 not marked as precise. Which could trick the
verifier into accepting unsafe programs. See the next patch for an
example of such program.
Commit is structured in a way to minimize conflicts when
'bpf' would be eventually merged with 'bpf-next'.
Fixes: ab5cfac139ab ("bpf: verify callbacks as if they are called unknown number of times")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260831-bug-015-backtrack-cb-args-precise-v1-1-68a8e2a821e0@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/backtrack.c | 37 +++++++++++++++++--------------------
1 file changed, 17 insertions(+), 20 deletions(-)
diff --git a/kernel/bpf/backtrack.c b/kernel/bpf/backtrack.c
index ac7341f003b02..53a1e52d73c5a 100644
--- a/kernel/bpf/backtrack.c
+++ b/kernel/bpf/backtrack.c
@@ -521,37 +521,34 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,
return -EFAULT;
}
} else if (opcode == BPF_EXIT) {
- bool r0_precise;
+ bool from_subprog_call, r0_precise;
+
+ /* BPF_EXIT in subprog or callback always returns
+ * right after the call instruction, so by checking
+ * whether the instruction at subseq_idx-1 is subprog
+ * call or not we can distinguish actual exit from
+ * *subprog* from exit from *callback*. In the former
+ * case, we need to propagate r0 precision, if
+ * necessary. In the former we never do that.
+ */
+ from_subprog_call = subseq_idx - 1 >= 0 &&
+ bpf_pseudo_call(&env->prog->insnsi[subseq_idx - 1]);
+
+ r0_precise = from_subprog_call && bt_is_reg_set(bt, BPF_REG_0);
/* Backtracking to a nested function call, 'idx' is a part of
* the inner frame 'subseq_idx' is a part of the outer frame.
* In case of a regular function call, instructions giving
* precision to registers R1-R5 should have been found already.
- * In case of a callback, it is ok to have R1-R5 marked for
- * backtracking, as these registers are set by the function
- * invoking callback.
+ * In case of a callback from bpf_loop(), R{1,4} in the calling
+ * frame would be set as precise and that is correct.
*/
- if (subseq_idx >= 0 && bpf_calls_callback(env, subseq_idx))
- for (i = BPF_REG_1; i <= BPF_REG_5; i++)
- bt_clear_reg(bt, i);
- if (bt_reg_mask(bt) & BPF_REGMASK_ARGS) {
+ if (from_subprog_call && (bt_reg_mask(bt) & BPF_REGMASK_ARGS)) {
verifier_bug(env, "backtracking exit unexpected regs %x",
bt_reg_mask(bt));
return -EFAULT;
}
- /* BPF_EXIT in subprog or callback always returns
- * right after the call instruction, so by checking
- * whether the instruction at subseq_idx-1 is subprog
- * call or not we can distinguish actual exit from
- * *subprog* from exit from *callback*. In the former
- * case, we need to propagate r0 precision, if
- * necessary. In the former we never do that.
- */
- r0_precise = subseq_idx - 1 >= 0 &&
- bpf_pseudo_call(&env->prog->insnsi[subseq_idx - 1]) &&
- bt_is_reg_set(bt, BPF_REG_0);
-
bt_clear_reg(bt, BPF_REG_0);
if (bt_subprog_enter(bt))
return -EFAULT;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 191/733] btrfs: scrub: report the failing sectors address, not the stripe base
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (189 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 190/733] bpf: backtracking shouldnt clear outer frame R1-R5 for callbacks Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 192/733] btrfs: fix transaction use-after-free in raid stripe insertion Greg Kroah-Hartman
` (553 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, James C. Owens,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: James C. Owens <jamesowens@optonline.net>
[ Upstream commit 33ce0aa4c57611c3a3485ec7c01ad67b3751447d ]
scrub_stripe_report_errors() iterates over the sectors of a stripe, but
every message it emits passes stripe->logical, the address of the first
sector of the 64KiB stripe, rather than the address of the sector being
reported. The physical address is likewise computed once, before the
loop, from stripe->logical.
This matters because scrub_print_common_warning() uses that logical
address for the backref walk which produces the "root %llu inode %llu
offset %llu ... (path: ...)" part of the message. As the address is
always the stripe base, the reported root/inode/offset/path can identify
a different file from the one whose sector actually failed.
A 64KiB stripe routinely spans several extents belonging to unrelated
files. On the machine where this was found, the stripe at logical
0x17D9380000 holds four sectors of /usr/share/plasma/emoji/bg.dict, then
a file inside a docker volume, then sectors referenced only by
snapshots. Every error anywhere in that stripe is attributed to bg.dict.
The effect is visible statistically: across ten months and four kernel
series that machine logged 81 distinct flagged logical addresses, and
every one of them is exactly 64KiB aligned. Since BTRFS_STRIPE_LEN is
64KiB and stripe->logical is stripe aligned by construction, real
failures distributed across sectors could not produce that.
Report the address of the sector actually being examined. Adding the
sector offset to the physical address is valid because BTRFS_STRIPE_LEN
is the unit contiguous on a single device for every profile, so a stripe
never crosses a device boundary.
Fixes: 0096580713ff ("btrfs: scrub: introduce error reporting functionality for scrub_stripe")
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: James C. Owens <jamesowens@optonline.net>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/scrub.c | 24 ++++++++++++++----------
1 file changed, 14 insertions(+), 10 deletions(-)
diff --git a/fs/btrfs/scrub.c b/fs/btrfs/scrub.c
index d2f7ac5b6e961..3b3f04521369d 100644
--- a/fs/btrfs/scrub.c
+++ b/fs/btrfs/scrub.c
@@ -1041,6 +1041,10 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
skip:
for_each_set_bit(sector_nr, &extent_bitmap, stripe->nr_sectors) {
+ const u64 sector_logical = stripe->logical +
+ ((u64)sector_nr << fs_info->sectorsize_bits);
+ const u64 sector_physical = physical +
+ ((u64)sector_nr << fs_info->sectorsize_bits);
bool repaired = false;
if (scrub_bitmap_test_bit_is_metadata(stripe, sector_nr)) {
@@ -1069,12 +1073,12 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
if (dev) {
btrfs_err_rl(fs_info,
"scrub: fixed up error at logical %llu on dev %s physical %llu",
- stripe->logical, btrfs_dev_name(dev),
- physical);
+ sector_logical, btrfs_dev_name(dev),
+ sector_physical);
} else {
btrfs_err_rl(fs_info,
"scrub: fixed up error at logical %llu on mirror %u",
- stripe->logical, stripe->mirror_num);
+ sector_logical, stripe->mirror_num);
}
continue;
}
@@ -1083,30 +1087,30 @@ static void scrub_stripe_report_errors(struct scrub_ctx *sctx,
if (dev) {
btrfs_err_rl(fs_info,
"scrub: unable to fixup (regular) error at logical %llu on dev %s physical %llu",
- stripe->logical, btrfs_dev_name(dev),
- physical);
+ sector_logical, btrfs_dev_name(dev),
+ sector_physical);
} else {
btrfs_err_rl(fs_info,
"scrub: unable to fixup (regular) error at logical %llu on mirror %u",
- stripe->logical, stripe->mirror_num);
+ sector_logical, stripe->mirror_num);
}
if (scrub_bitmap_test_bit_io_error(stripe, sector_nr))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("i/o error", dev, false,
- stripe->logical, physical);
+ sector_logical, sector_physical);
if (scrub_bitmap_test_bit_csum_error(stripe, sector_nr))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("checksum error", dev, false,
- stripe->logical, physical);
+ sector_logical, sector_physical);
if (scrub_bitmap_test_bit_meta_error(stripe, sector_nr))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("header error", dev, false,
- stripe->logical, physical);
+ sector_logical, sector_physical);
if (scrub_bitmap_test_bit_meta_gen_error(stripe, sector_nr))
if (__ratelimit(&rs) && dev)
scrub_print_common_warning("generation error", dev, false,
- stripe->logical, physical);
+ sector_logical, sector_physical);
}
/* Update the device stats. */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 192/733] btrfs: fix transaction use-after-free in raid stripe insertion
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (190 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 191/733] btrfs: scrub: report the failing sectors address, not the stripe base Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 193/733] btrfs: fix the possible bioc_list memory leak during error Greg Kroah-Hartman
` (552 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Shuangpeng Bai,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
[ Upstream commit a8813a923f9e43f788b357fb55c35f7f6ed6f98c ]
If allocation of a RAID stripe extent fails,
btrfs_insert_one_raid_extent() aborts and ends the transaction before
returning -ENOMEM.
btrfs_finish_one_ordered(), the production caller through
btrfs_insert_raid_extent(), still owns the transaction handle. It handles
the error by aborting the transaction and then reaches the common exit
path, which ends the transaction again.
The premature end can free the handle and drop its transaction reference.
Transaction cleanup can then free the transaction before the caller's
second abort accesses the handle and transaction, resulting in
use-after-free.
Keep the abort at the failure site, but let the caller's common exit path
end the transaction once, after it has finished using both objects.
Fixes: 02c372e1f016 ("btrfs: add support for inserting raid stripe extents")
Assisted-by: Codex:GPT-5
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Shuangpeng Bai <shuangpeng.kernel@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/raid-stripe-tree.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
index b210371ce91e3..89e259a47d8de 100644
--- a/fs/btrfs/raid-stripe-tree.c
+++ b/fs/btrfs/raid-stripe-tree.c
@@ -337,7 +337,6 @@ int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
stripe_extent = kzalloc(item_size, GFP_NOFS);
if (unlikely(!stripe_extent)) {
btrfs_abort_transaction(trans, -ENOMEM);
- btrfs_end_transaction(trans);
return -ENOMEM;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 193/733] btrfs: fix the possible bioc_list memory leak during error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (191 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 192/733] btrfs: fix transaction use-after-free in raid stripe insertion Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 194/733] btrfs: return proper negative error code for update_raid_extent_item() Greg Kroah-Hartman
` (551 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Thumshirn, Qu Wenruo,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit afbe73778338e6d1ac8c4486fbdf33f0cc1f2624 ]
There are two possible ways to leak bioc memory on
btrfs_ordered_extent::bioc_list:
- An error occurred for btrfs_insert_one_raid_extent()
Then the function btrfs_insert_raid_extent() immediately return
without freeing any bioc in the bioc_list.
- An ordered extent hit an IO error
In that case the ordered extent will have BTRFS_ORDERED_IOERR set, and
skip the call on btrfs_insert_raid_extent() completely.
Fix the problem by:
- Introduce a new helper, btrfs_cleanup_ordered_bioc_list()
Which will remove all bioc from the bioc_list, and release the bioc.
- Call the above helper for btrfs_insert_raid_extent()
So that the cleanup helper is always called no matter what.
- Call the above helper for btrfs_finish_one_ordered()
This is called just before the final release on the ordered extent.
This was reported by Sashiko when reviewing another patch.
Link: https://sashiko.dev/#/patchset/20260817021512.3010812-1-shuangpeng.kernel%40gmail.com
Fixes: 02c372e1f016 ("btrfs: add support for inserting raid stripe extents")
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/inode.c | 3 +++
fs/btrfs/raid-stripe-tree.c | 18 ++++++++++++------
fs/btrfs/raid-stripe-tree.h | 1 +
3 files changed, 16 insertions(+), 6 deletions(-)
diff --git a/fs/btrfs/inode.c b/fs/btrfs/inode.c
index 39a01f9cf6b51..188b4ac9889fc 100644
--- a/fs/btrfs/inode.c
+++ b/fs/btrfs/inode.c
@@ -3435,6 +3435,9 @@ int btrfs_finish_one_ordered(struct btrfs_ordered_extent *ordered_extent)
*/
btrfs_remove_ordered_extent(ordered_extent);
+ /* Cleanup any remaining biocs attached to the OE. */
+ btrfs_cleanup_ordered_bioc_list(ordered_extent);
+
/* once for us */
btrfs_put_ordered_extent(ordered_extent);
/* once for the tree */
diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
index 89e259a47d8de..6291775dbe0e7 100644
--- a/fs/btrfs/raid-stripe-tree.c
+++ b/fs/btrfs/raid-stripe-tree.c
@@ -373,7 +373,7 @@ int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
struct btrfs_ordered_extent *ordered_extent)
{
struct btrfs_io_context *bioc;
- int ret;
+ int ret = 0;
if (!btrfs_fs_incompat(trans->fs_info, RAID_STRIPE_TREE))
return 0;
@@ -381,17 +381,23 @@ int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
list_for_each_entry(bioc, &ordered_extent->bioc_list, rst_ordered_entry) {
ret = btrfs_insert_one_raid_extent(trans, bioc);
if (ret)
- return ret;
+ break;
}
- while (!list_empty(&ordered_extent->bioc_list)) {
- bioc = list_first_entry(&ordered_extent->bioc_list,
+ btrfs_cleanup_ordered_bioc_list(ordered_extent);
+ return ret;
+}
+
+void btrfs_cleanup_ordered_bioc_list(struct btrfs_ordered_extent *ordered)
+{
+ while (!list_empty(&ordered->bioc_list)) {
+ struct btrfs_io_context *bioc;
+
+ bioc = list_first_entry(&ordered->bioc_list,
typeof(*bioc), rst_ordered_entry);
list_del(&bioc->rst_ordered_entry);
btrfs_put_bioc(bioc);
}
-
- return 0;
}
int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,
diff --git a/fs/btrfs/raid-stripe-tree.h b/fs/btrfs/raid-stripe-tree.h
index 69942ad431408..eb02cf48511bc 100644
--- a/fs/btrfs/raid-stripe-tree.h
+++ b/fs/btrfs/raid-stripe-tree.h
@@ -28,6 +28,7 @@ int btrfs_get_raid_extent_offset(struct btrfs_fs_info *fs_info,
u32 stripe_index, struct btrfs_io_stripe *stripe);
int btrfs_insert_raid_extent(struct btrfs_trans_handle *trans,
struct btrfs_ordered_extent *ordered_extent);
+void btrfs_cleanup_ordered_bioc_list(struct btrfs_ordered_extent *ordered);
#ifdef CONFIG_BTRFS_FS_RUN_SANITY_TESTS
int btrfs_insert_one_raid_extent(struct btrfs_trans_handle *trans,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 194/733] btrfs: return proper negative error code for update_raid_extent_item()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (192 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 193/733] btrfs: fix the possible bioc_list memory leak during error Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 195/733] btrfs: zoned: finish active block group cleanup if call_zone_finish() fails Greg Kroah-Hartman
` (550 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Johannes Thumshirn, Qu Wenruo,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit a03fa65184545837d6461413275da71f30527385 ]
The function btrfs_abort_transaction() only accepts negative error code,
and have the macro VERIFY_NEGATIVE_ERROR() to verify that error code.
But inside update_raid_extent_item(), if there is such key found, we
return 1, breaking the negative error code scheme.
Furthermore if we hit some real error during the tree search, e.g. -EIO,
then the error code is always over-written to -EINVAL.
Fix both problems by following other call sites by overwriting @ret to
-ENOENT if the btrfs_search_slot() failed to locate the key.
This is very unlikely to hit, as we only enter update_raid_extent_item()
if there is a conflicting key already in the raid stripe tree.
This was reported by Sashiko when reviewing another patch.
Link: https://sashiko.dev/#/patchset/20260817021512.3010812-1-shuangpeng.kernel%40gmail.com
Fixes: 8c4cba2adbb0 ("btrfs: update stripe extents for existing logical addresses")
Reviewed-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/raid-stripe-tree.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/fs/btrfs/raid-stripe-tree.c b/fs/btrfs/raid-stripe-tree.c
index 6291775dbe0e7..d9e660447205f 100644
--- a/fs/btrfs/raid-stripe-tree.c
+++ b/fs/btrfs/raid-stripe-tree.c
@@ -310,8 +310,10 @@ static int update_raid_extent_item(struct btrfs_trans_handle *trans,
ret = btrfs_search_slot(trans, trans->fs_info->stripe_root, key, path,
0, 1);
- if (ret)
- return (ret == 1 ? ret : -EINVAL);
+ if (ret > 0)
+ ret = -ENOENT;
+ if (ret < 0)
+ return ret;
leaf = path->nodes[0];
slot = path->slots[0];
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 195/733] btrfs: zoned: finish active block group cleanup if call_zone_finish() fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (193 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 194/733] btrfs: return proper negative error code for update_raid_extent_item() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 196/733] btrfs: send: fix lost error return value in will_overwrite_ref() Greg Kroah-Hartman
` (549 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, Johannes Thumshirn,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johannes Thumshirn <johannes.thumshirn@wdc.com>
[ Upstream commit a18a6b93a2843b9d103d3456bbd4b3f90282a379 ]
do_zone_finish() clears BLOCK_GROUP_FLAG_ZONE_IS_ACTIVE before finishing
the zones. If call_zone_finish() then fails it returned early, leaving the
now inactive block group on fs_info->zone_active_bgs, leaking its
reference, the BTRFS_FS_NEED_ZONE_FINISH waiters are never woken, and as
its alloc_offset equals the zone capacity btrfs_zone_finish_one_bg() keeps
selecting it, spinning btrfs_zoned_activate_one_bg().
Fall through to the cleanup on failure too and return the error, but keep
the block group read-only as its zones are left inconsistent.
Fixes: d70cbdda75da ("btrfs: zoned: consolidate zone finish functions")
Link: https://sashiko.dev/#/patchset/20260818100037.1366563-1-johannes.thumshirn%40wdc.com
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Johannes Thumshirn <johannes.thumshirn@wdc.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/zoned.c | 11 ++++-------
1 file changed, 4 insertions(+), 7 deletions(-)
diff --git a/fs/btrfs/zoned.c b/fs/btrfs/zoned.c
index a016cb471beb4..7f0dde6398d4d 100644
--- a/fs/btrfs/zoned.c
+++ b/fs/btrfs/zoned.c
@@ -2626,16 +2626,13 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
down_read(&dev_replace->rwsem);
map = block_group->physical_map;
for (i = 0; i < map->num_stripes; i++) {
-
ret = call_zone_finish(block_group, &map->stripes[i]);
- if (ret) {
- up_read(&dev_replace->rwsem);
- return ret;
- }
+ if (ret)
+ break;
}
up_read(&dev_replace->rwsem);
- if (!fully_written)
+ if (!ret && !fully_written)
btrfs_dec_block_group_ro(block_group);
spin_lock(&fs_info->zone_active_bgs_lock);
@@ -2648,7 +2645,7 @@ static int do_zone_finish(struct btrfs_block_group *block_group, bool fully_writ
clear_and_wake_up_bit(BTRFS_FS_NEED_ZONE_FINISH, &fs_info->flags);
- return 0;
+ return ret;
}
int btrfs_zone_finish(struct btrfs_block_group *block_group)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 196/733] btrfs: send: fix lost error return value in will_overwrite_ref()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (194 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 195/733] btrfs: zoned: finish active block group cleanup if call_zone_finish() fails Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 197/733] btrfs: do not force reloc root creation during qgroup_account_snapshot() Greg Kroah-Hartman
` (548 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Avi Weiss, Filipe Manana,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Avi Weiss <thnkslprpt@gmail.com>
[ Upstream commit d0285dfbc3b46f41395b26ee2f4a16d99fb3e736 ]
The direct-return refactoring in commit b3047a42f55d ("btrfs: send:
directly return from will_overwrite_ref() and simplify it") changed
will_overwrite_ref() to return directly instead of going through the
common out label.
That resulted in a negative return value from is_inode_existent() to
start being converted to 0, making lookup errors unable to be
distinguished from the inode not existing.
process_recorded_refs() expects negative errors from
will_overwrite_ref() and aborts processing when it receives one.
Return the value from is_inode_existent() to restore the previous error
propagation behavior as it was before the refactor.
Fixes: b3047a42f55d ("btrfs: send: directly return from will_overwrite_ref() and simplify it")
Signed-off-by: Avi Weiss <thnkslprpt@gmail.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Reviewed-by: David Sterba <dsterba@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/send.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/btrfs/send.c b/fs/btrfs/send.c
index 3ae480c7474b0..a888202397edb 100644
--- a/fs/btrfs/send.c
+++ b/fs/btrfs/send.c
@@ -2066,7 +2066,7 @@ static int will_overwrite_ref(struct send_ctx *sctx, u64 dir, u64 dir_gen,
ret = is_inode_existent(sctx, dir, dir_gen, NULL, &parent_root_dir_gen);
if (ret <= 0)
- return 0;
+ return ret;
/*
* If we have a parent root we need to verify that the parent dir was
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 197/733] btrfs: do not force reloc root creation during qgroup_account_snapshot()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (195 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 196/733] btrfs: send: fix lost error return value in will_overwrite_ref() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 198/733] btrfs: zstd: fix lost wakeup when waiting for a workspace Greg Kroah-Hartman
` (547 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Disha Goel, Filipe Manana, Qu Wenruo,
David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qu Wenruo <wqu@suse.com>
[ Upstream commit cacf35832292997018837e484283f95a9301ebf5 ]
[BUG]
When running btrfs/252 with quota enabled through MKFS_OPTIONS="-O quota",
it has a high chance to trigger the following kernel warning and flips
the fs RO:
BTRFS info (device dm-2): relocating block group 30408704 flags metadata|dup
------------[ cut here ]------------
WARNING: fs/btrfs/extent-tree.c:879 at lookup_inline_extent_backref+0x74b/0x960 [btrfs], CPU#4: btrfs/2173
CPU: 4 UID: 0 PID: 2173 Comm: btrfs Not tainted 7.2.0-rc6-custom+ #457 PREEMPT(full) 3adc6528fb66f7a55fe1095385818e742f200aab
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS unknown 02/02/2022
RIP: 0010:lookup_inline_extent_backref+0x74b/0x960 [btrfs]
Call Trace:
<TASK>
insert_inline_extent_backref+0x7c/0x160 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
__btrfs_inc_extent_ref+0xa9/0x270 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
__btrfs_run_delayed_refs+0x4af/0x11c0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
btrfs_run_delayed_refs+0x9d/0xf0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
create_pending_snapshot+0x39d/0xf00 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
create_pending_snapshots+0x9b/0xc0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
btrfs_commit_transaction+0x280/0xeb0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
prepare_to_relocate+0x147/0x200 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
relocate_block_group+0x6b/0x5e0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
btrfs_relocate_block_group+0x92c/0x2380 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
btrfs_relocate_chunk+0x3f/0x1a0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
btrfs_balance+0xa2c/0x19c0 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
btrfs_ioctl+0x2839/0x2d30 [btrfs 32f09462c54d9c922fca74a3e4866f4aa7737b72]
__x64_sys_ioctl+0x416/0x9a0
do_syscall_64+0xe1/0x790
entry_SYSCALL_64_after_hwframe+0x4b/0x53
</TASK>
---[ end trace 0000000000000000 ]---
BTRFS info (device dm-2): leaf 4593991680 gen 233 total ptrs 175 free space 5953 owner 2
BTRFS info (device dm-2): refs 3 lock_owner 2173 current 2173
item 0 key (166772736 METADATA_ITEM 1) itemoff 16250 itemsize 33
extent refs 1 gen 222 flags 2
ref#0: tree block backref root 266
[ Skip the tree dump ]
item 174 key (263225344 METADATA_ITEM 0) itemoff 10328 itemsize 33
extent refs 1 gen 162 flags 258
ref#0: tree block backref root 267
BTRFS error (device dm-2): extent item not found for insert, bytenr 179847168 num_bytes 16384 parent 4594335744 root_objectid 273 owner 0 offset 0
BTRFS error (device dm-2): failed to run delayed ref for logical 179847168 num_bytes 16384 type 182 action 1 ref_mod 1: -117
[CAUSE]
The above error is showing that there is a tree reference to a metadata
extent that is no longer there.
With "ref_verify" mount option (requires CONFIG_BTRFS_DEBUG), there is
some extra debug output:
BTRFS error (device dm-2): dumping block entry [180961280 16384], num_refs 0, metadata 1, from disk 0
BTRFS error (device dm-2): root entry 256, num_refs 18446744073709551615
BTRFS error (device dm-2): root entry 273, num_refs 18446744073709551615
BTRFS error (device dm-2): Ref action 3, root 273, ref_root 273, parent 0, owner 0, offset 0, num_refs 1
btrfs_force_cow_block+0x129/0x7d0 [btrfs]
btrfs_cow_block+0x10a/0x250 [btrfs]
btrfs_search_slot+0x5eb/0xf40 [btrfs]
btrfs_insert_empty_items+0x3a/0x70 [btrfs]
insert_with_overflow+0x53/0x130 [btrfs]
btrfs_insert_dir_item+0x125/0x290 [btrfs]
btrfs_add_link+0xaa/0x410 [btrfs]
btrfs_rename+0x5ea/0xcd0 [btrfs]
btrfs_rename2+0x28/0x60 [btrfs]
vfs_rename+0x5b2/0xe10
filename_renameat2+0x244/0x430
__x64_sys_rename+0x48/0x70
do_syscall_64+0xe1/0x790
entry_SYSCALL_64_after_hwframe+0x4b/0x53
BTRFS error (device dm-2): Ref action 2, root 273, ref_root 273, parent 0, owner 0, offset 0, num_refs 18446744073709551615
btrfs_force_cow_block+0x327/0x7d0 [btrfs]
btrfs_cow_block+0x10a/0x250 [btrfs]
btrfs_search_slot+0x5eb/0xf40 [btrfs]
btrfs_lookup_file_extent+0x4d/0x70 [btrfs]
btrfs_drop_extents+0x151/0xf00 [btrfs]
insert_reserved_file_extent+0xfe/0x3e0 [btrfs]
btrfs_finish_one_ordered+0x549/0xc40 [btrfs]
btrfs_work_helper+0xde/0x350 [btrfs]
process_one_work+0x198/0x380
worker_thread+0x1c8/0x330
kthread+0xee/0x120
ret_from_fork+0x28f/0x310
ret_from_fork_asm+0x11/0x20
BTRFS error (device dm-2): Ref action 1, root 273, ref_root 0, parent 4594335744, owner 0, offset 0, num_refs 1
__btrfs_mod_ref+0x1c5/0x2d0 [btrfs]
btrfs_copy_root+0x262/0x390 [btrfs]
create_reloc_root+0xb9/0x370 [btrfs]
btrfs_init_reloc_root+0xb0/0x1b0 [btrfs]
record_root_in_trans+0xa6/0xd0 [btrfs]
create_pending_snapshot+0x383/0xf00 [btrfs]
create_pending_snapshots+0x9b/0xc0 [btrfs]
btrfs_commit_transaction+0x280/0xeb0 [btrfs]
prepare_to_relocate+0x147/0x200 [btrfs]
relocate_block_group+0x6b/0x5e0 [btrfs]
btrfs_relocate_block_group+0x92c/0x2380 [btrfs]
btrfs_relocate_chunk+0x3f/0x1a0 [btrfs]
btrfs_balance+0xa2c/0x19c0 [btrfs]
btrfs_ioctl+0x2839/0x2d30 [btrfs]
__x64_sys_ioctl+0x416/0x9a0
do_syscall_64+0xe1/0x790
The above shows the direct cause, Ref action 3 is the oldest operation,
which shows the tree block is created by COW. Then ref action 2 shows
it's COWed away, by a metadata update, meaning the tree block is already
released, should not be referred any more.
Then the final one, is trying to create a reloc tree for subvolume 273,
and that reloc root creation is referring to the already dropped tree
block.
The root cause is that, during qgroup_account_snapshot(), we are calling
record_root_in_trans() with "force = true".
So if the root has no reloc root, we will create one, but at that
timing it's already too late.
Normally reloc root should be created before the commit and current
roots diverge, to avoid the same problem we are hitting.
But during relocation initialization, we are committing the current
running transaction, with a new reloc_control attached halfway.
And if qgroup is enabled, the record_root_in_trans() with "force = true"
calls will force reloc root creation even if we do not and should not
create reloc root at that timing.
[FIX]
Do not force reloc root creation during record_root_in_trans() with
"force = true" cases, which is only called by qgroup_account_snapshot().
If we're really under relocation, the reloc root should be created way
early, before the commit and current root diverge. If the root has no
reloc tree yet, it means we're still initializing the reloc, and do not
need a reloc root.
So skipping the reloc tree creation in qgroup_account_snapshot() should
be safe.
Link: https://bugzilla.suse.com/show_bug.cgi?id=1275740
Fixes: 4d31778aa2fa ("btrfs: qgroup: Fix root item corruption when multiple same source snapshots are created with quota enabled")
Assisted-by: LLM (initial analysis, but incorrect conclusion with too many burnt tokens)
Tested-by: Disha Goel <disgoel@linux.ibm.com>
Reviewed-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/transaction.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/transaction.c b/fs/btrfs/transaction.c
index 80919590175fc..b64c6d2855c9a 100644
--- a/fs/btrfs/transaction.c
+++ b/fs/btrfs/transaction.c
@@ -458,8 +458,19 @@ static int record_root_in_trans(struct btrfs_trans_handle *trans,
* through btrfs_record_root_in_trans without having to take the
* lock. smp_wmb() makes sure that all the writes above are
* done before we pop in the zero below
+ *
+ * If @force is true, it means the call is from
+ * qgroup_account_snapshot(), which only requires radix tree
+ * tracking.
+ * We should not force reloc root creation here, as the root
+ * may have already been modified, and in that case
+ * root->commit_root has already been dropped.
+ *
+ * Using that commit root will cause the reloc root to refer
+ * to a deleted extent, causing extent tree corruption.
*/
- ret = btrfs_init_reloc_root(trans, root);
+ if (!force)
+ ret = btrfs_init_reloc_root(trans, root);
smp_mb__before_atomic();
clear_bit(BTRFS_ROOT_IN_TRANS_SETUP, &root->state);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 198/733] btrfs: zstd: fix lost wakeup when waiting for a workspace
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (196 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 197/733] btrfs: do not force reloc root creation during qgroup_account_snapshot() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 199/733] drm/amdgpu/userq: fix struct drm_amdgpu_info_device padding for 32bit compile Greg Kroah-Hartman
` (546 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qu Wenruo, FAN YE, David Sterba,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: FAN YE <fy15309206903@gmail.com>
[ Upstream commit 2acb9f3d1cc8f65dc81ed55e238cbf8e5b60bff7 ]
A writer can sleep forever in zstd_get_workspace() even though a workspace
is free. When zstd_alloc_workspace() fails, the task is queued on
zwsm->wait and schedules unconditionally, never re-testing the pool.
zstd_put_workspace() publishes the workspace and then calls cond_wake_up(),
which only wakes when a sleeper is already visible, so a workspace returned
between the failed allocation and prepare_to_wait() wakes nobody. The
window is wide: zstd_alloc_workspace() goes through kvmalloc() and may
enter reclaim.
Only a max level workspace triggers the wakeup and one is deliberately kept
allocated as the fallback every waiter waits for, so once its wakeup is
lost the writer stays in TASK_UNINTERRUPTIBLE until some other task happens
to return one. Re-check the pool after prepare_to_wait() has published the
waiter, and use the workspace if one turned up.
Fixes: 3f93aef535c8 ("btrfs: add zstd compression level support")
Assisted-by: Claude:claude-opus-5
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: FAN YE <fy15309206903@gmail.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/zstd.c | 11 ++++++++++-
1 file changed, 10 insertions(+), 1 deletion(-)
diff --git a/fs/btrfs/zstd.c b/fs/btrfs/zstd.c
index 86919293fd546..58d9ff76fe07b 100644
--- a/fs/btrfs/zstd.c
+++ b/fs/btrfs/zstd.c
@@ -307,8 +307,17 @@ struct list_head *zstd_get_workspace(struct btrfs_fs_info *fs_info, int level)
DEFINE_WAIT(wait);
prepare_to_wait(&zwsm->wait, &wait, TASK_UNINTERRUPTIBLE);
- schedule();
+ /*
+ * Re-check after being queued: zstd_put_workspace() only wakes
+ * a queue that already has a sleeper, so a workspace returned
+ * since the failed allocation woke nobody.
+ */
+ ws = zstd_find_workspace(fs_info, level);
+ if (!ws)
+ schedule();
finish_wait(&zwsm->wait, &wait);
+ if (ws)
+ return ws;
goto again;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 199/733] drm/amdgpu/userq: fix struct drm_amdgpu_info_device padding for 32bit compile
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (197 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 198/733] btrfs: zstd: fix lost wakeup when waiting for a workspace Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 200/733] ipvs: fix reversed sequence option serialization Greg Kroah-Hartman
` (545 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yogesh Mohan Marimuthu,
Christian König, Alex Deucher, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
[ Upstream commit 13af55f71399f5e562f6cb59ad413476e513c4d4 ]
need to pad before __u64 tcc_disabled_mask variable.
This patch fixes 64bit Kernel + 32 bit mesa combination. But at the same
time it will break 32bit Kernel(using this patch) + older 32bit mesa(not
using this patch).
This issue was discussd with alexander.deucher@amd.com,
christian.koenig@amd.com and pierre-eric.pelloux-prayer@amd.com.
Currently today 32 bit kernel + 32 bit userspace and 64 bit kernel and
64 bit userspace work. Mixed 64 bit kernel and 32 bit userspace is
currently broken. Since 32 bit kernel and userspace is probably pretty
rare these days and the data affected by this is not critical, Hence
we can go ahead with this patch.
Fixes: cf21e76a6005 ("drm/amdgpu: return tcc_disabled_mask to userspace")
Signed-off-by: Yogesh Mohan Marimuthu <yogesh.mohanmarimuthu@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 497b5090f2857ef8ad9a162aa31ada0de5814663)
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/uapi/drm/amdgpu_drm.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/include/uapi/drm/amdgpu_drm.h b/include/uapi/drm/amdgpu_drm.h
index 9f3090db2f163..322aef9b54bbe 100644
--- a/include/uapi/drm/amdgpu_drm.h
+++ b/include/uapi/drm/amdgpu_drm.h
@@ -1510,6 +1510,7 @@ struct drm_amdgpu_info_device {
__u64 high_va_max;
/* gfx10 pa_sc_tile_steering_override */
__u32 pa_sc_tile_steering_override;
+ __u32 pad;
/* disabled TCCs */
__u64 tcc_disabled_mask;
__u64 min_engine_clock;
@@ -1534,7 +1535,6 @@ struct drm_amdgpu_info_device {
__u32 csa_alignment;
/* Userq IP mask (1 << AMDGPU_HW_IP_*) */
__u32 userq_ip_mask;
- __u32 pad;
};
struct drm_amdgpu_info_hw_ip {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 200/733] ipvs: fix reversed sequence option serialization
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (198 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 199/733] drm/amdgpu/userq: fix struct drm_amdgpu_info_device padding for 32bit compile Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 201/733] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() Greg Kroah-Hartman
` (544 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Julian Anastasov,
Pablo Neira Ayuso, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
[ Upstream commit b04578b74f2d3755548fe9e829e3b2a6c6f966a1 ]
hton_seq() expects the host-order source first and the unaligned
network-order destination second. The version 1 sync sender passes these
arguments in reverse for both sequence blocks. This leaves 24 bytes of the
kmalloc-backed message unwritten. It may disclose stale heap data and
replace the live connection sequence state with values read from the
buffer.
Pass the connection sequence state as the source and the message payload as
the destination for both blocks.
Fixes: 986a07579533 ("IPVS: Backup, Change sending to Version 1 format")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/ipvs/ip_vs_sync.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/netfilter/ipvs/ip_vs_sync.c b/net/netfilter/ipvs/ip_vs_sync.c
index ea5fdd4f4ce76..fff2f7d6069aa 100644
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -747,9 +747,9 @@ void ip_vs_sync_conn(struct netns_ipvs *ipvs, struct ip_vs_conn *cp, int pkts)
if (cp->flags & IP_VS_CONN_F_SEQ_MASK) {
*(p++) = IPVS_OPT_SEQ_DATA;
*(p++) = sizeof(struct ip_vs_sync_conn_options);
- hton_seq((struct ip_vs_seq *)p, &cp->in_seq);
+ hton_seq(&cp->in_seq, (struct ip_vs_seq *)p);
p += sizeof(struct ip_vs_seq);
- hton_seq((struct ip_vs_seq *)p, &cp->out_seq);
+ hton_seq(&cp->out_seq, (struct ip_vs_seq *)p);
p += sizeof(struct ip_vs_seq);
}
/* Handle pe data */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 201/733] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (199 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 200/733] ipvs: fix reversed sequence option serialization Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 202/733] tracing/probes: Fix use-after-free on field name/type of events with multiple probes Greg Kroah-Hartman
` (543 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joas Antonio dos Santos,
Pablo Neira Ayuso, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joas Antonio dos Santos <joasantonio108@gmail.com>
[ Upstream commit e8f8231824b5815f57ce62cba116e511b10196de ]
sip_skip_whitespace() returns dptr unchanged when its own loop
exhausts the buffer (dptr == limit), instead of NULL like its sibling
sip_follow_continuation() returns on its own "no more data" path.
ct_sip_get_header() only checks for NULL after calling it:
dptr = sip_skip_whitespace(dptr, limit);
if (dptr == NULL)
break;
if (*dptr != ':' || ++dptr >= limit)
break;
so a recognized header name followed only by spaces/tabs running to
the exact end of the SIP payload, with no colon, makes the very next
statement read one byte past the buffer.
Make both "no more data" outcomes return NULL, matching the
convention sip_follow_continuation() already uses and that both
existing callers already check for.
Fixes: ea45f12a2766d ("[NETFILTER]: nf_conntrack_sip: parse SIP headers properly")
Signed-off-by: Joas Antonio dos Santos <joasantonio108@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nf_conntrack_sip.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/netfilter/nf_conntrack_sip.c b/net/netfilter/nf_conntrack_sip.c
index e4a70d1d77b0b..4fb33b5e9a85a 100644
--- a/net/netfilter/nf_conntrack_sip.c
+++ b/net/netfilter/nf_conntrack_sip.c
@@ -429,7 +429,7 @@ static const char *sip_skip_whitespace(const char *dptr, const char *limit)
dptr = sip_follow_continuation(dptr, limit);
break;
}
- return dptr;
+ return dptr < limit ? dptr : NULL;
}
/* Search within a SIP header value, dealing with continuation lines */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 202/733] tracing/probes: Fix use-after-free on field name/type of events with multiple probes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (200 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 201/733] netfilter: nf_conntrack_sip: fix OOB read in sip_skip_whitespace() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 203/733] bpf: reject BPF_PSEUDO_FUNC reference to the main program Greg Kroah-Hartman
` (542 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Henry Martin,
Masami Hiramatsu (Google), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin <bsdhenrymartin@gmail.com>
[ Upstream commit 86b7a239ec6b14a7544200ede85474c6f5526049 ]
The fields of a probe-based dynamic event (kprobe, uprobe, eprobe and
fprobe events) are created in traceprobe_define_arg_fields() by handing
the probe_arg name/type strings to trace_define_field(), which only
stores the pointers without copying. Those strings are owned by the
trace_probe and are freed when that probe is removed.
An event can have several probes attached. The field list is defined
only once, by the first probe that registers the event, but it is kept
alive by any surviving sibling probe. Deleting just that first probe by
symbol -
# primary A: fields are defined from A's args
echo 'p:kprobes/ev vfs_read a1=$arg1' > kprobe_events
# append B: shares A's event call
echo 'p:kprobes/ev vfs_write a1=$arg1' >> kprobe_events
# delete only A (matched by symbol), B survives
echo '-:kprobes/ev vfs_read' >> kprobe_events
frees A's args (trace_probe_cleanup() -> traceprobe_free_probe_arg()),
but trace_probe_unlink() keeps the trace_probe_event because the probe
list is not empty. The event call stays registered via B while its
fields now reference freed memory. Any field lookup then reads it, e.g.
echo 'a1 == 1' > events/kprobes/ev/filter
BUG: KASAN: slab-use-after-free in strcmp+0xa7/0xb0
Call Trace:
strcmp
trace_find_event_field
parse_pred
process_preds
create_filter
apply_event_filter
event_filter_write
field->name references parg->name (kstrdup'd, freed with the probe) and,
for array arguments, field->type references parg->fmt (kmalloc'd, freed
with the probe) - the scalar type otherwise points at the static
fmttype rodata, which is safe.
Have traceprobe_define_arg_fields() duplicate the name and type strings
and anchor the copies on the trace_probe_event, which embeds the event
call and outlives every individual probe; trace_probe_event_free()
releases them.
The reproducer above triggers reliably; the field lookup and the delete
both run under event_mutex, so this is a dangling reference after
removal rather than a race.
The issue was found by the autokbug dynamic kernel fuzzer at Tencent
Yunding Lab.
Link: https://lore.kernel.org/all/20260826030009.1855331-1-bsdhenrymartin@gmail.com/
Fixes: ca89bc071d5e4 ("tracing/kprobe: Add multi-probe per event support")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/trace_probe.c | 48 +++++++++++++++++++++++++++++++++++++-
kernel/trace/trace_probe.h | 2 ++
2 files changed, 49 insertions(+), 1 deletion(-)
diff --git a/kernel/trace/trace_probe.c b/kernel/trace/trace_probe.c
index aae60fbebeafb..f3c20a093f5dd 100644
--- a/kernel/trace/trace_probe.c
+++ b/kernel/trace/trace_probe.c
@@ -2108,19 +2108,60 @@ int traceprobe_set_print_fmt(struct trace_probe *tp, enum probe_print_type ptype
int traceprobe_define_arg_fields(struct trace_event_call *event_call,
size_t offset, struct trace_probe *tp)
{
+ struct trace_probe_event *tpe = trace_probe_event_from_call(event_call);
int ret, i;
+ /*
+ * A field created by trace_define_field() only stores the name and
+ * type pointers, it does not copy the strings. Here they point into
+ * the probe_arg of @tp, which is freed when @tp is removed. For an
+ * event with multiple probes attached, the field list is defined
+ * once by the first probe but kept alive by the surviving siblings,
+ * so removing that first probe would leave the fields referencing
+ * freed memory. Duplicate the strings and anchor the copies on the
+ * trace_probe_event, which lives as long as the field list itself.
+ *
+ * event_define_fields() ignores the return value of this hook, so
+ * if a previous attempt failed before creating any field, it may
+ * call here again. Release duplicates left behind by such an
+ * attempt before starting over.
+ */
+ for (i = 0; i < tpe->nr_field_strings; i++)
+ kfree(tpe->field_strings[i]);
+ kfree(tpe->field_strings);
+ tpe->field_strings = NULL;
+ tpe->nr_field_strings = 0;
+
+ if (tp->nr_args) {
+ tpe->field_strings = kcalloc(tp->nr_args * 2, sizeof(char *),
+ GFP_KERNEL);
+ if (!tpe->field_strings)
+ return -ENOMEM;
+ }
+
/* Set argument names as fields */
for (i = 0; i < tp->nr_args; i++) {
struct probe_arg *parg = &tp->args[i];
const char *fmt = parg->type->fmttype;
int size = parg->type->size;
+ char *name, *type;
if (parg->fmt)
fmt = parg->fmt;
if (parg->count)
size *= parg->count;
- ret = trace_define_field(event_call, fmt, parg->name,
+
+ name = kstrdup(parg->name, GFP_KERNEL);
+ type = kstrdup(fmt, GFP_KERNEL);
+ if (!name || !type) {
+ kfree(name);
+ kfree(type);
+ return -ENOMEM;
+ }
+ tpe->field_strings[tpe->nr_field_strings++] = name;
+ tpe->field_strings[tpe->nr_field_strings++] = type;
+
+ ret = trace_define_field(event_call, type, name,
offset + parg->offset, size,
parg->type->is_signed,
FILTER_OTHER);
@@ -2132,6 +2173,11 @@ int traceprobe_define_arg_fields(struct trace_event_call *event_call,
static void trace_probe_event_free(struct trace_probe_event *tpe)
{
+ int i;
+
+ for (i = 0; i < tpe->nr_field_strings; i++)
+ kfree(tpe->field_strings[i]);
+ kfree(tpe->field_strings);
kfree(tpe->class.system);
kfree(tpe->call.name);
kfree(tpe->call.print_fmt);
diff --git a/kernel/trace/trace_probe.h b/kernel/trace/trace_probe.h
index 0f09f7aaf93fb..480eb6acd883f 100644
--- a/kernel/trace/trace_probe.h
+++ b/kernel/trace/trace_probe.h
@@ -255,6 +255,8 @@ struct trace_probe_event {
struct trace_event_call call;
struct list_head files;
struct list_head probes;
+ char **field_strings;
+ int nr_field_strings;
struct trace_uprobe_filter filter[];
};
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 203/733] bpf: reject BPF_PSEUDO_FUNC reference to the main program
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (201 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 202/733] tracing/probes: Fix use-after-free on field name/type of events with multiple probes Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 204/733] bonding: do not clear curr_active_slave prematurely when releasing all slaves Greg Kroah-Hartman
` (541 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 374b2c5561db80fcdd7cdce44af37a49416f61c7 ]
fixups.c:jit_subprogs() rewrites BPF_PSEUDO_FUNC loads to contain real
function addresses. This function is invoked from bpf_jit_subprogs()
only when env->subprog_cnt > 1. Meaning that for any program like
below:
int main(void *ctx) {
void *ptr = main;
...
bpf_timer_set_callback(..., ptr);
...
}
The 'ptr' won't be ever converted to contain an address.
In combination with e.g. bpf_timer_set_callback() this would lead to a
function call at a bogus address.
Instead of complicating the implementation, just assume that no useful
program needs main to be a sync or async callback and reject
BPF_PSEUDO_FUNC loads for the main subprogram.
Fixes: 69c087ba6225 ("bpf: Add bpf_for_each_map_elem() helper")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260902233658.1186477-1-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 59f12ba70eb6e..b0118bccf3280 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -16291,6 +16291,15 @@ static int check_ld_imm(struct bpf_verifier_env *env, struct bpf_insn *insn)
verbose(env, "callback function not static\n");
return -EINVAL;
}
+ /*
+ * When env->subprog_cnt == 1 this instruction won't be rewritten
+ * to hold a real function address. Assume that no usable program
+ * combines e.g. main and timer callback and just reject here.
+ */
+ if (subprogno == 0) {
+ verbose(env, "callback function cannot be the main program\n");
+ return -EINVAL;
+ }
dst_reg->type = PTR_TO_FUNC;
dst_reg->subprogno = subprogno;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 204/733] bonding: do not clear curr_active_slave prematurely when releasing all slaves
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (202 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 203/733] bpf: reject BPF_PSEUDO_FUNC reference to the main program Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 205/733] net: Remove conflicting altnames for dying netns in __dev_change_net_namespace() Greg Kroah-Hartman
` (540 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Jay Vosburgh,
Nikolay Aleksandrov, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit af602c7aa5fedc9be3043244017aef4f26c96b70 ]
When releasing all slaves during bond destruction (all == true),
__bond_release_one() unconditionally clears bond->curr_active_slave to
NULL in every iteration.
If a backup slave is released before the active slave,
bond_alb_deinit_slave() triggers rlb_teach_disabled_mac_on_primary(),
which increments the active slave dev promiscuity counter and sets
bond_info->primary_is_promisc = 1.
Because bond->curr_active_slave was prematurely cleared to NULL when
releasing the backup slave, the subsequent iteration releasing the active
slave evaluates oldcurrent as NULL, so bond_change_active_slave(bond, NULL)
is skipped. Consequently, bond_alb_handle_active_change() is never called
to decrement the promiscuity counter, permanently leaking promiscuous
mode on the physical device after bond teardown.
When oldcurrent == slave, bond_change_active_slave(bond, NULL) already sets
bond->curr_active_slave to NULL. We only need to avoid selecting a new
active slave when all == true. Replace the if (all) branch with
if (!all && oldcurrent == slave).
Fixes: 0896341a44bf ("bonding: fix bond_release_all inconsistencies")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Acked-by: Jay Vosburgh <jv@jvosburgh.net>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260831203042.164466-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_main.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 909ecec0de4d6..6ea46a617ee60 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -2517,9 +2517,7 @@ static int __bond_release_one(struct net_device *bond_dev,
bond_alb_deinit_slave(bond, slave);
}
- if (all) {
- RCU_INIT_POINTER(bond->curr_active_slave, NULL);
- } else if (oldcurrent == slave) {
+ if (!all && oldcurrent == slave) {
/* Note that we hold RTNL over this sequence, so there
* is no concern that another slave add/remove event
* will interfere.
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 205/733] net: Remove conflicting altnames for dying netns in __dev_change_net_namespace().
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (203 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 204/733] bonding: do not clear curr_active_slave prematurely when releasing all slaves Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 206/733] net: macb: unify device pointer naming convention Greg Kroah-Hartman
` (539 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+74f338e09f1ef3ee6457,
Kuniyuki Iwashima, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit debac3a20dec524a59625cf10fa2f18571127824 ]
syzbot reported the warning in cfg80211_pernet_exit(). [0]
The repro does the following:
1. create two device in root netns and non-root netns
2. assign the same altname for the two devices
3. remove the non-root netns
Since commit 7663d522099e ("net: check for altname conflicts
when changing netdev's netns"), cfg80211_switch_netns() and
cfg802154_switch_netns() fail if init_net has a device with the
conflicting altname.
default_device_exit_net() had the same issue and commit d09486a04f5d
("net: fix removing a namespace with conflicting altnames") fixed it.
cfg80211_pernet_exit() and cfg802154_pernet_exit() need the same fix.
Let's generalise the fix by removing conflicting altnames for dying
netns in __dev_change_net_namespace().
[0]:
cfg80211_switch_netns(rdev, &init_net)
WARNING: net/wireless/core.c:1871 at cfg80211_pernet_exit+0xd5/0x120 net/wireless/core.c:1871, CPU#1: kworker/u8:9/1160
Modules linked in:
CPU: 1 UID: 0 PID: 1160 Comm: kworker/u8:9 Not tainted syzkaller #0 PREEMPT(full)
Hardware name: Google Google Compute Engine/Google Compute Engine, BIOS Google 07/24/2026
Workqueue: netns cleanup_net
RIP: 0010:cfg80211_pernet_exit+0xd5/0x120 net/wireless/core.c:1871
Code: e8 03 42 80 3c 20 00 74 08 4c 89 f7 e8 b4 ef 0e f7 4d 8b 36 49 81 fe 20 10 4a 90 74 12 e8 03 3d 9f f6 eb 85 e8 fc 3c 9f f6 90 <0f> 0b 90 eb cc e8 f1 3c 9f f6 eb 05 e8 ea 3c 9f f6 5b 41 5c 41 5e
RSP: 0018:ffffc900057a78f0 EFLAGS: 00010293
RAX: ffffffff8b287154 RBX: ffff88807ba72780 RCX: ffff8880213e8000
RDX: 0000000000000000 RSI: 00000000ffffffef RDI: 0000000000000000
RBP: 00000000ffffffef R08: ffffffff9024cc67 R09: 0000000000000000
R10: fffff52000af4eb0 R11: fffffbfff204998d R12: dffffc0000000000
R13: ffffffff904a1080 R14: ffff888144ed0008 R15: ffff888144ed0e20
FS: 0000000000000000(0000) GS:ffff888124de6000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00005642de0a8a70 CR3: 000000007a40c000 CR4: 00000000003526f0
Call Trace:
<TASK>
ops_exit_list net/core/net_namespace.c:200 [inline]
ops_undo_list+0x43d/0x8d0 net/core/net_namespace.c:253
cleanup_net+0x572/0x810 net/core/net_namespace.c:706
process_one_work kernel/workqueue.c:3387 [inline]
process_scheduled_works+0xc3d/0x1630 kernel/workqueue.c:3470
worker_thread+0xa47/0xfb0 kernel/workqueue.c:3551
kthread+0x38b/0x480 kernel/kthread.c:436
ret_from_fork+0x514/0xb70 arch/x86/kernel/process.c:158
ret_from_fork_asm+0x1a/0x30 arch/x86/entry/entry_64.S:245
</TASK>
Fixes: 36fbf1e52bd3 ("net: rtnetlink: add linkprop commands to add and delete alternative ifnames")
Reported-by: syzbot+74f338e09f1ef3ee6457@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a96219e.04428c52.29b18.0001.GAE@google.com/T/
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260901005550.2042357-1-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dev.c | 25 +++++++++++++------------
1 file changed, 13 insertions(+), 12 deletions(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 39807b68ff260..9ac8ac6004145 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -12541,7 +12541,7 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
const char *pat, int new_ifindex,
struct netlink_ext_ack *extack)
{
- struct netdev_name_node *name_node;
+ struct netdev_name_node *name_node, *tmp;
struct net *net_old = dev_net(dev);
char new_name[IFNAMSIZ] = {};
int err, new_nsid;
@@ -12587,13 +12587,19 @@ int __dev_change_net_namespace(struct net_device *dev, struct net *net,
}
/* Check that none of the altnames conflicts. */
err = -EEXIST;
- netdev_for_each_altname(dev, name_node) {
- if (netdev_name_in_use(net, name_node->name)) {
- NL_SET_ERR_MSG_FMT(extack,
- "An interface with the altname %s exists in the target netns",
- name_node->name);
- goto out;
+ netdev_for_each_altname_safe(dev, name_node, tmp) {
+ if (!netdev_name_in_use(net, name_node->name))
+ continue;
+
+ if (!check_net(net_old)) {
+ __netdev_name_node_alt_destroy(name_node);
+ continue;
}
+
+ NL_SET_ERR_MSG_FMT(extack,
+ "An interface with the altname %s exists in the target netns",
+ name_node->name);
+ goto out;
}
/* Check that new_ifindex isn't used yet. */
@@ -13044,7 +13050,6 @@ static struct pernet_operations __net_initdata netdev_net_ops = {
static void __net_exit default_device_exit_net(struct net *net)
{
- struct netdev_name_node *name_node, *tmp;
struct net_device *dev, *aux;
/*
* Push all migratable network devices back to the
@@ -13068,10 +13073,6 @@ static void __net_exit default_device_exit_net(struct net *net)
if (netdev_name_in_use(&init_net, fb_name))
snprintf(fb_name, IFNAMSIZ, "dev%%d");
- netdev_for_each_altname_safe(dev, name_node, tmp)
- if (netdev_name_in_use(&init_net, name_node->name))
- __netdev_name_node_alt_destroy(name_node);
-
err = dev_change_net_namespace(dev, &init_net, fb_name);
if (err) {
pr_emerg("%s: failed to move %s to init_net: %d\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 206/733] net: macb: unify device pointer naming convention
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (204 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 205/733] net: Remove conflicting altnames for dying netns in __dev_change_net_namespace() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 207/733] net: macb: exclude software FCS from TX byte statistics Greg Kroah-Hartman
` (538 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Conor Dooley, Nicolai Buchwitz,
Théo Lebrun, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Théo Lebrun <theo.lebrun@bootlin.com>
[ Upstream commit 07362f68e61d82ee53da0e9ae2c7f981c3538861 ]
Here are all device pointer variable permutations inside MACB:
struct device *dev;
struct net_device *dev;
struct net_device *ndev;
struct net_device *netdev;
struct pci_dev *pdev; // inside macb_pci.c
struct phy_device *phy;
struct phy_device *phydev;
struct platform_device *pdev;
struct platform_device *plat_dev; // inside macb_pci.c
Unify to this convention:
struct device *dev;
struct net_device *netdev;
struct pci_dev *pci;
struct phy_device *phydev;
struct platform_device *pdev;
Ensure nothing slipped through using ctags tooling:
⟩ ctags -o - --kinds-c='{local}{member}{parameter}' \
--fields='{typeref}' drivers/net/ethernet/cadence/* | \
awk -F"\t" '
$NF~/struct:.*(device|dev) / {print $NF, $1}' | \
sort -u
typeref:struct:device * dev
typeref:struct:in_device * idev // ignored
typeref:struct:net_device * netdev
typeref:struct:pci_dev * pci
typeref:struct:phy_device * phydev
typeref:struct:platform_device * pdev
Also fix some printk() calls to use __func__ instead of hardcoding.
This silences some checkpatch.pl warnings and doesn't deserve a
separate commit.
Reviewed-by: Conor Dooley <conor.dooley@microchip.com>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Signed-off-by: Théo Lebrun <theo.lebrun@bootlin.com>
Link: https://patch.msgid.link/20260812-macb-context-v9-2-7ddbf5f715e0@bootlin.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: d85f521a9afb ("net: macb: exclude software FCS from TX byte statistics")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb.h | 20 +-
drivers/net/ethernet/cadence/macb_main.c | 642 ++++++++++++-----------
drivers/net/ethernet/cadence/macb_pci.c | 46 +-
drivers/net/ethernet/cadence/macb_ptp.c | 18 +-
4 files changed, 365 insertions(+), 361 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 2de56017ee0d6..9857df5b57f09 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -1207,11 +1207,11 @@ struct macb_or_gem_ops {
/* MACB-PTP interface: adapt to platform needs. */
struct macb_ptp_info {
- void (*ptp_init)(struct net_device *ndev);
- void (*ptp_remove)(struct net_device *ndev);
+ void (*ptp_init)(struct net_device *netdev);
+ void (*ptp_remove)(struct net_device *netdev);
s32 (*get_ptp_max_adj)(void);
unsigned int (*get_tsu_rate)(struct macb *bp);
- int (*get_ts_info)(struct net_device *dev,
+ int (*get_ts_info)(struct net_device *netdev,
struct kernel_ethtool_ts_info *info);
int (*get_hwtst)(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config);
@@ -1326,7 +1326,7 @@ struct macb {
struct clk *tx_clk;
struct clk *rx_clk;
struct clk *tsu_clk;
- struct net_device *dev;
+ struct net_device *netdev;
/* Protects hw_stats and ethtool_stats */
spinlock_t stats_lock;
union {
@@ -1406,8 +1406,8 @@ enum macb_bd_control {
TSTAMP_ALL_FRAMES,
};
-void gem_ptp_init(struct net_device *ndev);
-void gem_ptp_remove(struct net_device *ndev);
+void gem_ptp_init(struct net_device *netdev);
+void gem_ptp_remove(struct net_device *netdev);
void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);
void gem_ptp_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc);
static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc)
@@ -1426,14 +1426,14 @@ static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, stru
gem_ptp_rxstamp(bp, skb, desc);
}
-int gem_get_hwtst(struct net_device *dev,
+int gem_get_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config);
-int gem_set_hwtst(struct net_device *dev,
+int gem_set_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config,
struct netlink_ext_ack *extack);
#else
-static inline void gem_ptp_init(struct net_device *ndev) { }
-static inline void gem_ptp_remove(struct net_device *ndev) { }
+static inline void gem_ptp_init(struct net_device *netdev) { }
+static inline void gem_ptp_remove(struct net_device *netdev) { }
static inline void gem_ptp_do_txstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }
static inline void gem_ptp_do_rxstamp(struct macb *bp, struct sk_buff *skb, struct macb_dma_desc *desc) { }
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index d394f1f43b685..02d10490b8adb 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -252,9 +252,9 @@ static void macb_set_hwaddr(struct macb *bp)
u32 bottom;
u16 top;
- bottom = get_unaligned_le32(bp->dev->dev_addr);
+ bottom = get_unaligned_le32(bp->netdev->dev_addr);
macb_or_gem_writel(bp, SA1B, bottom);
- top = get_unaligned_le16(bp->dev->dev_addr + 4);
+ top = get_unaligned_le16(bp->netdev->dev_addr + 4);
macb_or_gem_writel(bp, SA1T, top);
if (gem_has_ptp(bp)) {
@@ -291,13 +291,13 @@ static void macb_get_hwaddr(struct macb *bp)
addr[5] = (top >> 8) & 0xff;
if (is_valid_ether_addr(addr)) {
- eth_hw_addr_set(bp->dev, addr);
+ eth_hw_addr_set(bp->netdev, addr);
return;
}
}
dev_info(&bp->pdev->dev, "invalid hw address, using random\n");
- eth_hw_addr_random(bp->dev);
+ eth_hw_addr_random(bp->netdev);
}
static int macb_mdio_wait_for_idle(struct macb *bp)
@@ -509,12 +509,12 @@ static void macb_set_tx_clk(struct macb *bp, int speed)
ferr = abs(rate_rounded - rate);
ferr = DIV_ROUND_UP(ferr, rate / 100000);
if (ferr > 5)
- netdev_warn(bp->dev,
+ netdev_warn(bp->netdev,
"unable to generate target frequency: %ld Hz\n",
rate);
if (clk_set_rate(bp->tx_clk, rate_rounded))
- netdev_err(bp->dev, "adjusting tx_clk failed.\n");
+ netdev_err(bp->netdev, "adjusting tx_clk failed.\n");
}
static void macb_usx_pcs_link_up(struct phylink_pcs *pcs, unsigned int neg_mode,
@@ -697,8 +697,8 @@ static void macb_tx_lpi_wake(struct macb *bp)
static void macb_mac_disable_tx_lpi(struct phylink_config *config)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned long flags;
cancel_delayed_work_sync(&bp->tx_lpi_work);
@@ -712,8 +712,8 @@ static void macb_mac_disable_tx_lpi(struct phylink_config *config)
static int macb_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
bool tx_clk_stop)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned long flags;
spin_lock_irqsave(&bp->lock, flags);
@@ -732,8 +732,8 @@ static int macb_mac_enable_tx_lpi(struct phylink_config *config, u32 timer,
static void macb_mac_config(struct phylink_config *config, unsigned int mode,
const struct phylink_link_state *state)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned long flags;
u32 old_ctrl, ctrl;
u32 old_ncr, ncr;
@@ -774,8 +774,8 @@ static void macb_mac_config(struct phylink_config *config, unsigned int mode,
static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
phy_interface_t interface)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned int q;
u32 ctrl;
@@ -789,7 +789,7 @@ static void macb_mac_link_down(struct phylink_config *config, unsigned int mode,
ctrl = macb_readl(bp, NCR) & ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
- netif_tx_stop_all_queues(ndev);
+ netif_tx_stop_all_queues(netdev);
}
/* Use juggling algorithm to left rotate tx ring and tx skb array */
@@ -884,13 +884,13 @@ static void gem_shuffle_tx_rings(struct macb *bp)
}
static void macb_mac_link_up(struct phylink_config *config,
- struct phy_device *phy,
+ struct phy_device *phydev,
unsigned int mode, phy_interface_t interface,
int speed, int duplex,
bool tx_pause, bool rx_pause)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
@@ -946,14 +946,14 @@ static void macb_mac_link_up(struct phylink_config *config,
macb_writel(bp, NCR, ctrl | MACB_BIT(RE) | MACB_BIT(TE));
- netif_tx_wake_all_queues(ndev);
+ netif_tx_wake_all_queues(netdev);
}
static struct phylink_pcs *macb_mac_select_pcs(struct phylink_config *config,
phy_interface_t interface)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
if (interface == PHY_INTERFACE_MODE_10GBASER)
return &bp->phylink_usx_pcs;
@@ -982,7 +982,7 @@ static bool macb_phy_handle_exists(struct device_node *dn)
static int macb_phylink_connect(struct macb *bp)
{
struct device_node *dn = bp->pdev->dev.of_node;
- struct net_device *dev = bp->dev;
+ struct net_device *netdev = bp->netdev;
struct phy_device *phydev;
int ret;
@@ -992,7 +992,7 @@ static int macb_phylink_connect(struct macb *bp)
if (!dn || (ret && !macb_phy_handle_exists(dn))) {
phydev = phy_find_first(bp->mii_bus);
if (!phydev) {
- netdev_err(dev, "no PHY found\n");
+ netdev_err(netdev, "no PHY found\n");
return -ENXIO;
}
@@ -1001,7 +1001,7 @@ static int macb_phylink_connect(struct macb *bp)
}
if (ret) {
- netdev_err(dev, "Could not attach PHY (%d)\n", ret);
+ netdev_err(netdev, "Could not attach PHY (%d)\n", ret);
return ret;
}
@@ -1013,21 +1013,21 @@ static int macb_phylink_connect(struct macb *bp)
static void macb_get_pcs_fixed_state(struct phylink_config *config,
struct phylink_link_state *state)
{
- struct net_device *ndev = to_net_dev(config->dev);
- struct macb *bp = netdev_priv(ndev);
+ struct net_device *netdev = to_net_dev(config->dev);
+ struct macb *bp = netdev_priv(netdev);
state->link = (macb_readl(bp, NSR) & MACB_BIT(NSR_LINK)) != 0;
}
/* based on au1000_eth. c*/
-static int macb_mii_probe(struct net_device *dev)
+static int macb_mii_probe(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
bp->phylink_sgmii_pcs.ops = &macb_phylink_pcs_ops;
bp->phylink_usx_pcs.ops = &macb_phylink_usx_pcs_ops;
- bp->phylink_config.dev = &dev->dev;
+ bp->phylink_config.dev = &netdev->dev;
bp->phylink_config.type = PHYLINK_NETDEV;
bp->phylink_config.mac_managed_pm = true;
@@ -1086,7 +1086,7 @@ static int macb_mii_probe(struct net_device *dev)
bp->phylink = phylink_create(&bp->phylink_config, bp->pdev->dev.fwnode,
bp->phy_interface, &macb_phylink_ops);
if (IS_ERR(bp->phylink)) {
- netdev_err(dev, "Could not create a phylink instance (%ld)\n",
+ netdev_err(netdev, "Could not create a phylink instance (%ld)\n",
PTR_ERR(bp->phylink));
return PTR_ERR(bp->phylink);
}
@@ -1133,7 +1133,7 @@ static int macb_mii_init(struct macb *bp)
*/
mdio_np = of_get_child_by_name(np, "mdio");
if (!mdio_np && of_phy_is_fixed_link(np))
- return macb_mii_probe(bp->dev);
+ return macb_mii_probe(bp->netdev);
/* Enable management port */
macb_writel(bp, NCR, MACB_BIT(MPE));
@@ -1154,13 +1154,13 @@ static int macb_mii_init(struct macb *bp)
bp->mii_bus->priv = bp;
bp->mii_bus->parent = &bp->pdev->dev;
- dev_set_drvdata(&bp->dev->dev, bp->mii_bus);
+ dev_set_drvdata(&bp->netdev->dev, bp->mii_bus);
err = macb_mdiobus_register(bp, mdio_np);
if (err)
goto err_out_free_mdiobus;
- err = macb_mii_probe(bp->dev);
+ err = macb_mii_probe(bp->netdev);
if (err)
goto err_out_unregister_bus;
@@ -1268,8 +1268,8 @@ static void macb_tx_error_task(struct work_struct *work)
unsigned long flags;
queue_index = queue - bp->queues;
- netdev_vdbg(bp->dev, "macb_tx_error_task: q = %u, t = %u, h = %u\n",
- queue_index, queue->tx_tail, queue->tx_head);
+ netdev_vdbg(bp->netdev, "%s: q = %u, t = %u, h = %u\n",
+ __func__, queue_index, queue->tx_tail, queue->tx_head);
/* Prevent the queue NAPI TX poll from running, as it calls
* macb_tx_complete(), which in turn may call netif_wake_subqueue().
@@ -1281,14 +1281,14 @@ static void macb_tx_error_task(struct work_struct *work)
spin_lock_irqsave(&bp->lock, flags);
/* Make sure nobody is trying to queue up new packets */
- netif_tx_stop_all_queues(bp->dev);
+ netif_tx_stop_all_queues(bp->netdev);
/* Stop transmission now
* (in case we have just queued new packets)
* macb/gem must be halted to write TBQP register
*/
if (macb_halt_tx(bp)) {
- netdev_err(bp->dev, "BUG: halt tx timed out\n");
+ netdev_err(bp->netdev, "BUG: halt tx timed out\n");
macb_writel(bp, NCR, macb_readl(bp, NCR) & (~MACB_BIT(TE)));
halt_timeout = true;
}
@@ -1317,13 +1317,13 @@ static void macb_tx_error_task(struct work_struct *work)
* since it's the only one written back by the hardware
*/
if (!(ctrl & MACB_BIT(TX_BUF_EXHAUSTED))) {
- netdev_vdbg(bp->dev, "txerr skb %u (data %p) TX complete\n",
+ netdev_vdbg(bp->netdev, "txerr skb %u (data %p) TX complete\n",
macb_tx_ring_wrap(bp, tail),
skb->data);
- bp->dev->stats.tx_packets++;
+ bp->netdev->stats.tx_packets++;
queue->stats.tx_packets++;
packets++;
- bp->dev->stats.tx_bytes += skb->len;
+ bp->netdev->stats.tx_bytes += skb->len;
queue->stats.tx_bytes += skb->len;
bytes += skb->len;
}
@@ -1333,7 +1333,7 @@ static void macb_tx_error_task(struct work_struct *work)
* those. Statistics are updated by hardware.
*/
if (ctrl & MACB_BIT(TX_BUF_EXHAUSTED))
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"BUG: TX buffers exhausted mid-frame\n");
desc->ctrl = ctrl | MACB_BIT(TX_USED);
@@ -1342,7 +1342,7 @@ static void macb_tx_error_task(struct work_struct *work)
macb_tx_unmap(bp, tx_skb, 0);
}
- netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index),
+ netdev_tx_completed_queue(netdev_get_tx_queue(bp->netdev, queue_index),
packets, bytes);
/* Set end of TX queue */
@@ -1367,7 +1367,7 @@ static void macb_tx_error_task(struct work_struct *work)
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TE));
/* Now we are ready to start transmission again */
- netif_tx_start_all_queues(bp->dev);
+ netif_tx_start_all_queues(bp->netdev);
macb_writel(bp, NCR, macb_readl(bp, NCR) | MACB_BIT(TSTART));
spin_unlock_irqrestore(&bp->lock, flags);
@@ -1446,12 +1446,12 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
!ptp_one_step_sync(skb))
gem_ptp_do_txstamp(bp, skb, desc);
- netdev_vdbg(bp->dev, "skb %u (data %p) TX complete\n",
+ netdev_vdbg(bp->netdev, "skb %u (data %p) TX complete\n",
macb_tx_ring_wrap(bp, tail),
skb->data);
- bp->dev->stats.tx_packets++;
+ bp->netdev->stats.tx_packets++;
queue->stats.tx_packets++;
- bp->dev->stats.tx_bytes += skb->len;
+ bp->netdev->stats.tx_bytes += skb->len;
queue->stats.tx_bytes += skb->len;
packets++;
bytes += skb->len;
@@ -1469,14 +1469,14 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
}
}
- netdev_tx_completed_queue(netdev_get_tx_queue(bp->dev, queue_index),
+ netdev_tx_completed_queue(netdev_get_tx_queue(bp->netdev, queue_index),
packets, bytes);
queue->tx_tail = tail;
- if (__netif_subqueue_stopped(bp->dev, queue_index) &&
+ if (__netif_subqueue_stopped(bp->netdev, queue_index) &&
CIRC_CNT(queue->tx_head, queue->tx_tail,
bp->tx_ring_size) <= MACB_TX_WAKEUP_THRESH(bp))
- netif_wake_subqueue(bp->dev, queue_index);
+ netif_wake_subqueue(bp->netdev, queue_index);
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
if (packets)
@@ -1504,9 +1504,9 @@ static void gem_rx_refill(struct macb_queue *queue)
if (!queue->rx_skbuff[entry]) {
/* allocate sk_buff for this free entry in ring */
- skb = netdev_alloc_skb(bp->dev, bp->rx_buffer_size);
+ skb = netdev_alloc_skb(bp->netdev, bp->rx_buffer_size);
if (unlikely(!skb)) {
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"Unable to allocate sk_buff\n");
break;
}
@@ -1555,8 +1555,8 @@ static void gem_rx_refill(struct macb_queue *queue)
/* Make descriptor updates visible to hardware */
wmb();
- netdev_vdbg(bp->dev, "rx ring: queue: %p, prepared head %d, tail %d\n",
- queue, queue->rx_prepared_head, queue->rx_tail);
+ netdev_vdbg(bp->netdev, "rx ring: queue: %p, prepared head %d, tail %d\n",
+ queue, queue->rx_prepared_head, queue->rx_tail);
}
/* Mark DMA descriptors from begin up to and not including end as unused */
@@ -1616,17 +1616,17 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
count++;
if (!(ctrl & MACB_BIT(RX_SOF) && ctrl & MACB_BIT(RX_EOF))) {
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"not whole frame pointed by descriptor\n");
- bp->dev->stats.rx_dropped++;
+ bp->netdev->stats.rx_dropped++;
queue->stats.rx_dropped++;
break;
}
skb = queue->rx_skbuff[entry];
if (unlikely(!skb)) {
- netdev_err(bp->dev,
+ netdev_err(bp->netdev,
"inconsistent Rx descriptor chain\n");
- bp->dev->stats.rx_dropped++;
+ bp->netdev->stats.rx_dropped++;
queue->stats.rx_dropped++;
break;
}
@@ -1634,28 +1634,29 @@ static int gem_rx(struct macb_queue *queue, struct napi_struct *napi,
queue->rx_skbuff[entry] = NULL;
len = ctrl & bp->rx_frm_len_mask;
- netdev_vdbg(bp->dev, "gem_rx %u (len %u)\n", entry, len);
+ netdev_vdbg(bp->netdev, "%s %u (len %u)\n",
+ __func__, entry, len);
skb_put(skb, len);
dma_unmap_single(&bp->pdev->dev, addr,
bp->rx_buffer_size, DMA_FROM_DEVICE);
- skb->protocol = eth_type_trans(skb, bp->dev);
+ skb->protocol = eth_type_trans(skb, bp->netdev);
skb_checksum_none_assert(skb);
- if (bp->dev->features & NETIF_F_RXCSUM &&
- !(bp->dev->flags & IFF_PROMISC) &&
+ if (bp->netdev->features & NETIF_F_RXCSUM &&
+ !(bp->netdev->flags & IFF_PROMISC) &&
GEM_BFEXT(RX_CSUM, ctrl) & GEM_RX_CSUM_CHECKED_MASK)
skb->ip_summed = CHECKSUM_UNNECESSARY;
- bp->dev->stats.rx_packets++;
+ bp->netdev->stats.rx_packets++;
queue->stats.rx_packets++;
- bp->dev->stats.rx_bytes += skb->len;
+ bp->netdev->stats.rx_bytes += skb->len;
queue->stats.rx_bytes += skb->len;
gem_ptp_do_rxstamp(bp, skb, desc);
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
- netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
+ netdev_vdbg(bp->netdev, "received skb of length %u, csum: %08x\n",
skb->len, skb->csum);
print_hex_dump(KERN_DEBUG, " mac: ", DUMP_PREFIX_ADDRESS, 16, 1,
skb_mac_header(skb), 16, true);
@@ -1684,9 +1685,10 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
desc = macb_rx_desc(queue, last_frag);
len = desc->ctrl & bp->rx_frm_len_mask;
- netdev_vdbg(bp->dev, "macb_rx_frame frags %u - %u (len %u)\n",
- macb_rx_ring_wrap(bp, first_frag),
- macb_rx_ring_wrap(bp, last_frag), len);
+ netdev_vdbg(bp->netdev, "%s frags %u - %u (len %u)\n",
+ __func__,
+ macb_rx_ring_wrap(bp, first_frag),
+ macb_rx_ring_wrap(bp, last_frag), len);
/* The ethernet header starts NET_IP_ALIGN bytes into the
* first buffer. Since the header is 14 bytes, this makes the
@@ -1696,9 +1698,9 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
* the two padding bytes into the skb so that we avoid hitting
* the slowpath in memcpy(), and pull them off afterwards.
*/
- skb = netdev_alloc_skb(bp->dev, len + NET_IP_ALIGN);
+ skb = netdev_alloc_skb(bp->netdev, len + NET_IP_ALIGN);
if (!skb) {
- bp->dev->stats.rx_dropped++;
+ bp->netdev->stats.rx_dropped++;
for (frag = first_frag; ; frag++) {
desc = macb_rx_desc(queue, frag);
desc->addr &= ~MACB_BIT(RX_USED);
@@ -1742,11 +1744,11 @@ static int macb_rx_frame(struct macb_queue *queue, struct napi_struct *napi,
wmb();
__skb_pull(skb, NET_IP_ALIGN);
- skb->protocol = eth_type_trans(skb, bp->dev);
+ skb->protocol = eth_type_trans(skb, bp->netdev);
- bp->dev->stats.rx_packets++;
- bp->dev->stats.rx_bytes += skb->len;
- netdev_vdbg(bp->dev, "received skb of length %u, csum: %08x\n",
+ bp->netdev->stats.rx_packets++;
+ bp->netdev->stats.rx_bytes += skb->len;
+ netdev_vdbg(bp->netdev, "received skb of length %u, csum: %08x\n",
skb->len, skb->csum);
napi_gro_receive(napi, skb);
@@ -1826,7 +1828,7 @@ static int macb_rx(struct macb_queue *queue, struct napi_struct *napi,
unsigned long flags;
u32 ctrl;
- netdev_err(bp->dev, "RX queue corruption: reset it\n");
+ netdev_err(bp->netdev, "RX queue corruption: reset it\n");
spin_lock_irqsave(&bp->lock, flags);
@@ -1873,7 +1875,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)
work_done = bp->macbgem_ops.mog_rx(queue, napi, budget);
- netdev_vdbg(bp->dev, "RX poll: queue = %u, work_done = %d, budget = %d\n",
+ netdev_vdbg(bp->netdev, "RX poll: queue = %u, work_done = %d, budget = %d\n",
(unsigned int)(queue - bp->queues), work_done, budget);
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -1892,7 +1894,7 @@ static int macb_rx_poll(struct napi_struct *napi, int budget)
if (macb_rx_pending(queue)) {
queue_writel(queue, IDR, bp->rx_intr_mask);
macb_queue_isr_clear(bp, queue, MACB_BIT(RCOMP));
- netdev_vdbg(bp->dev, "poll: packets pending, reschedule\n");
+ netdev_vdbg(bp->netdev, "poll: packets pending, reschedule\n");
napi_schedule(napi);
}
}
@@ -1956,11 +1958,11 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)
rmb(); // ensure txubr_pending is up to date
if (queue->txubr_pending) {
queue->txubr_pending = false;
- netdev_vdbg(bp->dev, "poll: tx restart\n");
+ netdev_vdbg(bp->netdev, "poll: tx restart\n");
macb_tx_restart(queue);
}
- netdev_vdbg(bp->dev, "TX poll: queue = %u, work_done = %d, budget = %d\n",
+ netdev_vdbg(bp->netdev, "TX poll: queue = %u, work_done = %d, budget = %d\n",
(unsigned int)(queue - bp->queues), work_done, budget);
if (work_done < budget && napi_complete_done(napi, work_done)) {
@@ -1979,7 +1981,7 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)
if (macb_tx_complete_pending(queue)) {
queue_writel(queue, IDR, MACB_BIT(TCOMP));
macb_queue_isr_clear(bp, queue, MACB_BIT(TCOMP));
- netdev_vdbg(bp->dev, "TX poll: packets pending, reschedule\n");
+ netdev_vdbg(bp->netdev, "TX poll: packets pending, reschedule\n");
napi_schedule(napi);
}
}
@@ -1990,7 +1992,7 @@ static int macb_tx_poll(struct napi_struct *napi, int budget)
static void macb_hresp_error_task(struct work_struct *work)
{
struct macb *bp = from_work(bp, work, hresp_err_bh_work);
- struct net_device *dev = bp->dev;
+ struct net_device *netdev = bp->netdev;
struct macb_queue *queue;
unsigned int q;
u32 ctrl;
@@ -2004,8 +2006,8 @@ static void macb_hresp_error_task(struct work_struct *work)
ctrl &= ~(MACB_BIT(RE) | MACB_BIT(TE));
macb_writel(bp, NCR, ctrl);
- netif_tx_stop_all_queues(dev);
- netif_carrier_off(dev);
+ netif_tx_stop_all_queues(netdev);
+ netif_carrier_off(netdev);
bp->macbgem_ops.mog_init_rings(bp);
@@ -2022,8 +2024,8 @@ static void macb_hresp_error_task(struct work_struct *work)
ctrl |= MACB_BIT(RE) | MACB_BIT(TE);
macb_writel(bp, NCR, ctrl);
- netif_carrier_on(dev);
- netif_tx_start_all_queues(dev);
+ netif_carrier_on(netdev);
+ netif_tx_start_all_queues(netdev);
}
static void macb_wol_interrupt(struct macb_queue *queue, u32 status)
@@ -2032,7 +2034,7 @@ static void macb_wol_interrupt(struct macb_queue *queue, u32 status)
queue_writel(queue, IDR, MACB_BIT(WOL));
macb_writel(bp, WOL, 0);
- netdev_vdbg(bp->dev, "MACB WoL: queue = %u, isr = 0x%08lx\n",
+ netdev_vdbg(bp->netdev, "MACB WoL: queue = %u, isr = 0x%08lx\n",
(unsigned int)(queue - bp->queues),
(unsigned long)status);
macb_queue_isr_clear(bp, queue, MACB_BIT(WOL));
@@ -2045,7 +2047,7 @@ static void gem_wol_interrupt(struct macb_queue *queue, u32 status)
queue_writel(queue, IDR, GEM_BIT(WOL));
gem_writel(bp, WOL, 0);
- netdev_vdbg(bp->dev, "GEM WoL: queue = %u, isr = 0x%08lx\n",
+ netdev_vdbg(bp->netdev, "GEM WoL: queue = %u, isr = 0x%08lx\n",
(unsigned int)(queue - bp->queues),
(unsigned long)status);
macb_queue_isr_clear(bp, queue, GEM_BIT(WOL));
@@ -2055,10 +2057,10 @@ static void gem_wol_interrupt(struct macb_queue *queue, u32 status)
static int macb_interrupt_misc(struct macb_queue *queue, u32 status)
{
struct macb *bp = queue->bp;
- struct net_device *dev;
+ struct net_device *netdev;
u32 ctrl;
- dev = bp->dev;
+ netdev = bp->netdev;
if (unlikely(status & (MACB_TX_ERR_FLAGS))) {
queue_writel(queue, IDR, MACB_TX_INT_FLAGS);
@@ -2099,7 +2101,7 @@ static int macb_interrupt_misc(struct macb_queue *queue, u32 status)
if (status & MACB_BIT(HRESP)) {
queue_work(system_bh_wq, &bp->hresp_err_bh_work);
- netdev_err(dev, "DMA bus error: HRESP not OK\n");
+ netdev_err(netdev, "DMA bus error: HRESP not OK\n");
macb_queue_isr_clear(bp, queue, MACB_BIT(HRESP));
}
@@ -2118,7 +2120,7 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
{
struct macb_queue *queue = dev_id;
struct macb *bp = queue->bp;
- struct net_device *dev = bp->dev;
+ struct net_device *netdev = bp->netdev;
u32 status;
status = queue_readl(queue, ISR);
@@ -2130,13 +2132,13 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
while (status) {
/* close possible race with dev_close */
- if (unlikely(!netif_running(dev))) {
+ if (unlikely(!netif_running(netdev))) {
queue_writel(queue, IDR, -1);
macb_queue_isr_clear(bp, queue, -1);
break;
}
- netdev_vdbg(bp->dev, "queue = %u, isr = 0x%08lx\n",
+ netdev_vdbg(netdev, "queue = %u, isr = 0x%08lx\n",
(unsigned int)(queue - bp->queues),
(unsigned long)status);
@@ -2181,16 +2183,16 @@ static irqreturn_t macb_interrupt(int irq, void *dev_id)
/* Polling receive - used by netconsole and other diagnostic tools
* to allow network i/o with interrupts disabled.
*/
-static void macb_poll_controller(struct net_device *dev)
+static void macb_poll_controller(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
local_irq_save(flags);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue)
- macb_interrupt(dev->irq, queue);
+ macb_interrupt(netdev->irq, queue);
local_irq_restore(flags);
}
#endif
@@ -2277,7 +2279,7 @@ static unsigned int macb_tx_map(struct macb *bp,
/* Should never happen */
if (unlikely(!tx_skb)) {
- netdev_err(bp->dev, "BUG! empty skb!\n");
+ netdev_err(bp->netdev, "BUG! empty skb!\n");
return 0;
}
@@ -2328,7 +2330,7 @@ static unsigned int macb_tx_map(struct macb *bp,
if (i == queue->tx_head) {
ctrl |= MACB_BF(TX_LSO, lso_ctrl);
ctrl |= MACB_BF(TX_TCP_SEQ_SRC, seq_ctrl);
- if ((bp->dev->features & NETIF_F_HW_CSUM) &&
+ if ((bp->netdev->features & NETIF_F_HW_CSUM) &&
skb->ip_summed != CHECKSUM_PARTIAL && !lso_ctrl &&
!ptp_one_step_sync(skb))
ctrl |= MACB_BIT(TX_NOCRC);
@@ -2352,7 +2354,7 @@ static unsigned int macb_tx_map(struct macb *bp,
return 0;
dma_error:
- netdev_err(bp->dev, "TX DMA map failed\n");
+ netdev_err(bp->netdev, "TX DMA map failed\n");
for (i = queue->tx_head; i != tx_head; i++) {
tx_skb = macb_tx_skb(queue, i);
@@ -2364,7 +2366,7 @@ static unsigned int macb_tx_map(struct macb *bp,
}
static netdev_features_t macb_features_check(struct sk_buff *skb,
- struct net_device *dev,
+ struct net_device *netdev,
netdev_features_t features)
{
unsigned int nr_frags, f;
@@ -2416,7 +2418,7 @@ static inline int macb_clear_csum(struct sk_buff *skb)
return 0;
}
-static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
+static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *netdev)
{
bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
skb_is_nonlinear(*skb);
@@ -2425,7 +2427,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
struct sk_buff *nskb;
u32 fcs;
- if (!(ndev->features & NETIF_F_HW_CSUM) ||
+ if (!(netdev->features & NETIF_F_HW_CSUM) ||
!((*skb)->ip_summed != CHECKSUM_PARTIAL) ||
skb_shinfo(*skb)->gso_size || ptp_one_step_sync(*skb))
return 0;
@@ -2467,10 +2469,11 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *ndev)
return 0;
}
-static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
+static netdev_tx_t macb_start_xmit(struct sk_buff *skb,
+ struct net_device *netdev)
{
u16 queue_index = skb_get_queue_mapping(skb);
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue = &bp->queues[queue_index];
unsigned int desc_cnt, nr_frags, frag_size, f;
unsigned int hdrlen;
@@ -2483,7 +2486,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
return ret;
}
- if (macb_pad_and_fcs(&skb, dev)) {
+ if (macb_pad_and_fcs(&skb, netdev)) {
dev_kfree_skb_any(skb);
return ret;
}
@@ -2502,7 +2505,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
else
hdrlen = skb_tcp_all_headers(skb);
if (skb_headlen(skb) < hdrlen) {
- netdev_err(bp->dev, "Error - LSO headers fragmented!!!\n");
+ netdev_err(bp->netdev, "Error - LSO headers fragmented!!!\n");
/* if this is required, would need to copy to single buffer */
return NETDEV_TX_BUSY;
}
@@ -2510,7 +2513,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
hdrlen = umin(skb_headlen(skb), bp->max_tx_length);
#if defined(DEBUG) && defined(VERBOSE_DEBUG)
- netdev_vdbg(bp->dev,
+ netdev_vdbg(bp->netdev,
"start_xmit: queue %hu len %u head %p data %p tail %p end %p\n",
queue_index, skb->len, skb->head, skb->data,
skb_tail_pointer(skb), skb_end_pointer(skb));
@@ -2538,8 +2541,8 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* This is a hard error, log it. */
if (CIRC_SPACE(queue->tx_head, queue->tx_tail,
bp->tx_ring_size) < desc_cnt) {
- netif_stop_subqueue(dev, queue_index);
- netdev_dbg(bp->dev, "tx_head = %u, tx_tail = %u\n",
+ netif_stop_subqueue(netdev, queue_index);
+ netdev_dbg(netdev, "tx_head = %u, tx_tail = %u\n",
queue->tx_head, queue->tx_tail);
ret = NETDEV_TX_BUSY;
goto unlock;
@@ -2554,7 +2557,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
/* Make newly initialized descriptor visible to hardware */
wmb();
skb_tx_timestamp(skb);
- netdev_tx_sent_queue(netdev_get_tx_queue(bp->dev, queue_index),
+ netdev_tx_sent_queue(netdev_get_tx_queue(bp->netdev, queue_index),
skb->len);
spin_lock(&bp->lock);
@@ -2563,7 +2566,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb, struct net_device *dev)
spin_unlock(&bp->lock);
if (CIRC_SPACE(queue->tx_head, queue->tx_tail, bp->tx_ring_size) < 1)
- netif_stop_subqueue(dev, queue_index);
+ netif_stop_subqueue(netdev, queue_index);
unlock:
spin_unlock_irqrestore(&queue->tx_ptr_lock, flags);
@@ -2579,7 +2582,7 @@ static void macb_init_rx_buffer_size(struct macb *bp, size_t size)
bp->rx_buffer_size = MIN(size, RX_BUFFER_MAX);
if (bp->rx_buffer_size % RX_BUFFER_MULTIPLE) {
- netdev_dbg(bp->dev,
+ netdev_dbg(bp->netdev,
"RX buffer must be multiple of %d bytes, expanding\n",
RX_BUFFER_MULTIPLE);
bp->rx_buffer_size =
@@ -2587,8 +2590,8 @@ static void macb_init_rx_buffer_size(struct macb *bp, size_t size)
}
}
- netdev_dbg(bp->dev, "mtu [%u] rx_buffer_size [%zu]\n",
- bp->dev->mtu, bp->rx_buffer_size);
+ netdev_dbg(bp->netdev, "mtu [%u] rx_buffer_size [%zu]\n",
+ bp->netdev->mtu, bp->rx_buffer_size);
}
static void gem_free_rx_buffers(struct macb *bp)
@@ -2679,7 +2682,7 @@ static void macb_free_consistent(struct macb *bp)
}
queue->stats.tx_dropped += dropped;
- bp->dev->stats.tx_dropped += dropped;
+ bp->netdev->stats.tx_dropped += dropped;
kfree(queue->tx_skb);
queue->tx_skb = NULL;
@@ -2704,7 +2707,7 @@ static int gem_alloc_rx_buffers(struct macb *bp)
if (!queue->rx_skbuff)
return -ENOMEM;
else
- netdev_dbg(bp->dev,
+ netdev_dbg(bp->netdev,
"Allocated %d RX struct sk_buff entries at %p\n",
bp->rx_ring_size, queue->rx_skbuff);
}
@@ -2722,7 +2725,7 @@ static int macb_alloc_rx_buffers(struct macb *bp)
if (!queue->rx_buffers)
return -ENOMEM;
- netdev_dbg(bp->dev,
+ netdev_dbg(bp->netdev,
"Allocated RX buffers of %d bytes at %08lx (mapped %p)\n",
size, (unsigned long)queue->rx_buffers_dma, queue->rx_buffers);
return 0;
@@ -2748,14 +2751,14 @@ static int macb_alloc_consistent(struct macb *bp)
tx = dma_alloc_coherent(dev, size, &tx_dma, GFP_KERNEL);
if (!tx || upper_32_bits(tx_dma) != upper_32_bits(tx_dma + size - 1))
goto out_err;
- netdev_dbg(bp->dev, "Allocated %zu bytes for %u TX rings at %08lx (mapped %p)\n",
+ netdev_dbg(bp->netdev, "Allocated %zu bytes for %u TX rings at %08lx (mapped %p)\n",
size, bp->num_queues, (unsigned long)tx_dma, tx);
size = bp->num_queues * macb_rx_ring_size_per_queue(bp);
rx = dma_alloc_coherent(dev, size, &rx_dma, GFP_KERNEL);
if (!rx || upper_32_bits(rx_dma) != upper_32_bits(rx_dma + size - 1))
goto out_err;
- netdev_dbg(bp->dev, "Allocated %zu bytes for %u RX rings at %08lx (mapped %p)\n",
+ netdev_dbg(bp->netdev, "Allocated %zu bytes for %u RX rings at %08lx (mapped %p)\n",
size, bp->num_queues, (unsigned long)rx_dma, rx);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
@@ -2983,7 +2986,7 @@ static void macb_configure_dma(struct macb *bp)
else
dmacfg |= GEM_BIT(ENDIA_DESC); /* CPU in big endian */
- if (bp->dev->features & NETIF_F_HW_CSUM)
+ if (bp->netdev->features & NETIF_F_HW_CSUM)
dmacfg |= GEM_BIT(TXCOEN);
else
dmacfg &= ~GEM_BIT(TXCOEN);
@@ -2993,7 +2996,7 @@ static void macb_configure_dma(struct macb *bp)
dmacfg |= GEM_BIT(ADDR64);
if (macb_dma_ptp(bp))
dmacfg |= GEM_BIT(RXEXT) | GEM_BIT(TXEXT);
- netdev_dbg(bp->dev, "Cadence configure DMA with 0x%08x\n",
+ netdev_dbg(bp->netdev, "Cadence configure DMA with 0x%08x\n",
dmacfg);
gem_writel(bp, DMACFG, dmacfg);
}
@@ -3017,11 +3020,11 @@ static void macb_init_hw(struct macb *bp)
config |= MACB_BIT(JFRAME); /* Enable jumbo frames */
else
config |= MACB_BIT(BIG); /* Receive oversized frames */
- if (bp->dev->flags & IFF_PROMISC)
+ if (bp->netdev->flags & IFF_PROMISC)
config |= MACB_BIT(CAF); /* Copy All Frames */
- else if (macb_is_gem(bp) && bp->dev->features & NETIF_F_RXCSUM)
+ else if (macb_is_gem(bp) && bp->netdev->features & NETIF_F_RXCSUM)
config |= GEM_BIT(RXCOEN);
- if (!(bp->dev->flags & IFF_BROADCAST))
+ if (!(bp->netdev->flags & IFF_BROADCAST))
config |= MACB_BIT(NBC); /* No BroadCast */
config |= macb_dbw(bp);
macb_writel(bp, NCFGR, config);
@@ -3095,17 +3098,17 @@ static int hash_get_index(__u8 *addr)
}
/* Add multicast addresses to the internal multicast-hash table. */
-static void macb_sethashtable(struct net_device *dev)
+static void macb_sethashtable(struct net_device *netdev)
{
struct netdev_hw_addr *ha;
unsigned long mc_filter[2];
unsigned int bitnr;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
mc_filter[0] = 0;
mc_filter[1] = 0;
- netdev_for_each_mc_addr(ha, dev) {
+ netdev_for_each_mc_addr(ha, netdev) {
bitnr = hash_get_index(ha->addr);
mc_filter[bitnr >> 5] |= 1 << (bitnr & 31);
}
@@ -3115,14 +3118,14 @@ static void macb_sethashtable(struct net_device *dev)
}
/* Enable/Disable promiscuous and multicast modes. */
-static void macb_set_rx_mode(struct net_device *dev)
+static void macb_set_rx_mode(struct net_device *netdev)
{
unsigned long cfg;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
cfg = macb_readl(bp, NCFGR);
- if (dev->flags & IFF_PROMISC) {
+ if (netdev->flags & IFF_PROMISC) {
/* Enable promiscuous mode */
cfg |= MACB_BIT(CAF);
@@ -3134,20 +3137,20 @@ static void macb_set_rx_mode(struct net_device *dev)
cfg &= ~MACB_BIT(CAF);
/* Enable RX checksum offload only if requested */
- if (macb_is_gem(bp) && dev->features & NETIF_F_RXCSUM)
+ if (macb_is_gem(bp) && netdev->features & NETIF_F_RXCSUM)
cfg |= GEM_BIT(RXCOEN);
}
- if (dev->flags & IFF_ALLMULTI) {
+ if (netdev->flags & IFF_ALLMULTI) {
/* Enable all multicast mode */
macb_or_gem_writel(bp, HRB, -1);
macb_or_gem_writel(bp, HRT, -1);
cfg |= MACB_BIT(NCFGR_MTI);
- } else if (!netdev_mc_empty(dev)) {
+ } else if (!netdev_mc_empty(netdev)) {
/* Enable specific multicasts */
- macb_sethashtable(dev);
+ macb_sethashtable(netdev);
cfg |= MACB_BIT(NCFGR_MTI);
- } else if (dev->flags & (~IFF_ALLMULTI)) {
+ } else if (netdev->flags & (~IFF_ALLMULTI)) {
/* Disable all multicast mode */
macb_or_gem_writel(bp, HRB, 0);
macb_or_gem_writel(bp, HRT, 0);
@@ -3157,15 +3160,15 @@ static void macb_set_rx_mode(struct net_device *dev)
macb_writel(bp, NCFGR, cfg);
}
-static int macb_open(struct net_device *dev)
+static int macb_open(struct net_device *netdev)
{
- size_t bufsz = dev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;
- struct macb *bp = netdev_priv(dev);
+ size_t bufsz = netdev->mtu + ETH_HLEN + ETH_FCS_LEN + NET_IP_ALIGN;
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned int q;
int err;
- netdev_dbg(bp->dev, "open\n");
+ netdev_dbg(bp->netdev, "open\n");
err = pm_runtime_resume_and_get(&bp->pdev->dev);
if (err < 0)
@@ -3176,7 +3179,7 @@ static int macb_open(struct net_device *dev)
err = macb_alloc_consistent(bp);
if (err) {
- netdev_err(dev, "Unable to allocate DMA memory (error %d)\n",
+ netdev_err(netdev, "Unable to allocate DMA memory (error %d)\n",
err);
goto pm_exit;
}
@@ -3203,10 +3206,10 @@ static int macb_open(struct net_device *dev)
if (err)
goto phy_off;
- netif_tx_start_all_queues(dev);
+ netif_tx_start_all_queues(netdev);
if (bp->ptp_info)
- bp->ptp_info->ptp_init(dev);
+ bp->ptp_info->ptp_init(netdev);
return 0;
@@ -3225,19 +3228,19 @@ static int macb_open(struct net_device *dev)
return err;
}
-static int macb_close(struct net_device *dev)
+static int macb_close(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned long flags;
unsigned int q;
- netif_tx_stop_all_queues(dev);
+ netif_tx_stop_all_queues(netdev);
for (q = 0, queue = bp->queues; q < bp->num_queues; ++q, ++queue) {
napi_disable(&queue->napi_rx);
napi_disable(&queue->napi_tx);
- netdev_tx_reset_queue(netdev_get_tx_queue(dev, q));
+ netdev_tx_reset_queue(netdev_get_tx_queue(netdev, q));
}
cancel_delayed_work_sync(&bp->tx_lpi_work);
@@ -3249,38 +3252,38 @@ static int macb_close(struct net_device *dev)
spin_lock_irqsave(&bp->lock, flags);
macb_reset_hw(bp);
- netif_carrier_off(dev);
+ netif_carrier_off(netdev);
spin_unlock_irqrestore(&bp->lock, flags);
macb_free_consistent(bp);
if (bp->ptp_info)
- bp->ptp_info->ptp_remove(dev);
+ bp->ptp_info->ptp_remove(netdev);
pm_runtime_put(&bp->pdev->dev);
return 0;
}
-static int macb_change_mtu(struct net_device *dev, int new_mtu)
+static int macb_change_mtu(struct net_device *netdev, int new_mtu)
{
- if (netif_running(dev))
+ if (netif_running(netdev))
return -EBUSY;
- WRITE_ONCE(dev->mtu, new_mtu);
+ WRITE_ONCE(netdev->mtu, new_mtu);
return 0;
}
-static int macb_set_mac_addr(struct net_device *dev, void *addr)
+static int macb_set_mac_addr(struct net_device *netdev, void *addr)
{
int err;
- err = eth_mac_addr(dev, addr);
+ err = eth_mac_addr(netdev, addr);
if (err < 0)
return err;
- macb_set_hwaddr(netdev_priv(dev));
+ macb_set_hwaddr(netdev_priv(netdev));
return 0;
}
@@ -3318,7 +3321,7 @@ static void gem_get_stats(struct macb *bp, struct rtnl_link_stats64 *nstat)
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
- if (netif_running(bp->dev))
+ if (netif_running(bp->netdev))
gem_update_stats(bp);
nstat->rx_errors = (hwstat->rx_frame_check_sequence_errors +
@@ -3351,10 +3354,10 @@ static void gem_get_stats(struct macb *bp, struct rtnl_link_stats64 *nstat)
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_ethtool_stats(struct net_device *dev,
+static void gem_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
spin_lock_irq(&bp->stats_lock);
gem_update_stats(bp);
@@ -3363,9 +3366,9 @@ static void gem_get_ethtool_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static int gem_get_sset_count(struct net_device *dev, int sset)
+static int gem_get_sset_count(struct net_device *netdev, int sset)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
switch (sset) {
case ETH_SS_STATS:
@@ -3375,9 +3378,9 @@ static int gem_get_sset_count(struct net_device *dev, int sset)
}
}
-static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
+static void gem_get_ethtool_strings(struct net_device *netdev, u32 sset, u8 *p)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
unsigned int i;
unsigned int q;
@@ -3396,13 +3399,13 @@ static void gem_get_ethtool_strings(struct net_device *dev, u32 sset, u8 *p)
}
}
-static void macb_get_stats(struct net_device *dev,
+static void macb_get_stats(struct net_device *netdev,
struct rtnl_link_stats64 *nstat)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
- netdev_stats_to_stats64(nstat, &bp->dev->stats);
+ netdev_stats_to_stats64(nstat, &bp->netdev->stats);
if (macb_is_gem(bp)) {
gem_get_stats(bp, nstat);
return;
@@ -3446,10 +3449,10 @@ static void macb_get_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void macb_get_pause_stats(struct net_device *dev,
+static void macb_get_pause_stats(struct net_device *netdev,
struct ethtool_pause_stats *pause_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3459,10 +3462,10 @@ static void macb_get_pause_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_pause_stats(struct net_device *dev,
+static void gem_get_pause_stats(struct net_device *netdev,
struct ethtool_pause_stats *pause_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3472,10 +3475,10 @@ static void gem_get_pause_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void macb_get_eth_mac_stats(struct net_device *dev,
+static void macb_get_eth_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *mac_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3497,10 +3500,10 @@ static void macb_get_eth_mac_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_eth_mac_stats(struct net_device *dev,
+static void gem_get_eth_mac_stats(struct net_device *netdev,
struct ethtool_eth_mac_stats *mac_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3530,10 +3533,10 @@ static void gem_get_eth_mac_stats(struct net_device *dev,
}
/* TODO: Report SQE test errors when added to phy_stats */
-static void macb_get_eth_phy_stats(struct net_device *dev,
+static void macb_get_eth_phy_stats(struct net_device *netdev,
struct ethtool_eth_phy_stats *phy_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3542,10 +3545,10 @@ static void macb_get_eth_phy_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void gem_get_eth_phy_stats(struct net_device *dev,
+static void gem_get_eth_phy_stats(struct net_device *netdev,
struct ethtool_eth_phy_stats *phy_stats)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3554,11 +3557,11 @@ static void gem_get_eth_phy_stats(struct net_device *dev,
spin_unlock_irq(&bp->stats_lock);
}
-static void macb_get_rmon_stats(struct net_device *dev,
+static void macb_get_rmon_stats(struct net_device *netdev,
struct ethtool_rmon_stats *rmon_stats,
const struct ethtool_rmon_hist_range **ranges)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_stats *hwstat = &bp->hw_stats.macb;
spin_lock_irq(&bp->stats_lock);
@@ -3580,11 +3583,11 @@ static const struct ethtool_rmon_hist_range gem_rmon_ranges[] = {
{ },
};
-static void gem_get_rmon_stats(struct net_device *dev,
+static void gem_get_rmon_stats(struct net_device *netdev,
struct ethtool_rmon_stats *rmon_stats,
const struct ethtool_rmon_hist_range **ranges)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct gem_stats *hwstat = &bp->hw_stats.gem;
spin_lock_irq(&bp->stats_lock);
@@ -3615,10 +3618,10 @@ static int macb_get_regs_len(struct net_device *netdev)
return MACB_GREGS_NBR * sizeof(u32);
}
-static void macb_get_regs(struct net_device *dev, struct ethtool_regs *regs,
+static void macb_get_regs(struct net_device *netdev, struct ethtool_regs *regs,
void *p)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
unsigned int tail, head;
u32 *regs_buff = p;
@@ -3735,16 +3738,16 @@ static int macb_set_ringparam(struct net_device *netdev,
return 0;
}
- if (netif_running(bp->dev)) {
+ if (netif_running(bp->netdev)) {
reset = 1;
- macb_close(bp->dev);
+ macb_close(bp->netdev);
}
bp->rx_ring_size = new_rx_size;
bp->tx_ring_size = new_tx_size;
if (reset)
- macb_open(bp->dev);
+ macb_open(bp->netdev);
return 0;
}
@@ -3771,13 +3774,13 @@ static s32 gem_get_ptp_max_adj(void)
return 64000000;
}
-static int gem_get_ts_info(struct net_device *dev,
+static int gem_get_ts_info(struct net_device *netdev,
struct kernel_ethtool_ts_info *info)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
if (!macb_dma_ptp(bp)) {
- ethtool_op_get_ts_info(dev, info);
+ ethtool_op_get_ts_info(netdev, info);
return 0;
}
@@ -3824,7 +3827,7 @@ static int macb_get_ts_info(struct net_device *netdev,
static void gem_enable_flow_filters(struct macb *bp, bool enable)
{
- struct net_device *netdev = bp->dev;
+ struct net_device *netdev = bp->netdev;
struct ethtool_rx_fs_item *item;
u32 t2_scr;
int num_t2_scr;
@@ -4154,16 +4157,16 @@ static const struct ethtool_ops macb_ethtool_ops = {
.set_ringparam = macb_set_ringparam,
};
-static int macb_get_eee(struct net_device *dev, struct ethtool_keee *eee)
+static int macb_get_eee(struct net_device *netdev, struct ethtool_keee *eee)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
return phylink_ethtool_get_eee(bp->phylink, eee);
}
-static int macb_set_eee(struct net_device *dev, struct ethtool_keee *eee)
+static int macb_set_eee(struct net_device *netdev, struct ethtool_keee *eee)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
return phylink_ethtool_set_eee(bp->phylink, eee);
}
@@ -4194,43 +4197,43 @@ static const struct ethtool_ops gem_ethtool_ops = {
.set_eee = macb_set_eee,
};
-static int macb_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
+static int macb_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!netif_running(dev))
+ if (!netif_running(netdev))
return -EINVAL;
return phylink_mii_ioctl(bp->phylink, rq, cmd);
}
-static int macb_hwtstamp_get(struct net_device *dev,
+static int macb_hwtstamp_get(struct net_device *netdev,
struct kernel_hwtstamp_config *cfg)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!netif_running(dev))
+ if (!netif_running(netdev))
return -EINVAL;
if (!bp->ptp_info)
return -EOPNOTSUPP;
- return bp->ptp_info->get_hwtst(dev, cfg);
+ return bp->ptp_info->get_hwtst(netdev, cfg);
}
-static int macb_hwtstamp_set(struct net_device *dev,
+static int macb_hwtstamp_set(struct net_device *netdev,
struct kernel_hwtstamp_config *cfg,
struct netlink_ext_ack *extack)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
- if (!netif_running(dev))
+ if (!netif_running(netdev))
return -EINVAL;
if (!bp->ptp_info)
return -EOPNOTSUPP;
- return bp->ptp_info->set_hwtst(dev, cfg, extack);
+ return bp->ptp_info->set_hwtst(netdev, cfg, extack);
}
static inline void macb_set_txcsum_feature(struct macb *bp,
@@ -4253,7 +4256,7 @@ static inline void macb_set_txcsum_feature(struct macb *bp,
static inline void macb_set_rxcsum_feature(struct macb *bp,
netdev_features_t features)
{
- struct net_device *netdev = bp->dev;
+ struct net_device *netdev = bp->netdev;
u32 val;
if (!macb_is_gem(bp))
@@ -4300,7 +4303,7 @@ static int macb_set_features(struct net_device *netdev,
static void macb_restore_features(struct macb *bp)
{
- struct net_device *netdev = bp->dev;
+ struct net_device *netdev = bp->netdev;
netdev_features_t features = netdev->features;
struct ethtool_rx_fs_item *item;
@@ -4317,14 +4320,14 @@ static void macb_restore_features(struct macb *bp)
macb_set_rxflow_feature(bp, features);
}
-static int macb_taprio_setup_replace(struct net_device *ndev,
+static int macb_taprio_setup_replace(struct net_device *netdev,
struct tc_taprio_qopt_offload *conf)
{
u64 total_on_time = 0, start_time_sec = 0, start_time = conf->base_time;
u32 configured_queues = 0, speed = 0, start_time_nsec;
struct macb_queue_enst_config *enst_queue;
struct tc_taprio_sched_entry *entry;
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
struct ethtool_link_ksettings kset;
struct macb_queue *queue;
u32 queue_mask;
@@ -4333,13 +4336,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
int err;
if (conf->num_entries > bp->num_queues) {
- netdev_err(ndev, "Too many TAPRIO entries: %zu > %d queues\n",
+ netdev_err(netdev, "Too many TAPRIO entries: %zu > %d queues\n",
conf->num_entries, bp->num_queues);
return -EINVAL;
}
if (conf->base_time < 0) {
- netdev_err(ndev, "Invalid base_time: must be 0 or positive, got %lld\n",
+ netdev_err(netdev, "Invalid base_time: must be 0 or positive, got %lld\n",
conf->base_time);
return -ERANGE;
}
@@ -4347,13 +4350,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Get the current link speed */
err = phylink_ethtool_ksettings_get(bp->phylink, &kset);
if (unlikely(err)) {
- netdev_err(ndev, "Failed to get link settings: %d\n", err);
+ netdev_err(netdev, "Failed to get link settings: %d\n", err);
return err;
}
speed = kset.base.speed;
if (unlikely(speed <= 0)) {
- netdev_err(ndev, "Invalid speed: %d\n", speed);
+ netdev_err(netdev, "Invalid speed: %d\n", speed);
return -EINVAL;
}
@@ -4366,7 +4369,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
entry = &conf->entries[i];
if (entry->command != TC_TAPRIO_CMD_SET_GATES) {
- netdev_err(ndev, "Entry %zu: unsupported command %d\n",
+ netdev_err(netdev, "Entry %zu: unsupported command %d\n",
i, entry->command);
err = -EOPNOTSUPP;
goto cleanup;
@@ -4374,7 +4377,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Validate gate_mask: must be nonzero, single queue, and within range */
if (!is_power_of_2(entry->gate_mask)) {
- netdev_err(ndev, "Entry %zu: gate_mask 0x%x is not a power of 2 (only one queue per entry allowed)\n",
+ netdev_err(netdev, "Entry %zu: gate_mask 0x%x is not a power of 2 (only one queue per entry allowed)\n",
i, entry->gate_mask);
err = -EINVAL;
goto cleanup;
@@ -4383,7 +4386,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* gate_mask must not select queues outside the valid queues */
queue_id = order_base_2(entry->gate_mask);
if (queue_id >= bp->num_queues) {
- netdev_err(ndev, "Entry %zu: gate_mask 0x%x exceeds queue range (max_queues=%d)\n",
+ netdev_err(netdev, "Entry %zu: gate_mask 0x%x exceeds queue range (max_queues=%d)\n",
i, entry->gate_mask, bp->num_queues);
err = -EINVAL;
goto cleanup;
@@ -4393,7 +4396,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
start_time_sec = start_time;
start_time_nsec = do_div(start_time_sec, NSEC_PER_SEC);
if (start_time_sec > GENMASK(GEM_START_TIME_SEC_SIZE - 1, 0)) {
- netdev_err(ndev, "Entry %zu: Start time %llu s exceeds hardware limit\n",
+ netdev_err(netdev, "Entry %zu: Start time %llu s exceeds hardware limit\n",
i, start_time_sec);
err = -ERANGE;
goto cleanup;
@@ -4401,7 +4404,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Check for on time limit */
if (entry->interval > enst_max_hw_interval(speed)) {
- netdev_err(ndev, "Entry %zu: interval %u ns exceeds hardware limit %llu ns\n",
+ netdev_err(netdev, "Entry %zu: interval %u ns exceeds hardware limit %llu ns\n",
i, entry->interval, enst_max_hw_interval(speed));
err = -ERANGE;
goto cleanup;
@@ -4409,7 +4412,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Check for off time limit*/
if ((conf->cycle_time - entry->interval) > enst_max_hw_interval(speed)) {
- netdev_err(ndev, "Entry %zu: off_time %llu ns exceeds hardware limit %llu ns\n",
+ netdev_err(netdev, "Entry %zu: off_time %llu ns exceeds hardware limit %llu ns\n",
i, conf->cycle_time - entry->interval,
enst_max_hw_interval(speed));
err = -ERANGE;
@@ -4432,13 +4435,13 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
/* Check total interval doesn't exceed cycle time */
if (total_on_time > conf->cycle_time) {
- netdev_err(ndev, "Total ON %llu ns exceeds cycle time %llu ns\n",
+ netdev_err(netdev, "Total ON %llu ns exceeds cycle time %llu ns\n",
total_on_time, conf->cycle_time);
err = -EINVAL;
goto cleanup;
}
- netdev_dbg(ndev, "TAPRIO setup: %zu entries, base_time=%lld ns, cycle_time=%llu ns\n",
+ netdev_dbg(netdev, "TAPRIO setup: %zu entries, base_time=%lld ns, cycle_time=%llu ns\n",
conf->num_entries, conf->base_time, conf->cycle_time);
/* All validations passed - proceed with hardware configuration */
@@ -4463,7 +4466,7 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
gem_writel(bp, ENST_CONTROL, configured_queues);
}
- netdev_info(ndev, "TAPRIO configuration completed successfully: %zu entries, %d queues configured\n",
+ netdev_info(netdev, "TAPRIO configuration completed successfully: %zu entries, %d queues configured\n",
conf->num_entries, hweight32(configured_queues));
cleanup:
@@ -4471,14 +4474,14 @@ static int macb_taprio_setup_replace(struct net_device *ndev,
return err;
}
-static void macb_taprio_destroy(struct net_device *ndev)
+static void macb_taprio_destroy(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
u32 queue_mask;
unsigned int q;
- netdev_reset_tc(ndev);
+ netdev_reset_tc(netdev);
queue_mask = BIT_U32(bp->num_queues) - 1;
scoped_guard(spinlock_irqsave, &bp->lock) {
@@ -4493,30 +4496,30 @@ static void macb_taprio_destroy(struct net_device *ndev)
queue_writel(queue, ENST_OFF_TIME, 0);
}
}
- netdev_info(ndev, "TAPRIO destroy: All gates disabled\n");
+ netdev_info(netdev, "TAPRIO destroy: All gates disabled\n");
}
-static int macb_setup_taprio(struct net_device *ndev,
+static int macb_setup_taprio(struct net_device *netdev,
struct tc_taprio_qopt_offload *taprio)
{
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
int err = 0;
- if (unlikely(!(ndev->hw_features & NETIF_F_HW_TC)))
+ if (unlikely(!(netdev->hw_features & NETIF_F_HW_TC)))
return -EOPNOTSUPP;
/* Check if Device is in runtime suspend */
if (unlikely(pm_runtime_suspended(&bp->pdev->dev))) {
- netdev_err(ndev, "Device is in runtime suspend\n");
+ netdev_err(netdev, "Device is in runtime suspend\n");
return -EOPNOTSUPP;
}
switch (taprio->cmd) {
case TAPRIO_CMD_REPLACE:
- err = macb_taprio_setup_replace(ndev, taprio);
+ err = macb_taprio_setup_replace(netdev, taprio);
break;
case TAPRIO_CMD_DESTROY:
- macb_taprio_destroy(ndev);
+ macb_taprio_destroy(netdev);
break;
default:
err = -EOPNOTSUPP;
@@ -4525,23 +4528,23 @@ static int macb_setup_taprio(struct net_device *ndev,
return err;
}
-static int macb_setup_tc(struct net_device *dev, enum tc_setup_type type,
+static int macb_setup_tc(struct net_device *netdev, enum tc_setup_type type,
void *type_data)
{
- if (!dev || !type_data)
+ if (!netdev || !type_data)
return -EINVAL;
switch (type) {
case TC_SETUP_QDISC_TAPRIO:
- return macb_setup_taprio(dev, type_data);
+ return macb_setup_taprio(netdev, type_data);
default:
return -EOPNOTSUPP;
}
}
-static void macb_tx_timeout(struct net_device *dev, unsigned int q)
+static void macb_tx_timeout(struct net_device *netdev, unsigned int q)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
macb_tx_restart(&bp->queues[q]);
}
@@ -4749,9 +4752,9 @@ static int macb_clk_init(struct platform_device *pdev, struct clk **pclk,
static int macb_init_dflt(struct platform_device *pdev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
+ struct net_device *netdev = platform_get_drvdata(pdev);
unsigned int hw_q, q;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
struct macb_queue *queue;
int err;
u32 val, reg;
@@ -4767,8 +4770,8 @@ static int macb_init_dflt(struct platform_device *pdev)
queue = &bp->queues[q];
queue->bp = bp;
spin_lock_init(&queue->tx_ptr_lock);
- netif_napi_add(dev, &queue->napi_rx, macb_rx_poll);
- netif_napi_add_tx(dev, &queue->napi_tx, macb_tx_poll);
+ netif_napi_add(netdev, &queue->napi_rx, macb_rx_poll);
+ netif_napi_add_tx(netdev, &queue->napi_tx, macb_tx_poll);
if (hw_q) {
queue->ISR = GEM_ISR(hw_q - 1);
queue->IER = GEM_IER(hw_q - 1);
@@ -4798,7 +4801,7 @@ static int macb_init_dflt(struct platform_device *pdev)
*/
queue->irq = platform_get_irq(pdev, q);
err = devm_request_irq(&pdev->dev, queue->irq, macb_interrupt,
- IRQF_SHARED, dev->name, queue);
+ IRQF_SHARED, netdev->name, queue);
if (err) {
dev_err(&pdev->dev,
"Unable to request IRQ %d (error %d)\n",
@@ -4810,7 +4813,7 @@ static int macb_init_dflt(struct platform_device *pdev)
q++;
}
- dev->netdev_ops = &macb_netdev_ops;
+ netdev->netdev_ops = &macb_netdev_ops;
/* setup appropriated routines according to adapter type */
if (macb_is_gem(bp)) {
@@ -4818,39 +4821,39 @@ static int macb_init_dflt(struct platform_device *pdev)
bp->macbgem_ops.mog_free_rx_buffers = gem_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = gem_init_rings;
bp->macbgem_ops.mog_rx = gem_rx;
- dev->ethtool_ops = &gem_ethtool_ops;
+ netdev->ethtool_ops = &gem_ethtool_ops;
} else {
bp->macbgem_ops.mog_alloc_rx_buffers = macb_alloc_rx_buffers;
bp->macbgem_ops.mog_free_rx_buffers = macb_free_rx_buffers;
bp->macbgem_ops.mog_init_rings = macb_init_rings;
bp->macbgem_ops.mog_rx = macb_rx;
- dev->ethtool_ops = &macb_ethtool_ops;
+ netdev->ethtool_ops = &macb_ethtool_ops;
}
- netdev_sw_irq_coalesce_default_on(dev);
+ netdev_sw_irq_coalesce_default_on(netdev);
- dev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
+ netdev->priv_flags |= IFF_LIVE_ADDR_CHANGE;
/* Set features */
- dev->hw_features = NETIF_F_SG;
+ netdev->hw_features = NETIF_F_SG;
/* Check LSO capability; runtime detection can be overridden by a cap
* flag if the hardware is known to be buggy
*/
if (!(bp->caps & MACB_CAPS_NO_LSO) &&
GEM_BFEXT(PBUF_LSO, gem_readl(bp, DCFG6)))
- dev->hw_features |= MACB_NETIF_LSO;
+ netdev->hw_features |= MACB_NETIF_LSO;
/* Checksum offload is only available on gem with packet buffer */
if (macb_is_gem(bp) && !(bp->caps & MACB_CAPS_FIFO_MODE))
- dev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
+ netdev->hw_features |= NETIF_F_HW_CSUM | NETIF_F_RXCSUM;
if (bp->caps & MACB_CAPS_SG_DISABLED)
- dev->hw_features &= ~NETIF_F_SG;
+ netdev->hw_features &= ~NETIF_F_SG;
/* Enable HW_TC if hardware supports QBV */
if (bp->caps & MACB_CAPS_QBV)
- dev->hw_features |= NETIF_F_HW_TC;
+ netdev->hw_features |= NETIF_F_HW_TC;
- dev->features = dev->hw_features;
+ netdev->features = netdev->hw_features;
/* Check RX Flow Filters support.
* Max Rx flows set by availability of screeners & compare regs:
@@ -4868,7 +4871,7 @@ static int macb_init_dflt(struct platform_device *pdev)
reg = GEM_BFINS(ETHTCMP, (uint16_t)ETH_P_IP, reg);
gem_writel_n(bp, ETHT, SCRT2_ETHT, reg);
/* Filtering is supported in hw but don't enable it in kernel now */
- dev->hw_features |= NETIF_F_NTUPLE;
+ netdev->hw_features |= NETIF_F_NTUPLE;
/* init Rx flow definitions */
bp->rx_fs_list.count = 0;
spin_lock_init(&bp->rx_fs_lock);
@@ -5078,9 +5081,9 @@ static void at91ether_stop(struct macb *lp)
}
/* Open the ethernet interface */
-static int at91ether_open(struct net_device *dev)
+static int at91ether_open(struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *lp = netdev_priv(netdev);
u32 ctl;
int ret;
@@ -5102,7 +5105,7 @@ static int at91ether_open(struct net_device *dev)
if (ret)
goto stop;
- netif_start_queue(dev);
+ netif_start_queue(netdev);
return 0;
@@ -5114,11 +5117,11 @@ static int at91ether_open(struct net_device *dev)
}
/* Close the interface */
-static int at91ether_close(struct net_device *dev)
+static int at91ether_close(struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *lp = netdev_priv(netdev);
- netif_stop_queue(dev);
+ netif_stop_queue(netdev);
phylink_stop(lp->phylink);
phylink_disconnect_phy(lp->phylink);
@@ -5132,14 +5135,14 @@ static int at91ether_close(struct net_device *dev)
/* Transmit packet */
static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
- struct net_device *dev)
+ struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *lp = netdev_priv(netdev);
if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) {
int desc = 0;
- netif_stop_queue(dev);
+ netif_stop_queue(netdev);
/* Store packet information (to free when Tx completed) */
lp->rm9200_txq[desc].skb = skb;
@@ -5148,8 +5151,8 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
skb->len, DMA_TO_DEVICE);
if (dma_mapping_error(&lp->pdev->dev, lp->rm9200_txq[desc].mapping)) {
dev_kfree_skb_any(skb);
- dev->stats.tx_dropped++;
- netdev_err(dev, "%s: DMA mapping error\n", __func__);
+ netdev->stats.tx_dropped++;
+ netdev_err(netdev, "%s: DMA mapping error\n", __func__);
return NETDEV_TX_OK;
}
@@ -5159,7 +5162,8 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
macb_writel(lp, TCR, skb->len);
} else {
- netdev_err(dev, "%s called, but device is busy!\n", __func__);
+ netdev_err(netdev, "%s called, but device is busy!\n",
+ __func__);
return NETDEV_TX_BUSY;
}
@@ -5169,9 +5173,9 @@ static netdev_tx_t at91ether_start_xmit(struct sk_buff *skb,
/* Extract received frame from buffer descriptors and sent to upper layers.
* (Called from interrupt context)
*/
-static void at91ether_rx(struct net_device *dev)
+static void at91ether_rx(struct net_device *netdev)
{
- struct macb *lp = netdev_priv(dev);
+ struct macb *lp = netdev_priv(netdev);
struct macb_queue *q = &lp->queues[0];
struct macb_dma_desc *desc;
unsigned char *p_recv;
@@ -5182,21 +5186,21 @@ static void at91ether_rx(struct net_device *dev)
while (desc->addr & MACB_BIT(RX_USED)) {
p_recv = q->rx_buffers + q->rx_tail * AT91ETHER_MAX_RBUFF_SZ;
pktlen = MACB_BF(RX_FRMLEN, desc->ctrl);
- skb = netdev_alloc_skb(dev, pktlen + 2);
+ skb = netdev_alloc_skb(netdev, pktlen + 2);
if (skb) {
skb_reserve(skb, 2);
skb_put_data(skb, p_recv, pktlen);
- skb->protocol = eth_type_trans(skb, dev);
- dev->stats.rx_packets++;
- dev->stats.rx_bytes += pktlen;
+ skb->protocol = eth_type_trans(skb, netdev);
+ netdev->stats.rx_packets++;
+ netdev->stats.rx_bytes += pktlen;
netif_rx(skb);
} else {
- dev->stats.rx_dropped++;
+ netdev->stats.rx_dropped++;
}
if (desc->ctrl & MACB_BIT(RX_MHASH_MATCH))
- dev->stats.multicast++;
+ netdev->stats.multicast++;
/* reset ownership bit */
desc->addr &= ~MACB_BIT(RX_USED);
@@ -5214,8 +5218,8 @@ static void at91ether_rx(struct net_device *dev)
/* MAC interrupt handler */
static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
{
- struct net_device *dev = dev_id;
- struct macb *lp = netdev_priv(dev);
+ struct net_device *netdev = dev_id;
+ struct macb *lp = netdev_priv(netdev);
u32 intstatus, ctl;
unsigned int desc;
@@ -5226,13 +5230,13 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
/* Receive complete */
if (intstatus & MACB_BIT(RCOMP))
- at91ether_rx(dev);
+ at91ether_rx(netdev);
/* Transmit complete */
if (intstatus & MACB_BIT(TCOMP)) {
/* The TCOM bit is set even if the transmission failed */
if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE)))
- dev->stats.tx_errors++;
+ netdev->stats.tx_errors++;
desc = 0;
if (lp->rm9200_txq[desc].skb) {
@@ -5240,10 +5244,10 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
lp->rm9200_txq[desc].skb = NULL;
dma_unmap_single(&lp->pdev->dev, lp->rm9200_txq[desc].mapping,
lp->rm9200_txq[desc].size, DMA_TO_DEVICE);
- dev->stats.tx_packets++;
- dev->stats.tx_bytes += lp->rm9200_txq[desc].size;
+ netdev->stats.tx_packets++;
+ netdev->stats.tx_bytes += lp->rm9200_txq[desc].size;
}
- netif_wake_queue(dev);
+ netif_wake_queue(netdev);
}
/* Work-around for EMAC Errata section 41.3.1 */
@@ -5255,18 +5259,18 @@ static irqreturn_t at91ether_interrupt(int irq, void *dev_id)
}
if (intstatus & MACB_BIT(ISR_ROVR))
- netdev_err(dev, "ROVR error\n");
+ netdev_err(netdev, "ROVR error\n");
return IRQ_HANDLED;
}
#ifdef CONFIG_NET_POLL_CONTROLLER
-static void at91ether_poll_controller(struct net_device *dev)
+static void at91ether_poll_controller(struct net_device *netdev)
{
unsigned long flags;
local_irq_save(flags);
- at91ether_interrupt(dev->irq, dev);
+ at91ether_interrupt(netdev->irq, netdev);
local_irq_restore(flags);
}
#endif
@@ -5313,17 +5317,17 @@ static int at91ether_clk_init(struct platform_device *pdev, struct clk **pclk,
static int at91ether_init(struct platform_device *pdev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct macb *bp = netdev_priv(dev);
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct macb *bp = netdev_priv(netdev);
int err;
bp->queues[0].bp = bp;
- dev->netdev_ops = &at91ether_netdev_ops;
- dev->ethtool_ops = &macb_ethtool_ops;
+ netdev->netdev_ops = &at91ether_netdev_ops;
+ netdev->ethtool_ops = &macb_ethtool_ops;
- err = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt,
- 0, dev->name, dev);
+ err = devm_request_irq(&pdev->dev, netdev->irq, at91ether_interrupt,
+ 0, netdev->name, netdev);
if (err)
return err;
@@ -5452,8 +5456,8 @@ static int fu540_c000_init(struct platform_device *pdev)
static int init_reset_optional(struct platform_device *pdev)
{
- struct net_device *dev = platform_get_drvdata(pdev);
- struct macb *bp = netdev_priv(dev);
+ struct net_device *netdev = platform_get_drvdata(pdev);
+ struct macb *bp = netdev_priv(netdev);
int ret;
if (bp->phy_interface == PHY_INTERFACE_MODE_SGMII) {
@@ -5761,7 +5765,7 @@ static int macb_probe(struct platform_device *pdev)
const struct macb_config *macb_config;
struct clk *tsu_clk = NULL;
phy_interface_t interface;
- struct net_device *dev;
+ struct net_device *netdev;
struct resource *regs;
u32 wtrmrk_rst_val;
void __iomem *mem;
@@ -5796,19 +5800,19 @@ static int macb_probe(struct platform_device *pdev)
goto err_disable_clocks;
}
- dev = alloc_etherdev_mq(sizeof(*bp), num_queues);
- if (!dev) {
+ netdev = alloc_etherdev_mq(sizeof(*bp), num_queues);
+ if (!netdev) {
err = -ENOMEM;
goto err_disable_clocks;
}
- dev->base_addr = regs->start;
+ netdev->base_addr = regs->start;
- SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_NETDEV_DEV(netdev, &pdev->dev);
- bp = netdev_priv(dev);
+ bp = netdev_priv(netdev);
bp->pdev = pdev;
- bp->dev = dev;
+ bp->netdev = netdev;
bp->regs = mem;
bp->native_io = native_io;
if (native_io) {
@@ -5881,21 +5885,21 @@ static int macb_probe(struct platform_device *pdev)
bp->caps |= MACB_CAPS_DMA_64B;
}
#endif
- platform_set_drvdata(pdev, dev);
+ platform_set_drvdata(pdev, netdev);
- dev->irq = platform_get_irq(pdev, 0);
- if (dev->irq < 0) {
- err = dev->irq;
+ netdev->irq = platform_get_irq(pdev, 0);
+ if (netdev->irq < 0) {
+ err = netdev->irq;
goto err_out_free_netdev;
}
/* MTU range: 68 - 1518 or 10240 */
- dev->min_mtu = GEM_MTU_MIN_SIZE;
+ netdev->min_mtu = GEM_MTU_MIN_SIZE;
if ((bp->caps & MACB_CAPS_JUMBO) && bp->jumbo_max_len)
- dev->max_mtu = MIN(bp->jumbo_max_len, RX_BUFFER_MAX) -
+ netdev->max_mtu = MIN(bp->jumbo_max_len, RX_BUFFER_MAX) -
ETH_HLEN - ETH_FCS_LEN;
else
- dev->max_mtu = 1536 - ETH_HLEN - ETH_FCS_LEN;
+ netdev->max_mtu = 1536 - ETH_HLEN - ETH_FCS_LEN;
if (bp->caps & MACB_CAPS_BD_RD_PREFETCH) {
val = GEM_BFEXT(RXBD_RDBUFF, gem_readl(bp, DCFG10));
@@ -5913,7 +5917,7 @@ static int macb_probe(struct platform_device *pdev)
if (bp->caps & MACB_CAPS_NEEDS_RSTONUBR)
bp->rx_intr_mask |= MACB_BIT(RXUBR);
- err = of_get_ethdev_address(np, bp->dev);
+ err = of_get_ethdev_address(np, bp->netdev);
if (err == -EPROBE_DEFER)
goto err_out_free_netdev;
else if (err)
@@ -5935,9 +5939,9 @@ static int macb_probe(struct platform_device *pdev)
if (err)
goto err_out_phy_exit;
- netif_carrier_off(dev);
+ netif_carrier_off(netdev);
- err = register_netdev(dev);
+ err = register_netdev(netdev);
if (err) {
dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
goto err_out_unregister_mdio;
@@ -5946,9 +5950,9 @@ static int macb_probe(struct platform_device *pdev)
INIT_WORK(&bp->hresp_err_bh_work, macb_hresp_error_task);
INIT_DELAYED_WORK(&bp->tx_lpi_work, macb_tx_lpi_work_fn);
- netdev_info(dev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
+ netdev_info(netdev, "Cadence %s rev 0x%08x at 0x%08lx irq %d (%pM)\n",
macb_is_gem(bp) ? "GEM" : "MACB", macb_readl(bp, MID),
- dev->base_addr, dev->irq, dev->dev_addr);
+ netdev->base_addr, netdev->irq, netdev->dev_addr);
pm_runtime_put_autosuspend(&bp->pdev->dev);
@@ -5962,7 +5966,7 @@ static int macb_probe(struct platform_device *pdev)
phy_exit(bp->phy);
err_out_free_netdev:
- free_netdev(dev);
+ free_netdev(netdev);
err_disable_clocks:
macb_clks_disable(pclk, hclk, tx_clk, rx_clk, tsu_clk);
@@ -5975,14 +5979,14 @@ static int macb_probe(struct platform_device *pdev)
static void macb_remove(struct platform_device *pdev)
{
- struct net_device *dev;
+ struct net_device *netdev;
struct macb *bp;
- dev = platform_get_drvdata(pdev);
+ netdev = platform_get_drvdata(pdev);
- if (dev) {
- bp = netdev_priv(dev);
- unregister_netdev(dev);
+ if (netdev) {
+ bp = netdev_priv(netdev);
+ unregister_netdev(netdev);
phy_exit(bp->phy);
mdiobus_unregister(bp->mii_bus);
mdiobus_free(bp->mii_bus);
@@ -5994,7 +5998,7 @@ static void macb_remove(struct platform_device *pdev)
pm_runtime_dont_use_autosuspend(&pdev->dev);
pm_runtime_set_suspended(&pdev->dev);
phylink_destroy(bp->phylink);
- free_netdev(dev);
+ free_netdev(netdev);
}
}
@@ -6009,7 +6013,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
u32 tmp, ifa_local;
unsigned int q;
- if (!device_may_wakeup(&bp->dev->dev))
+ if (!device_may_wakeup(&bp->netdev->dev))
phy_exit(bp->phy);
if (!netif_running(netdev))
@@ -6019,7 +6023,7 @@ static int __maybe_unused macb_suspend(struct device *dev)
if (bp->wolopts & WAKE_ARP) {
/* Check for IP address in WOL ARP mode */
rcu_read_lock();
- idev = __in_dev_get_rcu(bp->dev);
+ idev = __in_dev_get_rcu(bp->netdev);
if (idev)
ifa = rcu_dereference(idev->ifa_list);
if (!ifa) {
@@ -6121,7 +6125,7 @@ static int __maybe_unused macb_resume(struct device *dev)
unsigned long flags;
unsigned int q;
- if (!device_may_wakeup(&bp->dev->dev))
+ if (!device_may_wakeup(&bp->netdev->dev))
phy_init(bp->phy);
if (!netif_running(netdev))
diff --git a/drivers/net/ethernet/cadence/macb_pci.c b/drivers/net/ethernet/cadence/macb_pci.c
index b79dec17e6b09..ac009007118f3 100644
--- a/drivers/net/ethernet/cadence/macb_pci.c
+++ b/drivers/net/ethernet/cadence/macb_pci.c
@@ -24,48 +24,48 @@
#define GEM_PCLK_RATE 50000000
#define GEM_HCLK_RATE 50000000
-static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
+static int macb_probe(struct pci_dev *pci, const struct pci_device_id *id)
{
int err;
- struct platform_device *plat_dev;
+ struct platform_device *pdev;
struct platform_device_info plat_info;
struct macb_platform_data plat_data;
struct resource res[2];
/* enable pci device */
- err = pcim_enable_device(pdev);
+ err = pcim_enable_device(pci);
if (err < 0) {
- dev_err(&pdev->dev, "Enabling PCI device has failed: %d", err);
+ dev_err(&pci->dev, "Enabling PCI device has failed: %d", err);
return err;
}
- pci_set_master(pdev);
+ pci_set_master(pci);
/* set up resources */
memset(res, 0x00, sizeof(struct resource) * ARRAY_SIZE(res));
- res[0].start = pci_resource_start(pdev, 0);
- res[0].end = pci_resource_end(pdev, 0);
+ res[0].start = pci_resource_start(pci, 0);
+ res[0].end = pci_resource_end(pci, 0);
res[0].name = PCI_DRIVER_NAME;
res[0].flags = IORESOURCE_MEM;
- res[1].start = pci_irq_vector(pdev, 0);
+ res[1].start = pci_irq_vector(pci, 0);
res[1].name = PCI_DRIVER_NAME;
res[1].flags = IORESOURCE_IRQ;
- dev_info(&pdev->dev, "EMAC physical base addr: %pa\n",
+ dev_info(&pci->dev, "EMAC physical base addr: %pa\n",
&res[0].start);
/* set up macb platform data */
memset(&plat_data, 0, sizeof(plat_data));
/* initialize clocks */
- plat_data.pclk = clk_register_fixed_rate(&pdev->dev, "pclk", NULL, 0,
+ plat_data.pclk = clk_register_fixed_rate(&pci->dev, "pclk", NULL, 0,
GEM_PCLK_RATE);
if (IS_ERR(plat_data.pclk)) {
err = PTR_ERR(plat_data.pclk);
goto err_pclk_register;
}
- plat_data.hclk = clk_register_fixed_rate(&pdev->dev, "hclk", NULL, 0,
+ plat_data.hclk = clk_register_fixed_rate(&pci->dev, "hclk", NULL, 0,
GEM_HCLK_RATE);
if (IS_ERR(plat_data.hclk)) {
err = PTR_ERR(plat_data.hclk);
@@ -74,24 +74,24 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
/* set up platform device info */
memset(&plat_info, 0, sizeof(plat_info));
- plat_info.parent = &pdev->dev;
- plat_info.fwnode = pdev->dev.fwnode;
+ plat_info.parent = &pci->dev;
+ plat_info.fwnode = pci->dev.fwnode;
plat_info.name = PLAT_DRIVER_NAME;
- plat_info.id = pdev->devfn;
+ plat_info.id = pci->devfn;
plat_info.res = res;
plat_info.num_res = ARRAY_SIZE(res);
plat_info.data = &plat_data;
plat_info.size_data = sizeof(plat_data);
- plat_info.dma_mask = pdev->dma_mask;
+ plat_info.dma_mask = pci->dma_mask;
/* register platform device */
- plat_dev = platform_device_register_full(&plat_info);
- if (IS_ERR(plat_dev)) {
- err = PTR_ERR(plat_dev);
+ pdev = platform_device_register_full(&plat_info);
+ if (IS_ERR(pdev)) {
+ err = PTR_ERR(pdev);
goto err_plat_dev_register;
}
- pci_set_drvdata(pdev, plat_dev);
+ pci_set_drvdata(pci, pdev);
return 0;
@@ -105,14 +105,14 @@ static int macb_probe(struct pci_dev *pdev, const struct pci_device_id *id)
return err;
}
-static void macb_remove(struct pci_dev *pdev)
+static void macb_remove(struct pci_dev *pci)
{
- struct platform_device *plat_dev = pci_get_drvdata(pdev);
- struct macb_platform_data *plat_data = dev_get_platdata(&plat_dev->dev);
+ struct platform_device *pdev = pci_get_drvdata(pci);
+ struct macb_platform_data *plat_data = dev_get_platdata(&pdev->dev);
struct clk *pclk = plat_data->pclk;
struct clk *hclk = plat_data->hclk;
- platform_device_unregister(plat_dev);
+ platform_device_unregister(pdev);
clk_unregister_fixed_rate(pclk);
clk_unregister_fixed_rate(hclk);
}
diff --git a/drivers/net/ethernet/cadence/macb_ptp.c b/drivers/net/ethernet/cadence/macb_ptp.c
index d91f7b1aa39ca..e5195d7dac1d5 100644
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -324,9 +324,9 @@ void gem_ptp_txstamp(struct macb *bp, struct sk_buff *skb,
skb_tstamp_tx(skb, &shhwtstamps);
}
-void gem_ptp_init(struct net_device *dev)
+void gem_ptp_init(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
bp->ptp_clock_info = gem_ptp_caps_template;
@@ -334,7 +334,7 @@ void gem_ptp_init(struct net_device *dev)
bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
gem_ptp_init_timer(bp);
- bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &dev->dev);
+ bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &netdev->dev);
if (IS_ERR(bp->ptp_clock)) {
pr_err("ptp clock register failed: %ld\n",
PTR_ERR(bp->ptp_clock));
@@ -353,9 +353,9 @@ void gem_ptp_init(struct net_device *dev)
GEM_PTP_TIMER_NAME);
}
-void gem_ptp_remove(struct net_device *ndev)
+void gem_ptp_remove(struct net_device *netdev)
{
- struct macb *bp = netdev_priv(ndev);
+ struct macb *bp = netdev_priv(netdev);
if (bp->ptp_clock) {
ptp_clock_unregister(bp->ptp_clock);
@@ -378,10 +378,10 @@ static int gem_ptp_set_ts_mode(struct macb *bp,
return 0;
}
-int gem_get_hwtst(struct net_device *dev,
+int gem_get_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config)
{
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
*tstamp_config = bp->tstamp_config;
if (!macb_dma_ptp(bp))
@@ -402,13 +402,13 @@ static void gem_ptp_set_one_step_sync(struct macb *bp, u8 enable)
macb_writel(bp, NCR, reg_val & ~MACB_BIT(OSSMODE));
}
-int gem_set_hwtst(struct net_device *dev,
+int gem_set_hwtst(struct net_device *netdev,
struct kernel_hwtstamp_config *tstamp_config,
struct netlink_ext_ack *extack)
{
enum macb_bd_control tx_bd_control = TSTAMP_DISABLED;
enum macb_bd_control rx_bd_control = TSTAMP_DISABLED;
- struct macb *bp = netdev_priv(dev);
+ struct macb *bp = netdev_priv(netdev);
u32 regval;
if (!macb_dma_ptp(bp))
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 207/733] net: macb: exclude software FCS from TX byte statistics
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (205 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 206/733] net: macb: unify device pointer naming convention Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 208/733] net/rds: use wq_has_sleeper() in release_in_xmit() Greg Kroah-Hartman
` (537 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolai Buchwitz <nb@tipi-net.de>
[ Upstream commit d85f521a9afb786b1d95bbcb218d3afdf3fe73ab ]
Frames for which macb_pad_and_fcs() supplies the FCS have four FCS
bytes appended, and TX completion then accounts the grown skb->len.
tx_bytes is defined to exclude the FCS, so these frames are reported
four bytes too large.
Track only the number of FCS bytes appended in software, 0 or
ETH_FCS_LEN, and subtract that from skb->len at completion. skb->len
already reflects the padded length by then, so there is nothing else
to store. macb_pad_and_fcs() already returns 0 on every non-error
path. Return the FCS length from there instead, rather than
recomputing the same check in the caller. BQL stays on the padded
skb->len that netdev_tx_sent_queue() saw.
Fixes: 653e92a9175e ("net: macb: add support for padding and fcs computation")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260831113128.1678674-1-nb@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb.h | 3 +++
drivers/net/ethernet/cadence/macb_main.c | 21 +++++++++++++--------
2 files changed, 16 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.h b/drivers/net/ethernet/cadence/macb.h
index 9857df5b57f09..f8bff3e71b682 100644
--- a/drivers/net/ethernet/cadence/macb.h
+++ b/drivers/net/ethernet/cadence/macb.h
@@ -974,6 +974,8 @@ struct macb_dma_desc_ptp {
* of the frame
* @mapping: DMA address of the skb's fragment buffer
* @size: size of the DMA mapped buffer
+ * @fcs_len: FCS bytes appended in software, 0 or ETH_FCS_LEN, only
+ * set for the last buffer of the frame
* @mapped_as_page: true when buffer was mapped with skb_frag_dma_map(),
* false when buffer was mapped with dma_map_single()
*/
@@ -981,6 +983,7 @@ struct macb_tx_skb {
struct sk_buff *skb;
dma_addr_t mapping;
size_t size;
+ u8 fcs_len;
bool mapped_as_page;
};
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 02d10490b8adb..05eda2545597b 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1323,8 +1323,8 @@ static void macb_tx_error_task(struct work_struct *work)
bp->netdev->stats.tx_packets++;
queue->stats.tx_packets++;
packets++;
- bp->netdev->stats.tx_bytes += skb->len;
- queue->stats.tx_bytes += skb->len;
+ bp->netdev->stats.tx_bytes += skb->len - tx_skb->fcs_len;
+ queue->stats.tx_bytes += skb->len - tx_skb->fcs_len;
bytes += skb->len;
}
} else {
@@ -1451,8 +1451,8 @@ static int macb_tx_complete(struct macb_queue *queue, int budget)
skb->data);
bp->netdev->stats.tx_packets++;
queue->stats.tx_packets++;
- bp->netdev->stats.tx_bytes += skb->len;
- queue->stats.tx_bytes += skb->len;
+ bp->netdev->stats.tx_bytes += skb->len - tx_skb->fcs_len;
+ queue->stats.tx_bytes += skb->len - tx_skb->fcs_len;
packets++;
bytes += skb->len;
}
@@ -2200,7 +2200,8 @@ static void macb_poll_controller(struct net_device *netdev)
static unsigned int macb_tx_map(struct macb *bp,
struct macb_queue *queue,
struct sk_buff *skb,
- unsigned int hdrlen)
+ unsigned int hdrlen,
+ u8 fcs_len)
{
unsigned int f, nr_frags = skb_shinfo(skb)->nr_frags;
unsigned int len, i, tx_head = queue->tx_head;
@@ -2285,6 +2286,7 @@ static unsigned int macb_tx_map(struct macb *bp,
/* This is the last buffer of the frame: save socket buffer */
tx_skb->skb = skb;
+ tx_skb->fcs_len = fcs_len;
/* Update TX ring: update buffer descriptors in reverse order
* to avoid race condition
@@ -2418,6 +2420,7 @@ static inline int macb_clear_csum(struct sk_buff *skb)
return 0;
}
+/* Returns a negative errno, or the FCS bytes appended (0 or ETH_FCS_LEN). */
static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *netdev)
{
bool cloned = skb_cloned(*skb) || skb_header_cloned(*skb) ||
@@ -2466,7 +2469,7 @@ static int macb_pad_and_fcs(struct sk_buff **skb, struct net_device *netdev)
skb_put_u8(*skb, (fcs >> 16) & 0xff);
skb_put_u8(*skb, (fcs >> 24) & 0xff);
- return 0;
+ return ETH_FCS_LEN;
}
static netdev_tx_t macb_start_xmit(struct sk_buff *skb,
@@ -2478,6 +2481,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb,
unsigned int desc_cnt, nr_frags, frag_size, f;
unsigned int hdrlen;
unsigned long flags;
+ int fcs_len;
bool is_lso;
netdev_tx_t ret = NETDEV_TX_OK;
@@ -2486,7 +2490,8 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb,
return ret;
}
- if (macb_pad_and_fcs(&skb, netdev)) {
+ fcs_len = macb_pad_and_fcs(&skb, netdev);
+ if (fcs_len < 0) {
dev_kfree_skb_any(skb);
return ret;
}
@@ -2549,7 +2554,7 @@ static netdev_tx_t macb_start_xmit(struct sk_buff *skb,
}
/* Map socket buffer for DMA transfer */
- if (macb_tx_map(bp, queue, skb, hdrlen)) {
+ if (macb_tx_map(bp, queue, skb, hdrlen, fcs_len)) {
dev_kfree_skb_any(skb);
goto unlock;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 208/733] net/rds: use wq_has_sleeper() in release_in_xmit()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (206 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 207/733] net: macb: exclude software FCS from TX byte statistics Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 209/733] net/rds: use clear_bit_unlock() in release_refill() Greg Kroah-Hartman
` (536 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Allison Henderson, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 6d0c8b7073913011459cf968cbbadd341e166bc3 ]
release_in_xmit() clears RDS_IN_XMIT with clear_bit_unlock() and then
checks waitqueue_active() to decide whether anyone needs waking.
clear_bit_unlock() is only a release operation: it orders the
critical section before the bit clear, but does not order the
subsequent plain load of the wait queue head after it. The waiter
side does the mirror image - it adds itself to the wait queue and
then tests the bit. That is the classic store-buffering pattern: the
releasing CPU can read the wait queue as empty while the waiting CPU
still reads the bit as set, so the sleeper is never woken.
The waiters are rds_conn_shutdown() and rds_tcp_reset_callbacks(),
both in uninterruptible wait_event() with no timeout. A lost wake-up
strands the shutdown worker on its single-threaded workqueue until
some other sender releases the bit again - and on a connection that
is being torn down precisely because it failed, there may never be
another sender.
The barrier used to be there: release_in_xmit() did clear_bit()
followed by smp_mb__after_atomic() until commit 1422f28826d2 ("rds:
introduce acquire/release ordering in acquire/release_in_xmit()")
folded both into clear_bit_unlock(), which strengthened the lock
hand-off but silently dropped the full barrier the wake-up check
depends on. The refill counterpart, release_refill() in
net/rds/ib_recv.c, still carries its smp_mb__after_atomic() for
exactly this reason.
Use wq_has_sleeper(), which is waitqueue_active() preceded by the
required full barrier.
Fixes: 1422f28826d2 ("rds: introduce acquire/release ordering in acquire/release_in_xmit()")
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-2-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/send.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/rds/send.c b/net/rds/send.c
index 68be1bf0e0adf..db8bea6d632ec 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -114,8 +114,13 @@ static void release_in_xmit(struct rds_conn_path *cp)
* hot path and finding waiters is very rare. We don't want to walk
* the system-wide hashed waitqueue buckets in the fast path only to
* almost never find waiters.
+ *
+ * wq_has_sleeper() supplies the full barrier that orders the wait
+ * queue read after the bit clear; clear_bit_unlock() alone is only
+ * a release and would let this check read a stale empty queue,
+ * losing the wake-up.
*/
- if (waitqueue_active(&cp->cp_waitq))
+ if (wq_has_sleeper(&cp->cp_waitq))
wake_up_all(&cp->cp_waitq);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 209/733] net/rds: use clear_bit_unlock() in release_refill()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (207 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 208/733] net/rds: use wq_has_sleeper() in release_in_xmit() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 210/733] net/rds: clear cp_flags bits individually in rds_conn_path_reset() Greg Kroah-Hartman
` (535 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Allison Henderson, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 17c4476dbb9c3bfd34193a6c22f2c3da8747134a ]
release_refill() drops the RDS_RECV_REFILL bit with a plain
clear_bit(). clear_bit() has no ordering semantics, and the
smp_mb__after_atomic() that follows it sits on the wrong side for a
lock release: it orders the clear against the waitqueue_active() load
below it, but does nothing to order the refill critical section's ring
and descriptor stores before the clear itself.
That matters once connection teardown owns RDS_RECV_REFILL as a lock
across the transport shutdown and path reset, rather than sampling it
clear, which "net/rds: acquire the fastpath locks in
rds_conn_shutdown()" later in this series arranges: on a weakly
ordered architecture the teardown can win the bit and start the
shutdown and reset while some of the refill's stores are not yet
visible to it. The same gap existed under the sample-based scheme - a
waiter that saw the bit clear had no guarantee it also observed the
refill's stores - but taking the bit as a lock makes the missing
release pairing load-bearing.
Switch to clear_bit_unlock(), which orders the critical section before
the release, and replace the open-coded barrier-plus-waitqueue_active()
with wq_has_sleeper(), whose internal full barrier keeps the
store-buffering guarantee between clearing the bit and checking for
sleepers. This mirrors what "net/rds: use wq_has_sleeper() in
release_in_xmit()" does for RDS_IN_XMIT.
The fast-path acquire side, acquire_refill(), uses test_and_set_bit(),
a full-barrier RMW that pairs with this release. The teardown at this
point in the series still samples the bit, so on its own this change
is release-side hardening; the shutdown-conversion patch named above
makes the teardown acquire the bit with the same RMW, completing the
pairing at the end of the series.
Fixes: 73ce4317bf98 ("RDS: make sure we post recv buffers")
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-3-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/ib_recv.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index 357128d34a546..a6983861eec70 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -363,15 +363,14 @@ static int acquire_refill(struct rds_connection *conn)
static void release_refill(struct rds_connection *conn)
{
- clear_bit(RDS_RECV_REFILL, &conn->c_flags);
- smp_mb__after_atomic();
+ clear_bit_unlock(RDS_RECV_REFILL, &conn->c_flags);
/* We don't use wait_on_bit()/wake_up_bit() because our waking is in a
* hot path and finding waiters is very rare. We don't want to walk
* the system-wide hashed waitqueue buckets in the fast path only to
* almost never find waiters.
*/
- if (waitqueue_active(&conn->c_waitq))
+ if (wq_has_sleeper(&conn->c_waitq))
wake_up_all(&conn->c_waitq);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 210/733] net/rds: clear cp_flags bits individually in rds_conn_path_reset()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (208 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 209/733] net/rds: use clear_bit_unlock() in release_refill() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 211/733] net/rds: tcp: dont force RDS_CONN_RESETTING over a concurrent shutdown Greg Kroah-Hartman
` (534 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Allison Henderson, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 103c4b13c4f50322910078d1c02f29334a574122 ]
rds_conn_path_reset() wipes the whole flag word with a plain
cp->cp_flags = 0 store. Every other accessor of that word uses
atomic bitops, and some of them can run concurrently with the reset:
RDS_LL_SEND_FULL is set from rds_send_xmit() and cleared from the
transport completion paths, neither of which holds anything that
excludes the shutdown worker. A plain store racing an atomic
read-modify-write on the same word is a data race, and whichever
side loses has its update silently discarded.
Clear the two bits the reset is actually responsible for instead.
RDS_IN_XMIT and RDS_RECV_REFILL need no store at all here: they
belong to the caller, rds_conn_shutdown(), which waits for both to be
clear before calling the transport shutdown and this reset.
This also gives every bit in cp_flags a single well-defined writer
discipline, which the following patches rely on when they turn
RDS_IN_XMIT and RDS_RECV_REFILL into bit locks held across the
teardown: a blanket store mid-teardown would destroy lock ownership
that an atomic clear preserves.
Oracle UEK carries the same conversion ("net/rds: Preserve essential
connection state flags"), motivated by its asynchronous shutdown
state machine, whose progress and destroy flags must survive the
reset. UEK's variant also clears RDS_IN_XMIT and RDS_RECV_REFILL
because there the reset runs as the final step of a teardown that
owns both bits, making those clears its unlock. Upstream that
release belongs in rds_conn_shutdown(): once a later patch in this
series turns the two bits into locks held across the teardown, ending
ownership needs release semantics and a wake-up that a plain clear
inside the reset would not provide.
Based on Oracle UEK commit "net/rds: Preserve essential connection
state flags" by Gerd Rausch.
Fixes: 00e0f34c6166 ("RDS: Connection handling")
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-4-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/connection.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 7c8ab8e973e1b..46ac72088f842 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -120,7 +120,15 @@ static void rds_conn_path_reset(struct rds_conn_path *cp)
rds_stats_inc(s_conn_reset);
rds_send_path_reset(cp);
- cp->cp_flags = 0;
+
+ /* Clear the bits the reset is responsible for individually: a
+ * blanket cp_flags = 0 is a plain store that can clobber a
+ * concurrent atomic read-modify-write on the same word.
+ * RDS_IN_XMIT and RDS_RECV_REFILL belong to the caller,
+ * rds_conn_shutdown(), and are left alone here.
+ */
+ clear_bit(RDS_LL_SEND_FULL, &cp->cp_flags);
+ clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
/* Do not clear next_rx_seq here, else we cannot distinguish
* retransmitted packets from new packets, and will hand all
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 211/733] net/rds: tcp: dont force RDS_CONN_RESETTING over a concurrent shutdown
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (209 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 210/733] net/rds: clear cp_flags bits individually in rds_conn_path_reset() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 212/733] net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks() Greg Kroah-Hartman
` (533 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Gerd Rausch, Allison Henderson,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gerd Rausch <gerd.rausch@oracle.com>
[ Upstream commit e8e60d74fec49ccae2aea9b04a6eb162feb8d9af ]
rds_tcp_reset_callbacks() resolves a duelling SYN by storing
RDS_CONN_RESETTING into cp_state unconditionally. Nothing serializes
that store against the shutdown path: rds_tcp_accept_one() checks
for RDS_CONN_CONNECTING or RDS_CONN_ERROR under t_conn_path_lock, but
neither rds_conn_path_drop(), which forces RDS_CONN_ERROR, nor
rds_conn_shutdown(), which moves the path to RDS_CONN_DISCONNECTING
under cp_cm_lock, takes that lock. The store can therefore land on
top of a shutdown that is already in progress, or that gets queued
right after the accept-side check.
When it does, the shutdown worker's final DISCONNECTING -> DOWN
transition fails and the path goes through rds_conn_path_error() and
a second drop/shutdown cycle instead of a clean reconnect, tearing
down the socket the accept path has just installed. Before commit
ad22d24be635 ("net/rds: No shortcut out of RDS_CONN_ERROR") a path
found in RDS_CONN_RESETTING even made rds_conn_shutdown() bail out
altogether.
Make the transition conditional: move CONNECTING -> RESETTING (or
stay in RESETTING from an earlier duel), and drop the path in any
other state. The drop has side effects of its own: it replaces the
shutdown's RDS_CONN_DISCONNECTING (or RDS_CONN_ERROR) with
RDS_CONN_ERROR and queues one more cp_down_w run. The difference is
that rds_conn_shutdown() accepts RDS_CONN_ERROR in its final
transition to RDS_CONN_DOWN, so the shutdown in flight completes
normally instead of through rds_conn_path_error(); the extra
down-work pass then finds the path already down and falls through to
the reconnect check, or catches a reconnect that has already started
and restarts it. The accept path still installs the new socket,
rds_connect_path_complete() then fails its RESETTING -> UP transition
and drops it: the raced socket ends up torn down as it does today.
The comment at that call site, which promised that
rds_connect_path_complete() marks the path RDS_CONN_UP, is updated to
name this outcome as well.
The state can change again between the failed transitions and the
drop. That is inherent to rds_conn_path_drop(), which the socket
state-change callbacks also call unconditionally, and costs at most
one extra drop/reconnect cycle.
Based on Oracle UEK commit "net/rds: Don't force state
RDS_CONN_RESETTING" by Gerd Rausch.
Fixes: 9c79440e2c5e ("RDS: TCP: fix race windows in send-path quiescence by rds_tcp_accept_one()")
Signed-off-by: Gerd Rausch <gerd.rausch@oracle.com>
[achender: port to net-next: use the two-argument
rds_conn_path_transition()/rds_conn_path_drop() and rewrite the
changelog for the upstream shutdown path]
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-5-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/tcp.c | 17 +++++++++++++++--
net/rds/tcp_listen.c | 6 +++++-
2 files changed, 20 insertions(+), 3 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index b263634ac750d..ad14217867a4d 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -150,9 +150,22 @@ void rds_tcp_reset_callbacks(struct socket *sock,
* end up deadlocking with tcp_sendmsg(), and the RDS_IN_XMIT
* would not get set. As a result, we set c_state to
* RDS_CONN_RESETTTING, to ensure that rds_tcp_state_change
- * cannot mark rds_conn_path_up() in the window before lock_sock()
+ * cannot mark rds_conn_path_up() in the window before lock_sock().
+ *
+ * Only make that transition if the path is still connecting
+ * (or already resetting from an earlier duel). A path in any
+ * other state - typically RDS_CONN_DISCONNECTING or
+ * RDS_CONN_ERROR with a shutdown in flight - is dropped
+ * instead. That still replaces its state, with RDS_CONN_ERROR,
+ * and queues one more shutdown pass, but rds_conn_shutdown()
+ * accepts RDS_CONN_ERROR in its final transition to
+ * RDS_CONN_DOWN, so the shutdown in flight completes normally.
*/
- atomic_set(&cp->cp_state, RDS_CONN_RESETTING);
+ if (!rds_conn_path_transition(cp, RDS_CONN_CONNECTING,
+ RDS_CONN_RESETTING) &&
+ !rds_conn_path_transition(cp, RDS_CONN_RESETTING,
+ RDS_CONN_RESETTING))
+ rds_conn_path_drop(cp, 0);
wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags));
/* reset receive side state for rds_tcp_data_recv() for osock */
cancel_delayed_work_sync(&cp->cp_send_w);
diff --git a/net/rds/tcp_listen.c b/net/rds/tcp_listen.c
index a3db9b057084d..13fa60c1985bb 100644
--- a/net/rds/tcp_listen.c
+++ b/net/rds/tcp_listen.c
@@ -295,7 +295,11 @@ int rds_tcp_accept_one(struct rds_tcp_net *rtn)
if (rs_tcp->t_sock) {
/* Duelling SYN has been handled in rds_tcp_accept_one() */
rds_tcp_reset_callbacks(new_sock, cp);
- /* rds_connect_path_complete() marks RDS_CONN_UP */
+ /* rds_connect_path_complete() marks RDS_CONN_UP, or,
+ * if a concurrent shutdown won the duel, drops the
+ * path again and the pass that drop queues reaps the
+ * socket installed above.
+ */
rds_connect_path_complete(cp, RDS_CONN_RESETTING);
} else {
rds_tcp_set_callbacks(new_sock, cp);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 212/733] net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (210 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 211/733] net/rds: tcp: dont force RDS_CONN_RESETTING over a concurrent shutdown Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 213/733] net/rds: acquire the fastpath locks in rds_conn_shutdown() Greg Kroah-Hartman
` (532 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Allison Henderson, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 02c5f9dc2efd823e061954d564ce00bacd1bebeb ]
rds_tcp_reset_callbacks() quiesces the transmit path by setting the
path state to RDS_CONN_RESETTING and then waiting for RDS_IN_XMIT to
be sampled clear before swapping the underlying socket and calling
rds_send_path_reset().
Sampling the bit clear is not the same as owning it: rds_send_xmit()
can re-acquire RDS_IN_XMIT right after the wait_event() returns. Its
state recheck after taking the lock is a store-buffering pattern (the
resetter writes the state and reads the bit, the sender writes the
bit and reads the state) and acquire_in_xmit() is only an acquire
operation, so on weakly ordered architectures both sides can miss
each other's write and the transmit path then runs concurrently with
rds_send_path_reset() rewriting cp_xmit_* state - which is exactly
what the comment above rds_send_path_reset() tells its callers to
prevent.
Take the lock instead, hold it across the socket swap and
rds_send_path_reset(), and release it with a wake-up at the end. The
lock-ordering constraint documented above the wait still holds: the
lock is acquired before lock_sock(), so a sender inside tcp_sendmsg()
can never be waited on while we hold the socket lock.
Two details of the old code go away with the same change:
- t_sock is now read only after the lock is acquired. The old code
cached it before waiting; the teardown in rds_conn_shutdown()
releases that socket and clears t_sock, so a pointer cached before
the wait can be stale by the time the accept path resumes. Reading
it under RDS_IN_XMIT is what makes the exclusion complete once the
teardown owns the same lock, which the next patch arranges; until
then the teardown still only samples the bit, and the two paths
remain as exposed to each other as they are today.
- The old !osock early path called rds_send_path_reset() with no
serialization at all. It now runs under the lock like the normal
path. The conditional RDS_CONN_RESETTING transition of the
previous patch happens before the socket check either way: a path
found without a socket is either still connecting (its reconnect
worker blocked on t_conn_path_lock) and legitimately goes
RESETTING -> UP on the new socket, or it has been torn down
meanwhile and is dropped.
The in-function comment describing the old wait-based quiesce is
rewritten to describe the lock-based one, and the stale block comment
above the function (which still described a return value and an
incomplete list of t_sock writers) is refreshed to name all four
writers - the connect, accept, teardown and swap paths - and what
serializes each of them.
Fixes: 335b48d980f6 ("RDS: TCP: Add/use rds_tcp_reset_callbacks to reset tcp socket safely")
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-6-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/tcp.c | 70 +++++++++++++++++++++++++++++++++------------------
1 file changed, 45 insertions(+), 25 deletions(-)
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index ad14217867a4d..f4c83e3683905 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -115,42 +115,48 @@ void rds_tcp_restore_callbacks(struct socket *sock,
}
/*
- * rds_tcp_reset_callbacks() switches the to the new sock and
- * returns the existing tc->t_sock.
+ * rds_tcp_reset_callbacks() switches a path to a new socket and
+ * releases the old one it finds in tc->t_sock, resolving a duelling
+ * SYN.
*
- * The only functions that set tc->t_sock are rds_tcp_set_callbacks
- * and rds_tcp_reset_callbacks. Send and receive trust that
- * it is set. The absence of RDS_CONN_UP bit protects those paths
- * from being called while it isn't set.
+ * tc->t_sock is set by rds_tcp_set_callbacks() and cleared by
+ * rds_tcp_restore_callbacks(). Four paths write it: the active
+ * connect in rds_tcp_conn_path_connect(), which sets it and clears it
+ * again on failure; the accept path in rds_tcp_accept_one(), which
+ * sets it for a path with no socket yet; the teardown in
+ * rds_tcp_conn_path_shutdown(), which clears it; and the swap done
+ * here, which does both. The connect and accept paths are serialized
+ * against each other by t_conn_path_lock. Send and receive trust
+ * that it is set: the absence of RDS_CONN_UP protects those paths
+ * from being called while it isn't, and the swap done here runs under
+ * RDS_IN_XMIT so that it cannot interleave with a sender already
+ * inside rds_send_xmit().
*/
void rds_tcp_reset_callbacks(struct socket *sock,
struct rds_conn_path *cp)
{
struct rds_tcp_connection *tc = cp->cp_transport_data;
- struct socket *osock = tc->t_sock;
-
- if (!osock)
- goto newsock;
+ struct socket *osock;
/* Need to resolve a duelling SYN between peers.
* We have an outstanding SYN to this peer, which may
* potentially have transitioned to the RDS_CONN_UP state,
* so we must quiesce any send threads before resetting
- * cp_transport_data. We quiesce these threads by setting
- * cp_state to something other than RDS_CONN_UP, and then
- * waiting for any existing threads in rds_send_xmit to
- * complete release_in_xmit(). (Subsequent threads entering
- * rds_send_xmit() will bail on !rds_conn_up().
+ * cp_transport_data. Setting cp_state to something other
+ * than RDS_CONN_UP stops new senders, and owning RDS_IN_XMIT
+ * excludes any thread already inside rds_send_xmit() for the
+ * whole socket swap and the rds_send_path_reset() below.
*
- * However an incoming syn-ack at this point would end up
- * marking the conn as RDS_CONN_UP, and would again permit
- * rds_send_xmi() threads through, so ideally we would
- * synchronize on RDS_CONN_UP after lock_sock(), but cannot
- * do that: waiting on !RDS_IN_XMIT after lock_sock() may
- * end up deadlocking with tcp_sendmsg(), and the RDS_IN_XMIT
- * would not get set. As a result, we set c_state to
- * RDS_CONN_RESETTTING, to ensure that rds_tcp_state_change
- * cannot mark rds_conn_path_up() in the window before lock_sock().
+ * An incoming syn-ack at this point would end up marking the
+ * conn as RDS_CONN_UP, and would again permit rds_send_xmit()
+ * threads through, so ideally we would synchronize on
+ * RDS_CONN_UP after lock_sock(), but cannot do that: acquiring
+ * RDS_IN_XMIT after lock_sock() may end up deadlocking with
+ * tcp_sendmsg(), which takes the socket lock while holding
+ * RDS_IN_XMIT. As a result, we set c_state to
+ * RDS_CONN_RESETTING, to ensure that rds_tcp_state_change
+ * cannot mark rds_conn_path_up() in the window before
+ * lock_sock().
*
* Only make that transition if the path is still connecting
* (or already resetting from an earlier duel). A path in any
@@ -166,7 +172,18 @@ void rds_tcp_reset_callbacks(struct socket *sock,
!rds_conn_path_transition(cp, RDS_CONN_RESETTING,
RDS_CONN_RESETTING))
rds_conn_path_drop(cp, 0);
- wait_event(cp->cp_waitq, !test_bit(RDS_IN_XMIT, &cp->cp_flags));
+ wait_event(cp->cp_waitq,
+ !test_and_set_bit_lock(RDS_IN_XMIT, &cp->cp_flags));
+
+ /* Read t_sock only while owning RDS_IN_XMIT, never before the
+ * wait: the teardown in rds_conn_shutdown() releases the old
+ * socket and clears t_sock, so a pointer sampled earlier can
+ * be stale by the time we wake up.
+ */
+ osock = tc->t_sock;
+ if (!osock)
+ goto newsock;
+
/* reset receive side state for rds_tcp_data_recv() for osock */
cancel_delayed_work_sync(&cp->cp_send_w);
cancel_delayed_work_sync(&cp->cp_recv_w);
@@ -185,6 +202,9 @@ void rds_tcp_reset_callbacks(struct socket *sock,
lock_sock(sock->sk);
rds_tcp_set_callbacks(sock, cp);
release_sock(sock->sk);
+
+ clear_bit_unlock(RDS_IN_XMIT, &cp->cp_flags);
+ wake_up_all(&cp->cp_waitq);
}
/* Add tc to rds_tcp_tc_list and set tc->t_sock. See comments
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 213/733] net/rds: acquire the fastpath locks in rds_conn_shutdown()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (211 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 212/733] net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 214/733] net/rds: dont let rds_conn_shutdown() consume a concurrent drop Greg Kroah-Hartman
` (531 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Håkon Bugge, Allison Henderson,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Håkon Bugge <haakon.bugge@oracle.com>
[ Upstream commit 813f3582ac7ae9f60f917937d54660e0952d5f2d ]
rds_conn_shutdown() quiesces the transmit and receive-refill paths by
waiting for RDS_IN_XMIT and RDS_RECV_REFILL to be sampled clear, and
then runs the transport shutdown and rds_conn_path_reset(). Sampling
the bits clear is not the same as owning them: the moment after the
wait_event() returns, rds_send_xmit() can re-acquire RDS_IN_XMIT (or
rds_ib_recv_refill() can re-acquire RDS_RECV_REFILL) and run
concurrently with the teardown.
The sender does recheck the connection state after taking the lock,
but that recheck is a classic store-buffering pattern: teardown writes
the state and reads the bit while the sender writes the bit and reads
the state. acquire_in_xmit() is only an acquire operation, so on
weakly ordered architectures both sides can miss each other's write,
and the transmit path then runs while the transport zeroes its rings
(e.g. rds_ib_ring_init()) and rds_send_path_reset() rewrites the
transmit state under it.
Oracle UEK fixed the same class of crashes - a 14-year tail of
BUG_ON()s in rds_ib_sub_signaled(), unexpected op-codes and NULL
dereferences in rds_ib_send_cqe_handler() during failover testing -
by making the teardown path *acquire* the fastpath bit locks instead
of testing them ("rds: Make sure transmit path and connection
tear-down does not run concurrently"). Ownership of a single word is
decided by RMW atomicity, so no cross-variable ordering is needed.
Do the same here: take both locks before calling the transport
shutdown, hold them across rds_conn_path_reset(), and release them
explicitly with a wake-up afterwards. Both are released with
clear_bit_unlock(), so that the ring re-initialization done by the
transport shutdown and the transmit state rewritten by
rds_send_path_reset() are ordered before either bit is seen clear by
the next acquire_in_xmit() or acquire_refill().
The fastpath users of these bits - rds_send_xmit() and
rds_ib_recv_refill() - are trylock style and back off while teardown
owns the locks, so no new lock dependency is introduced for them.
rds_tcp_reset_callbacks() is different: since the previous patch it
acquires RDS_IN_XMIT as well, and it blocks doing so, so its wait now
spans the teardown instead of at most one send batch. That waiter
runs from rds_tcp_accept_one() on the single-threaded krdsd workqueue
and holds rds_tcp_accept_lock and t_conn_path_lock while it waits, so
a duelling SYN accepted while its path is being torn down parks
accept processing for the duration of the teardown - for TCP bounded
by the (up to 5 s) drain loop in rds_tcp_conn_path_shutdown(). An IB
path's drain in rds_ib_conn_path_shutdown() has no round cap, but no
blocking waiter either: rds_tcp_reset_callbacks() is the only blocking
acquirer of these bits and waits only on its own TCP path, and the
fastpaths are trylock-and-back-off on both transports, so a long IB
drain lengthens only that path's own quiesce. The
window is narrow: the accept-side state check has to pass before the
teardown moves the path to RDS_CONN_DISCONNECTING.
Because krdsd is a single global workqueue, everything else queued
there - accept processing for other connections and network
namespaces, and the flush_workqueue(rds_wq) in rds_tcp_listen_stop()
during namespace teardown - waits behind the parked accept worker for
that time. It cannot deadlock, although the waits do point at each
other: the teardown blocks until the bit's holder releases it, and
the holder may be that krdsd accept worker. The holder finishes
without needing anything the teardown owns: the sync cancels
rds_tcp_reset_callbacks() issues target cp_send_w and cp_recv_w on
the path's ordered cp_wq, whose only execution slot is occupied by
the blocked cp_down_w itself, so they are pending at most and cancel
without flushing - a reliance on cp_wq being ordered that is now
noted next to those cancels (on the allocation-failure fallback where
a path shares rds_wq, the work items simply serialize).
Nor is the blocking wait itself new: rds_tcp_reset_callbacks() has
waited on RDS_IN_XMIT from the krdsd work item since
commit 335b48d980f6 ("RDS: TCP: Add/use rds_tcp_reset_callbacks to
reset tcp socket safely"); this patch stretches its worst case from
a sender's batch to the teardown's drain. The alternative to parking
is the accept path racing the teardown, which is what these patches
close; making the teardown itself non-blocking is a separate item.
One observable side effect: the SENDING flag reported by rds-info has
always mirrored RDS_IN_XMIT, so it now also covers the window where
teardown owns the bit.
The comments that describe the old sample-based handshake or name
rds_send_xmit() as the only other holder of these bits - in
rds_send_xmit(), above rds_conn_path_reset(), in rds_ib_recv_refill()
and in rds_tcp_reset_callbacks() - are updated to match.
For anyone backporting this patch standalone: it depends on
"net/rds: clear cp_flags bits individually in rds_conn_path_reset()"
and "net/rds: acquire RDS_IN_XMIT in rds_tcp_reset_callbacks()"
earlier in this series. Without the former, the blanket cp_flags
clear in rds_conn_path_reset() would drop both held bits in the middle
of the teardown; without the latter, rds_tcp_reset_callbacks() would
still sample t_sock without owning RDS_IN_XMIT. "net/rds: use
clear_bit_unlock() in release_refill()" is needed for the refill
side's release to pair with the acquire added here, and the follow-up
"net/rds: don't let rds_conn_shutdown() consume a concurrent drop"
completes the teardown-state handling for the waiter this patch
parks; a backport should carry all four.
Fixes: 0f4b1c7e89e6 ("rds: fix rds_send_xmit() serialization")
Signed-off-by: Håkon Bugge <haakon.bugge@oracle.com>
[achender: reimplement for net-next shutdown path: acquire the existing
RDS_IN_XMIT/RDS_RECV_REFILL bit locks in rds_conn_shutdown() and release
after teardown; update comments and commit message]
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-7-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/connection.c | 40 ++++++++++++++++++++++++++++++++--------
net/rds/ib_recv.c | 4 +++-
net/rds/send.c | 7 +++++--
net/rds/tcp.c | 19 +++++++++++++++----
4 files changed, 55 insertions(+), 15 deletions(-)
diff --git a/net/rds/connection.c b/net/rds/connection.c
index 46ac72088f842..fbbac55a0e818 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -106,10 +106,12 @@ static struct rds_connection *rds_conn_lookup(struct net *net,
}
/*
- * This is called by transports as they're bringing down a connection.
- * It clears partial message state so that the transport can start sending
- * and receiving over this connection again in the future. It is up to
- * the transport to have serialized this call with its send and recv.
+ * This is called by rds_conn_shutdown() once the transport has brought
+ * a path down. It clears partial message state so that the transport
+ * can start sending and receiving over this path again in the future.
+ * The caller owns RDS_IN_XMIT and RDS_RECV_REFILL across this call,
+ * which is what serializes it against the send and receive-refill
+ * paths.
*/
static void rds_conn_path_reset(struct rds_conn_path *cp)
{
@@ -124,8 +126,9 @@ static void rds_conn_path_reset(struct rds_conn_path *cp)
/* Clear the bits the reset is responsible for individually: a
* blanket cp_flags = 0 is a plain store that can clobber a
* concurrent atomic read-modify-write on the same word.
- * RDS_IN_XMIT and RDS_RECV_REFILL belong to the caller,
- * rds_conn_shutdown(), and are left alone here.
+ * RDS_IN_XMIT and RDS_RECV_REFILL are held as locks by the
+ * caller, rds_conn_shutdown(), which releases them once the
+ * teardown is complete.
*/
clear_bit(RDS_LL_SEND_FULL, &cp->cp_flags);
clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
@@ -414,14 +417,35 @@ void rds_conn_shutdown(struct rds_conn_path *cp)
}
mutex_unlock(&cp->cp_cm_lock);
+ /* Quiesce the transmit and receive-refill paths by
+ * acquiring their bit locks, not merely waiting for
+ * them to be released: with a plain wait, either path
+ * can re-take its lock the instant after we sample it
+ * clear and then run concurrently with the transport
+ * shutdown and the path reset below. Holding both
+ * locks across the teardown makes that structurally
+ * impossible.
+ */
wait_event(cp->cp_waitq,
- !test_bit(RDS_IN_XMIT, &cp->cp_flags));
+ !test_and_set_bit_lock(RDS_IN_XMIT, &cp->cp_flags));
wait_event(cp->cp_waitq,
- !test_bit(RDS_RECV_REFILL, &cp->cp_flags));
+ !test_and_set_bit(RDS_RECV_REFILL, &cp->cp_flags));
conn->c_trans->conn_path_shutdown(cp);
rds_conn_path_reset(cp);
+ /* Release the two locks and wake any waiter (e.g.
+ * rds_tcp_reset_callbacks()) that blocked on them while
+ * we held them. The unlock orders the transport's ring
+ * re-initialization and the path reset above before
+ * either bit is seen clear. rds_conn_path_reset() leaves
+ * both bits alone: ownership ends here, not inside the
+ * reset.
+ */
+ clear_bit_unlock(RDS_IN_XMIT, &cp->cp_flags);
+ clear_bit_unlock(RDS_RECV_REFILL, &cp->cp_flags);
+ wake_up_all(&cp->cp_waitq);
+
if (!rds_conn_path_transition(cp, RDS_CONN_DISCONNECTING,
RDS_CONN_DOWN) &&
!rds_conn_path_transition(cp, RDS_CONN_ERROR,
diff --git a/net/rds/ib_recv.c b/net/rds/ib_recv.c
index a6983861eec70..bd6cb3ffaa571 100644
--- a/net/rds/ib_recv.c
+++ b/net/rds/ib_recv.c
@@ -391,7 +391,9 @@ void rds_ib_recv_refill(struct rds_connection *conn, int prefill, gfp_t gfp)
/* the goal here is to just make sure that someone, somewhere
* is posting buffers. If we can't get the refill lock,
- * let them do their thing
+ * let them do their thing. The holder may also be
+ * rds_conn_shutdown() tearing the path down, in which case
+ * there is nothing to post.
*/
if (!acquire_refill(conn))
return;
diff --git a/net/rds/send.c b/net/rds/send.c
index db8bea6d632ec..ffb3dd9998380 100644
--- a/net/rds/send.c
+++ b/net/rds/send.c
@@ -236,8 +236,11 @@ int rds_send_xmit(struct rds_conn_path *cp)
WRITE_ONCE(cp->cp_send_gen, send_gen);
/*
- * rds_conn_shutdown() sets the conn state and then tests RDS_IN_XMIT,
- * we do the opposite to avoid races.
+ * rds_conn_shutdown() sets the conn state and then acquires
+ * RDS_IN_XMIT; we take the lock first and then check the state.
+ * Ownership is decided by the atomic RMW on the cp_flags word:
+ * if the teardown won the bit we back off here, and if we won
+ * it the teardown waits until we release it.
*/
if (!rds_conn_path_up(cp)) {
release_in_xmit(cp);
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index f4c83e3683905..69c6d3145b5ab 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -144,8 +144,10 @@ void rds_tcp_reset_callbacks(struct socket *sock,
* so we must quiesce any send threads before resetting
* cp_transport_data. Setting cp_state to something other
* than RDS_CONN_UP stops new senders, and owning RDS_IN_XMIT
- * excludes any thread already inside rds_send_xmit() for the
- * whole socket swap and the rds_send_path_reset() below.
+ * excludes any thread already inside rds_send_xmit() - or a
+ * teardown in rds_conn_shutdown(), which holds the same lock
+ * for the duration of the transport shutdown - for the whole
+ * socket swap and the rds_send_path_reset() below.
*
* An incoming syn-ack at this point would end up marking the
* conn as RDS_CONN_UP, and would again permit rds_send_xmit()
@@ -178,13 +180,22 @@ void rds_tcp_reset_callbacks(struct socket *sock,
/* Read t_sock only while owning RDS_IN_XMIT, never before the
* wait: the teardown in rds_conn_shutdown() releases the old
* socket and clears t_sock, so a pointer sampled earlier can
- * be stale by the time we wake up.
+ * be stale by the time we wake up. The teardown holds the
+ * same lock while it does so, so what we read here cannot
+ * change under us until we release it.
*/
osock = tc->t_sock;
if (!osock)
goto newsock;
- /* reset receive side state for rds_tcp_data_recv() for osock */
+ /* reset receive side state for rds_tcp_data_recv() for osock.
+ *
+ * The sync cancels while owning RDS_IN_XMIT rely on cp_wq
+ * being ordered: a teardown blocked on the bit occupies
+ * cp_wq's only execution slot, so cp_send_w and cp_recv_w are
+ * pending at most and the cancels never flush. Nothing here
+ * may flush or wait on cp_wq itself.
+ */
cancel_delayed_work_sync(&cp->cp_send_w);
cancel_delayed_work_sync(&cp->cp_recv_w);
lock_sock(osock->sk);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 214/733] net/rds: dont let rds_conn_shutdown() consume a concurrent drop
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (212 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 213/733] net/rds: acquire the fastpath locks in rds_conn_shutdown() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 215/733] powerpc: Dont drop _TIF_RESTOREALL on syscall restart Greg Kroah-Hartman
` (530 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Allison Henderson, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Allison Henderson <achender@kernel.org>
[ Upstream commit 260c6308fe2e19ad519389d44d582e292aecc3af ]
rds_conn_shutdown() finishes by moving the path from
RDS_CONN_DISCONNECTING to RDS_CONN_DOWN, and also accepts
RDS_CONN_ERROR as the starting state of that final transition, so that
a FIN processed in softirq context during the teardown does not derail
the shutdown into a noisy error path.
But consuming that RDS_CONN_ERROR also consumes the shutdown pass that
came with it: rds_conn_path_drop() sets RDS_CONN_ERROR and then queues
cp_down_w, and a pass that starts on a path already in RDS_CONN_DOWN
is a no-op. For the FIN case that is harmless - the socket the FIN
arrived on is the very socket the teardown just released. It is not
harmless for a dropper that attached something to the path first.
rds_tcp_accept_one() is such a dropper. Its path claim in
rds_tcp_accept_one_path() transitions RDS_CONN_DOWN ->
RDS_CONN_CONNECTING, and a concurrent drop - a FIN on a previous
socket in softirq context, an administrative reset - can put the path
into RDS_CONN_ERROR between that claim and the state check that
follows, which accepts RDS_CONN_ERROR. The accept then installs the
freshly accepted socket with rds_tcp_set_callbacks() while the queued
teardown - which sampled tc->t_sock before this socket existed - is
still running. rds_connect_path_complete() fails its transition to
RDS_CONN_UP and drops the path again, queueing the pass that should
reap the socket it just installed. If the in-flight shutdown's final
transition consumes that drop's RDS_CONN_ERROR, the queued pass finds
the path in RDS_CONN_DOWN and does nothing. The installed socket is
never torn down: it sits established with its callbacks armed and its
rds_tcp_connection on rds_tcp_tc_list, the peer sees a connection that
nothing ever reads, and the path is wedged in RDS_CONN_DOWN until some
later event drops it again. Reproduced with widened race windows as
an ever-growing receive queue on a socket owned by a path stuck in
RDS_CONN_DOWN, with the peer's send path wedged behind it.
Make the final transition only DISCONNECTING -> DOWN. If it fails
because the path is in RDS_CONN_ERROR, a drop raced the teardown:
cancel the reconnect timer and clear RDS_RECONNECT_PENDING - the one
piece of the skipped tail that must not be left behind - and return,
letting the pass the drop queued finish the job: it tears down
whatever attached to the path in the meantime, completes the
transition to RDS_CONN_DOWN, and re-arms the reconnect from its own
tail.
The timer quiesce in that branch matters because the racing drop does
not always queue that pass: rds_conn_path_drop() returns without
queueing when a destroy is pending - exactly the situation during a
netns teardown or module unload, when a FIN on the dying socket is
processed while rds_conn_path_destroy() flushes cp_down_w. If the
flushed pass is the one that takes this return, no later pass exists,
and rds_conn_path_destroy() would find cp_conn_w still armed
(WARN_ON) and then free a path whose reconnect timer can still fire.
With the cancel in the branch, every exit of a shutdown pass leaves
the timer quiesced no matter which pass completes the transition.
The FIN case keeps making progress, one pass later and still without
noisy logging. Any other state keeps today's rds_conn_path_error()
handling; no current cp_state writer can leave a DISCONNECTING path
in anything but RDS_CONN_ERROR (every other writer is a cmpxchg from
a non-DISCONNECTING state), so that branch is defensive.
On kernels without the preceding patches the same hazard exists with
the sample-based quiesce; the fix applies there equally.
Fixes: e97656d03ca0 ("rds: tcp: allow progress of rds_conn_shutdown if the rds_connection is marked ERROR by an intervening FIN")
Signed-off-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/20260828223921.202913-8-achender@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/connection.c | 43 ++++++++++++++++++++++++++++++++-----------
net/rds/tcp.c | 9 ++++++---
2 files changed, 38 insertions(+), 14 deletions(-)
diff --git a/net/rds/connection.c b/net/rds/connection.c
index fbbac55a0e818..b6c4beb50eaf0 100644
--- a/net/rds/connection.c
+++ b/net/rds/connection.c
@@ -447,19 +447,40 @@ void rds_conn_shutdown(struct rds_conn_path *cp)
wake_up_all(&cp->cp_waitq);
if (!rds_conn_path_transition(cp, RDS_CONN_DISCONNECTING,
- RDS_CONN_DOWN) &&
- !rds_conn_path_transition(cp, RDS_CONN_ERROR,
RDS_CONN_DOWN)) {
- /* This can happen - eg when we're in the middle of tearing
- * down the connection, and someone unloads the rds module.
- * Quite reproducible with loopback connections.
- * Mostly harmless.
+ /* The path was dropped again while we tore it
+ * down: by a socket state-change callback in
+ * irq context on receipt of a FIN, or by an
+ * accept that claimed the path just before a
+ * drop put it back to RDS_CONN_ERROR and then
+ * installed a fresh socket on it. Unless a
+ * pending destroy suppressed it, the drop also
+ * queued another shutdown pass, and that pass
+ * must run, because it is what tears down
+ * whatever attached to the path after the
+ * transport shutdown above sampled its state.
+ * Consuming the RDS_CONN_ERROR here would turn
+ * that pass into a no-op: leave the state
+ * alone, and let the pass finish the job.
*
- * Note that this also happens with rds-tcp because
- * we could have triggered rds_conn_path_drop in irq
- * mode from rds_tcp_state change on the receipt of
- * a FIN, thus we need to recheck for RDS_CONN_ERROR
- * here.
+ * Quiesce the reconnect timer before bailing
+ * out, though. When a pending destroy did
+ * suppress the queue, no later pass runs, and
+ * rds_conn_path_destroy() is about to flush
+ * cp_down_w and free the path: it must not
+ * find cp_conn_w still armed. A successor
+ * pass, when there is one, re-arms the
+ * reconnect from its own tail.
+ */
+ cancel_delayed_work_sync(&cp->cp_conn_w);
+ clear_bit(RDS_RECONNECT_PENDING, &cp->cp_flags);
+
+ if (rds_conn_path_state(cp) == RDS_CONN_ERROR)
+ return;
+ /* No current cp_state writer leaves a
+ * DISCONNECTING path in any state but
+ * RDS_CONN_ERROR; report loudly if one ever
+ * does.
*/
rds_conn_path_error(cp, "%s: failed to transition "
"to state DOWN, current state "
diff --git a/net/rds/tcp.c b/net/rds/tcp.c
index 69c6d3145b5ab..774a71f88d375 100644
--- a/net/rds/tcp.c
+++ b/net/rds/tcp.c
@@ -165,9 +165,12 @@ void rds_tcp_reset_callbacks(struct socket *sock,
* other state - typically RDS_CONN_DISCONNECTING or
* RDS_CONN_ERROR with a shutdown in flight - is dropped
* instead. That still replaces its state, with RDS_CONN_ERROR,
- * and queues one more shutdown pass, but rds_conn_shutdown()
- * accepts RDS_CONN_ERROR in its final transition to
- * RDS_CONN_DOWN, so the shutdown in flight completes normally.
+ * and, unless a pending destroy is about to reap the whole
+ * connection anyway, queues one more shutdown pass. A shutdown
+ * already in flight leaves that RDS_CONN_ERROR alone when it
+ * finishes; the queued pass then completes the transition to
+ * RDS_CONN_DOWN and tears down anything that attached to the
+ * path in the meantime.
*/
if (!rds_conn_path_transition(cp, RDS_CONN_CONNECTING,
RDS_CONN_RESETTING) &&
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 215/733] powerpc: Dont drop _TIF_RESTOREALL on syscall restart
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (213 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 214/733] net/rds: dont let rds_conn_shutdown() consume a concurrent drop Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 216/733] powerpc: Do not restore KUAP in arch_exit_to_user_mode_prepare() Greg Kroah-Hartman
` (529 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Venkat Rao Bagalkote,
Ritesh Harjani (IBM), Amit Machhiwal, Shrikanth Hegde,
Mukesh Kumar Chaurasiya (IBM), Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
[ Upstream commit c7585b8e99ad97a0f5dd21e45c90a33aeab0d92b ]
So the syscall return sequence is as follows:
A syscall return to userspace is prepared and then a short asm sequence
that actually does the RFI. Note that this asm range is restartable i.e.
EE is still on, so an interrupt (e.g. decrementer or external interrupt)
can hit while SRR/GPRs are being loaded. This is defined via:
RESTART_TABLE(.Lsyscall_rst_start, .Lsyscall_rst_end, syscall_restart)
This restart table then sends us to syscall_restart rather than resuming
in the middle of the RFI. The same stub is also used if irq_happened
already has a pending bit (soft-masked irq that has not been replayed
yet (PowerPC special case of local_irq_disable())).
Here is a bit of a flow of sequence of code to visualize:
syscall_exit_prepare
decide full-GPR restore (_TIF_RESTOREALL) for signal,
rt_sigreturn or syscall trace
save that in regs->exit_result and return it in r3
|
v
.Lsyscall_rst_start .. _end EE still on
irq_happened set or interrupt in this range?
| no | yes
v v
cmpdi r3,0 syscall_exit_restart
restore all / zero replay irq, try exit again
volatiles; RFI must return flags in r3
again for the same cmpdi
Now r3 after prepare is the flags word, not the actual syscall return. A nested
interrupt clobbers it, so the restart stub reloads RESULT into r3 and the
C handler (syscall_exit_restart()) should put the flags back (because later asm
checks whether r3 returned from C has _TIF_RESTOREALL set or not):
cmpdi r3, 0
bne .Lsyscall_restore_regs
Note that syscall_exit_restart() already ORs any new _TIF_RESTOREALL into
exit_result, but then it only returns the new sample and not the full
regs->exit_result.
That sample could be often 0 even when restore-all is still required:
- rt_sigreturn / syscall trace set the bit in prepare's local
ret and in exit_result. They never set exit_flags, which is
what restart samples.
- a signal does set exit_flags but restart clears it. A
second pass through the stub then returns 0 while
exit_result still has the bit.
The asm as mentioned earlier then treats r3==0 as the fast path and
zeros r0/r4-r12. That means the userspace that needed the full register
set could SIGSEGVs, (which could happen often in ld64.so.2 like while
doing a parallel kernel build as reported by Venkat).
So we should instead return the accumulated exit_result, like how we do
in interrupt_exit_user_restart(). Note that prior to this commit
263e5159e00a ("powerpc: Fix exit_flags field placement in pt_regs for ptrace")
we were returning regs->exit_result from syscall_exit_restart(), but
this commit changed that behaviour.
Fixes: 263e5159e00a ("powerpc: Fix exit_flags field placement in pt_regs for ptrace")
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Closes: https://lore.kernel.org/all/75419f88-eab9-444b-bf97-28a9765819ad@linux.ibm.com/
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Tested-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Reviewed-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/10c86c909f870d90b3094f76b692b44ebe9caeac.1787976185.git.ritesh.list@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kernel/interrupt.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kernel/interrupt.c b/arch/powerpc/kernel/interrupt.c
index 5b88bf72786c7..55f9c0c9922ac 100644
--- a/arch/powerpc/kernel/interrupt.c
+++ b/arch/powerpc/kernel/interrupt.c
@@ -175,7 +175,7 @@ notrace unsigned long syscall_exit_restart(unsigned long r3, struct pt_regs *reg
current_thread_info()->exit_flags &= ~_TIF_RESTOREALL;
regs->exit_result |= ret;
- return ret;
+ return regs->exit_result;
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 216/733] powerpc: Do not restore KUAP in arch_exit_to_user_mode_prepare()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (214 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 215/733] powerpc: Dont drop _TIF_RESTOREALL on syscall restart Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 217/733] net: airoha: enable RX_DONE interrupt for RX queue 31 Greg Kroah-Hartman
` (528 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ritesh Harjani (IBM),
Venkat Rao Bagalkote, Mukesh Kumar Chaurasiya (IBM),
Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
[ Upstream commit c2549d749539487239475fbc8c614a1f9244d655 ]
KUAP means kernel cannot touch user memory unless it explicitly is
enabled. In the kernel it should stay AMR_KUAP_BLOCKED. While returning
to userspace just before RFI, kernel should restore the user AMR value
back.
Looks like GENERIC_ENTRY might be treating arch_exit_to_user_mode_prepare()
as the last architecture step before returning to userspace.
commit bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature")
therefore called kuap_user_restore() from that hook. But on PowerPC that
is too early. After irqentry_exit() / syscall_exit_to_user_mode() we
still run platform specific exit routines.
e.g. code snippets showing both exception handling and system call
handling as the callers of function arch_exit_to_user_mode_prepare()
which does kuap_user_restore(). The below path shows that calling
kuap_user_restore() is too early when called from
arch_exit_to_user_mode_prepare().
Exception handling in exceptions-64s.S
=======================================
bl CFUNC(do_page_fault)
..DEFINE_INTERRUPT_HANDLER_ASYNC(do_page_fault)
arch_interrupt_async_enter_prepare(regs);
state = irqentry_enter(regs);
instrumentation_begin();
irq_enter_rcu();
handler(regs);
nap_adjust_return(regs);
irq_exit_rcu();
instrumentation_end();
arch_interrupt_async_exit_prepare(regs);
irqentry_exit(regs, state); <<< too early
irqentry_exit_to_user_mode()
__exit_to_user_mode_prepare(regs, EXIT_TO_USER_MODE_WORK_IRQ);
arch_exit_to_user_mode_prepare(regs, ti_work); <<< too early
b interrupt_return_srr
.. bl CFUNC(interrupt_exit_user_prepare) <<< already calls kuap_user_restore
prep_irq_for_enabled_exit() retry can run kernel code with IRQs on. So
only when that routine is fully finished is when the user KUAP should be
fully restored which interrupt_exit_user_prepare() already takes care of
before returning.
Similarly for system call handling in interrupt_64.S
======================================================
bl CFUNC(system_call_exception)
.Lsyscall_exit:
addi r4,r1,STACK_INT_FRAME_REGS
li r5,0 /* !scv */
bl CFUNC(syscall_exit_prepare)
.. kuap_assert_locked();
syscall_exit_to_user_mode(regs); <<< too early
syscall_exit_to_user_mode_prepare(regs); <<< too early
kuap_user_restore(regs); <<< already calls
syscall_exit_prepare(), which can enable IRQs, replay a pending
interrupt, and only then rfi. Those functions already restore KUAP
immediately before rfi.
Note that if we restore the user AMR too early like in the current code
as shown from the code snippets above, then we get the following warning
when CONFIG_PPC_KUAP_DEBUG is enabled:
WARNING: arch/powerpc/include/asm/book3s/64/kup.h:293 at interrupt_exit_user_prepare+0x1a0/0x1c0
Hardware name: IBM pSeries (emulated by qemu) POWER10 (architected)
TRAP: 0700
LR: c00000000000d8d4 CTR: c0000000021fe500
MSR: <SF,EE,ME,IR,DR,RI,LE> CR: 44000804 XER: 20040000
interrupt_exit_user_prepare+0x1a0/0x1c0
interrupt_return_srr_user+0x8/0x12c
Fixes: bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature")
Fixes: 02565a782c1ee ("powerpc: Introduce syscall exit arch functions")
Signed-off-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Reviewed-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/52fee44fd23acf8e1c024ace668728e626a783a8.1788101609.git.ritesh.list@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/include/asm/entry-common.h | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h
index c5adb50063610..94083516df574 100644
--- a/arch/powerpc/include/asm/entry-common.h
+++ b/arch/powerpc/include/asm/entry-common.h
@@ -515,8 +515,14 @@ static inline void arch_exit_to_user_mode_prepare(struct pt_regs *regs,
#ifdef CONFIG_PPC_TRANSACTIONAL_MEM
local_paca->tm_scratch = regs->msr;
#endif
- /* Restore user access locks last */
- kuap_user_restore(regs);
+ /*
+ * Do not restore KUAP here. Generic entry might treat this as the last
+ * arch step before userspace but PowerPC still has kernel work after
+ * irqentry_exit()/syscall_exit_to_user_mode() i.e. in
+ * interrupt_exit_user_prepare() / syscall_exit_prepare() may enable
+ * IRQs and retry. Those functions restore KUAP immediately before rfi,
+ * which is where it should belong.
+ */
}
#define arch_exit_to_user_mode_prepare arch_exit_to_user_mode_prepare
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 217/733] net: airoha: enable RX_DONE interrupt for RX queue 31
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (215 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 216/733] powerpc: Do not restore KUAP in arch_exit_to_user_mode_prepare() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 218/733] net: stmmac: reconfigure RX packet parser table in stmmac_hw_setup() after reset Greg Kroah-Hartman
` (527 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Simon Horman,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo@kernel.org>
[ Upstream commit 7db28abbea0f7dc1ec4fdfdc149db5fbd9e4c994 ]
RX queue 31 has always been allocated and filled by airoha_qdma_init_rx()
since RX_DONE_INT_MASK spans queues 0-31, but none of the RX_IRQ*
_BANK_PIN_MASK values covered BIT(31). As a consequence the RX_DONE
interrupt for queue 31 was never enabled, airoha_qdma_rx_process() never
ran on that queue and its buffers were never reaped.
Route RX queue 31's RX_DONE interrupt to IRQ bank 1 so that the queue
is drained and its buffers returned to the page pool.
Fixes: f252493e1835 ("net: airoha: Enable multiple IRQ lines support in airoha_eth driver.")
Signed-off-by: Lorenzo Bianconi <lorenzo@kernel.org>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260830-airoha-rxdone-rxq31-v1-1-830a91503f2f@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/airoha/airoha_eth.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/airoha/airoha_eth.h b/drivers/net/ethernet/airoha/airoha_eth.h
index b894828b13752..70f16189b2582 100644
--- a/drivers/net/ethernet/airoha/airoha_eth.h
+++ b/drivers/net/ethernet/airoha/airoha_eth.h
@@ -538,7 +538,7 @@ struct airoha_wdma_info {
/* RX queue to IRQ mapping: BIT(q) in IRQ(n) */
#define RX_IRQ0_BANK_PIN_MASK 0x839f
-#define RX_IRQ1_BANK_PIN_MASK 0x7fe00000
+#define RX_IRQ1_BANK_PIN_MASK 0xffe00000
#define RX_IRQ2_BANK_PIN_MASK 0x20
#define RX_IRQ3_BANK_PIN_MASK 0x40
#define RX_IRQ_BANK_PIN_MASK(_n) \
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 218/733] net: stmmac: reconfigure RX packet parser table in stmmac_hw_setup() after reset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (216 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 217/733] net: airoha: enable RX_DONE interrupt for RX queue 31 Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 219/733] net: gro: Fix nesting of TCP GSO SKBs in skb_gro_receive_list() Greg Kroah-Hartman
` (526 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit 6b8fed2675fb75d23e6cf2b7e49c94926e884b34 ]
The core software reset issued in stmmac_init_dma_engine() during
ndo_open() callback clears the MTL RX packet parser registers, but
stmmac_rxp_config() is only invoked from the cls_u32 add/delete paths.
After an ifdown/ifup cycle the hardware therefore runs with the default
all-pass table while priv->tc_entries still reports the filters as
installed. Re-apply the RX packet parser table from priv->tc_entries in
stmmac_hw_setup(), right after the software reset, so the filters are
restored when the interface is brought up again.
Fixes: 4dbbe8dde848 ("net: stmmac: Add support for U32 TC filter using Flexible RX Parser")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260831-stmmac_tc_cls32_reconfigure-v1-1-21cb459e64ae@oss.qualcomm.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 8 ++++++++
1 file changed, 8 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1946361081fc2..1e88575fdddbb 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -3676,6 +3676,14 @@ static int stmmac_hw_setup(struct net_device *dev)
/* Initialize MTL*/
stmmac_mtl_configuration(priv);
+ /* Apply the RX packet parser table */
+ if (priv->tc_entries) {
+ ret = stmmac_rxp_config(priv, priv->hw->pcsr, priv->tc_entries,
+ priv->tc_entries_max);
+ if (ret)
+ return ret;
+ }
+
/* Initialize Safety Features */
stmmac_safety_feat_configuration(priv);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 219/733] net: gro: Fix nesting of TCP GSO SKBs in skb_gro_receive_list()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (217 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 218/733] net: stmmac: reconfigure RX packet parser table in stmmac_hw_setup() after reset Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 220/733] arm64: trans_pgd: clone only the linear map that exists at runtime Greg Kroah-Hartman
` (525 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhaoping Shu, HW He,
Willem de Bruijn, Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: HW He <hw.he@mediatek.com>
[ Upstream commit 66817a9794263cd2a5dc4e99bf8e5fcc5ff7181e ]
Fraglist GRO and hardware GRO can create an fraglist of
HW-GRO packets. This cannot be segmented back into
the original form on TCP tethering scenario.
Avoid constructing such a GSO packet, by flushing an already
built fraglist GRO packet if a hardware GRO packet arrives.
Scenario (Tethering/Forwarding):
1.Driver submits a single TCP packet, P1. P1 is kept in the
gro_list as the first packet.
2. The driver submits a TCP GSO skb, P2. P2 has already aggregated
multiple TCP packets by HW_GRO, and its non-linear data is stored in
frags[].
3. P1 and P2 match the GRO rules, and since there is no local socket,
they are aggregated by skb_gro_receive_list(). The resulting skb,
P3, has a frag_list entry that still contains frags[]:
P3: [ Linear Data ] -> frag_list -> [ Linear Data ]
[ frag[1] ]
[ frag[2] ]
...
4. Later, tcp4_gso_segment() or tcp6_gso_segment() calls
skb_segment_list() to segment P3. However, skb_segment_list() only
segments the entries in frag_list. It does not segment the frags[]
inside P2, so P3 is not restored to the original packets, which leads
to IP fragmentation or packet drop in the following path.
Check skb_is_gso(skb) and current GRO method, make sure fraglist GRO
applies to consecutive non-GSO skb, others adopt regular GRO path.
Fixes: 8d95dc474f85 ("net: add code for TCP fraglist GRO")
Signed-off-by: Zhaoping Shu <zhaoping.shu@mediatek.com>
Signed-off-by: HW He <hw.he@mediatek.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260901082312.14596-1-zhaoping.shu@mediatek.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/tcp_offload.c | 22 ++++++++++++++++------
net/ipv6/tcpv6_offload.c | 15 +++++++++++++--
2 files changed, 29 insertions(+), 8 deletions(-)
diff --git a/net/ipv4/tcp_offload.c b/net/ipv4/tcp_offload.c
index 3b1fdcd3cb29b..e74d99ca9face 100644
--- a/net/ipv4/tcp_offload.c
+++ b/net/ipv4/tcp_offload.c
@@ -332,6 +332,7 @@ struct sk_buff *tcp_gro_receive(struct list_head *head, struct sk_buff *skb,
flush |= skb->ip_summed != p->ip_summed;
flush |= skb->csum_level != p->csum_level;
flush |= NAPI_GRO_CB(p)->count >= 64;
+ flush |= NAPI_GRO_CB(p)->is_flist != NAPI_GRO_CB(skb)->is_flist;
skb_set_network_header(skb, skb_gro_receive_network_offset(skb));
if (flush || skb_gro_receive_list(p, skb))
@@ -395,12 +396,20 @@ static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
struct net *net;
int iif, sdif;
- if (likely(!(skb->dev->features & NETIF_F_GRO_FRAGLIST)))
- return;
-
p = tcp_gro_lookup(head, th);
if (p) {
- NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
+ /* flist GRO applies to consecutive non-GSO skbs */
+ if (!skb_is_gso(skb) || !NAPI_GRO_CB(p)->is_flist) {
+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
+ return;
+ }
+
+ /* Fall back to the regular GRO path */
+ if (NAPI_GRO_CB(p)->count == 1)
+ NAPI_GRO_CB(p)->is_flist = 0;
+
+ NAPI_GRO_CB(skb)->is_flist = 0;
+
return;
}
@@ -410,7 +419,7 @@ static void tcp4_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
sk = __inet_lookup_established(net, iph->saddr, th->source,
iph->daddr, ntohs(th->dest),
iif, sdif);
- NAPI_GRO_CB(skb)->is_flist = !sk;
+ NAPI_GRO_CB(skb)->is_flist = !sk && !skb_is_gso(skb);
if (sk)
sock_gen_put(sk);
}
@@ -430,7 +439,8 @@ struct sk_buff *tcp4_gro_receive(struct list_head *head, struct sk_buff *skb)
if (!th)
goto flush;
- tcp4_check_fraglist_gro(head, skb, th);
+ if (unlikely(skb->dev->features & NETIF_F_GRO_FRAGLIST))
+ tcp4_check_fraglist_gro(head, skb, th);
return tcp_gro_receive(head, skb, th);
diff --git a/net/ipv6/tcpv6_offload.c b/net/ipv6/tcpv6_offload.c
index f2a659cd6183c..eec3778855eb8 100644
--- a/net/ipv6/tcpv6_offload.c
+++ b/net/ipv6/tcpv6_offload.c
@@ -26,7 +26,18 @@ static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
p = tcp_gro_lookup(head, th);
if (p) {
- NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
+ /* flist GRO applies to consecutive non-GSO skbs */
+ if (!skb_is_gso(skb) || !NAPI_GRO_CB(p)->is_flist) {
+ NAPI_GRO_CB(skb)->is_flist = NAPI_GRO_CB(p)->is_flist;
+ return;
+ }
+
+ /* Fall back to the regular GRO path */
+ if (NAPI_GRO_CB(p)->count == 1)
+ NAPI_GRO_CB(p)->is_flist = 0;
+
+ NAPI_GRO_CB(skb)->is_flist = 0;
+
return;
}
@@ -36,7 +47,7 @@ static void tcp6_check_fraglist_gro(struct list_head *head, struct sk_buff *skb,
sk = __inet6_lookup_established(net, &hdr->saddr, th->source,
&hdr->daddr, ntohs(th->dest),
iif, sdif);
- NAPI_GRO_CB(skb)->is_flist = !sk;
+ NAPI_GRO_CB(skb)->is_flist = !sk && !skb_is_gso(skb);
if (sk)
sock_gen_put(sk);
#endif /* IS_ENABLED(CONFIG_IPV6) */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 220/733] arm64: trans_pgd: clone only the linear map that exists at runtime
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (218 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 219/733] net: gro: Fix nesting of TCP GSO SKBs in skb_gro_receive_list() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 221/733] erofs: disable LZ4 rolling decompression for now Greg Kroah-Hartman
` (524 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Breno Leitao, Yury Smirnov,
Will Deacon, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Breno Leitao <leitao@debian.org>
[ Upstream commit 1537e55728ec2bc506c74ea69b93cd859da58fb8 ]
kexec_file_load() fails on arm64 if we have CONFIG_ARM64_VA_BITS_52 but
it runs on a !FEAT_LPA2 host (such as my loving Grace machine).
That is because trans_pgd_create_copy() uses the compile time
PAGE_OFFSET (VA 52) instead of the actual VA size (48 -- due to the lack
of LPA2). With the fifth level folded, pgd_none() is always false, so
the walk cannot skip the 15 extra PGDIR_SIZE slots, and they all alias
back to the same table: the whole kernel page table gets cloned 16
times, KASAN shadow included. Without KASAN it does not blow up, it just
wastes ~RAM/32 in page tables.
Fix it by copying the linear map that is the actual one, not the
compiled one.
Fixes: a6bbf5d4d9d1 ("arm64: mm: Add definitions to support 5 levels of paging")
Signed-off-by: Breno Leitao <leitao@debian.org>
Tested-by: Yury Smirnov <yurymonzon@gmail.com>
Signed-off-by: Will Deacon <will@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/kernel/machine_kexec.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/arch/arm64/kernel/machine_kexec.c b/arch/arm64/kernel/machine_kexec.c
index c5693a32e49b0..8f9bc2327dc85 100644
--- a/arch/arm64/kernel/machine_kexec.c
+++ b/arch/arm64/kernel/machine_kexec.c
@@ -129,7 +129,8 @@ int machine_kexec_post_load(struct kimage *kimage)
}
/* Create a copy of the linear map */
- rc = trans_pgd_create_copy(&info, &trans_pgd, PAGE_OFFSET, PAGE_END);
+ rc = trans_pgd_create_copy(&info, &trans_pgd,
+ _PAGE_OFFSET(vabits_actual), PAGE_END);
if (rc)
return rc;
kimage->arch.ttbr1 = __pa(trans_pgd);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 221/733] erofs: disable LZ4 rolling decompression for now
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (219 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 220/733] arm64: trans_pgd: clone only the linear map that exists at runtime Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 222/733] selftests/alsa: Fix the step check for INTEGER controls Greg Kroah-Hartman
` (523 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Walther, Jens-Uwe, Yann Collet,
Gao Xiang, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gao Xiang <xiang@kernel.org>
[ Upstream commit 82e664cf1219c459c33aae931b222cf951af9cb7 ]
LZ4 rolling decompression [1] was introduced to reduce the memory
footprint of temporary pages:
For many cases, it is needed for users to read small data within
a compressed extent (pcluster), either due to random small read, or
since uptodate folios (typically order-0) cannot be reused for
decompression again since decompression algorithm refills
already-uptodate folios.
Rolling decompression works because LZ4 is LZ77-based and only refers
to the most recent 64 KiB of decompressed data, so in theory only a
bounded rolling window of temporary pages is needed when decompressing.
It can save a lot of temporary memory, e.g.
601,960-byte data can be compressed into a 256k LZ4 compressed extent,
which means it needs 146 extra pages per request in the worst case if
rolling decompression is disabled.
However, the upstream LZ4 implementation is not under EROFS' control:
For example, the literal copy memmove() may still **copy long literals
backward** on x86 based on the address comparison even when the source
and destination ranges do not overlap (IOWs, inline decompression
doesn't need to be considered here). That breaks the rolling assumption
and makes the optimization broken.
Disable it for now to make sure the data correctness first since EROFS
is used everywhere now: The rolling window approach can be revived once
we either ensure that the official LZ4 code always copies forward for
non-overlapping ranges or maintain our own LZ4 implementation in EROFS.
The main impact is a higher runtime memory footprint; However, recent
commit 0f6273ab4637 ("erofs: add a reserved buffer pool for lz4
decompression") helps mitigate this when enabled but it's still not
perfect.
[1] https://www.usenix.org/conference/atc19/presentation/gao
§ 3.3 Decompression
Reported-by: "Walther, Jens-Uwe" <waltju@amazon.de>
Closes: https://lore.kernel.org/r/BEZP281MB2102E57CD31862B8D958B33DD2AC2@BEZP281MB2102.DEUP281.PROD.OUTLOOK.COM
Fixes: 8e6c8fa9f2e9 ("erofs: enable big pcluster feature")
Cc: Yann Collet <yann.collet.73@gmail.com>
Signed-off-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/decompressor.c | 55 +++++++++--------------------------------
fs/erofs/internal.h | 6 +----
fs/erofs/zdata.c | 18 +++-----------
3 files changed, 16 insertions(+), 63 deletions(-)
diff --git a/fs/erofs/decompressor.c b/fs/erofs/decompressor.c
index 27caf4bebddc3..d387b27c4ee21 100644
--- a/fs/erofs/decompressor.c
+++ b/fs/erofs/decompressor.c
@@ -7,8 +7,6 @@
#include "compress.h"
#include <linux/lz4.h>
-#define LZ4_MAX_DISTANCE_PAGES (DIV_ROUND_UP(LZ4_DISTANCE_MAX, PAGE_SIZE) + 1)
-
static int z_erofs_load_lz4_config(struct super_block *sb,
struct erofs_super_block *dsb, void *data, int size)
{
@@ -21,8 +19,6 @@ static int z_erofs_load_lz4_config(struct super_block *sb,
erofs_err(sb, "invalid lz4 cfgs, size=%u", size);
return -EINVAL;
}
- distance = le16_to_cpu(lz4->max_distance);
-
sbi->lz4.max_pclusterblks = le16_to_cpu(lz4->max_pclusterblks);
if (!sbi->lz4.max_pclusterblks) {
sbi->lz4.max_pclusterblks = 1; /* reserved case */
@@ -39,45 +35,25 @@ static int z_erofs_load_lz4_config(struct super_block *sb,
sbi->lz4.max_pclusterblks = 1;
sbi->available_compr_algs = 1 << Z_EROFS_COMPRESSION_LZ4;
}
-
- sbi->lz4.max_distance_pages = distance ?
- DIV_ROUND_UP(distance, PAGE_SIZE) + 1 :
- LZ4_MAX_DISTANCE_PAGES;
return z_erofs_gbuf_growsize(sbi->lz4.max_pclusterblks);
}
/*
- * Fill all gaps with bounce pages if it's a sparse page list. Also check if
- * all physical pages are consecutive, which can be seen for moderate CR.
+ * Fill all gaps with bounce pages if it's a sparse page list (for example some
+ * folios are already uptodate and thus can be mapped into userspace). Also
+ * check if pages are physically consecutive, which can be seen for moderate CR.
*/
-static int z_erofs_lz4_prepare_dstpages(struct z_erofs_decompress_req *rq,
- struct page **pagepool)
+static int z_erofs_oneshot_prepare_dstpages(struct z_erofs_decompress_req *rq,
+ struct page **pagepool)
{
- struct page *availables[LZ4_MAX_DISTANCE_PAGES] = { NULL };
- unsigned long bounced[DIV_ROUND_UP(LZ4_MAX_DISTANCE_PAGES,
- BITS_PER_LONG)] = { 0 };
- unsigned int lz4_max_distance_pages =
- EROFS_SB(rq->sb)->lz4.max_distance_pages;
void *kaddr = NULL;
- unsigned int i, j, top;
+ unsigned int i;
- top = 0;
- for (i = j = 0; i < rq->outpages; ++i, ++j) {
- struct page *const page = rq->out[i];
- struct page *victim;
-
- if (j >= lz4_max_distance_pages)
- j = 0;
-
- /* 'valid' bounced can only be tested after a complete round */
- if (!rq->fillgaps && test_bit(j, bounced)) {
- DBG_BUGON(i < lz4_max_distance_pages);
- DBG_BUGON(top >= lz4_max_distance_pages);
- availables[top++] = rq->out[i - lz4_max_distance_pages];
- }
+ for (i = 0; i < rq->outpages; ++i) {
+ struct page *page, *victim;
+ page = rq->out[i];
if (page) {
- __clear_bit(j, bounced);
if (!PageHighMem(page)) {
if (!i) {
kaddr = page_address(page);
@@ -89,21 +65,14 @@ static int z_erofs_lz4_prepare_dstpages(struct z_erofs_decompress_req *rq,
continue;
}
}
- kaddr = NULL;
- continue;
- }
- kaddr = NULL;
- __set_bit(j, bounced);
-
- if (top) {
- victim = availables[--top];
} else {
victim = __erofs_allocpage(pagepool, rq->gfp, true);
if (!victim)
return -ENOMEM;
set_page_private(victim, Z_EROFS_SHORTLIVED_PAGE);
+ rq->out[i] = victim;
}
- rq->out[i] = victim;
+ kaddr = NULL;
}
return kaddr ? 1 : 0;
}
@@ -266,7 +235,7 @@ static const char *z_erofs_lz4_decompress(struct z_erofs_decompress_req *rq,
dst_maptype = 0;
} else {
/* general decoding path which can be used for all cases */
- ret = z_erofs_lz4_prepare_dstpages(rq, pagepool);
+ ret = z_erofs_oneshot_prepare_dstpages(rq, pagepool);
if (ret < 0)
return ERR_PTR(ret);
if (ret > 0) {
diff --git a/fs/erofs/internal.h b/fs/erofs/internal.h
index bee2f50c8488f..be98c9222bf79 100644
--- a/fs/erofs/internal.h
+++ b/fs/erofs/internal.h
@@ -71,12 +71,8 @@ struct erofs_dev_context {
bool flatdev;
};
-/* all filesystem-wide lz4 configurations */
struct erofs_sb_lz4_info {
- /* # of pages needed for EROFS lz4 rolling decompression */
- u16 max_distance_pages;
- /* maximum possible blocks for pclusters in the filesystem */
- u16 max_pclusterblks;
+ u16 max_pclusterblks; /* maximum physical blocks for LZ4 pclusters */
};
struct erofs_xattr_prefix_item {
diff --git a/fs/erofs/zdata.c b/fs/erofs/zdata.c
index 0e9cac8ee12d3..f0759211b7234 100644
--- a/fs/erofs/zdata.c
+++ b/fs/erofs/zdata.c
@@ -1264,7 +1264,7 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, bool eio)
const struct z_erofs_decompressor *alg =
z_erofs_decomp[pcl->algorithmformat];
bool try_free = true;
- int i, j, jtop, err2, err = eio ? -EIO : 0;
+ int i, err2, err = eio ? -EIO : 0;
struct page *page;
bool overlapped;
const char *reason;
@@ -1353,7 +1353,6 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, bool eio)
be->compressed_pages >= be->onstack_pages + Z_EROFS_ONSTACK_PAGES)
kvfree(be->compressed_pages);
- jtop = 0;
z_erofs_fill_other_copies(be, err);
for (i = 0; i < be->nr_pages; ++i) {
page = be->decompressed_pages[i];
@@ -1361,22 +1360,11 @@ static int z_erofs_decompress_pcluster(struct z_erofs_backend *be, bool eio)
continue;
DBG_BUGON(z_erofs_page_is_invalidated(page));
- if (!z_erofs_is_shortlived_page(page)) {
+ if (!z_erofs_is_shortlived_page(page))
erofs_onlinefolio_end(page_folio(page), err, true);
- continue;
- }
- if (pcl->algorithmformat != Z_EROFS_COMPRESSION_LZ4) {
+ else
erofs_pagepool_add(be->pagepool, page);
- continue;
- }
- for (j = 0; j < jtop && be->decompressed_pages[j] != page; ++j)
- ;
- if (j >= jtop) /* this bounce page is newly detected */
- be->decompressed_pages[jtop++] = page;
}
- while (jtop)
- erofs_pagepool_add(be->pagepool,
- be->decompressed_pages[--jtop]);
if (be->decompressed_pages != be->onstack_pages)
kvfree(be->decompressed_pages);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 222/733] selftests/alsa: Fix the step check for INTEGER controls
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (220 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 221/733] erofs: disable LZ4 rolling decompression for now Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 223/733] ALSA: caiaq: Fix potential double-free at error path Greg Kroah-Hartman
` (522 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Takashi Iwai,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <sammiee5311@gmail.com>
[ Upstream commit 8efd5f623c63584c2e284a837a7795d95a0491cb ]
The modulo sits inside the subtraction, so the check evaluates
int_val - (min % step) rather than (int_val - min) % step. The
INTEGER64 branch below it is parenthesised correctly.
The written form passes only when the value equals min % step, and such
a value is always on a step boundary, so it never misses a real
violation. It only reports valid values as invalid.
snd-aloop declares step 1 on four controls, so every non-zero value on
them is reported. Before:
# PCM Rate Shift 100000.0 value 100000 invalid for step 1 minimum 80000
# Totals: pass:660 fail:101 xfail:0 xpass:0 skip:296 error:0
After, same card, nothing else changed:
# Totals: pass:740 fail:21 xfail:0 xpass:0 skip:296 error:0
Eighteen files under sound/ declare a non-zero step.
Fixes: 5aaf9efffc57 ("kselftest: alsa: Add simplistic test for ALSA mixer controls kselftest")
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5
Link: https://patch.msgid.link/20260903123832.97377-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/alsa/mixer-test.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/alsa/mixer-test.c b/tools/testing/selftests/alsa/mixer-test.c
index a329f901c5edf..0857d64c322a0 100644
--- a/tools/testing/selftests/alsa/mixer-test.c
+++ b/tools/testing/selftests/alsa/mixer-test.c
@@ -319,8 +319,8 @@ static bool ctl_value_index_valid(struct ctl_data *ctl,
/* Only check step size if there is one and we're in bounds */
if (snd_ctl_elem_info_get_step(ctl->info) &&
- (int_val - snd_ctl_elem_info_get_min(ctl->info) %
- snd_ctl_elem_info_get_step(ctl->info))) {
+ (int_val - snd_ctl_elem_info_get_min(ctl->info)) %
+ snd_ctl_elem_info_get_step(ctl->info)) {
ksft_print_msg("%s.%d value %ld invalid for step %ld minimum %ld\n",
ctl->name, index, int_val,
snd_ctl_elem_info_get_step(ctl->info),
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 223/733] ALSA: caiaq: Fix potential double-free at error path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (221 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 222/733] selftests/alsa: Fix the step check for INTEGER controls Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 224/733] drm/rockchip: dw_dp: Select DRM_BRIDGE_CONNECTOR Greg Kroah-Hartman
` (521 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Takashi Iwai, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <tiwai@suse.de>
[ Upstream commit 3b26ceef88c110f4d188387cffa0df78657be904 ]
The fix for caiaq driver's resource management to handle the errors
tries to release the resources in a common destructor call, but as a
sashiko review for another patch suggested, some of the audio
resources such as URBs have been already freed, and this may lead to a
double-free.
For addressing the double-free, call the common destructor function
from each place, and assure that the resource pointers get cleared.
Link: https://sashiko.dev/#/patchset/20260903084747.535367-1-eadavis%40sina.com
Fixes: 28abd224db4a ("ALSA: caiaq: Handle probe errors properly")
Link: https://patch.msgid.link/20260903103855.1807838-1-tiwai@suse.de
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/caiaq/audio.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
diff --git a/sound/usb/caiaq/audio.c b/sound/usb/caiaq/audio.c
index ba3f73455ebee..bb6280aa35334 100644
--- a/sound/usb/caiaq/audio.c
+++ b/sound/usb/caiaq/audio.c
@@ -828,16 +828,13 @@ int snd_usb_caiaq_audio_init(struct snd_usb_caiaqdev *cdev)
cdev->data_urbs_in = alloc_urbs(cdev, SNDRV_PCM_STREAM_CAPTURE, &ret);
if (ret < 0) {
- kfree(cdev->data_cb_info);
- free_urbs(cdev->data_urbs_in);
+ snd_usb_caiaq_audio_free(cdev);
return ret;
}
cdev->data_urbs_out = alloc_urbs(cdev, SNDRV_PCM_STREAM_PLAYBACK, &ret);
if (ret < 0) {
- kfree(cdev->data_cb_info);
- free_urbs(cdev->data_urbs_in);
- free_urbs(cdev->data_urbs_out);
+ snd_usb_caiaq_audio_free(cdev);
return ret;
}
@@ -858,6 +855,9 @@ void snd_usb_caiaq_audio_free(struct snd_usb_caiaqdev *cdev)
dev_dbg(dev, "%s(%p)\n", __func__, cdev);
free_urbs(cdev->data_urbs_in);
+ cdev->data_urbs_in = NULL;
free_urbs(cdev->data_urbs_out);
+ cdev->data_urbs_out = NULL;
kfree(cdev->data_cb_info);
+ cdev->data_cb_info = NULL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 224/733] drm/rockchip: dw_dp: Select DRM_BRIDGE_CONNECTOR
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (222 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 223/733] ALSA: caiaq: Fix potential double-free at error path Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 225/733] drm/rockchip: rk3066_hdmi: Add missing Kconfig selects Greg Kroah-Hartman
` (520 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Igor Paunovic, Heiko Stuebner,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Paunovic <royalnet026@gmail.com>
[ Upstream commit c83e3e806d4c115f1dad9ef756db4cd91448a262 ]
dw_dp-rockchip.c calls drm_bridge_connector_init(), but ROCKCHIP_DW_DP
does not select DRM_BRIDGE_CONNECTOR. A configuration with
ROCKCHIP_DW_DP as the only enabled Rockchip output option fails to
link:
aarch64-linux-gnu-ld: drivers/gpu/drm/rockchip/dw_dp-rockchip.o: in function `dw_dp_rockchip_bind':
dw_dp-rockchip.c:(.text+0x1d4): undefined reference to `drm_bridge_connector_init'
Five other Rockchip encoder options that call
drm_bridge_connector_init() (ROCKCHIP_ANALOGIX_DP, ROCKCHIP_CDN_DP,
ROCKCHIP_DW_HDMI_QP, ROCKCHIP_LVDS, ROCKCHIP_RGB) already select it,
which masks the gap in any configuration that enables one of them.
ROCKCHIP_INNO_HDMI is covered through its DRM_INNO_HDMI core option.
The same change was posted by Marius Dinu in March and dropped when
the failure stopped reproducing in his build. The failure is
configuration-dependent - any other enabled option that selects
DRM_BRIDGE_CONNECTOR hides it - and it still reproduces on current
drm-misc-next with the configuration described above.
Select DRM_BRIDGE_CONNECTOR like the other users do.
Fixes: d68ba7bac955 ("drm/rockchip: Add RK3588 DPTX output support")
Link: https://lore.kernel.org/r/aneNCDU12OzG99UX@venus # ack to handle this apart from the dw-dp series
Link: https://lore.kernel.org/r/20260319155051.1944-1-m95d+git@psihoexpert.ro # earlier submission by Marius Dinu
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260813144019.12089-2-royalnet026@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/rockchip/Kconfig | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index e7f49fe845eae..697c0748eecae 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -68,6 +68,7 @@ config ROCKCHIP_CDN_DP
config ROCKCHIP_DW_DP
bool "Rockchip specific extensions for Synopsys DW DP"
+ select DRM_BRIDGE_CONNECTOR
help
This selects support for Rockchip SoC specific extensions
to enable Synopsys DesignWare Cores based DisplayPort transmit
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 225/733] drm/rockchip: rk3066_hdmi: Add missing Kconfig selects
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (223 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 224/733] drm/rockchip: dw_dp: Select DRM_BRIDGE_CONNECTOR Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 226/733] bpf: Reject key-less BTF for hash maps Greg Kroah-Hartman
` (519 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Igor Paunovic, Heiko Stuebner,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Igor Paunovic <royalnet026@gmail.com>
[ Upstream commit d72aa5cf045a69d5fd433cde5dd4e113d9558fd1 ]
rk3066_hdmi.c calls drm_bridge_connector_init(), but
ROCKCHIP_RK3066_HDMI selects neither DRM_BRIDGE_CONNECTOR nor
DRM_DISPLAY_HELPER, whose module carries the bridge-connector code. A
configuration with ROCKCHIP_RK3066_HDMI as the only enabled Rockchip
output option fails to link:
aarch64-linux-gnu-ld: drivers/gpu/drm/rockchip/rk3066_hdmi.o: in function `rk3066_hdmi_bind':
rk3066_hdmi.c:(.text+0x7a4): undefined reference to `drm_bridge_connector_init'
aarch64-linux-gnu-ld: drivers/gpu/drm/rockchip/rk3066_hdmi.o: in function `rk3066_hdmi_bridge_atomic_enable':
rk3066_hdmi.c:(.text+0xe74): undefined reference to `drm_atomic_helper_connector_hdmi_update_infoframes'
Select both, like ROCKCHIP_CDN_DP, ROCKCHIP_LVDS and ROCKCHIP_RGB do.
DRM_BRIDGE_CONNECTOR in turn selects DRM_DISPLAY_HDMI_STATE_HELPER,
which resolves the second symbol.
Fixes: 57d6811e8a6d ("drm/rockchip: rk3066_hdmi: switch to drm bridge")
Signed-off-by: Igor Paunovic <royalnet026@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260813144019.12089-3-royalnet026@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/rockchip/Kconfig | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/gpu/drm/rockchip/Kconfig b/drivers/gpu/drm/rockchip/Kconfig
index 697c0748eecae..4e58685f58ff9 100644
--- a/drivers/gpu/drm/rockchip/Kconfig
+++ b/drivers/gpu/drm/rockchip/Kconfig
@@ -146,6 +146,8 @@ config ROCKCHIP_RGB
config ROCKCHIP_RK3066_HDMI
bool "Rockchip specific extensions for RK3066 HDMI"
depends on DRM_ROCKCHIP
+ select DRM_DISPLAY_HELPER
+ select DRM_BRIDGE_CONNECTOR
help
This selects support for Rockchip SoC specific extensions
for the RK3066 HDMI driver. If you want to enable
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 226/733] bpf: Reject key-less BTF for hash maps
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (224 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 225/733] drm/rockchip: rk3066_hdmi: Add missing Kconfig selects Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 227/733] bpf: Fix NULL-ptr-deref when showing a void BTF type Greg Kroah-Hartman
` (518 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+37b56485bbbf90ad8489,
Jiayuan Chen, Ihor Solodrai, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 0895a0c0734703be5532f3883c42db95615fd98b ]
map_check_btf() allows a key-less BTF (btf_key_type_id == 0) only for
maps that have a ->map_check_btf callback, and leaves the actual
decision to that callback. Hash maps used to have no ->map_check_btf,
so a key-less BTF was rejected outright.
That changed when htab and rhtab gained a ->map_check_btf to register a
dtor - htab in commit 1df97a7453ee ("bpf: Register dtor for freeing
special fields") and rhtab in commit 6905f8601298 ("bpf: Allow special
fields in resizable hashtab"). Neither looks at the key, so a key-less
hash map now passes map_check_btf() and gets created. Reading it back
through bpffs feeds the key type_id 0 into btf_type_seq_show();
btf_type_by_id() returns the void type, kind_ops[BTF_KIND_UNKN] is NULL,
and btf_type_show() dereferences it:
RIP: 0010:btf_type_show+0x223/0x2e0 kernel/bpf/btf.c:8232
RSP: 0018:ffffc9000399f868 EFLAGS: 00010206
RAX: dffffc0000000000 RBX: 0000000000000000 RCX: 0000000000000000
RDX: 0000000000000005 RSI: 0000000000000000 RDI: 0000000000000028
RBP: 0000000000000000 R08: 0000000000000001 R09: 0000000000000000
R10: ffffc9000399f970 R11: 0000000000000001 R12: ffffffff9b96b140
R13: ffffc9000399f8e0 R14: ffff88803d393c00 R15: 0000000000000003
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000200000000000 CR3: 000000003d213000 CR4: 0000000000352ef0
DR0: 0000000039ae8f55 DR1: 0000000000000000 DR2: 0000000000000000
DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400
Call Trace:
<TASK>
btf_type_seq_show_flags+0xca/0x120 kernel/bpf/btf.c:8250
htab_map_seq_show_elem+0x12e/0x350 kernel/bpf/hashtab.c:1669
map_seq_show+0x13d/0x1e0 kernel/bpf/inode.c:293
traverse.part.0.constprop.0+0x107/0x650 fs/seq_file.c:112
traverse fs/seq_file.c:99 [inline]
seq_read_iter+0x93f/0x1270 fs/seq_file.c:196
seq_read+0x344/0x4d0 fs/seq_file.c:163
vfs_read+0x1e4/0xb40 fs/read_write.c:572
ksys_pread64 fs/read_write.c:764 [inline]
__do_sys_pread64 fs/read_write.c:772 [inline]
__se_sys_pread64 fs/read_write.c:769 [inline]
__x64_sys_pread64+0x1eb/0x250 fs/read_write.c:769
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x123/0x790 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Reject a key-less BTF in htab_map_check_btf() and rhtab_map_check_btf(),
restoring the previous behavior.
Fixes: 1df97a7453ee ("bpf: Register dtor for freeing special fields")
Fixes: 6905f8601298 ("bpf: Allow special fields in resizable hashtab")
Reported-by: syzbot+37b56485bbbf90ad8489@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/all/6a8f4e88.27659fcc.2ceef7.0008.GAE@google.com/T/
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-2-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index dd4da18312ac1..7f70db4d5dcf0 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -530,6 +530,9 @@ static int htab_map_check_btf(struct bpf_map *map, const struct btf *btf,
{
struct bpf_htab *htab = container_of(map, struct bpf_htab, map);
+ if (btf_type_is_void(key_type))
+ return -EINVAL;
+
if (htab_is_prealloc(htab))
return 0;
/*
@@ -3113,6 +3116,9 @@ static int rhtab_map_check_btf(struct bpf_map *map, const struct btf *btf,
{
struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
+ if (btf_type_is_void(key_type))
+ return -EINVAL;
+
return bpf_ma_set_dtor(map, &rhtab->ma, rhtab_mem_dtor);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 227/733] bpf: Fix NULL-ptr-deref when showing a void BTF type
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (225 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 226/733] bpf: Reject key-less BTF for hash maps Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 228/733] bpf: Fix NULL-ptr-deref in btf_var_show() Greg Kroah-Hartman
` (517 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Ihor Solodrai,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 4ea508b9ebd78bce7f212166d2e2cba66b875f08 ]
btf_modifier_show() resolves the modifier and then calls
btf_type_ops(t)->show() unconditionally. For the void type (type_id 0,
BTF_KIND_UNKN) kind_ops[] has no entry, so ->show is NULL.
A "const void" (a modifier resolving to void) cannot be a map key or
value - map_check_btf() rejects it because void has no size - so the map
dump path does not reach it. But bpf_snprintf_btf() takes a type_id
straight from the BPF program, and passing such a "const void" from the
vmlinux BTF NULL-derefs:
KASAN: null-ptr-deref in range [0x0000000000000028-0x000000000000002f]
RIP: 0010:btf_modifier_show (kernel/bpf/btf.c:2914)
Call Trace:
<TASK>
btf_type_show (kernel/bpf/btf.c:8251)
btf_type_snprintf_show (kernel/bpf/btf.c:8321)
bpf_snprintf_btf (kernel/trace/bpf_trace.c:1047)
bpf_prog_test_run_raw_tp (net/bpf/test_run.c:829)
__sys_bpf (kernel/bpf/syscall.c:4804)
do_syscall_64 (arch/x86/entry/syscall_64.c:94)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Fall back to btf_df_show() when the resolved type has no show op; it
emits the "<unsupported kind:N>" placeholder already used for kinds like
FWD and FUNC. bpf_snprintf_btf() then returns the length as usual.
Fixes: c4d0bfb45068 ("bpf: Add bpf_snprintf_btf helper")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-3-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 608be952717d4..f64eb43cb1f04 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -2912,7 +2912,14 @@ static void btf_modifier_show(const struct btf *btf,
else
t = btf_type_skip_modifiers(btf, type_id, NULL);
- btf_type_ops(t)->show(btf, t, type_id, data, bits_offset, show);
+ /*
+ * A modifier can resolve to void, which has no show op; print a
+ * placeholder rather than dereferencing NULL.
+ */
+ if (!btf_type_ops(t))
+ btf_df_show(btf, t, type_id, data, bits_offset, show);
+ else
+ btf_type_ops(t)->show(btf, t, type_id, data, bits_offset, show);
}
static void btf_var_show(const struct btf *btf, const struct btf_type *t,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 228/733] bpf: Fix NULL-ptr-deref in btf_var_show()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (226 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 227/733] bpf: Fix NULL-ptr-deref when showing a void BTF type Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 229/733] bpf: Mark signal tracepoint siginfo arguments as scalar Greg Kroah-Hartman
` (516 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Ihor Solodrai,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 5403a383f52fc0905703b488f7c3db4b2447dc58 ]
btf_var_show() calls btf_type_id_resolve() unconditionally, which
dereferences btf->resolved_ids. That is NULL for a base BTF - e.g. the
vmlinux BTF that bpf_snprintf_btf() renders against - since base BTF is
not resolved during parsing. btf_modifier_show() guards this with
'if (btf->resolved_ids)', but btf_var_show() does not.
A BPF program that passes the type_id of a BTF_KIND_VAR from the vmlinux
BTF to bpf_snprintf_btf() thus NULL-derefs:
KASAN: probably user-memory-access in range [0x46638-0x4663f]
RIP: 0010:btf_var_show (kernel/bpf/btf.c:2929)
Call Trace:
<TASK>
btf_type_show (kernel/bpf/btf.c:8259)
btf_type_snprintf_show (kernel/bpf/btf.c:8329)
bpf_snprintf_btf (kernel/trace/bpf_trace.c:1047)
bpf_prog_test_run_raw_tp (net/bpf/test_run.c:829)
__sys_bpf (kernel/bpf/syscall.c:4804)
do_syscall_64 (arch/x86/entry/syscall_64.c:84)
entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Resolve the var's type directly with btf_type_skip_modifiers() when
resolved_ids is NULL, mirroring btf_modifier_show().
Fixes: c4d0bfb45068 ("bpf: Add bpf_snprintf_btf helper")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Acked-by: Ihor Solodrai <ihor.solodrai@linux.dev>
Link: https://lore.kernel.org/r/20260901104924.346187-4-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index f64eb43cb1f04..8b88771571b42 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -2926,7 +2926,15 @@ static void btf_var_show(const struct btf *btf, const struct btf_type *t,
u32 type_id, void *data, u8 bits_offset,
struct btf_show *show)
{
- t = btf_type_id_resolve(btf, &type_id);
+ /*
+ * btf_type_id_resolve() dereferences btf->resolved_ids, which is NULL
+ * for a base BTF (e.g. the vmlinux BTF that bpf_snprintf_btf() uses).
+ * Resolve the var's type directly in that case.
+ */
+ if (btf->resolved_ids)
+ t = btf_type_id_resolve(btf, &type_id);
+ else
+ t = btf_type_skip_modifiers(btf, t->type, &type_id);
btf_type_ops(t)->show(btf, t, type_id, data, bits_offset, show);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 229/733] bpf: Mark signal tracepoint siginfo arguments as scalar
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (227 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 228/733] bpf: Fix NULL-ptr-deref in btf_var_show() Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 230/733] bpf: Reject tail calls directly from callback frames Greg Kroah-Hartman
` (515 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 77515ab12e4983e6416f8c35039a3f0c0822ac70 ]
The signal_generate and signal_deliver tracepoints declare their info
argument as a struct kernel_siginfo pointer. btf_ctx_access() therefore
treats it as a trusted pointer for tp_btf programs.
Signal delivery also uses SEND_SIG_NOINFO and SEND_SIG_PRIV as special
values for this argument. Those values are zero and one respectively,
and are not pointers. A tp_btf program can currently dereference either
value and fault the kernel. In particular, signal_generate can run from
timer interrupt context, turning the fault into a kernel panic.
Record both tracepoints in raw_tp_null_args[] and mark argument one as
a non-pointer. This preserves scalar access to the cookie while rejecting
direct and helper-mediated pointer use. Merely marking it nullable would
not suffice because SEND_SIG_PRIV is nonzero.
Fixes: 838a10bd2ebf ("bpf: Augment raw_tp arguments with PTR_MAYBE_NULL")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 8b88771571b42..0f7b4006a08f4 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6740,6 +6740,9 @@ static const struct bpf_raw_tp_null_args raw_tp_null_args[] = {
{ "rxrpc_resend", 0x10 },
{ "rxrpc_tq", 0x10 },
{ "rxrpc_client", 0x1 },
+ /* signal */
+ { "signal_generate", 0x20 },
+ { "signal_deliver", 0x20 },
/* skb */
{"kfree_skb", 0x1000},
/* sunrpc */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 230/733] bpf: Reject tail calls directly from callback frames
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (228 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 229/733] bpf: Mark signal tracepoint siginfo arguments as scalar Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:08 ` [PATCH 7.2 231/733] bpf: Reject resilient lock operations in rbtree callbacks Greg Kroah-Hartman
` (514 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 266aa4ad0b2e82397cd9045752c9bff03d98eddd ]
A tail call from a non-zero frame is modeled as a return from that frame.
The verifier makes R0 unknown and calls prepare_func_exit() for the taken
branch.
When the current frame is a synchronous callback, prepare_func_exit()
enforces the callback return-value contract and marks R0 precise. Since the
tail-call path synthesized R0 rather than deriving it from an instruction,
precision backtracking reaches the callback-calling instruction with R0
still requested and triggers the "callback unexpected regs" verifier bug.
A CAP_BPF task can therefore cause a WARN and an -EFAULT BPF_PROG_LOAD.
Tail calls reachable from callbacks are already rejected later by
check_max_stack_depth(). Reject a tail call made directly by a callback
before constructing the inconsistent return state, using the existing
diagnostic. Tail calls from ordinary subprograms keep their current
behavior.
Fixes: e3245f899043 ("bpf: properly verify tail call behavior")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 11 +++++++++++
1 file changed, 11 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index b0118bccf3280..aeb5711211245 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -10672,6 +10672,17 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
if (env->cur_state->curframe) {
struct bpf_verifier_state *branch;
+ /*
+ * A taken tail call is modeled as a return from the current
+ * frame. A callback frame cannot be left that way because
+ * prepare_func_exit() would apply its return contract to the
+ * unknown R0 synthesized below. Stack-depth validation rejects
+ * this construct anyway.
+ */
+ if (cur_func(env)->in_callback_fn) {
+ verbose(env, "cannot tail call within callback\n");
+ return -EINVAL;
+ }
mark_reg_scratched(env, BPF_REG_0);
branch = push_stack(env, env->insn_idx + 1, env->insn_idx, false);
if (IS_ERR(branch))
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 231/733] bpf: Reject resilient lock operations in rbtree callbacks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (229 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 230/733] bpf: Reject tail calls directly from callback frames Greg Kroah-Hartman
@ 2026-09-17 15:08 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 232/733] bpf: Mark sched_process_wait argument as nullable Greg Kroah-Hartman
` (513 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:08 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 7b7b8b5960102566bd625ae829d1f330c5b5d104 ]
__bpf_rbtree_add() keeps parent and link pointers live across calls to the
program-supplied comparison callback. The verifier therefore requires the
root's lock to remain held throughout the callback.
The helper path enforces this rule for bpf_spin_lock() and
bpf_spin_unlock(), but the resilient lock kfunc argument path does not.
Since resilient locks may protect BPF rbtree roots, a callback can release
the root lock and let another CPU remove and free the node referenced by
the in-progress tree walk. The walk then resumes using freed pointers.
Reject resilient lock kfuncs in an rbtree comparison callback, matching
the existing policy for the spin lock helpers. Resilient-lock-protected
trees remain valid when their comparison callbacks leave lock state alone.
Fixes: 0de2046137f9 ("bpf: Implement verifier support for rqspinlock")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-6-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index aeb5711211245..bc5aea31df589 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12544,6 +12544,11 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
{
int flags = PROCESS_RES_LOCK;
+ if (in_rbtree_lock_required_cb(env)) {
+ verbose(env, "can't res_spin_{lock,unlock} in rbtree cb\n");
+ return -EACCES;
+ }
+
if (reg->type != PTR_TO_MAP_VALUE && reg->type != (PTR_TO_BTF_ID | MEM_ALLOC)) {
verbose(env, "%s doesn't point to map value or allocated object\n",
reg_arg_name(env, argno));
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 232/733] bpf: Mark sched_process_wait argument as nullable
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (230 preceding siblings ...)
2026-09-17 15:08 ` [PATCH 7.2 231/733] bpf: Reject resilient lock operations in rbtree callbacks Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 233/733] bpf: Mark syscall helpers as sleepable Greg Kroah-Hartman
` (512 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit a453d6e3b8e8e1a321c8744d6189d763af9287d0 ]
do_wait() passes wo->wo_pid to the sched_process_wait tracepoint.
kernel_wait4() leaves wo_pid NULL for wait4(-1), and
kernel_waitid_prepare() does likewise for waitid(P_ALL).
btf_ctx_access() currently types argument 0 as PTR_TO_BTF_ID |
PTR_TRUSTED. Without PTR_MAYBE_NULL, the verifier accepts an unchecked
dereference. Trusted pointer loads have no fault protection, so a wait for
any child can then cause a NULL pointer dereference in JITed BPF code.
Add sched_process_wait to raw_tp_null_args[] with argument 0 marked
nullable. The verifier rejects an unchecked dereference while preserving
access after the program checks the pointer for NULL.
Fixes: 838a10bd2ebf ("bpf: Augment raw_tp arguments with PTR_MAYBE_NULL")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-8-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 0f7b4006a08f4..96b38fce885d3 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -6673,6 +6673,10 @@ struct bpf_raw_tp_null_args {
static const struct bpf_raw_tp_null_args raw_tp_null_args[] = {
/* sched */
{ "sched_pi_setprio", 0x10 },
+ /*
+ * do_wait() passes NULL for wait4(-1) and waitid(P_ALL).
+ */
+ { "sched_process_wait", 0x1 },
/* ... from sched_numa_pair_template event class */
{ "sched_stick_numa", 0x100 },
{ "sched_swap_numa", 0x100 },
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 233/733] bpf: Mark syscall helpers as sleepable
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (231 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 232/733] bpf: Mark sched_process_wait argument as nullable Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 234/733] ring-buffer: Add checking nr_subbufs to persistent ring buffer validation Greg Kroah-Hartman
` (511 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit d05524794240b52fdc3b6c1220dd05505715824d ]
bpf_sys_bpf() executes the bpf(2) syscall body, which can take mutexes,
allocate with GFP_KERNEL, and wait for an RCU grace period.
bpf_sys_close() reaches close_fd() and filp_close(), which can sleep as
well.
Both helpers are limited to BPF_PROG_TYPE_SYSCALL, whose main program is
sleepable. That does not make every callback sleepable: a syscall program
can register a bpf_timer callback, and the verifier checks that callback
in a non-sleepable context while retaining the syscall helper set.
Without .might_sleep on the prototypes, such a callback can invoke
bpf_sys_bpf() from hrtimer softirq context and trigger a
scheduling-while-atomic failure. bpf_sys_close() is exposed through the
same missing context check.
Set .might_sleep on both prototypes so the existing helper-context check
rejects them from timer callbacks and other atomic regions. Calls from the
sleepable main body remain valid.
Fixes: 79a7f8bdb159 ("bpf: Introduce bpf_sys_bpf() helper and program type.")
Fixes: 3abea089246f ("bpf: Add bpf_sys_close() helper.")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903144433.1716731-10-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/syscall.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/bpf/syscall.c b/kernel/bpf/syscall.c
index fb678b9dcd3e6..c7cb336fb0648 100644
--- a/kernel/bpf/syscall.c
+++ b/kernel/bpf/syscall.c
@@ -6633,6 +6633,7 @@ EXPORT_SYMBOL_NS(kern_sys_bpf, "BPF_INTERNAL");
static const struct bpf_func_proto bpf_sys_bpf_proto = {
.func = bpf_sys_bpf,
.gpl_only = false,
+ .might_sleep = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_ANYTHING,
.arg2_type = ARG_PTR_TO_MEM | MEM_RDONLY,
@@ -6658,6 +6659,7 @@ BPF_CALL_1(bpf_sys_close, u32, fd)
static const struct bpf_func_proto bpf_sys_close_proto = {
.func = bpf_sys_close,
.gpl_only = false,
+ .might_sleep = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_ANYTHING,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 234/733] ring-buffer: Add checking nr_subbufs to persistent ring buffer validation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (232 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 233/733] bpf: Mark syscall helpers as sleepable Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 235/733] nvme: remove stale namespaces by NSID range during scan Greg Kroah-Hartman
` (510 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Vincent Donnefort,
Steven Rostedt, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 6c001a62c34f13fe1c6a24304c289b387d9e697d ]
Sashiko reported that the code was using meta->nr_subbufs without making
sure that it matched the nr_pages + 1 on data that was assuming the two
were the same.
Add a check to the persistent ring buffer validation code to make sure
that the saved nr_subbufs matches what we expect.
Link: https://patch.msgid.link/20260903132728.7fb27d34@gandalf.local.home
Fixes: f5b95f1fa2ef3 ("ring-buffer: Validate the persistent meta data subbuf array")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260901164836.D962D1F000E9@smtp.kernel.org/
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/ring_buffer.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 1925ee9cc36da..70e43fe3a1006 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -1836,6 +1836,11 @@ static bool rb_cpu_meta_valid(struct ring_buffer_cpu_meta *meta, int cpu,
return false;
}
+ if (meta->nr_subbufs != nr_pages + 1) {
+ pr_info("Ring buffer boot meta [%d] invalid nr_subbufs\n", cpu);
+ return false;
+ }
+
buffers_start = meta->first_buffer;
buffers_end = meta->first_buffer + (subbuf_size * meta->nr_subbufs);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 235/733] nvme: remove stale namespaces by NSID range during scan
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (233 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 234/733] ring-buffer: Add checking nr_subbufs to persistent ring buffer validation Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 236/733] nvme: print namespace IDs as unsigned 32bit value Greg Kroah-Hartman
` (509 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mohamed Khalfella, Sagi Grimberg,
Randy Jennings, Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Khalfella <mkhalfella@purestorage.com>
[ Upstream commit 4ed7f3d7d435bf5b63da2814dc9270f5ba896011 ]
nvme_scan_ns_list() drops the stale namespaces in each gap in the
reported NSID list one NSID at a time. Every iteration calls
nvme_find_get_ns() to look the namespace up and removes it if it is
present. The loop runs once per NSID in the gap rather than once per
namespace actually present.
NSIDs are 32-bit, so a target with a sparse NSID space can make a
single gap spin the loop billions of times with nothing to remove.
watchdog: BUG: soft lockup - CPU#4 stuck for 26s!
Workqueue: nvme-wq nvme_scan_work [nvme_core]
RIP: 0010:__srcu_read_unlock+0xb/0x20
Call Trace:
nvme_find_get_ns+0x7d/0xb0 [nvme_core]
nvme_scan_ns_list+0xe8/0x280 [nvme_core]
nvme_scan_work+0x18a/0x280 [nvme_core]
process_one_work+0x197/0x380
worker_thread+0x2fe/0x410
kthread+0xe0/0x100
Rename nvme_remove_invalid_namespaces() to nvme_remove_nsid_range()
and give it an open (start, end) NSID range. ctrl->namespaces is
sorted by NSID, so the whole gap is dropped in a single walk that
stops once end is reached. This bounds the work by the namespaces
that are present instead of by the size of the gap.
Fixes: 540c801c65eb ("NVMe: Implement namespace list scanning")
Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Reviewed-by: Randy Jennings <randyj@purestorage.com>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 18 +++++++++---------
1 file changed, 9 insertions(+), 9 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 706df45b26e77..3dd2466105b7a 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -148,8 +148,6 @@ static const struct class nvme_ns_chr_class = {
};
static void nvme_put_subsystem(struct nvme_subsystem *subsys);
-static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
- unsigned nsid);
static void nvme_update_keep_alive(struct nvme_ctrl *ctrl,
struct nvme_command *cmd);
static int nvme_get_log_lsi(struct nvme_ctrl *ctrl, u32 nsid, u8 log_page,
@@ -4485,15 +4483,16 @@ static void nvme_scan_ns_async(void *data, async_cookie_t cookie)
nvme_scan_ns(scan_info->ctrl, nsid);
}
-static void nvme_remove_invalid_namespaces(struct nvme_ctrl *ctrl,
- unsigned nsid)
+static void nvme_remove_nsid_range(struct nvme_ctrl *ctrl, u32 start, u32 end)
{
struct nvme_ns *ns, *next;
LIST_HEAD(rm_list);
mutex_lock(&ctrl->namespaces_lock);
list_for_each_entry_safe(ns, next, &ctrl->namespaces, list) {
- if (ns->head->ns_id > nsid) {
+ if (ns->head->ns_id >= end)
+ break;
+ if (ns->head->ns_id > start) {
list_del_rcu(&ns->list);
synchronize_srcu(&ctrl->srcu);
list_add_tail_rcu(&ns->list, &rm_list);
@@ -4543,13 +4542,14 @@ static int nvme_scan_ns_list(struct nvme_ctrl *ctrl)
goto out;
async_schedule_domain(nvme_scan_ns_async, &scan_info,
&domain);
- while (++prev < nsid)
- nvme_ns_remove_by_nsid(ctrl, prev);
+ if (prev + 1 < nsid)
+ nvme_remove_nsid_range(ctrl, prev, nsid);
+ prev = max(prev + 1, nsid);
}
async_synchronize_full_domain(&domain);
}
out:
- nvme_remove_invalid_namespaces(ctrl, prev);
+ nvme_remove_nsid_range(ctrl, prev, UINT_MAX);
free:
async_synchronize_full_domain(&domain);
kfree(ns_list);
@@ -4569,7 +4569,7 @@ static void nvme_scan_ns_sequential(struct nvme_ctrl *ctrl)
for (i = 1; i <= nn; i++)
nvme_scan_ns(ctrl, i);
- nvme_remove_invalid_namespaces(ctrl, nn);
+ nvme_remove_nsid_range(ctrl, nn, UINT_MAX);
}
static void nvme_clear_changed_ns_log(struct nvme_ctrl *ctrl)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 236/733] nvme: print namespace IDs as unsigned 32bit value
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (234 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 235/733] nvme: remove stale namespaces by NSID range during scan Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 237/733] nvmet: " Greg Kroah-Hartman
` (508 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mohamed Khalfella, Sagi Grimberg,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Khalfella <mkhalfella@purestorage.com>
[ Upstream commit b2d8f2a3723103abd0f8b388691ad95817d4fff4 ]
NSIDs are 32-bit unsigned values, but a number of log messages print
them with %d. An NSID larger than 0x7fffffff is rendered as a negative
number, which is confusing in the kernel log and makes the message hard
to correlate with the namespace it talks about. Sparse NSID spaces
where high NSIDs are common are the most likely to hit this.
The nsid sysfs attribute has the same problem, and there it is worse
because userspace parses the value.
For example:
$ grep . /sys/class/block/nvme0*/nsid
/sys/class/block/nvme0c0n1/nsid:10
/sys/class/block/nvme0c0n2/nsid:-16
/sys/class/block/nvme0c0n3/nsid:11
/sys/class/block/nvme0c0n4/nsid:-2000000016
/sys/class/block/nvme0n1/nsid:10
/sys/class/block/nvme0n2/nsid:-16
/sys/class/block/nvme0n3/nsid:11
/sys/class/block/nvme0n4/nsid:-2000000016
$
Print all of them with %u. Several messages in these files, including
two in zns.c right next to the ones being changed, already use %u, so
this only makes the rest consistent with them. No functional change
other than how the NSID is formatted.
Fixes: 2b9b6e86bca7 ("NVMe: Export namespace attributes to sysfs")
Fixes: 1d5df6af8c74 ("nvme: don't blindly overwrite identifiers on disk revalidate")
Fixes: ed754e5deeb1 ("nvme: track shared namespaces")
Fixes: 9ad1927a3bc2 ("nvme: always search for namespace head")
Fixes: 71010c309454 ("nvme: implement multiple I/O Command Set support")
Fixes: 2f4c9ba23b88 ("nvme: export zoned namespaces without Zone Append support read-only")
Fixes: 0ec84df4953b ("nvme-core: check ctrl css before setting up zns")
Fixes: 2079f41ec6ff ("nvme: check that EUI/GUID/UUID are globally unique")
Fixes: ce8d78616a6b ("nvme: warn about shared namespaces without CONFIG_NVME_MULTIPATH")
Fixes: ac522fc6c316 ("nvme: don't reject probe due to duplicate IDs for single-ported PCIe devices")
Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/core.c | 18 +++++++++---------
drivers/nvme/host/sysfs.c | 2 +-
drivers/nvme/host/zns.c | 4 ++--
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/drivers/nvme/host/core.c b/drivers/nvme/host/core.c
index 3dd2466105b7a..a73cc6a43f5e6 100644
--- a/drivers/nvme/host/core.c
+++ b/drivers/nvme/host/core.c
@@ -1592,7 +1592,7 @@ static int nvme_identify_ns_descs(struct nvme_ctrl *ctrl,
}
if (nvme_multi_css(ctrl) && !csi_seen) {
- dev_warn(ctrl->device, "Command set not reported for nsid:%d\n",
+ dev_warn(ctrl->device, "Command set not reported for nsid:%u\n",
info->nsid);
status = -EINVAL;
}
@@ -4095,13 +4095,13 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
((ns->ctrl->subsys->cmic & NVME_CTRL_CMIC_MULTI_CTRL) &&
info->is_shared)) {
dev_err(ctrl->device,
- "ignoring nsid %d because of duplicate IDs\n",
+ "ignoring nsid %u because of duplicate IDs\n",
info->nsid);
return ret;
}
dev_err(ctrl->device,
- "clearing duplicate IDs for nsid %d\n", info->nsid);
+ "clearing duplicate IDs for nsid %u\n", info->nsid);
dev_err(ctrl->device,
"use of /dev/disk/by-id/ may cause data corruption\n");
memset(&info->ids.nguid, 0, sizeof(info->ids.nguid));
@@ -4116,7 +4116,7 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
ret = nvme_subsys_check_duplicate_ids(ctrl->subsys, &info->ids);
if (ret) {
dev_err(ctrl->device,
- "duplicate IDs in subsystem for nsid %d\n",
+ "duplicate IDs in subsystem for nsid %u\n",
info->nsid);
goto out_unlock;
}
@@ -4130,20 +4130,20 @@ static int nvme_init_ns_head(struct nvme_ns *ns, struct nvme_ns_info *info)
if ((!info->is_shared || !head->shared) &&
!list_empty(&head->list)) {
dev_err(ctrl->device,
- "Duplicate unshared namespace %d\n",
+ "Duplicate unshared namespace %u\n",
info->nsid);
goto out_put_ns_head;
}
if (!nvme_ns_ids_equal(&head->ids, &info->ids)) {
dev_err(ctrl->device,
- "IDs don't match for shared namespace %d\n",
+ "IDs don't match for shared namespace %u\n",
info->nsid);
goto out_put_ns_head;
}
if (!multipath) {
dev_warn(ctrl->device,
- "Found shared namespace %d, but multipathing not supported.\n",
+ "Found shared namespace %u, but multipathing not supported.\n",
info->nsid);
dev_warn_once(ctrl->device,
"Shared namespace support requires core_nvme.multipath=Y.\n");
@@ -4392,7 +4392,7 @@ static void nvme_validate_ns(struct nvme_ns *ns, struct nvme_ns_info *info)
if (!nvme_ns_ids_equal(&ns->head->ids, &info->ids)) {
dev_err(ns->ctrl->device,
- "identifiers changed for nsid %d\n", ns->head->ns_id);
+ "identifiers changed for nsid %u\n", ns->head->ns_id);
goto out;
}
@@ -4419,7 +4419,7 @@ static void nvme_scan_ns(struct nvme_ctrl *ctrl, unsigned nsid)
if (info.ids.csi != NVME_CSI_NVM && !nvme_multi_css(ctrl)) {
dev_warn(ctrl->device,
- "command set not reported for nsid: %d\n", nsid);
+ "command set not reported for nsid: %u\n", nsid);
return;
}
diff --git a/drivers/nvme/host/sysfs.c b/drivers/nvme/host/sysfs.c
index 75b2d69b59578..be94739e17dcf 100644
--- a/drivers/nvme/host/sysfs.c
+++ b/drivers/nvme/host/sysfs.c
@@ -166,7 +166,7 @@ static DEVICE_ATTR_RO(eui);
static ssize_t nsid_show(struct device *dev, struct device_attribute *attr,
char *buf)
{
- return sysfs_emit(buf, "%d\n", dev_to_ns_head(dev)->ns_id);
+ return sysfs_emit(buf, "%u\n", dev_to_ns_head(dev)->ns_id);
}
static DEVICE_ATTR_RO(nsid);
diff --git a/drivers/nvme/host/zns.c b/drivers/nvme/host/zns.c
index 8ed1b6a33454e..9477cfbd3a513 100644
--- a/drivers/nvme/host/zns.c
+++ b/drivers/nvme/host/zns.c
@@ -48,12 +48,12 @@ int nvme_query_zone_info(struct nvme_ns *ns, unsigned lbaf,
NVME_CMD_EFFECTS_CSUPP)) {
if (test_and_clear_bit(NVME_NS_FORCE_RO, &ns->flags))
dev_warn(ns->ctrl->device,
- "Zone Append supported for zoned namespace:%d. Remove read-only mode\n",
+ "Zone Append supported for zoned namespace:%u. Remove read-only mode\n",
ns->head->ns_id);
} else {
set_bit(NVME_NS_FORCE_RO, &ns->flags);
dev_warn(ns->ctrl->device,
- "Zone Append not supported for zoned namespace:%d. Forcing to read-only mode\n",
+ "Zone Append not supported for zoned namespace:%u. Forcing to read-only mode\n",
ns->head->ns_id);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 237/733] nvmet: print namespace IDs as unsigned 32bit value
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (235 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 236/733] nvme: print namespace IDs as unsigned 32bit value Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 238/733] nvme-tcp: defer TLS inline send to io_work Greg Kroah-Hartman
` (507 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mohamed Khalfella, Sagi Grimberg,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mohamed Khalfella <mkhalfella@purestorage.com>
[ Upstream commit 59fe1cbc57235495a5f08dd53db176e3e3250356 ]
struct nvmet_ns.nsid is a u32, but a few messages print it with %d.
An NSID larger than 0x7fffffff is rendered as a negative number, which
is misleading in general and particularly so for the configfs messages
that echo back the NSID the user just asked for.
For example:
[ T200] nvmet: adding nsid -16 to subsystem mysubsystem
Print them with %u. The invalid-NSID error in nvmet_ns_make() keeps its
%#x because the two values it rejects, 0 and NVME_NSID_ALL, are more
readable in hex format. No functional change other than how the NSID is
formatted.
Fixes: a07b4970f464 ("nvmet: add a generic NVMe target")
Fixes: c6925093d0b2 ("nvmet: Optionally use PCI P2P memory")
Fixes: 5a47c2080a73 ("nvmet: support reservation feature")
Signed-off-by: Mohamed Khalfella <mkhalfella@purestorage.com>
Reviewed-by: Sagi Grimberg <sagi@grimberg.me>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/target/configfs.c | 4 ++--
drivers/nvme/target/core.c | 2 +-
drivers/nvme/target/pr.c | 2 +-
3 files changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/nvme/target/configfs.c b/drivers/nvme/target/configfs.c
index 413ee2d16d29c..6286e38436ddf 100644
--- a/drivers/nvme/target/configfs.c
+++ b/drivers/nvme/target/configfs.c
@@ -814,7 +814,7 @@ static ssize_t nvmet_ns_resv_enable_store(struct config_item *item,
mutex_lock(&ns->subsys->lock);
if (ns->enabled) {
- pr_err("the ns:%d is already enabled.\n", ns->nsid);
+ pr_err("the ns:%u is already enabled.\n", ns->nsid);
mutex_unlock(&ns->subsys->lock);
return -EINVAL;
}
@@ -880,7 +880,7 @@ static struct config_group *nvmet_ns_make(struct config_group *group,
goto out;
config_group_init_type_name(&ns->group, name, &nvmet_ns_type);
- pr_info("adding nsid %d to subsystem %s\n", nsid, subsys->subsysnqn);
+ pr_info("adding nsid %u to subsystem %s\n", nsid, subsys->subsysnqn);
return &ns->group;
out:
diff --git a/drivers/nvme/target/core.c b/drivers/nvme/target/core.c
index 23fa90ec3c00e..269daefb88854 100644
--- a/drivers/nvme/target/core.c
+++ b/drivers/nvme/target/core.c
@@ -558,7 +558,7 @@ static void nvmet_p2pmem_ns_add_p2p(struct nvmet_ctrl *ctrl,
if (ret < 0)
pci_dev_put(p2p_dev);
- pr_info("using p2pmem on %s for nsid %d\n", pci_name(p2p_dev),
+ pr_info("using p2pmem on %s for nsid %u\n", pci_name(p2p_dev),
ns->nsid);
}
diff --git a/drivers/nvme/target/pr.c b/drivers/nvme/target/pr.c
index 7d937093b2262..ad07f55e7f173 100644
--- a/drivers/nvme/target/pr.c
+++ b/drivers/nvme/target/pr.c
@@ -145,7 +145,7 @@ static void nvmet_pr_add_resv_log(struct nvmet_ctrl *ctrl, u8 log_type,
log.nsid = cpu_to_le32(nsid);
if (!kfifo_put(&log_mgr->log_queue, log)) {
- pr_info("a reservation log lost, cntlid:%d, log_type:%d, nsid:%d\n",
+ pr_info("a reservation log lost, cntlid:%d, log_type:%d, nsid:%u\n",
ctrl->cntlid, log_type, nsid);
log_mgr->lost_count++;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 238/733] nvme-tcp: defer TLS inline send to io_work
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (236 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 237/733] nvmet: " Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 239/733] ASoC: Intel: avs: Clean up the bus when fetching ML caps fails Greg Kroah-Hartman
` (506 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hannes Reinecke, Xixin Liu,
Keith Busch, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
[ Upstream commit 08acb54b063a33730eb1ae1e0f89bf36542bac9f ]
blk_mq holds set->srcu while queuing and running requests. The kTLS
software send path takes ctx->tx_lock. lockdep knows that tx_lock
nests under elevator_lock which then waits on srcu, so an inline
send from that path under TLS triggers circular locking.
Skip the inline send optimization for TLS queues so the send runs
from the workqueue instead. The same workqueue already retries TLS
sends on write-space notifications. Plain TCP keeps the inline path.
Fixes: be8e82caa685 ("nvme-tcp: enable TLS handshake upcall")
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Signed-off-by: Keith Busch <kbusch@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/nvme/host/tcp.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/nvme/host/tcp.c b/drivers/nvme/host/tcp.c
index ddbb34a22f688..52efc6e4f7623 100644
--- a/drivers/nvme/host/tcp.c
+++ b/drivers/nvme/host/tcp.c
@@ -411,8 +411,13 @@ static inline void nvme_tcp_queue_request(struct nvme_tcp_request *req,
* if we're the first on the send_list and we can try to send
* directly, otherwise queue io_work. Also, only do that if we
* are on the same cpu, so we don't introduce contention.
+ *
+ * TLS kTLS send takes ctx->tx_lock while blk_mq holds set->srcu.
+ * lockdep reports circular locking via elevator_lock. Defer TLS
+ * sends to the io workqueue instead of inline from this path.
*/
if (queue->io_cpu == raw_smp_processor_id() &&
+ !nvme_tcp_queue_tls(queue) &&
empty && mutex_trylock(&queue->send_mutex)) {
nvme_tcp_send_all(queue);
mutex_unlock(&queue->send_mutex);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 239/733] ASoC: Intel: avs: Clean up the bus when fetching ML caps fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (237 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 238/733] nvme-tcp: defer TLS inline send to io_work Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 240/733] ASoC: Intel: avs: Clean up streams if their initialization fails Greg Kroah-Hartman
` (505 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amadeusz Sławiński,
Cezary Rojewski, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit 559ea14b7ae7c7562b48759fa545b64958f35b73 ]
snd_hdac_ext_bus_get_ml_capabilities() may fail and its return code
shall be checked and accounted for. Address the issue by updating the
error-path for avs_pci_probe().
At the same time, if the function in question succeeds but the next part
of avs_pci_probe() fails, the hlink list shall be cleaned up before
leaving the scope.
Fixes: 1affc44ea5dd ("ASoC: Intel: avs: PCI driver implementation")
Co-developed-by: Amadeusz Sławiński <amade@asmblr.net>
Signed-off-by: Amadeusz Sławiński <amade@asmblr.net>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260902081814.1590883-5-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/avs/core.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index 1a53856c2ffbe..a6b877f41e8b2 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -473,8 +473,13 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
}
snd_hdac_bus_parse_capabilities(bus);
- if (bus->mlcap)
- snd_hdac_ext_bus_get_ml_capabilities(bus);
+ if (bus->mlcap) {
+ ret = snd_hdac_ext_bus_get_ml_capabilities(bus);
+ if (ret < 0) {
+ dev_err(dev, "failed to get ml capabilities: %d\n", ret);
+ goto err_ml_cap;
+ }
+ }
if (dma_set_mask_and_coherent(dev, DMA_BIT_MASK(64)))
dma_set_mask_and_coherent(dev, DMA_BIT_MASK(32));
@@ -516,6 +521,8 @@ static int avs_pci_probe(struct pci_dev *pci, const struct pci_device_id *id)
snd_hdac_bus_free_stream_pages(bus);
snd_hdac_ext_stream_free_all(bus);
err_init_streams:
+ snd_hdac_ext_link_free_all(bus);
+err_ml_cap:
iounmap(adev->dsp_ba);
err_remap_bar4:
iounmap(bus->remap_addr);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 240/733] ASoC: Intel: avs: Clean up streams if their initialization fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (238 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 239/733] ASoC: Intel: avs: Clean up the bus when fetching ML caps fails Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 241/733] ASoC: Intel: avs: Do not ignore -ENOENT when loading a topology Greg Kroah-Hartman
` (504 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Amadeusz Sławiński,
Cezary Rojewski, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit f4ba00bb56a8511bafbd19826501d27157141c6d ]
When streams are being initialized the memory allocation may fail.
Have an error path and return early if that is the case.
Fixes: 1affc44ea5dd ("ASoC: Intel: avs: PCI driver implementation")
Co-developed-by: Amadeusz Sławiński <amade@asmblr.net>
Signed-off-by: Amadeusz Sławiński <amade@asmblr.net>
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260902081814.1590883-6-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/avs/core.c | 18 +++++++++++++++---
1 file changed, 15 insertions(+), 3 deletions(-)
diff --git a/sound/soc/intel/avs/core.c b/sound/soc/intel/avs/core.c
index a6b877f41e8b2..29e67c0502e8c 100644
--- a/sound/soc/intel/avs/core.c
+++ b/sound/soc/intel/avs/core.c
@@ -91,16 +91,28 @@ static int avs_hdac_bus_init_streams(struct hdac_bus *bus)
{
unsigned int cp_streams, pb_streams;
unsigned int gcap;
+ int ret;
gcap = snd_hdac_chip_readw(bus, GCAP);
cp_streams = (gcap >> 8) & 0x0F;
pb_streams = (gcap >> 12) & 0x0F;
bus->num_streams = cp_streams + pb_streams;
- snd_hdac_ext_stream_init_all(bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE);
- snd_hdac_ext_stream_init_all(bus, cp_streams, pb_streams, SNDRV_PCM_STREAM_PLAYBACK);
+ ret = snd_hdac_ext_stream_init_all(bus, 0, cp_streams, SNDRV_PCM_STREAM_CAPTURE);
+ if (ret)
+ return ret;
+ ret = snd_hdac_ext_stream_init_all(bus, cp_streams, pb_streams, SNDRV_PCM_STREAM_PLAYBACK);
+ if (ret)
+ goto err;
+
+ ret = snd_hdac_bus_alloc_stream_pages(bus);
+ if (ret)
+ goto err;
- return snd_hdac_bus_alloc_stream_pages(bus);
+ return 0;
+err:
+ snd_hdac_ext_stream_free_all(bus);
+ return ret;
}
static bool avs_hdac_bus_init_chip(struct hdac_bus *bus, bool full_reset)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 241/733] ASoC: Intel: avs: Do not ignore -ENOENT when loading a topology
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (239 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 240/733] ASoC: Intel: avs: Clean up streams if their initialization fails Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 242/733] ASoC: Intel: avs: Fix unbalanced module reference count Greg Kroah-Hartman
` (503 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cezary Rojewski, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit c6dceca9f78fbd478c41735457c4de9c25a6b1c8 ]
avs_load_topology() combines request_firmware() and
snd_soc_tplg_component_load(). The fallback mechanism introduced for
the HDAudio based boards honors -ENOENT and checks for a generic
topology if no specific is found before giving up and failing the
component probing.
However, if -ENOENT is returned by the latter function -
snd_soc_tplg_component_load() - is shall not be ignored. That means
there is an actual problem with the topology file and no fallback shall
be attempted.
Fixes: 739c031110da ("ASoC: Intel: avs: Provide support for fallback topology")
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260902081814.1590883-7-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/avs/pcm.c | 34 ++++++++++++++++++++--------------
sound/soc/intel/avs/topology.c | 2 +-
sound/soc/intel/avs/topology.h | 1 +
3 files changed, 22 insertions(+), 15 deletions(-)
diff --git a/sound/soc/intel/avs/pcm.c b/sound/soc/intel/avs/pcm.c
index 797b9c9163b49..094ea1366ea8f 100644
--- a/sound/soc/intel/avs/pcm.c
+++ b/sound/soc/intel/avs/pcm.c
@@ -6,6 +6,7 @@
// Amadeusz Slawinski <amadeuszx.slawinski@linux.intel.com>
//
+#include <linux/cleanup.h>
#include <linux/debugfs.h>
#include <linux/device.h>
#include <sound/hda_register.h>
@@ -987,13 +988,25 @@ static int avs_component_load_libraries(struct avs_soc_component *acomp)
return ret;
}
+static int avs_request_topology(struct snd_soc_component *component, const char *name,
+ const struct firmware **fw)
+{
+ char *fullname __free(kfree) = NULL;
+
+ fullname = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix, name);
+ if (!fullname)
+ return -ENOMEM;
+
+ return request_firmware(fw, fullname, component->dev);
+}
+
static int avs_component_probe(struct snd_soc_component *component)
{
struct snd_soc_card *card = component->card;
struct snd_soc_acpi_mach *mach;
struct avs_soc_component *acomp;
+ const struct firmware *fw;
struct avs_dev *adev;
- char *filename;
int ret;
dev_dbg(card->dev, "probing %s card %s\n", component->name, card->name);
@@ -1009,13 +1022,7 @@ static int avs_component_probe(struct snd_soc_component *component)
goto finalize;
/* Load specified topology and create debugfs for it. */
- filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
- mach->tplg_filename);
- if (!filename)
- return -ENOMEM;
-
- ret = avs_load_topology(component, filename);
- kfree(filename);
+ ret = avs_request_topology(component, mach->tplg_filename, &fw);
if (ret == -ENOENT && !strncmp(mach->tplg_filename, "hda-", 4)) {
unsigned int vendor_id;
@@ -1030,18 +1037,17 @@ static int avs_component_probe(struct snd_soc_component *component)
"hda-generic-tplg.bin");
if (!mach->tplg_filename)
return -ENOMEM;
- filename = kasprintf(GFP_KERNEL, "%s/%s", component->driver->topology_name_prefix,
- mach->tplg_filename);
- if (!filename)
- return -ENOMEM;
dev_info(card->dev, "trying to load fallback topology %s\n", mach->tplg_filename);
- ret = avs_load_topology(component, filename);
- kfree(filename);
+ ret = avs_request_topology(component, mach->tplg_filename, &fw);
}
if (ret < 0)
return ret;
+ ret = snd_soc_tplg_component_load(component, &avs_tplg_ops, fw);
+ if (ret)
+ return ret;
+
ret = avs_component_load_libraries(acomp);
if (ret < 0) {
dev_err(card->dev, "libraries loading failed: %d\n", ret);
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index 9033f683393c4..0a267937044de 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -2194,7 +2194,7 @@ avs_control_load(struct snd_soc_component *comp, int index, struct snd_kcontrol_
return 0;
}
-static const struct snd_soc_tplg_ops avs_tplg_ops = {
+const struct snd_soc_tplg_ops avs_tplg_ops = {
.io_ops = avs_control_ops,
.io_ops_count = ARRAY_SIZE(avs_control_ops),
.control_load = avs_control_load,
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index 1cf7455b6c010..b5799c994b887 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -230,6 +230,7 @@ struct avs_tplg_module {
struct list_head node;
};
+extern const struct snd_soc_tplg_ops avs_tplg_ops;
struct avs_tplg *avs_tplg_new(struct snd_soc_component *comp);
int avs_load_topology(struct snd_soc_component *comp, const char *filename);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 242/733] ASoC: Intel: avs: Fix unbalanced module reference count
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (240 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 241/733] ASoC: Intel: avs: Do not ignore -ENOENT when loading a topology Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 243/733] ASoC: Intel: avs: Refactor and fix init_config access Greg Kroah-Hartman
` (502 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cezary Rojewski, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit d4fa6f94b91137e329ea3f5b360e140b227bb696 ]
strace_open() invokes try_module_get() which on success takes
the module reference. If any follow up operation causes
strace_open() to fail, the refcount shall be put down.
Fixes: 0a5fb3cc28fd ("ASoC: Intel: avs: Keep module refcount up when gathering traces")
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260902081814.1590883-9-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/avs/debugfs.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
diff --git a/sound/soc/intel/avs/debugfs.c b/sound/soc/intel/avs/debugfs.c
index 701c247227bf9..fc321f61fc929 100644
--- a/sound/soc/intel/avs/debugfs.c
+++ b/sound/soc/intel/avs/debugfs.c
@@ -8,6 +8,7 @@
#include <linux/debugfs.h>
#include <linux/kfifo.h>
+#include <linux/module.h>
#include <linux/wait.h>
#include <linux/sched/signal.h>
#include <linux/string_helpers.h>
@@ -235,15 +236,20 @@ static int strace_open(struct inode *inode, struct file *file)
if (!try_module_get(adev->dev->driver->owner))
return -ENODEV;
- if (kfifo_initialized(&adev->trace_fifo))
- return -EBUSY;
+ if (kfifo_initialized(&adev->trace_fifo)) {
+ ret = -EBUSY;
+ goto err;
+ }
ret = kfifo_alloc(&adev->trace_fifo, PAGE_SIZE, GFP_KERNEL);
if (ret < 0)
- return ret;
+ goto err;
file->private_data = adev;
return 0;
+err:
+ module_put(adev->dev->driver->owner);
+ return ret;
}
static int strace_release(struct inode *inode, struct file *file)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 243/733] ASoC: Intel: avs: Refactor and fix init_config access
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (241 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 242/733] ASoC: Intel: avs: Fix unbalanced module reference count Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 244/733] net: bcmasp: clear txcb->last before writing each descriptor Greg Kroah-Hartman
` (501 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Cezary Rojewski, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cezary Rojewski <cezary.rojewski@intel.com>
[ Upstream commit 681e91035dc794896a904852040837190e5041f5 ]
Existing code accesses enties found in ->init_configs array through
indexes that are part of ->config_ids array. Those two are limited by:
->num_init_configs and ->num_config_ids respectively. Using ID larger
or equal to ->num_init_configs leads to out-of-bounds access:
avs_path_module_send_init_configs()
loop:
(...) &acomp->tplg->init_configs[ids[i]]
^ out-of-bounds candidate
Rather than adding another if-statement, refactor the code. There is no
need to store the IDs, have a list of pointers to actual config-entries
instead. As the verification of ->init_config entries does not differ from
verification of other types that are part of the topology.c file, simply
reuse the code.
Fixes: 8a49ef789b1b ("ASoC: Intel: avs: Send initial config to module if present")
Signed-off-by: Cezary Rojewski <cezary.rojewski@intel.com>
Link: https://patch.msgid.link/20260902081814.1590883-10-cezary.rojewski@intel.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/avs/path.c | 11 +++-----
sound/soc/intel/avs/topology.c | 47 +++++++++++++++++++---------------
sound/soc/intel/avs/topology.h | 4 +--
3 files changed, 32 insertions(+), 30 deletions(-)
diff --git a/sound/soc/intel/avs/path.c b/sound/soc/intel/avs/path.c
index 2291f9728a54f..de699e23c9e22 100644
--- a/sound/soc/intel/avs/path.c
+++ b/sound/soc/intel/avs/path.c
@@ -838,15 +838,10 @@ static int avs_path_module_type_create(struct avs_dev *adev, struct avs_path_mod
static int avs_path_module_send_init_configs(struct avs_dev *adev, struct avs_path_module *mod)
{
- struct avs_soc_component *acomp;
-
- acomp = to_avs_soc_component(mod->template->owner->owner->owner->owner->comp);
-
- u32 num_ids = mod->template->num_config_ids;
- u32 *ids = mod->template->config_ids;
+ struct avs_tplg_module *template = mod->template;
- for (int i = 0; i < num_ids; i++) {
- struct avs_tplg_init_config *config = &acomp->tplg->init_configs[ids[i]];
+ for (int i = 0; i < template->num_init_configs; i++) {
+ struct avs_tplg_init_config *config = template->init_configs[i];
size_t len = config->length;
void *data = config->data;
u32 param = config->param;
diff --git a/sound/soc/intel/avs/topology.c b/sound/soc/intel/avs/topology.c
index 0a267937044de..c9837d78e6234 100644
--- a/sound/soc/intel/avs/topology.c
+++ b/sound/soc/intel/avs/topology.c
@@ -350,6 +350,7 @@ AVS_DEFINE_PTR_PARSER(modcfg_base, struct avs_tplg_modcfg_base, modcfgs_base);
AVS_DEFINE_PTR_PARSER(modcfg_ext, struct avs_tplg_modcfg_ext, modcfgs_ext);
AVS_DEFINE_PTR_PARSER(pplcfg, struct avs_tplg_pplcfg, pplcfgs);
AVS_DEFINE_PTR_PARSER(binding, struct avs_tplg_binding, bindings);
+AVS_DEFINE_PTR_PARSER(init_config, struct avs_tplg_init_config, init_configs);
AVS_DEFINE_PTR_PARSER(nhlt_config, struct avs_tplg_nhlt_config, nhlt_configs);
static int
@@ -1198,7 +1199,7 @@ static const struct avs_tplg_token_parser module_parsers[] = {
{
.token = AVS_TKN_MOD_INIT_CONFIG_NUM_IDS_U32,
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
- .offset = offsetof(struct avs_tplg_module, num_config_ids),
+ .offset = offsetof(struct avs_tplg_module, num_init_configs),
.parse = avs_parse_byte_token,
},
{
@@ -1214,10 +1215,32 @@ static const struct avs_tplg_token_parser init_config_parsers[] = {
.token = AVS_TKN_MOD_INIT_CONFIG_ID_U32,
.type = SND_SOC_TPLG_TUPLE_TYPE_WORD,
.offset = 0,
- .parse = avs_parse_word_token,
+ .parse = avs_parse_init_config_ptr,
},
};
+static int avs_tplg_module_init_configs(struct snd_soc_component *comp,
+ struct avs_tplg_module *module,
+ struct snd_soc_tplg_vendor_array *tuples, u32 block_size)
+{
+ struct avs_tplg_init_config **cfgs;
+ int ret;
+
+ if (!module->num_init_configs)
+ return -EINVAL;
+
+ cfgs = devm_kcalloc(comp->card->dev, module->num_init_configs, sizeof(*cfgs), GFP_KERNEL);
+ if (!cfgs)
+ return -ENOMEM;
+
+ ret = parse_dictionary_entries(comp, tuples, block_size, cfgs, module->num_init_configs,
+ sizeof(*cfgs), AVS_TKN_MOD_INIT_CONFIG_ID_U32,
+ init_config_parsers, ARRAY_SIZE(init_config_parsers));
+ if (!ret)
+ module->init_configs = cfgs;
+ return ret;
+}
+
static struct avs_tplg_module *
avs_tplg_module_create(struct snd_soc_component *comp, struct avs_tplg_pipeline *owner,
struct snd_soc_tplg_vendor_array *tuples, u32 block_size)
@@ -1244,27 +1267,11 @@ avs_tplg_module_create(struct snd_soc_component *comp, struct avs_tplg_pipeline
block_size -= esize;
/* Parse trailing config ids if any. */
if (block_size) {
- u32 num_config_ids = module->num_config_ids;
- u32 *config_ids;
-
- if (!num_config_ids)
- return ERR_PTR(-EINVAL);
-
- config_ids = devm_kcalloc(comp->card->dev, num_config_ids, sizeof(*config_ids),
- GFP_KERNEL);
- if (!config_ids)
- return ERR_PTR(-ENOMEM);
-
tuples = avs_tplg_vendor_array_at(tuples, esize);
- ret = parse_dictionary_entries(comp, tuples, block_size,
- config_ids, num_config_ids, sizeof(*config_ids),
- AVS_TKN_MOD_INIT_CONFIG_ID_U32,
- init_config_parsers,
- ARRAY_SIZE(init_config_parsers));
+
+ ret = avs_tplg_module_init_configs(comp, module, tuples, block_size);
if (ret)
return ERR_PTR(ret);
-
- module->config_ids = config_ids;
}
module->owner = owner;
diff --git a/sound/soc/intel/avs/topology.h b/sound/soc/intel/avs/topology.h
index b5799c994b887..189984ce7b51e 100644
--- a/sound/soc/intel/avs/topology.h
+++ b/sound/soc/intel/avs/topology.h
@@ -221,8 +221,8 @@ struct avs_tplg_module {
u8 domain;
struct avs_tplg_modcfg_ext *cfg_ext;
u32 ctl_id;
- u32 num_config_ids;
- u32 *config_ids;
+ u32 num_init_configs;
+ struct avs_tplg_init_config **init_configs;
struct avs_tplg_nhlt_config *nhlt_config;
struct avs_tplg_pipeline *owner;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 244/733] net: bcmasp: clear txcb->last before writing each descriptor
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (242 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 243/733] ASoC: Intel: avs: Refactor and fix init_config access Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 245/733] net: bcmasp: fix tx_spb_ring_full() checking same slot cnt times Greg Kroah-Hartman
` (500 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Justin Chen, Danesh Petigara,
Florian Fainelli, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Chen <justin.chen@broadcom.com>
[ Upstream commit 18e5e0ec0e9282c897e2aa81a3e43ccaee03b003 ]
bcmasp_xmit() only wrote txcb->last = true for the final fragment
of an SKB; non-final fragments left the field untouched. If a
descriptor slot was reused while it still held a stale true from
a previous SKB (possible when tx_spb_ring_full() underreported
fullness), bcmasp_tx_reclaim() would see last == true mid-SKB and
call dev_consume_skb_any() prematurely, freeing the sk_buff while
its remaining fragments were still in flight.
Unconditionally clear txcb->last before the conditional set so every
descriptor slot starts from a known false state regardless of what a
prior transmission left behind.
Fixes: 490cb412007d ("net: bcmasp: Add support for ASP2.0 Ethernet controller")
Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Signed-off-by: Danesh Petigara <danesh.petigara@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260831184235.4133351-2-danesh.petigara@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
index ed0977832ce4f..2bd035f74fa24 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -301,6 +301,7 @@ static netdev_tx_t bcmasp_xmit(struct sk_buff *skb, struct net_device *dev)
txcb->bytes_sent = total_bytes;
dma_unmap_addr_set(txcb, dma_addr, mapping);
dma_unmap_len_set(txcb, dma_len, size);
+ txcb->last = false;
if (!i) {
desc->flags |= DESC_SOF;
if (csum_hw)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 245/733] net: bcmasp: fix tx_spb_ring_full() checking same slot cnt times
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (243 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 244/733] net: bcmasp: clear txcb->last before writing each descriptor Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 246/733] mlxsw: spectrum_ptp: Fix napi_gro_receive() call from GC workqueue context Greg Kroah-Hartman
` (499 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Justin Chen, Danesh Petigara,
Florian Fainelli, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Chen <justin.chen@broadcom.com>
[ Upstream commit 0c5cf62e72d7a666ee4da757e122dc1600df1ecc ]
The loop initialised next_index from intf->tx_spb_index on every
iteration, so incr_ring() always produced the same result and only
one slot was ever tested. Move the initialisation before the loop
so each iteration advances next_index and the function correctly
checks that cnt consecutive descriptor slots are available before
allowing a new transmission.
Fixes: 490cb412007d ("net: bcmasp: Add support for ASP2.0 Ethernet controller")
Signed-off-by: Justin Chen <justin.chen@broadcom.com>
Signed-off-by: Danesh Petigara <danesh.petigara@broadcom.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260831184235.4133351-3-danesh.petigara@broadcom.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
index 2bd035f74fa24..f2176ef3a127b 100644
--- a/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
+++ b/drivers/net/ethernet/broadcom/asp2/bcmasp_intf.c
@@ -148,8 +148,9 @@ static int tx_spb_ring_full(struct bcmasp_intf *intf, int cnt)
int next_index, i;
/* Check if we have enough room for cnt descriptors */
+ next_index = intf->tx_spb_index;
for (i = 0; i < cnt; i++) {
- next_index = incr_ring(intf->tx_spb_index, DESC_RING_COUNT);
+ next_index = incr_ring(next_index, DESC_RING_COUNT);
if (next_index == intf->tx_spb_clean_index)
return 1;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 246/733] mlxsw: spectrum_ptp: Fix napi_gro_receive() call from GC workqueue context
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (244 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 245/733] net: bcmasp: fix tx_spb_ring_full() checking same slot cnt times Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 247/733] bpf: zero extend the result of an arena 32-bit cmpxchg Greg Kroah-Hartman
` (498 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taylor Bates, Petr Machata,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taylor Bates <tmbates12@gmail.com>
[ Upstream commit 2ac174dfcdde399fa95ba889541fb5e688d8bb35 ]
Currently mlxsw_sp1_ptp_ht_gc_collect() is run from the PTP
garbage-collection workqueue, rather than the NAPI poll context. For any
unmatched PTP entries carrying an SKB, it calls
mlxsw_sp1_ptp_unmatched_finish() -> mlxsw_sp1_ptp_packet_finish(). For
ingress packets, this calls mlxsw_sp_rx_listener_no_mark_func(). The end
of that function is the following:
skb->protocol = eth_type_trans(skb, skb->dev);
napi_gro_receive(mlxsw_skb_cb(skb)->rx_md_info.napi, skb);
The napi pointer is one that was placed in the SKB control block when the
trapped packet was received in the NAPI context. Later, when the GC reaps
the unmatched entry (up to MLXSW_SP1_PTP_HT_GC_TIMEOUT later), the call to
napi_gro_receive() mutates the NAPI instance's GRO list, which is unsafe
if the poll is running concurrently on another CPU.
In mlxsw_sp1_ptp_ht_gc_collect(), local_bh_disable() is called to prevent
softirq processing, but this only applies to the local CPU. Additionally,
its comment is stale. It states that mlxsw_sp1_ptp_unmatched_finish()
invokes netif_receive_skb(). This has not been accurate since the
referenced commit; this patch makes that comment accurate again.
mlxsw_pci_napi_devs_init() calls netif_threaded_enable() on the NAPI RX
net_device without any conditions. The NAPI instance's poll, which may be
running concurrent to the GC, is running as an independently-scheduled
kthread which may be on a different CPU. The call to local_bh_disable()
does not guard against this.
If a tx-timestamp timeout produces an unmatched entry (which can be easily
reproduced by running ptp4l and waiting for a port to reach the
UNCALIBRATED/SLAVE state) while the owning NAPI thread is in the middle of
a poll on another CPU, both sides mutate the GRO list concurrently, as
shown below:
[39.846] port 1 (swp1): MASTER to UNCALIBRATED on RS_SLAVE
list_add corruption. next->prev should be prev (ffff8d620faf4138), but was ffff8d624150f700. (next=ffff8d620faf4138).
kernel BUG at lib/list_debug.c:29!
Oops: invalid opcode: 0000 [#1] SMP PTI
CPU: 1 UID: 0 PID: 539 Comm: napi/mlxsw_rx-0 Not tainted 6.18.48 #1-NixOS PREEMPT(lazy)
Hardware name: Mellanox Technologies Ltd. MSN2410/VMOD0001, BIOS 4.6.5 09/13/2018
RIP: 0010:__list_add_valid_or_report+0x79/0xb0
RSP: 0018:ffffcdf8c0f27c08 EFLAGS: 00010246
RAX: 0000000000000075 RBX: ffff8d624150fd00 RCX: 0000000000000000
RDX: 0000000000000000 RSI: 0000000000000001 RDI: ffff8d6315d1e540
RBP: ffff8d620faf4070 R08: 0000000000000000 R09: 00000000ffffdfff
R10: ffffffffa5c60fe0 R11: ffffcdf8c0f27ab8 R12: 0000000000000003
R13: 000000000000003d R14: 00000000000001bc R15: 0000000000000001
FS: 0000000000000000(0000) GS:ffff8d636f63f000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 0000562689a60c24 CR3: 000000015f224004 CR4: 00000000001726f0
Call Trace:
<TASK>
gro_receive_skb+0xee/0x230
mlxsw_sp1_ptp_got_packet+0x61/0x140 [mlxsw_spectrum]
mlxsw_core_skb_receive+0xdf/0x1b0 [mlxsw_core]
mlxsw_pci_napi_poll_cq_rx+0x780/0x9d0 [mlxsw_pci]
__napi_poll+0x31/0x1e0
napi_threaded_poll_loop+0x16b/0x1c0
napi_threaded_poll+0x71/0xa0
kthread+0xfb/0x260
ret_from_fork+0x22d/0x260
ret_from_fork_asm+0x1a/0x30
</TASK>
Kernel panic - not syncing: Fatal exception in interrupt
The machinery that leads to this kernel panic has not been changed between
6.18.48 and mainline.
This patch adds an ingress-delivery helper for the PTP packet_finish()
path that calls netif_receive_skb() instead of napi_gro_receive().
netif_receive_skb(), unlike napi_gro_receive(), can be called from outside
of the NAPI instance's poll context, which can occur at the call site for
this path. RX stats accounting and the skb->dev assignment are still
preserved; the only change is the delivery call itself.
This removes GRO batching for any PTP event traffic received by the mlxsw
trap, but given the relatively low volume of traffic characteristic of the
protocol, and impact limited to only Spectrum-1 ASICs, this is an
acceptable solution.
Fixes: 1ba06ca96ca2 ("mlxsw: Switch to napi_gro_receive()")
Signed-off-by: Taylor Bates <tmbates12@gmail.com>
Reviewed-by: Petr Machata <petrm@nvidia.com>
Link: https://patch.msgid.link/20260902024949.2273997-1-tmbates12@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../ethernet/mellanox/mlxsw/spectrum_ptp.c | 34 ++++++++++++++++++-
1 file changed, 33 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
index 9939749c47bcc..9c5862f4e16a3 100644
--- a/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
+++ b/drivers/net/ethernet/mellanox/mlxsw/spectrum_ptp.c
@@ -572,6 +572,38 @@ mlxsw_sp1_ptp_unmatched_remove(struct mlxsw_sp *mlxsw_sp,
mlxsw_sp1_ptp_unmatched_ht_params);
}
+/* mlxsw_sp1_ptp_packet_finish() is reached both from the NAPI poll context
+ * (mlxsw_sp1_ptp_got_packet(), mlxsw_sp1_ptp_got_piece() and
+ * mlxsw_sp1_packet_timestamp()) and from process context, by way of the GC
+ * workqueue (mlxsw_sp1_ptp_ht_gc_collect() ->
+ * mlxsw_sp1_ptp_unmatched_finish()).
+ *
+ * mlxsw_sp_rx_listener_no_mark_func() ends in napi_gro_receive(), using the
+ * NAPI pointer that was placed in the SKB control block when the trapped
+ * packet was received in the NAPI context. That pointer may only be used
+ * from its own poll context, which this call site cannot guarantee.
+ *
+ * netif_receive_skb(), unlike napi_gro_receive(), can be called from outside
+ * of the NAPI instance's poll context. RX stats accounting and the skb->dev
+ * assignment are still preserved; the only change is the delivery call.
+ */
+static void mlxsw_sp1_ptp_rx_finish(struct mlxsw_sp_port *mlxsw_sp_port,
+ struct sk_buff *skb)
+{
+ struct mlxsw_sp_port_pcpu_stats *pcpu_stats;
+
+ skb->dev = mlxsw_sp_port->dev;
+
+ pcpu_stats = this_cpu_ptr(mlxsw_sp_port->pcpu_stats);
+ u64_stats_update_begin(&pcpu_stats->syncp);
+ pcpu_stats->rx_packets++;
+ pcpu_stats->rx_bytes += skb->len;
+ u64_stats_update_end(&pcpu_stats->syncp);
+
+ skb->protocol = eth_type_trans(skb, skb->dev);
+ netif_receive_skb(skb);
+}
+
/* This function is called in the following scenarios:
*
* 1) When a packet is matched with its timestamp.
@@ -600,7 +632,7 @@ static void mlxsw_sp1_ptp_packet_finish(struct mlxsw_sp *mlxsw_sp,
if (ingress) {
if (hwtstamps)
*skb_hwtstamps(skb) = *hwtstamps;
- mlxsw_sp_rx_listener_no_mark_func(skb, local_port, mlxsw_sp);
+ mlxsw_sp1_ptp_rx_finish(mlxsw_sp_port, skb);
} else {
/* skb_tstamp_tx() allows hwtstamps to be NULL. */
skb_tstamp_tx(skb, hwtstamps);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 247/733] bpf: zero extend the result of an arena 32-bit cmpxchg
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (245 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 246/733] mlxsw: spectrum_ptp: Fix napi_gro_receive() call from GC workqueue context Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 248/733] bpf: dont rewrite bpf_fastcall patterns entered by a jump Greg Kroah-Hartman
` (497 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 4814ed6406f3493bd554ad046da5f7fc04833571 ]
bpf_convert_ctx_accesses() rewrites an atomic on an arena pointer from
BPF_STX | BPF_ATOMIC to BPF_STX | BPF_PROBE_ATOMIC, and it runs before
bpf_opt_subreg_zext_lo32_rnd_hi32().
That pass emits an explicit zero extension for a 32-bit cmpxchg even
when bpf_jit_needs_zext() is false. This is done because on some
architectures 32-bit cmpxchg requires explicit zero extension for the
dst register. E.g. on x86-64 'lock cmpxchg' does not change the %eax
if comparison is successful, while BPF semantics declare that each
operation on a 32-bit register zero extends it's upper half.
is_cmpxchg_insn() matches BPF_MODE == BPF_ATOMIC only, so an arena
cmpxchg misses said zero extension adjustment. This patch adjusts
is_cmpxchg_insn() to match BPF_PROBE_ATOMIC alongside BPF_ATOMIC.
Fixes: d503a04f8bc0 ("bpf: Add support for certain atomics in bpf_arena to x86 JIT")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260903171542.1438050-1-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/fixups.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/kernel/bpf/fixups.c b/kernel/bpf/fixups.c
index cd42eb838d6c2..48acb61854ed4 100644
--- a/kernel/bpf/fixups.c
+++ b/kernel/bpf/fixups.c
@@ -13,10 +13,15 @@
#define verbose(env, fmt, args...) bpf_verifier_log_write(env, fmt, ##args)
+/*
+ * Matches BPF_PROBE_ATOMIC too: bpf_convert_ctx_accesses() rewrites arena
+ * atomics before bpf_opt_subreg_zext_lo32_rnd_hi32() runs.
+ */
static bool is_cmpxchg_insn(const struct bpf_insn *insn)
{
return BPF_CLASS(insn->code) == BPF_STX &&
- BPF_MODE(insn->code) == BPF_ATOMIC &&
+ (BPF_MODE(insn->code) == BPF_ATOMIC ||
+ BPF_MODE(insn->code) == BPF_PROBE_ATOMIC) &&
insn->imm == BPF_CMPXCHG;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 248/733] bpf: dont rewrite bpf_fastcall patterns entered by a jump
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (246 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 247/733] bpf: zero extend the result of an arena 32-bit cmpxchg Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 249/733] bpf: Track verifier instruction stats for each subprogram Greg Kroah-Hartman
` (496 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 0b1c83dc3c4401cd7e846548f62e3caf3d06742e ]
mark_fastcall_pattern_for_call() must ensure that matched
"spill; call; fill" instruction series is not interrupted by a jump.
Otherwise the rewrite applied by bpf_remove_fastcall_spills_fills()
is not sound.
Record the instructions targeted by jumps in
insn_aux_data[*].jump_target when the CFG is built and use this flag
to stop growing a pattern at such an instruction. Jumps to the first
spill are fine.
Note that existing insn_aux_data[*].jmp_point field can't be reused,
as it marks subprogram return instructions.
Fixes: 5b5f51bff1b6 ("bpf: no_caller_saved_registers attribute for helper calls")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260903205820.1743087-1-eddyz87@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf_verifier.h | 12 ++++++++++++
kernel/bpf/cfg.c | 3 +++
kernel/bpf/verifier.c | 8 ++++++++
3 files changed, 23 insertions(+)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 39a851e690ec4..ad7b8335ebc82 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -704,6 +704,8 @@ struct bpf_insn_aux_data {
*/
u32 calls_callback:1;
u32 indirect_target:1; /* if it is an indirect jump target */
+ /* true if some jump or call instruction targets this instruction */
+ u32 jump_target:1;
/*
* CFG strongly connected component this instruction belongs to,
* zero if it is a singleton SCC.
@@ -1115,6 +1117,16 @@ static inline void mark_jmp_point(struct bpf_verifier_env *env, int idx)
env->insn_aux_data[idx].jmp_point = true;
}
+static inline void mark_jump_target(struct bpf_verifier_env *env, int idx)
+{
+ env->insn_aux_data[idx].jump_target = true;
+}
+
+static inline bool bpf_is_jump_target(struct bpf_verifier_env *env, int insn_idx)
+{
+ return env->insn_aux_data[insn_idx].jump_target;
+}
+
static inline struct bpf_func_state *cur_func(struct bpf_verifier_env *env)
{
struct bpf_verifier_state *cur = env->cur_state;
diff --git a/kernel/bpf/cfg.c b/kernel/bpf/cfg.c
index 26d37066465f3..d5fc03f12969b 100644
--- a/kernel/bpf/cfg.c
+++ b/kernel/bpf/cfg.c
@@ -120,6 +120,7 @@ static int push_insn(int t, int w, int e, struct bpf_verifier_env *env)
/* mark branch target for state pruning */
mark_prune_point(env, w);
mark_jmp_point(env, w);
+ mark_jump_target(env, w);
}
if (insn_state[w] == 0) {
@@ -378,6 +379,7 @@ static int visit_gotox_insn(int t, struct bpf_verifier_env *env)
}
mark_jmp_point(env, w);
+ mark_jump_target(env, w);
/* EXPLORED || DISCOVERED */
if (insn_state[w])
@@ -539,6 +541,7 @@ static int visit_insn(int t, struct bpf_verifier_env *env)
mark_prune_point(env, t + off + 1);
mark_jmp_point(env, t + off + 1);
+ mark_jump_target(env, t + off + 1);
return ret;
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index bc5aea31df589..d1f6365e2a817 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -16856,6 +16856,10 @@ bool bpf_get_call_summary(struct bpf_verifier_env *env, struct bpf_insn *call,
* r0 = *(u64 *)(r10 - 8); r0 += r1;
* r0 += r1; exit;
* exit;
+ *
+ * Both uses of the marks assume that a pattern is entered at its first
+ * spill and thus executes as a unit, hence a pattern is not grown past
+ * an instruction targeted by a jump.
*/
static void mark_fastcall_pattern_for_call(struct bpf_verifier_env *env,
struct bpf_subprog_info *subprog,
@@ -16894,6 +16898,10 @@ static void mark_fastcall_pattern_for_call(struct bpf_verifier_env *env,
for (i = 1, off = lowest_off; i <= ARRAY_SIZE(caller_saved); ++i, off += BPF_REG_SIZE) {
if (insn_idx - i < 0 || insn_idx + i >= env->prog->len)
break;
+ /* stx/ldx/call must not be a jump targets, a jump to the first stx is fine */
+ if (bpf_is_jump_target(env, insn_idx - i + 1) ||
+ bpf_is_jump_target(env, insn_idx + i))
+ break;
stx = &insns[insn_idx - i];
ldx = &insns[insn_idx + i];
/* must be a stack spill/fill pair */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 249/733] bpf: Track verifier instruction stats for each subprogram
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (247 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 248/733] bpf: dont rewrite bpf_fastcall patterns entered by a jump Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 250/733] bpf: Check ancestor frames for rbtree callbacks Greg Kroah-Hartman
` (495 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kumar Kartikeya Dwivedi,
Eduard Zingerman, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 14c950ac2be8cadb63e1bfe22111ab0fdc829eb8 ]
The verifier currently records one instruction count for the main program
and each global subprogram checked independently. Static subprograms are
explored within callers, so their verification cost cannot be reported
separately.
Track both self and inclusive instruction counts for every subprogram.
Charge each processed instruction as self work to the current subprogram and
to a path-local subtotal in its function frame. When a function returns, add
the callee subtotal to its inclusive count and to its parent subtotal. Fold
any remaining frames when a path terminates or is pruned.
Instruction subtotals are accounting state, not semantic verifier state.
Clear them when a verifier state is copied so work before a path fork is
charged once, rather than again when a saved branch is explored. If copying
a saved state fails before all frames are allocated, skip missing frames
while folding the current path.
This generic frame accounting also records self and inclusive totals when an
asynchronous callback starts as a fresh frame-zero state. It does not yet
charge that independently explored callback path back to the main or global
exploration root which scheduled it. That will be done in subsequent
changes.
This does not change the verification statistics output format. It only
prepares the counters for per-subprogram reporting.
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://patch.msgid.link/20260812221925.3358041-2-memxor@gmail.com
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Stable-dep-of: 369f4ce73457 ("bpf: Check ancestor frames for rbtree callbacks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf_verifier.h | 5 +++-
kernel/bpf/verifier.c | 55 ++++++++++++++++++++++++++++++------
2 files changed, 50 insertions(+), 10 deletions(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index ad7b8335ebc82..70a6133c5e7b0 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -385,6 +385,8 @@ struct bpf_func_state {
* | number of simulations is tracked in frame N
*/
u32 callback_depth;
+ /* Instructions processed in this frame and callees on the current path. */
+ u32 insns_subtotal;
/* The following fields should be last. See copy_func_state() */
/* The state of the stack. Each element of the array describes BPF_REG_SIZE
@@ -805,7 +807,8 @@ struct bpf_subprog_info {
u32 exit_idx; /* Index of one of the BPF_EXIT instructions in this subprogram */
u16 stack_depth; /* max. stack depth used by this function */
u16 stack_extra;
- u32 insn_processed;
+ u32 insns_total;
+ u32 insns_self;
/* offsets in range [stack_depth .. fastcall_stack_off)
* are used for bpf_fastcall spills and fills.
*/
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d1f6365e2a817..989d418da374c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -1613,6 +1613,8 @@ static int copy_func_state(struct bpf_func_state *dst,
const struct bpf_func_state *src)
{
memcpy(dst, src, offsetof(struct bpf_func_state, stack));
+ /* Instruction accounting is path-local, not part of verifier state. */
+ dst->insns_subtotal = 0;
return copy_stack_state(dst, src);
}
@@ -9718,6 +9720,42 @@ static int set_task_work_schedule_callback_state(struct bpf_verifier_env *env,
static bool is_rbtree_lock_required_kfunc(u32 btf_id);
+static void account_processed_insn(struct bpf_verifier_env *env)
+{
+ struct bpf_func_state *frame = cur_func(env);
+
+ env->insn_processed++;
+ frame->insns_subtotal++;
+ env->subprog_info[frame->subprogno].insns_self++;
+}
+
+static void account_processed_insns(struct bpf_verifier_env *env,
+ struct bpf_func_state *callee,
+ struct bpf_func_state *caller)
+{
+ u32 insns;
+
+ if (!callee)
+ return;
+
+ insns = callee->insns_subtotal;
+
+ env->subprog_info[callee->subprogno].insns_total += insns;
+ if (caller)
+ caller->insns_subtotal += insns;
+ callee->insns_subtotal = 0;
+}
+
+static void account_current_path(struct bpf_verifier_env *env)
+{
+ struct bpf_verifier_state *state = env->cur_state;
+ int frame;
+
+ for (frame = state->curframe; frame >= 0; frame--)
+ account_processed_insns(env, state->frame[frame],
+ frame ? state->frame[frame - 1] : NULL);
+}
+
/* Are we currently verifying the callback for a rbtree helper that must
* be called with lock held? If so, no need to complain about unreleased
* lock
@@ -9814,6 +9852,7 @@ static int prepare_func_exit(struct bpf_verifier_env *env, int *insn_idx)
verbose(env, "to caller at %d:\n", *insn_idx);
print_verifier_state(env, state, caller->frameno, true);
}
+ account_processed_insns(env, callee, caller);
/* clear everything in the callee. In case of exceptional exits using
* bpf_throw, this will be done by copy_verifier_state for extra frames. */
free_func_state(callee);
@@ -17445,7 +17484,9 @@ static int do_check(struct bpf_verifier_env *env)
insn = &insns[env->insn_idx];
insn_aux = &env->insn_aux_data[env->insn_idx];
- if (++env->insn_processed > BPF_COMPLEXITY_LIMIT_INSNS) {
+ account_processed_insn(env);
+
+ if (env->insn_processed > BPF_COMPLEXITY_LIMIT_INSNS) {
verbose(env,
"BPF program is too large. Processed %d insn\n",
env->insn_processed);
@@ -17585,6 +17626,7 @@ static int do_check(struct bpf_verifier_env *env)
"speculation barrier after jump instruction may not have the desired effect"))
return -EFAULT;
process_bpf_exit:
+ account_current_path(env);
mark_verifier_state_scratched(env);
err = bpf_update_branch_counts(env, env->cur_state);
if (err)
@@ -18579,6 +18621,7 @@ static int do_check_common(struct bpf_verifier_env *env, int subprog)
ret = do_check(env);
out:
+ account_current_path(env);
if (!ret && pop_log)
bpf_vlog_reset(&env->log, 0);
free_states(env);
@@ -18610,7 +18653,6 @@ static int do_check_subprogs(struct bpf_verifier_env *env)
struct bpf_prog_aux *aux = env->prog->aux;
struct bpf_func_info_aux *sub_aux;
int i, ret, new_cnt;
- u32 insn_processed;
if (!aux->func_info)
return 0;
@@ -18625,8 +18667,6 @@ static int do_check_subprogs(struct bpf_verifier_env *env)
if (!bpf_subprog_is_global(env, i))
continue;
- insn_processed = env->insn_processed;
-
sub_aux = subprog_aux(env, i);
if (!sub_aux->called || sub_aux->verified)
continue;
@@ -18634,7 +18674,6 @@ static int do_check_subprogs(struct bpf_verifier_env *env)
env->insn_idx = env->subprog_info[i].start;
WARN_ON_ONCE(env->insn_idx == 0);
ret = do_check_common(env, i);
- env->subprog_info[i].insn_processed = env->insn_processed - insn_processed;
if (ret) {
return ret;
} else if (env->log.level & BPF_LOG_LEVEL) {
@@ -18661,12 +18700,10 @@ static int do_check_subprogs(struct bpf_verifier_env *env)
static int do_check_main(struct bpf_verifier_env *env)
{
- u32 insn_processed = env->insn_processed;
int ret;
env->insn_idx = 0;
ret = do_check_common(env, 0);
- env->subprog_info[0].insn_processed = env->insn_processed - insn_processed;
if (!ret)
env->prog->aux->stack_depth = env->subprog_info[0].stack_depth;
return ret;
@@ -18685,10 +18722,10 @@ static void print_verification_stats(struct bpf_verifier_env *env)
for (i = 1; i < subprog_cnt; i++)
verbose(env, "+%d", env->subprog_info[i].stack_depth);
verbose(env, " max %d\n", env->max_stack_depth);
- verbose(env, "insns processed %d", env->subprog_info[0].insn_processed);
+ verbose(env, "insns processed %d", env->subprog_info[0].insns_total);
for (i = 1; i < subprog_cnt; i++)
if (bpf_subprog_is_global(env, i))
- verbose(env, "+%d", env->subprog_info[i].insn_processed);
+ verbose(env, "+%d", env->subprog_info[i].insns_total);
verbose(env, "\n");
}
verbose(env, "processed %d insns (limit %d) max_states_per_insn %d "
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 250/733] bpf: Check ancestor frames for rbtree callbacks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (248 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 249/733] bpf: Track verifier instruction stats for each subprogram Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 251/733] bpf: Mark bpf_btf_find_by_name_kind() as sleepable Greg Kroah-Hartman
` (494 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Eduard Zingerman, Alexei Starovoitov,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 369f4ce734570bdfedaa4b5ca50e2a3f6a892728 ]
bpf_rbtree_add() invokes its comparator while the caller holds the root
lock. The native insertion code retains raw parent and link pointers across
the callback, so the verifier prohibits unlocking, consuming tree nodes,
or changing RCU state from that callback.
in_rbtree_lock_required_cb() only checks the innermost verifier frame.
Static subprogram calls are permitted while holding a spin lock, and such a
call pushes a frame without in_callback_fn set. Consequently, all callback
restrictions disappear in the nested frame. The subprogram can unlock the
tree, remove and drop the node being compared, then relock. Native insertion
resumes with the stale parent pointer and links freed memory into the tree.
Walk all active frames for the rbtree callback instead. Benign static
subprograms remain permitted, while callback restrictions follow execution
into nested frames.
Fixes: a44b1334aadd ("bpf: Allow calling static subprogs while holding a bpf_spin_lock")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260903214758.2727663-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 25 ++++++++++++++-----------
1 file changed, 14 insertions(+), 11 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 989d418da374c..9554eb6bd2016 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -9756,9 +9756,10 @@ static void account_current_path(struct bpf_verifier_env *env)
frame ? state->frame[frame - 1] : NULL);
}
-/* Are we currently verifying the callback for a rbtree helper that must
- * be called with lock held? If so, no need to complain about unreleased
- * lock
+/*
+ * Are we currently verifying the callback for an rbtree kfunc that must
+ * be called with a lock held, or one of that callback's subprogs? If so,
+ * no need to complain about an unreleased lock.
*/
static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env)
{
@@ -9766,17 +9767,19 @@ static bool in_rbtree_lock_required_cb(struct bpf_verifier_env *env)
struct bpf_insn *insn = env->prog->insnsi;
struct bpf_func_state *callee;
int kfunc_btf_id;
+ u32 frame;
- if (!state->curframe)
- return false;
-
- callee = state->frame[state->curframe];
+ for (frame = state->curframe; frame; frame--) {
+ callee = state->frame[frame];
+ if (!callee->in_callback_fn)
+ continue;
- if (!callee->in_callback_fn)
- return false;
+ kfunc_btf_id = insn[callee->callsite].imm;
+ if (is_rbtree_lock_required_kfunc(kfunc_btf_id))
+ return true;
+ }
- kfunc_btf_id = insn[callee->callsite].imm;
- return is_rbtree_lock_required_kfunc(kfunc_btf_id);
+ return false;
}
static bool retval_range_within(struct bpf_retval_range range, const struct bpf_reg_state *reg)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 251/733] bpf: Mark bpf_btf_find_by_name_kind() as sleepable
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (249 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 250/733] bpf: Check ancestor frames for rbtree callbacks Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 252/733] bpf: Mark faultable stack helpers " Greg Kroah-Hartman
` (493 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Kumar Kartikeya Dwivedi,
Eduard Zingerman, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 620614bf7672130c43b3cff375525a2202f61979 ]
When bpf_btf_find_by_name_kind() finds a type in module BTF, it
returns a new BTF object fd through __btf_new_fd(). This reaches
anon_inode_getfd(), which can sleep while allocating or expanding the
current task fd table.
The helper prototype does not set might_sleep, so the verifier allows
the helper in non-sleepable contexts such as BPF timer callbacks. The
fd allocation can then sleep in softirq context and install the fd into
the interrupted task.
Mark the helper as sleepable. This preserves calls from the main body
of a sleepable syscall program while rejecting calls from its
non-sleepable regions.
Fixes: 3d78417b60fb ("bpf: Add bpf_btf_find_by_name_kind() helper.")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/bpf/20260903155150.D57251F000E9@smtp.kernel.org
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260903214758.2727663-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/btf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/kernel/bpf/btf.c b/kernel/bpf/btf.c
index 96b38fce885d3..022d5a594dc95 100644
--- a/kernel/bpf/btf.c
+++ b/kernel/bpf/btf.c
@@ -8729,6 +8729,7 @@ BPF_CALL_4(bpf_btf_find_by_name_kind, char *, name, int, name_sz, u32, kind, int
const struct bpf_func_proto bpf_btf_find_by_name_kind_proto = {
.func = bpf_btf_find_by_name_kind,
.gpl_only = false,
+ .might_sleep = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_MEM | MEM_RDONLY,
.arg2_type = ARG_CONST_SIZE,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 252/733] bpf: Mark faultable stack helpers as sleepable
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (250 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 251/733] bpf: Mark bpf_btf_find_by_name_kind() as sleepable Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 253/733] bpf: Reject legacy packet loads from callbacks Greg Kroah-Hartman
` (492 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kumar Kartikeya Dwivedi,
Eduard Zingerman, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 9d02927fdf4e930893c92e35fed01a2704496900 ]
The faultable variants of bpf_get_stack() and bpf_get_task_stack() pass
may_fault=true into the common stack collection code. Resolving user-space
build IDs may then call build_id_parse_file() and block on filesystem
reads.
Neither helper prototype sets might_sleep. Since prototype selection uses
the sleepability of the whole program, the verifier can still allow these
helpers from a non-sleepable region within that program, such as an
explicit RCU or preemption-disabled region. The task-stack helper can also
be called from a non-sleepable timer callback of a sleepable program.
Mark both faultable prototypes as sleepable. The existing helper context
check then rejects these calls while continuing to allow them in genuinely
sleepable contexts.
Fixes: d4dd9775ec24 ("bpf: wire up sleepable bpf_get_stack() and bpf_get_task_stack() helpers")
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260903214758.2727663-6-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/stackmap.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/bpf/stackmap.c b/kernel/bpf/stackmap.c
index 142a65672c6f9..e41fb1c567cd7 100644
--- a/kernel/bpf/stackmap.c
+++ b/kernel/bpf/stackmap.c
@@ -880,6 +880,7 @@ BPF_CALL_4(bpf_get_stack_sleepable, struct pt_regs *, regs, void *, buf, u32, si
const struct bpf_func_proto bpf_get_stack_sleepable_proto = {
.func = bpf_get_stack_sleepable,
.gpl_only = true,
+ .might_sleep = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_CTX,
.arg2_type = ARG_PTR_TO_UNINIT_MEM,
@@ -933,6 +934,7 @@ BPF_CALL_4(bpf_get_task_stack_sleepable, struct task_struct *, task, void *, buf
const struct bpf_func_proto bpf_get_task_stack_sleepable_proto = {
.func = bpf_get_task_stack_sleepable,
.gpl_only = false,
+ .might_sleep = true,
.ret_type = RET_INTEGER,
.arg1_type = ARG_PTR_TO_BTF_ID,
.arg1_btf_id = &btf_tracing_ids[BTF_TRACING_TYPE_TASK],
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 253/733] bpf: Reject legacy packet loads from callbacks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (251 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 252/733] bpf: Mark faultable stack helpers " Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 254/733] bpf: Dont infer non-NULL from a pointer with an unbounded offset Greg Kroah-Hartman
` (491 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Kumar Kartikeya Dwivedi,
Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit e7d28823c662128caae63f14e16bd394916c139b ]
check_ld_abs() models a failed BPF_LD_ABS or BPF_LD_IND in a
subprogram as an implicit return with R0 set to zero. It calls
prepare_func_exit() to explore this synthesized path.
When the load is reached directly from a synchronous callback,
prepare_func_exit() enforces the callback return contract and marks R0
precise. R0 is not derived from a real instruction on this path, so
precision backtracking reaches the callback call with R0 still requested
and triggers the "callback unexpected regs" verifier bug. A privileged
program loader can therefore cause a verifier warning and an -EFAULT
BPF_PROG_LOAD.
These legacy packet-load instructions are deprecated. Reject them from
callbacks rather than complicating their implicit-return model. Check all
active frames before constructing the implicit return so nested static
subprograms cannot hide the callback context.
Global functions are verified independently with a fresh frame zero, so
an active-frame check cannot identify a global function called from a
callback. Also check the complete subprogram call graph during stack-depth
validation and reject a function containing a legacy load when any caller
is a callback. This covers global and static descendants without making
has_ld_abs transitive, preserving its per-function BTF return-type check.
Ordinary uses outside callbacks remain supported.
Fixes: ee861486e377 ("bpf: Fix ld_{abs,ind} failure path analysis in subprogs")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/bpf/20260903152147.C0E241F00A3A@smtp.kernel.org
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260903214758.2727663-8-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 9554eb6bd2016..96aaa9155e59e 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -5119,6 +5119,15 @@ static int check_max_stack_depth_subprog(struct bpf_verifier_env *env, int idx,
if (!priv_stack_supported)
subprog[idx].priv_stack_mode = NO_PRIV_STACK;
process_func:
+ if (subprog[idx].has_ld_abs) {
+ for (tmp = idx; tmp >= 0; tmp = dinfo[tmp].caller) {
+ if (subprog[tmp].is_cb) {
+ verbose(env, "cannot use BPF_LD_[ABS|IND] within callback\n");
+ return -EINVAL;
+ }
+ }
+ }
+
/* protect against potential stack overflow that might happen when
* bpf2bpf calls get combined with tailcalls. Limit the caller's stack
* depth for such case down to 256 so that the worst case scenario
@@ -16420,6 +16429,7 @@ static bool may_access_skb(enum bpf_prog_type type)
*/
static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
{
+ struct bpf_verifier_state *state = env->cur_state;
struct bpf_reg_state *regs = cur_regs(env);
static const int ctx_reg = BPF_REG_6;
u8 mode = BPF_MODE(insn->code);
@@ -16430,6 +16440,13 @@ static int check_ld_abs(struct bpf_verifier_env *env, struct bpf_insn *insn)
return -EINVAL;
}
+ for (i = state->curframe; i; i--) {
+ if (state->frame[i]->in_callback_fn) {
+ verbose(env, "cannot use BPF_LD_[ABS|IND] within callback\n");
+ return -EINVAL;
+ }
+ }
+
if (!env->ops->gen_ld_abs) {
verifier_bug(env, "gen_ld_abs is null");
return -EFAULT;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 254/733] bpf: Dont infer non-NULL from a pointer with an unbounded offset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (252 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 253/733] bpf: Reject legacy packet loads from callbacks Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 255/733] bpf: Dont resurrect a scalar id dropped by collect_linked_regs() Greg Kroah-Hartman
` (490 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 67b529f521a6676cdfc78b91b0217d7eaa84216b ]
reg_not_null() decides that a register holds a non-NULL value by
looking at its type alone. For pointer types that allow arithmetic the
type only guarantees a non-NULL base, in case of an unbound offset
the runtime offset value might still add up to NULL.
Consider the followng program:
r6 = bpf_map_lookup_elem(map, &0); /* present */
if (r6 == 0) return 0;
r7 = bpf_map_lookup_elem(map, &1); /* absent, NULL at runtime */
r8 = r7;
r8 -= r6; /* pointer - pointer: unknown scalar, -r6 */
r8 <<= 1;
r8 >>= 1; /* any non-negative offset is accepted by */
/* check_reg_sane_offset_ptr() */
r6 += r8; /* verifier: map value; runtime: zero */
if (r7 != r6) return 0;
*(u8 *)(r7 + 0); /* r7 is inferred non-NULL, both are zero */
At runtime both registers are zero, the comparison is true and the
load faults with NULL pointer dereference.
Require the offset to be within +-BPF_MAX_VAR_OFF in reg_not_null().
Fixes: cac616db39c2 ("bpf: Verifier track null pointer branch_taken with JNE and JEQ")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-1-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 96aaa9155e59e..84b05958c3250 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -367,6 +367,13 @@ static bool reg_not_null(struct bpf_verifier_env *env, const struct bpf_reg_stat
if (type_may_be_null(type))
return false;
+ /*
+ * The types below guarantee a non-NULL base, an unbounded offset can
+ * still wrap base + offset to zero.
+ */
+ if (reg_smin(reg) <= -BPF_MAX_VAR_OFF || reg_smax(reg) >= BPF_MAX_VAR_OFF)
+ return false;
+
type = base_type(type);
return type == PTR_TO_SOCKET ||
type == PTR_TO_TCP_SOCK ||
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 255/733] bpf: Dont resurrect a scalar id dropped by collect_linked_regs()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (253 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 254/733] bpf: Dont infer non-NULL from a pointer with an unbounded offset Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 256/733] bpf: Dont predict JMP32 pointer vs zero comparisons Greg Kroah-Hartman
` (489 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 73a98f96811e2cb0f4210b1caa8cb322f92f2a2b ]
check_cond_jmp_op() copies the compared registers into
env->{false,true}_reg{1,2} before collect_linked_regs() runs and copies
those snapshots back into both branch states afterwards.
collect_linked_regs() records at most LINKED_REGS_MAX members of a
linked registers group in the jump history and calls clear_scalar_id()
for every member that does not fit. The compared register is not exempt
from that.
As a consequence, sync_linked_regs() might adjust ranges for more
registers than bpf_bt_sync_linked_regs() can propagate precision to.
Collect the linked registers before the snapshots are taken instead.
This might lead to some unnecessary clear_scalar_id's, but from
previous testing situations with many linked registers are
extremely rare.
Fixes: ec1d77cb0ee9 ("bpf: Use bpf_verifier_env buffers for reg_set_min_max")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-3-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 84b05958c3250..2c1da0d38450c 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -16142,6 +16142,16 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
return err;
}
+ /*
+ * Collect the linked registers before env->{true,false}_reg{1,2} setup,
+ * otherwise ids dropped by collect_linked_regs() would be resurrected
+ * when env->{true,false}_reg{1,2} are copied back.
+ */
+ if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id)
+ collect_linked_regs(env, this_branch, src_reg->id, &linked_regs);
+ if (dst_reg->type == SCALAR_VALUE && dst_reg->id)
+ collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs);
+
is_jmp32 = BPF_CLASS(insn->code) == BPF_JMP32;
env->false_reg1 = *dst_reg;
env->false_reg2 = *src_reg;
@@ -16196,10 +16206,6 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
* 'this_branch' and 'other_branch' share this history
* if parent state is created.
*/
- if (BPF_SRC(insn->code) == BPF_X && src_reg->type == SCALAR_VALUE && src_reg->id)
- collect_linked_regs(env, this_branch, src_reg->id, &linked_regs);
- if (dst_reg->type == SCALAR_VALUE && dst_reg->id)
- collect_linked_regs(env, this_branch, dst_reg->id, &linked_regs);
if (linked_regs.cnt > 1) {
err = bpf_push_jmp_history(env, this_branch, 0, 0, 0, linked_regs_pack(&linked_regs));
if (err)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 256/733] bpf: Dont predict JMP32 pointer vs zero comparisons
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (254 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 255/733] bpf: Dont resurrect a scalar id dropped by collect_linked_regs() Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 257/733] bpf: Mark the zero register precise for a register-form NULL check Greg Kroah-Hartman
` (488 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit e51179a4e09846f8fd0f26a05068520de2b301bf ]
Consider the following program:
r1 = map_value; /* low 32 bits are zero at runtime */
r6 = 0xdead000000000000;
if w1 != 0 goto l1;
l0: r1 += r6;
r2 = *(u64 *)(r1 + 0);
exit;
l1: r6 = 0;
goto l0;
At the moment is_branch_taken() reports the jump as always taken,
because it does not distinguish between BPF_JMP and BPF_JMP32
comparisons when processing 'if w1 != 0 ...'.
Fixes: cac616db39c2 ("bpf: Verifier track null pointer branch_taken with JNE and JEQ")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-5-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 2c1da0d38450c..d68f54a53c644 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -15576,6 +15576,13 @@ static int is_branch_taken(struct bpf_verifier_env *env, struct bpf_reg_state *r
if (__is_pointer_value(false, reg1) || __is_pointer_value(false, reg2)) {
u64 val;
+ /*
+ * The low 32 bits of a valid pointer may well be zero, hence
+ * nothing below applies to a 32-bit comparison.
+ */
+ if (is_jmp32)
+ return -1;
+
/* arrange that reg2 is a scalar, and reg1 is a pointer */
if (!is_reg_const(reg2, is_jmp32)) {
opcode = flip_opcode(opcode);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 257/733] bpf: Mark the zero register precise for a register-form NULL check
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (255 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 256/733] bpf: Dont predict JMP32 pointer vs zero comparisons Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 258/733] thermal: sysfs: switch to use scnprintf() to suppress truncation warning Greg Kroah-Hartman
` (487 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Eduard Zingerman,
Kumar Kartikeya Dwivedi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 6aed0134d3cda6382385a734ae0158eb7df6b142 ]
check_cond_jmp_op() accepts "if rA <op> rB" as a NULL check for a
nullable pointer rA when rB is a scalar known to be zero,
lifts PTR_MAYBE_NULL from rA in the corresponding branch and does not
mark rB precise. Consider the following program:
r0 = bpf_get_prandom_u32();
r6 = 1; /* the r6 == 0 path is explored first */
if (r0 == 0) goto 1f;
r6 = 0;
1:
r0 = bpf_map_lookup_elem(map, &0); /* absent, NULL at runtime */
if (r0 == r6) goto 2f; /* taken as a NULL check for r0 */
*(u8 *)(r0 + 0); /* verifier: map value; runtime: zero */
2:
return 0;
The r6 == 0 path is explored first and the dereference is accepted.
The r6 == 1 path is pruned at the checkpoint recorded for (1),
so the comparison is never verified with a non-zero r6. At runtime a
failed lookup returns NULL, NULL != 1 takes the non-NULL edge and the
program dereferences a pointer that is zero.
Fixes: 2f4cb53eed44 ("bpf: detect non null pointer with register operand in JEQ/JNE.")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/bpf/20260904083325.2083493-7-eddyz87@gmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 9 +++++++++
1 file changed, 9 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index d68f54a53c644..f913e3603a5ea 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -16296,6 +16296,15 @@ static int check_cond_jmp_op(struct bpf_verifier_env *env,
type_may_be_null(dst_reg->type) &&
((BPF_SRC(insn->code) == BPF_K && insn->imm == 0) ||
(BPF_SRC(insn->code) == BPF_X && bpf_register_is_null(src_reg)))) {
+ /*
+ * For BPF_X the zero is a property of this execution path,
+ * hence src_reg has to be precise.
+ */
+ if (BPF_SRC(insn->code) == BPF_X) {
+ err = mark_chain_precision(env, insn->src_reg);
+ if (err)
+ return err;
+ }
/* Mark all identical registers in each branch as either
* safe or unknown depending R == 0 or R != 0 conditional.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 258/733] thermal: sysfs: switch to use scnprintf() to suppress truncation warning
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (256 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 257/733] bpf: Mark the zero register precise for a register-form NULL check Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 259/733] bpf: Require MEM_PERCPU for percpu kptr stores Greg Kroah-Hartman
` (486 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Shevchenko, Lukasz Luba,
Rafael J. Wysocki, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
[ Upstream commit 5ad0af4f4367202b1bc71813052fe39b5116cdb9 ]
Switch the sysfs code to use scnprintf() to avoid warnings about potential
truncation of the names of the sysfs attributes. We can't increase the buffer
size because the size is the part of an ABI for some reason. Note, with
the current size of buffer the affected attributes have a room for up to
1000 names, which ought to be enough for all cases. There is no functional
change, as the same limitation was implied before.
Fixes: c56f5c0342df ("Thermal: Make Thermal trip points writeable")
Signed-off-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Reviewed-by: Lukasz Luba <lukasz.luba@arm.com>
Link: https://patch.msgid.link/20260817103324.1020212-1-andriy.shevchenko@linux.intel.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/thermal/thermal_sysfs.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/thermal/thermal_sysfs.c b/drivers/thermal/thermal_sysfs.c
index b44abfc997edf..44bd7c50e4ac2 100644
--- a/drivers/thermal/thermal_sysfs.c
+++ b/drivers/thermal/thermal_sysfs.c
@@ -400,8 +400,8 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
struct thermal_trip_attrs *trip_attrs = &td->trip_attrs;
/* create trip type attribute */
- snprintf(trip_attrs->type.name, THERMAL_NAME_LENGTH,
- "trip_point_%d_type", i);
+ scnprintf(trip_attrs->type.name, sizeof(trip_attrs->type.name),
+ "trip_point_%d_type", i);
sysfs_attr_init(&trip_attrs->type.attr.attr);
trip_attrs->type.attr.attr.name = trip_attrs->type.name;
@@ -410,8 +410,8 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
attrs[i] = &trip_attrs->type.attr.attr;
/* create trip temp attribute */
- snprintf(trip_attrs->temp.name, THERMAL_NAME_LENGTH,
- "trip_point_%d_temp", i);
+ scnprintf(trip_attrs->temp.name, sizeof(trip_attrs->temp.name),
+ "trip_point_%d_temp", i);
sysfs_attr_init(&trip_attrs->temp.attr.attr);
trip_attrs->temp.attr.attr.name = trip_attrs->temp.name;
@@ -423,8 +423,8 @@ static int create_trip_attrs(struct thermal_zone_device *tz)
}
attrs[i + tz->num_trips] = &trip_attrs->temp.attr.attr;
- snprintf(trip_attrs->hyst.name, THERMAL_NAME_LENGTH,
- "trip_point_%d_hyst", i);
+ scnprintf(trip_attrs->hyst.name, sizeof(trip_attrs->hyst.name),
+ "trip_point_%d_hyst", i);
sysfs_attr_init(&trip_attrs->hyst.attr.attr);
trip_attrs->hyst.attr.attr.name = trip_attrs->hyst.name;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 259/733] bpf: Require MEM_PERCPU for percpu kptr stores
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (257 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 258/733] thermal: sysfs: switch to use scnprintf() to suppress truncation warning Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 260/733] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs Greg Kroah-Hartman
` (485 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit 048029ba1c793f8cabc4ad5eea765da01903f8f1 ]
map_kptr_match_type() treats perm_flags as the set of register type flags
that a kptr field permits. Adding MEM_PERCPU to that set for
BPF_KPTR_PERCPU does not require the source register to carry it, however.
The subset test consequently accepts both a plain bpf_obj_new() allocation
and a referenced kernel pointer into a __percpu_kptr map field.
Loads from the field are always marked MEM_PERCPU. Consumers then treat the
stored value as the cookie returned by bpf_percpu_obj_new(): per-CPU pointer
helpers relocate it, and map teardown selects the per-CPU free path. A plain
allocation can therefore provide an arbitrary kernel read/write, while a
kernel pointer can be relocated into an invalid address or sent through a
missing destructor.
Require the source MEM_PERCPU flag to match the destination field kind.
This preserves valid bpf_percpu_obj_new() stores and rejects both the
program-BTF and kernel-BTF variants.
Fixes: 36d8bdf75a93 ("bpf: Add alloc/xchg/direct_access support for local percpu kptr")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904084325.52250-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 7 +++++++
1 file changed, 7 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index f913e3603a5ea..6d66a5dbf8dff 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -4320,6 +4320,13 @@ static int map_kptr_match_type(struct bpf_verifier_env *env,
if (type_flag(reg->type) & ~perm_flags)
goto bad_type;
+ /*
+ * A BPF_KPTR_PERCPU field is read back as MEM_PERCPU, so the value
+ * stored in it must carry the same flag.
+ */
+ if ((kptr_field->type == BPF_KPTR_PERCPU) != !!(reg->type & MEM_PERCPU))
+ goto bad_type;
+
/* We need to verify reg->type and reg->btf, before accessing reg->btf */
reg_name = btf_type_name(reg->btf, reg->btf_id);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 260/733] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (258 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 259/733] bpf: Require MEM_PERCPU for percpu kptr stores Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 261/733] bpf: Reject untrusted allocated-object pointers Greg Kroah-Hartman
` (484 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Ning Ding,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ning Ding <dingning04@gmail.com>
[ Upstream commit dc36739e5cc9f60485418a910b42bc95339218d2 ]
bpf_refcount_acquire() is fallible for a borrowed reference because the
object may have reached a zero refcount. The verifier therefore keeps
KF_RET_NULL on the return value unless the argument is an owning reference.
An RCU-protected load of a local kptr is marked MEM_ALLOC, but it only
receives NON_OWN_REF when the pointee contains a graph node. A refcounted
object without a graph node consequently looks like an owning reference
even though the loaded register has no acquired reference state. If the
program drops the last real reference while remaining in the RCU critical
section, refcount_inc_not_zero() returns NULL while the verifier treats the
result as non-NULL.
Only classify the argument as owning when it is backed by a verifier-tracked
reference. This retains the non-NULL return for pointers from bpf_obj_new(),
bpf_kptr_xchg(), or an earlier successful acquisition, while requiring a
NULL check for borrowed RCU kptrs.
Fixes: 1b12171533a9 ("bpf: Mark direct ld of stashed bpf_{rb,list}_node as non-owning ref")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Ning Ding <dingning04@gmail.com>
[ kkd: Rewrote commit log ]
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904084325.52250-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 6d66a5dbf8dff..72994e41843ca 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -12537,7 +12537,7 @@ static int check_kfunc_args(struct bpf_verifier_env *env, struct bpf_kfunc_call_
reg_arg_name(env, argno));
return -EINVAL;
}
- if (!type_is_non_owning_ref(reg->type))
+ if (!type_is_non_owning_ref(reg->type) && reg_is_referenced(env, reg))
meta->arg_owning_ref = true;
rec = reg_btf_record(reg);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 261/733] bpf: Reject untrusted allocated-object pointers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (259 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 260/733] bpf: Keep refcount_acquire nullable for borrowed RCU kptrs Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 262/733] tracing: Fix to avoid creating trace instances with duplicate names Greg Kroah-Hartman
` (483 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Ning Ding,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ning Ding <dingning04@gmail.com>
[ Upstream commit 7441ee8276641bddaf1cba7bb75ef9c1458ceb3b ]
When the final RCU read-side critical section ends, a local kptr is demoted
to PTR_UNTRUSTED but retains MEM_ALLOC. The pointer may be NULL or may refer
to an object whose lifetime is no longer protected.
type_is_ptr_alloc_obj() nevertheless recognizes any PTR_TO_BTF_ID with
MEM_ALLOC as a live allocated object. In particular, a refcount-only local
kptr never carries NON_OWN_REF, so it still passes the
bpf_refcount_acquire() argument check after RCU protection ends. The kfunc
can then dereference NULL or stale memory.
Make type_is_ptr_alloc_obj() reject PTR_UNTRUSTED pointers. Since
type_is_non_owning_ref() is based on the same predicate, graph kfunc
arguments obey the same live-object requirement. Fault-protected reads of
the demoted pointer remain valid: writes are already rejected, and read
fixups use bpf_may_fault_on_deref() rather than this predicate.
Fixes: 1b12171533a9 ("bpf: Mark direct ld of stashed bpf_{rb,list}_node as non-owning ref")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Ning Ding <dingning04@gmail.com>
[ kkd: Rewrote commit log ]
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904084325.52250-8-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf_verifier.h | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 70a6133c5e7b0..7ad03ffb9300f 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -1322,7 +1322,9 @@ static inline bool bpf_type_has_unsafe_modifiers(u32 type)
static inline bool type_is_ptr_alloc_obj(u32 type)
{
- return base_type(type) == PTR_TO_BTF_ID && type_flag(type) & MEM_ALLOC;
+ return base_type(type) == PTR_TO_BTF_ID &&
+ type_flag(type) & MEM_ALLOC &&
+ !(type_flag(type) & PTR_UNTRUSTED);
}
static inline bool type_is_non_owning_ref(u32 type)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 262/733] tracing: Fix to avoid creating trace instances with duplicate names
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (260 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 261/733] bpf: Reject untrusted allocated-object pointers Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 263/733] selftests/bpf: Fix flaky bpf_nf test when random NAT port is 0 Greg Kroah-Hartman
` (482 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Masami Hiramatsu (Google),
Steven Rostedt, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
[ Upstream commit d7dbdd2ee01e12211046d4a535623ac732b749fb ]
Since commit e645535a954a ("tracing: Add option to use memmapped
memory for trace boot instance") changed trace_array_get_by_name() to
trace_array_create_systems(), enable_instances() does not reuse the
same name instance. Therefore, if an administrator mistakenly specifies
multiple `trace_instance=` options with duplicate names, all are
created but only the first is accessible via tracefs.
Check whether an instance with the same name already exists before
creating a new one, and reject duplicates with a warning.
Link: https://patch.msgid.link/178847790399.283263.5313150997200138426.stgit@devnote2
Fixes: e645535a954a ("tracing: Add option to use memmapped memory for trace boot instance")
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/trace.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index fc964001783f3..e6915fc7de832 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -9708,6 +9708,11 @@ __init static void enable_instances(void)
if (flag_delim)
*flag_delim++ = '\0';
+ if (trace_array_find(name)) {
+ pr_warn("Tracing: Instance %s already exists\n", name);
+ continue;
+ }
+
if (backup) {
if (backup_instance_area(backup, &addr, &size) < 0)
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 263/733] selftests/bpf: Fix flaky bpf_nf test when random NAT port is 0
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (261 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 262/733] tracing: Fix to avoid creating trace instances with duplicate names Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 264/733] bpf: Preserve special fields in recycled rhtab elements Greg Kroah-Hartman
` (481 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiayuan Chen, Alexei Starovoitov,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiayuan Chen <jiayuan.chen@linux.dev>
[ Upstream commit 5e8c349bc8d790fe031a4332e502f5d4f9878644 ]
The bpf_nf test allocs a ct, sets snat and dnat with random addr and
port via bpf_ct_set_nat_info(), then looks the ct up and checks the
reply tuple against what was set.
The port comes from bpf_get_prandom_u32() and can be 0. For
bpf_ct_set_nat_info(), port 0 means "port not specified", so only the
addr is mapped and the kernel keeps the original port. The check then
compares that port with 0 and fails, which shows up as a flaky
"Test for source natting" failure in CI [1][2].
Keep the random port in 1..65535 so it is always specified.
[1] https://github.com/kernel-patches/bpf/actions/runs/33830002889/job/100893868791
[2] https://github.com/kernel-patches/bpf/actions/runs/33829976794/job/100893220999
Fixes: b06b45e82b59 ("selftests/bpf: add tests for bpf_ct_set_nat_info kfunc")
Signed-off-by: Jiayuan Chen <jiayuan.chen@linux.dev>
Link: https://lore.kernel.org/r/20260904073745.363314-1-jiayuan.chen@linux.dev
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/bpf/progs/test_bpf_nf.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/tools/testing/selftests/bpf/progs/test_bpf_nf.c b/tools/testing/selftests/bpf/progs/test_bpf_nf.c
index df43649ecb785..eda9b7bbab758 100644
--- a/tools/testing/selftests/bpf/progs/test_bpf_nf.c
+++ b/tools/testing/selftests/bpf/progs/test_bpf_nf.c
@@ -190,8 +190,8 @@ nf_ct_test(struct nf_conn *(*lookup_fn)(void *, struct bpf_sock_tuple *, u32,
ct = alloc_fn(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def,
sizeof(opts_def));
if (ct) {
- __u16 sport = bpf_get_prandom_u32();
- __u16 dport = bpf_get_prandom_u32();
+ __u16 sport = bpf_get_prandom_u32() % 65535 + 1;
+ __u16 dport = bpf_get_prandom_u32() % 65535 + 1;
union nf_inet_addr saddr = {};
union nf_inet_addr daddr = {};
struct nf_conn *ct_ins;
@@ -293,8 +293,8 @@ nf_ct_opts_new_test(struct nf_conn *(*lookup_fn)(void *, struct bpf_sock_tuple *
ct = alloc_fn(ctx, &bpf_tuple, sizeof(bpf_tuple.ipv4), &opts_def,
sizeof(opts_def));
if (ct) {
- __u16 sport = bpf_get_prandom_u32();
- __u16 dport = bpf_get_prandom_u32();
+ __u16 sport = bpf_get_prandom_u32() % 65535 + 1;
+ __u16 dport = bpf_get_prandom_u32() % 65535 + 1;
union nf_inet_addr saddr = {};
union nf_inet_addr daddr = {};
struct nf_conn *ct_ins;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 264/733] bpf: Preserve special fields in recycled rhtab elements
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (262 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 263/733] selftests/bpf: Fix flaky bpf_nf test when random NAT port is 0 Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 265/733] bpf: Cancel special fields when recycling " Greg Kroah-Hartman
` (480 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini, Yuan Chen,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuan Chen <chenyuan@kylinos.cn>
[ Upstream commit 5df46ddcb7b36878c1b691e9057a0509042a2567 ]
rhtab_map_update_elem() initializes special fields after obtaining an
element from bpf_mem_cache_alloc(). The allocator can return a fresh,
zeroed unit, or recycle one from its RCU-pending lists before the
registered destructor has run.
A BPF program can retain a map-value pointer after deleting its element
and initialize and arm a timer through that pointer. If the deleted unit
is recycled, check_and_init_map_value() clears the only pointer to the
timer. Neither a later deletion nor rhtab_mem_dtor() can then cancel it,
and the callback can run with its key and value pointing into freed memory.
Do not reinitialize special fields on insertion. Fresh allocator units are
already zeroed. For recycled units, the special fields are ownership state
that must remain visible to the eventual destructor. copy_map_value()
already skips those fields, matching the non-preallocated hash-map path and
the lifecycle established by commit 275c30bcee66 ("bpf: Don't reinit map
value in prealloc_lru_pop").
Fixes: 6905f8601298 ("bpf: Allow special fields in resizable hashtab")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Yuan Chen <chenyuan@kylinos.cn>
[ kkd: Split out the fix and rewrote the commit log ]
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904104203.345917-2-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index 7f70db4d5dcf0..df22236d1ccf9 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -3072,7 +3072,6 @@ static long rhtab_map_update_elem(struct bpf_map *map, void *key, void *value, u
memcpy(elem->data, key, map->key_size);
copy_map_value(map, rhtab_elem_value(elem, map->key_size), value);
- check_and_init_map_value(map, rhtab_elem_value(elem, map->key_size));
/* Prevent deadlock for NMI programs attempting to take bucket lock */
bpf_disable_instrumentation();
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 265/733] bpf: Cancel special fields when recycling rhtab elements
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (263 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 264/733] bpf: Preserve special fields in recycled rhtab elements Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 266/733] bpf: Mark NULL kptr stores precise Greg Kroah-Hartman
` (479 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nuoqi Gui, Mykyta Yatsenko,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
[ Upstream commit 65cc95eba9e8b46312cac38c227473605a4b996a ]
rhtab_map_update_existing() and rhtab_delete_elem() call
bpf_obj_free_fields() when replacing or deleting a value. These map
operations can run from BPF programs in NMI context, where releasing a
referenced kptr or another complex field is not generally safe.
Array and hash maps avoid that problem by cancelling only the asynchronous
fields which can be stopped safely in the caller context. Other ownership
state remains attached to the allocation until its memory allocator
destructor performs the final cleanup.
Use bpf_obj_cancel_fields() for the corresponding rhtab paths as well. This
cancels timers, workqueues, and task work while allowing rhtab_mem_dtor() to
release referenced kptrs when the allocation is eventually destroyed.
Fixes: 6905f8601298 ("bpf: Allow special fields in resizable hashtab")
Signed-off-by: Nuoqi Gui <gnq25@mails.tsinghua.edu.cn>
Acked-by: Mykyta Yatsenko <yatsenko@meta.com>
[ kkd: Rebased, used direct helper calls, and rewrote the commit log ]
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904104203.345917-4-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/hashtab.c | 17 +++--------------
1 file changed, 3 insertions(+), 14 deletions(-)
diff --git a/kernel/bpf/hashtab.c b/kernel/bpf/hashtab.c
index df22236d1ccf9..59406da06424d 100644
--- a/kernel/bpf/hashtab.c
+++ b/kernel/bpf/hashtab.c
@@ -2869,16 +2869,6 @@ static int rhtab_map_alloc_check(union bpf_attr *attr)
return htab_map_alloc_check(attr);
}
-static void rhtab_check_and_free_fields(struct bpf_rhtab *rhtab,
- struct rhtab_elem *elem)
-{
- if (IS_ERR_OR_NULL(rhtab->map.record))
- return;
-
- bpf_obj_free_fields(rhtab->map.record,
- rhtab_elem_value(elem, rhtab->map.key_size));
-}
-
static void rhtab_mem_dtor(void *obj, void *ctx)
{
struct htab_btf_record *hrec = ctx;
@@ -2968,8 +2958,8 @@ static int rhtab_delete_elem(struct bpf_rhtab *rhtab, struct rhtab_elem *elem, v
rhtab_read_elem_value(&rhtab->map, copy, elem, flags);
check_and_init_map_value(&rhtab->map, copy);
}
- /* Release internal structs: kptr, bpf_timer, task_work, wq */
- rhtab_check_and_free_fields(rhtab, elem);
+ bpf_obj_cancel_fields(&rhtab->map,
+ rhtab_elem_value(elem, rhtab->map.key_size));
bpf_mem_cache_free_rcu(&rhtab->ma, elem);
return 0;
}
@@ -3011,7 +3001,6 @@ static int rhtab_map_lookup_and_delete_elem(struct bpf_map *map, void *key, void
static long rhtab_map_update_existing(struct bpf_map *map, struct rhtab_elem *elem, void *value,
u64 map_flags)
{
- struct bpf_rhtab *rhtab = container_of(map, struct bpf_rhtab, map);
void *old_val = rhtab_elem_value(elem, map->key_size);
if (map_flags & BPF_NOEXIST)
@@ -3031,7 +3020,7 @@ static long rhtab_map_update_existing(struct bpf_map *map, struct rhtab_elem *el
* kptrs/etc. still sit in the slot. Cancel them after the copy
* to match arraymap's update semantics.
*/
- rhtab_check_and_free_fields(rhtab, elem);
+ bpf_obj_cancel_fields(map, old_val);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 266/733] bpf: Mark NULL kptr stores precise
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (264 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 265/733] bpf: Cancel special fields when recycling " Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 267/733] bpf: Preserve inner map identity in callback frames Greg Kroah-Hartman
` (478 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Eduard Zingerman, Alexei Starovoitov,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit ecdc5043794c9184aa8e6c814603899479c46b35 ]
check_map_kptr_access() permits a scalar store into an untrusted kptr
field only when the register is known to contain zero. Unlike other
verifier checks whose outcome depends on a scalar value, it does not mark
that register precise.
A state checkpoint reached with an imprecise zero can therefore prune a
second path that reaches the store with an arbitrary nonzero scalar. The
program can write attacker-controlled bits into the kptr field and load
them back as a PTR_TO_BTF_ID.
Call mark_chain_precision() before accepting a known-zero register. This
forces state equivalence to compare its scalar range and makes the verifier
visit and reject a path carrying a nonzero value.
Fixes: 61df10c7799e ("bpf: Allow storing unreferenced kptr in map")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Acked-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260904104203.345917-6-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 72994e41843ca..14bd6889f6de9 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -4528,8 +4528,15 @@ static int check_map_kptr_access(struct bpf_verifier_env *env,
return ret;
} else if (class == BPF_STX) {
val_reg = reg_state(env, value_regno);
- if (!bpf_register_is_null(val_reg) &&
- map_kptr_match_type(env, kptr_field, val_reg, value_regno))
+ if (bpf_register_is_null(val_reg)) {
+ /*
+ * This store is valid only because the scalar is known to be
+ * zero. Mark it precise so another scalar cannot be pruned
+ * against this state.
+ */
+ return mark_chain_precision(env, value_regno);
+ }
+ if (map_kptr_match_type(env, kptr_field, val_reg, value_regno))
return -EACCES;
} else if (class == BPF_ST) {
if (insn->imm) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 267/733] bpf: Preserve inner map identity in callback frames
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (265 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 266/733] bpf: Mark NULL kptr stores precise Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 268/733] ring-buffer: Remove ring_buffer_per_cpu::mapped Greg Kroah-Hartman
` (477 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicholas Carlini,
Kumar Kartikeya Dwivedi, Alexei Starovoitov, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit b90c5d770dad910fb89e6c1b15052a8a1e8db752 ]
Callback frame constructors initialize map-typed argument registers with
__mark_reg_known_zero() and then restore map_ptr. This clears map_uid,
which is the only field distinguishing inner maps that share an
inner_map_meta template.
When a timer callback invokes bpf_for_each_map_elem() on a second inner
map, both the saved first map and the second map value can reach the nested
callback as the same template with map_uid zero. bpf_timer_init() then
accepts pairing the timer from the second map with the first map.
The runtime records the first map in the timer without taking a reference.
Freeing that map does not find the timer stored in the second map, so a
later timer callback dereferences the freed map.
Copy map_uid from the same caller register as map_ptr when constructing
for-each, timer/workqueue, and task-work callback arguments. The existing
identity check can then reject mismatched inner maps while allowing a
callback value to be paired with its actual map.
Fixes: 3e8ce29850f1 ("bpf: Prevent pointer mismatch in bpf_timer_init.")
Fixes: 69c087ba6225 ("bpf: Add bpf_for_each_map_elem() helper")
Fixes: 5c8fd7e2b5b0 ("bpf: bpf task work plumbing")
Reported-by: Nicholas Carlini <npc@anthropic.com>
Suggested-by: Nicholas Carlini <npc@anthropic.com>
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://lore.kernel.org/r/20260904104203.345917-8-memxor@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 14bd6889f6de9..be282185d5653 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -9529,10 +9529,12 @@ int map_set_for_each_callback_args(struct bpf_verifier_env *env,
callee->regs[BPF_REG_2].type = PTR_TO_MAP_KEY;
__mark_reg_known_zero(&callee->regs[BPF_REG_2]);
callee->regs[BPF_REG_2].map_ptr = caller->regs[BPF_REG_1].map_ptr;
+ callee->regs[BPF_REG_2].map_uid = caller->regs[BPF_REG_1].map_uid;
callee->regs[BPF_REG_3].type = PTR_TO_MAP_VALUE;
__mark_reg_known_zero(&callee->regs[BPF_REG_3]);
callee->regs[BPF_REG_3].map_ptr = caller->regs[BPF_REG_1].map_ptr;
+ callee->regs[BPF_REG_3].map_uid = caller->regs[BPF_REG_1].map_uid;
/* pointer to stack or null */
callee->regs[BPF_REG_4] = caller->regs[BPF_REG_3];
@@ -9610,6 +9612,7 @@ static int set_timer_callback_state(struct bpf_verifier_env *env,
int insn_idx)
{
struct bpf_map *map_ptr = caller->regs[BPF_REG_1].map_ptr;
+ u32 map_uid = caller->regs[BPF_REG_1].map_uid;
/* bpf_timer_set_callback(struct bpf_timer *timer, void *callback_fn);
* callback_fn(struct bpf_map *map, void *key, void *value);
@@ -9617,14 +9620,17 @@ static int set_timer_callback_state(struct bpf_verifier_env *env,
callee->regs[BPF_REG_1].type = CONST_PTR_TO_MAP;
__mark_reg_known_zero(&callee->regs[BPF_REG_1]);
callee->regs[BPF_REG_1].map_ptr = map_ptr;
+ callee->regs[BPF_REG_1].map_uid = map_uid;
callee->regs[BPF_REG_2].type = PTR_TO_MAP_KEY;
__mark_reg_known_zero(&callee->regs[BPF_REG_2]);
callee->regs[BPF_REG_2].map_ptr = map_ptr;
+ callee->regs[BPF_REG_2].map_uid = map_uid;
callee->regs[BPF_REG_3].type = PTR_TO_MAP_VALUE;
__mark_reg_known_zero(&callee->regs[BPF_REG_3]);
callee->regs[BPF_REG_3].map_ptr = map_ptr;
+ callee->regs[BPF_REG_3].map_uid = map_uid;
/* unused */
bpf_mark_reg_not_init(env, &callee->regs[BPF_REG_4]);
@@ -9724,6 +9730,7 @@ static int set_task_work_schedule_callback_state(struct bpf_verifier_env *env,
int insn_idx)
{
struct bpf_map *map_ptr = caller->regs[BPF_REG_3].map_ptr;
+ u32 map_uid = caller->regs[BPF_REG_3].map_uid;
/*
* callback_fn(struct bpf_map *map, void *key, void *value);
@@ -9731,14 +9738,17 @@ static int set_task_work_schedule_callback_state(struct bpf_verifier_env *env,
callee->regs[BPF_REG_1].type = CONST_PTR_TO_MAP;
__mark_reg_known_zero(&callee->regs[BPF_REG_1]);
callee->regs[BPF_REG_1].map_ptr = map_ptr;
+ callee->regs[BPF_REG_1].map_uid = map_uid;
callee->regs[BPF_REG_2].type = PTR_TO_MAP_KEY;
__mark_reg_known_zero(&callee->regs[BPF_REG_2]);
callee->regs[BPF_REG_2].map_ptr = map_ptr;
+ callee->regs[BPF_REG_2].map_uid = map_uid;
callee->regs[BPF_REG_3].type = PTR_TO_MAP_VALUE;
__mark_reg_known_zero(&callee->regs[BPF_REG_3]);
callee->regs[BPF_REG_3].map_ptr = map_ptr;
+ callee->regs[BPF_REG_3].map_uid = map_uid;
/* unused */
bpf_mark_reg_not_init(env, &callee->regs[BPF_REG_4]);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 268/733] ring-buffer: Remove ring_buffer_per_cpu::mapped
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (266 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 267/733] bpf: Preserve inner map identity in callback frames Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 269/733] tracing: Fix subbuf resize races with trace_pipe_raw readers Greg Kroah-Hartman
` (476 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit 8b502bf6eb3da15f4b954ad3632335ff10ed746a ]
ring_buffer_per_cpu::mapped tracks if a ring-buffer is either mapped by
user-space or if it is a persistent buffer. We already have user_mapped
for the former and ring_meta for the latter. Get rid of mapped and
instead create rb_is_static(). A static ring-buffer cannot be resized,
swapped or have its pages extracted.
Link: https://patch.msgid.link/20260813131152.3589632-10-vdonnefort@google.com
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Stable-dep-of: dae8dda341d2 ("tracing: Fix subbuf resize races with trace_pipe_raw readers")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/ring_buffer.c | 45 ++++++++++++++------------------------
1 file changed, 17 insertions(+), 28 deletions(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 70e43fe3a1006..86e4c224071b3 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -514,7 +514,7 @@ struct ring_buffer_per_cpu {
int cpu;
atomic_t record_disabled;
atomic_t resize_disabled;
- struct trace_buffer *buffer;
+ struct trace_buffer *buffer;
raw_spinlock_t reader_lock; /* serialize readers */
arch_spinlock_t lock;
struct lock_class_key lock_key;
@@ -552,7 +552,6 @@ struct ring_buffer_per_cpu {
/* pages removed since last reset */
unsigned long pages_removed;
- unsigned int mapped;
unsigned int user_mapped; /* user space mapping */
struct mutex mapping_lock;
struct buffer_page **subbuf_ids; /* ID to subbuf VA */
@@ -632,6 +631,11 @@ unsigned long rb_subbuf_start(struct trace_buffer *buffer, unsigned long addr)
return addr & ~((unsigned long)(rb_subbuf_size(buffer) - 1));
}
+static bool rb_is_static(struct ring_buffer_per_cpu *cpu_buffer)
+{
+ return cpu_buffer->user_mapped || cpu_buffer->remote || cpu_buffer->ring_meta;
+}
+
struct ring_buffer_iter {
struct ring_buffer_per_cpu *cpu_buffer;
unsigned long head;
@@ -2567,7 +2571,6 @@ rb_allocate_cpu_buffer(struct trace_buffer *buffer, long nr_pages, int cpu)
* Range mapped buffers have the same restrictions as memory
* mapped ones do.
*/
- cpu_buffer->mapped = 1;
cpu_buffer->ring_meta = rb_range_meta(buffer, nr_pages, cpu);
bpage->page = rb_range_buffer(cpu_buffer, 0);
if (!bpage->page)
@@ -6661,12 +6664,11 @@ rb_reset_cpu(struct ring_buffer_per_cpu *cpu_buffer)
rb_head_page_activate(cpu_buffer);
cpu_buffer->pages_removed = 0;
- if (cpu_buffer->mapped) {
- rb_update_meta_page(cpu_buffer);
- if (cpu_buffer->ring_meta) {
- struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
- meta->commit_buffer = meta->head_buffer;
- }
+ rb_update_meta_page(cpu_buffer);
+ if (cpu_buffer->ring_meta) {
+ struct ring_buffer_cpu_meta *meta = cpu_buffer->ring_meta;
+
+ meta->commit_buffer = meta->head_buffer;
}
}
@@ -6915,8 +6917,8 @@ int ring_buffer_swap_cpu(struct trace_buffer *buffer_a,
cpu_buffer_a = buffer_a->buffers[cpu];
cpu_buffer_b = buffer_b->buffers[cpu];
- /* It's up to the callers to not try to swap mapped buffers */
- if (WARN_ON_ONCE(cpu_buffer_a->mapped || cpu_buffer_b->mapped))
+ /* It's up to the callers to not try to swap static buffers */
+ if (WARN_ON_ONCE(rb_is_static(cpu_buffer_a) || rb_is_static(cpu_buffer_b)))
return -EBUSY;
/* At least make sure the two buffers are somewhat the same */
@@ -7128,7 +7130,6 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
unsigned int size;
unsigned int read;
u64 save_timestamp;
- bool force_memcpy;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
return -1;
@@ -7167,8 +7168,6 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
/* Check if any events were dropped */
missed_events = cpu_buffer->lost_events;
- force_memcpy = cpu_buffer->mapped || cpu_buffer->remote;
-
/*
* If this page has been partially read or
* if len is not big enough to read the rest of the page or
@@ -7178,7 +7177,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
*/
if (read || (len < (size - read)) ||
cpu_buffer->reader_page == cpu_buffer->commit_page ||
- force_memcpy) {
+ rb_is_static(cpu_buffer)) {
struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
unsigned int rpos = read;
unsigned int pos = 0;
@@ -7620,11 +7619,7 @@ static int __rb_inc_dec_mapped(struct ring_buffer_per_cpu *cpu_buffer,
lockdep_assert_held(&cpu_buffer->mapping_lock);
- /* mapped is always greater or equal to user_mapped */
- if (WARN_ON(cpu_buffer->mapped < cpu_buffer->user_mapped))
- return -EINVAL;
-
- if (inc && cpu_buffer->mapped == UINT_MAX)
+ if (inc && cpu_buffer->user_mapped == UINT_MAX)
return -EBUSY;
if (WARN_ON(!inc && cpu_buffer->user_mapped == 0))
@@ -7633,13 +7628,10 @@ static int __rb_inc_dec_mapped(struct ring_buffer_per_cpu *cpu_buffer,
mutex_lock(&cpu_buffer->buffer->mutex);
raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
- if (inc) {
+ if (inc)
cpu_buffer->user_mapped++;
- cpu_buffer->mapped++;
- } else {
+ else
cpu_buffer->user_mapped--;
- cpu_buffer->mapped--;
- }
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
mutex_unlock(&cpu_buffer->buffer->mutex);
@@ -7811,7 +7803,6 @@ int ring_buffer_map(struct trace_buffer *buffer, int cpu,
if (!err) {
raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
/* This is the first time it is mapped by user */
- cpu_buffer->mapped++;
cpu_buffer->user_mapped = 1;
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
} else {
@@ -7868,8 +7859,6 @@ int ring_buffer_unmap(struct trace_buffer *buffer, int cpu)
raw_spin_lock_irqsave(&cpu_buffer->reader_lock, flags);
/* This is the last user space mapping */
- if (!WARN_ON_ONCE(cpu_buffer->mapped < cpu_buffer->user_mapped))
- cpu_buffer->mapped--;
cpu_buffer->user_mapped = 0;
raw_spin_unlock_irqrestore(&cpu_buffer->reader_lock, flags);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 269/733] tracing: Fix subbuf resize races with trace_pipe_raw readers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (267 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 268/733] ring-buffer: Remove ring_buffer_per_cpu::mapped Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 270/733] ring-buffer: Cap static ring buffer nr_pages Greg Kroah-Hartman
` (475 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit dae8dda341d2d9034a90d59e8a7d502e1263813f ]
Concurrent subbuffer resizes may crash trace_pipe_raw readers or leak
uninitialized memory to userspace due to stale size values.
Modify ring_buffer_alloc_read_page() to handle the resizing of an
existing buffer_data_read_page if necessary and add a new
ring_buffer_read_page_size(). This new function enables ring-buffer
buffer_data_read_page users to not call the racy
ring_buffer_subbuf_size_get(). This makes the spare_size member of
ftrace_buffer_info redundant.
Finally, handle buffer_data_read_page/reader_page order discrepancy in
ring_buffer_read_page(). On a mismatch simply copy manually the data to
the buffer_data_read_page.
Link: https://lore.kernel.org/all/20260817140812.2C7D41F00A3A@smtp.kernel.org/
Link: https://patch.msgid.link/20260904164450.1345852-3-vdonnefort@google.com
Fixes: bce761d75745 ("ring-buffer: Read and write to ring buffers with custom sub buffer size")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/ring_buffer.h | 5 +-
kernel/trace/ring_buffer.c | 135 ++++++++++++++++++---------
kernel/trace/ring_buffer_benchmark.c | 6 +-
kernel/trace/trace.c | 97 +++++++++----------
kernel/trace/trace.h | 9 +-
5 files changed, 144 insertions(+), 108 deletions(-)
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 0670742b2d601..afc7daa6ee7dc 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -218,14 +218,15 @@ bool ring_buffer_time_stamp_abs(struct trace_buffer *buffer);
size_t ring_buffer_nr_dirty_pages(struct trace_buffer *buffer, int cpu);
struct buffer_data_read_page;
-struct buffer_data_read_page *
-ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu);
+int ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu,
+ struct buffer_data_read_page **rpage);
void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu,
struct buffer_data_read_page *page);
int ring_buffer_read_page(struct trace_buffer *buffer,
struct buffer_data_read_page *data_page,
size_t len, int cpu, int full);
void *ring_buffer_read_page_data(struct buffer_data_read_page *page);
+unsigned int ring_buffer_read_page_size(struct buffer_data_read_page *rpage);
struct trace_seq;
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 86e4c224071b3..8e4fb3bf309c6 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -330,6 +330,11 @@ struct buffer_data_read_page {
struct buffer_data_page *data; /* actual data, stored in this page */
};
+static __always_inline unsigned int rb_read_page_capacity(struct buffer_data_read_page *rpage)
+{
+ return (PAGE_SIZE << rpage->order) - BUF_PAGE_HDR_SIZE;
+}
+
/*
* Note, the buffer_page list must be first. The buffer pages
* are allocated in cache lines, which means that each buffer
@@ -6984,56 +6989,78 @@ EXPORT_SYMBOL_GPL(ring_buffer_swap_cpu);
* ring_buffer_alloc_read_page - allocate a page to read from buffer
* @buffer: the buffer to allocate for.
* @cpu: the cpu buffer to allocate.
+ * @rpage: pointer to pass in an already allocated page (can be NULL)
+ * and returns the allocated page.
*
- * This function is used in conjunction with ring_buffer_read_page.
+ * This function is used in conjunction with ring_buffer_read_page().
* When reading a full page from the ring buffer, these functions
* can be used to speed up the process. The calling function should
* allocate a few pages first with this function. Then when it
* needs to get pages from the ring buffer, it passes the result
- * of this function into ring_buffer_read_page, which will swap
+ * of this function into ring_buffer_read_page(), which will swap
* the page that was allocated, with the read page of the buffer.
*
+ * If @rpage is provided, and it has a different order than the current
+ * subbuffer order, its payload will be freed and re-allocated. If it
+ * already matches the order, it is simply returned.
+ *
* Returns:
- * The page allocated, or ERR_PTR
+ * 0 on success, < 0 on error
*/
-struct buffer_data_read_page *
-ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu)
+int ring_buffer_alloc_read_page(struct trace_buffer *buffer, int cpu,
+ struct buffer_data_read_page **rpage)
{
struct ring_buffer_per_cpu *cpu_buffer;
- struct buffer_data_read_page *bpage = NULL;
unsigned long flags;
+ unsigned int order;
if (!cpumask_test_cpu(cpu, buffer->cpumask))
- return ERR_PTR(-ENODEV);
+ return -ENODEV;
- bpage = kzalloc_obj(*bpage);
- if (!bpage)
- return ERR_PTR(-ENOMEM);
+ if (!rpage)
+ return -EINVAL;
+
+ order = READ_ONCE(buffer->subbuf_order);
- bpage->order = buffer->subbuf_order;
+ if (*rpage) {
+ if ((*rpage)->order == order)
+ return 0;
+
+ /* We can reuse rpage, but we discard the payload */
+ free_pages((unsigned long)(*rpage)->data, (*rpage)->order);
+ (*rpage)->data = NULL;
+ } else {
+ *rpage = kzalloc_obj(**rpage);
+ if (!*rpage)
+ return -ENOMEM;
+ }
+
+ (*rpage)->order = order;
cpu_buffer = buffer->buffers[cpu];
+
local_irq_save(flags);
arch_spin_lock(&cpu_buffer->lock);
if (cpu_buffer->free_page.data) {
- *bpage = cpu_buffer->free_page;
+ **rpage = cpu_buffer->free_page;
cpu_buffer->free_page.data = NULL;
}
arch_spin_unlock(&cpu_buffer->lock);
local_irq_restore(flags);
- if (bpage->data) {
- rb_init_data_page(bpage->data);
+ if ((*rpage)->data) {
+ rb_init_data_page((*rpage)->data);
} else {
- bpage->data = alloc_cpu_data(cpu, bpage->order);
- if (!bpage->data) {
- kfree(bpage);
- return ERR_PTR(-ENOMEM);
+ (*rpage)->data = alloc_cpu_data(cpu, (*rpage)->order);
+ if (!(*rpage)->data) {
+ kfree(*rpage);
+ *rpage = NULL;
+ return -ENOMEM;
}
}
- return bpage;
+ return 0;
}
EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
@@ -7041,21 +7068,30 @@ EXPORT_SYMBOL_GPL(ring_buffer_alloc_read_page);
* ring_buffer_free_read_page - free an allocated read page
* @buffer: the buffer the page was allocate for
* @cpu: the cpu buffer the page came from
- * @data_page: the page to free
+ * @rpage: the buffer_data_read_page to free
*
* Free a page allocated from ring_buffer_alloc_read_page.
*/
void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu,
- struct buffer_data_read_page *data_page)
+ struct buffer_data_read_page *rpage)
{
struct ring_buffer_per_cpu *cpu_buffer;
- struct buffer_data_page *dpage = data_page->data;
- struct page *page = virt_to_page(dpage);
+ struct buffer_data_page *dpage;
unsigned long flags;
+ struct page *page;
if (!buffer || !buffer->buffers || !buffer->buffers[cpu])
return;
+ if (!rpage)
+ return;
+
+ dpage = rpage->data;
+ if (!dpage)
+ goto out;
+
+ page = virt_to_page(dpage);
+
cpu_buffer = buffer->buffers[cpu];
/*
@@ -7063,14 +7099,14 @@ void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu,
* is different from the subbuffer order of the buffer -
* we can't reuse it
*/
- if (page_ref_count(page) > 1 || data_page->order != buffer->subbuf_order)
+ if (page_ref_count(page) > 1 || rpage->order != READ_ONCE(buffer->subbuf_order))
goto out;
local_irq_save(flags);
arch_spin_lock(&cpu_buffer->lock);
if (!cpu_buffer->free_page.data) {
- cpu_buffer->free_page = *data_page;
+ cpu_buffer->free_page = *rpage;
dpage = NULL;
}
@@ -7078,8 +7114,8 @@ void ring_buffer_free_read_page(struct trace_buffer *buffer, int cpu,
local_irq_restore(flags);
out:
- free_pages((unsigned long)dpage, data_page->order);
- kfree(data_page);
+ free_pages((unsigned long)dpage, rpage->order);
+ kfree(rpage);
}
EXPORT_SYMBOL_GPL(ring_buffer_free_read_page);
@@ -7150,10 +7186,9 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
if (!dpage)
return -1;
- guard(raw_spinlock_irqsave)(&cpu_buffer->reader_lock);
+ len = min_t(size_t, len, rb_read_page_capacity(data_page));
- if (data_page->order != cpu_buffer->reader_page->order)
- return -1;
+ guard(raw_spinlock_irqsave)(&cpu_buffer->reader_lock);
reader = rb_get_reader_page(cpu_buffer);
if (!reader)
@@ -7168,16 +7203,18 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
/* Check if any events were dropped */
missed_events = cpu_buffer->lost_events;
- /*
- * If this page has been partially read or
- * if len is not big enough to read the rest of the page or
- * a writer is still on the page, then
- * we must copy the data from the page to the buffer.
- * Otherwise, we can simply swap the page with the one passed in.
- */
+ /*
+ * It is not possible to swap the reader page if:
+ * - It has been partially read
+ * - len is not big enough to read it entirely
+ * - A writer is still on it
+ * - The ring buffer is static
+ * - The order doesn't match
+ */
if (read || (len < (size - read)) ||
cpu_buffer->reader_page == cpu_buffer->commit_page ||
- rb_is_static(cpu_buffer)) {
+ rb_is_static(cpu_buffer) ||
+ data_page->order != reader->order) {
struct buffer_data_page *rpage = cpu_buffer->reader_page->page;
unsigned int rpos = read;
unsigned int pos = 0;
@@ -7271,7 +7308,7 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
* missed events, then record it there.
*/
if (missed_events > 0 &&
- rb_page_capacity(reader) - size >= sizeof(missed_events)) {
+ rb_read_page_capacity(data_page) - size >= sizeof(missed_events)) {
memcpy(&dpage->data[size], &missed_events,
sizeof(missed_events));
local_add(RB_MISSED_STORED, &dpage->commit);
@@ -7291,8 +7328,8 @@ int ring_buffer_read_page(struct trace_buffer *buffer,
/*
* This page may be off to user land. Zero it out here.
*/
- if (size < rb_page_capacity(reader))
- memset(&dpage->data[size], 0, rb_page_capacity(reader) - size);
+ if (size < rb_read_page_capacity(data_page))
+ memset(&dpage->data[size], 0, rb_read_page_capacity(data_page) - size);
return read;
}
@@ -7310,6 +7347,18 @@ void *ring_buffer_read_page_data(struct buffer_data_read_page *page)
}
EXPORT_SYMBOL_GPL(ring_buffer_read_page_data);
+/**
+ * ring_buffer_read_page_size - get size of the read page.
+ * @page: the page to get the size from
+ *
+ * Returns size of the page in bytes.
+ */
+unsigned int ring_buffer_read_page_size(struct buffer_data_read_page *rpage)
+{
+ return rpage ? PAGE_SIZE << rpage->order : 0;
+}
+EXPORT_SYMBOL_GPL(ring_buffer_read_page_size);
+
/**
* ring_buffer_subbuf_size_get - get size of the sub buffer.
* @buffer: the buffer to get the sub buffer size from
@@ -7395,7 +7444,7 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)
/* Make sure all commits have finished */
synchronize_rcu();
- buffer->subbuf_order = order;
+ WRITE_ONCE(buffer->subbuf_order, order);
/* Make sure all new buffers are allocated, before deleting the old ones */
for_each_buffer_cpu(buffer, cpu) {
@@ -7499,7 +7548,7 @@ int ring_buffer_subbuf_order_set(struct trace_buffer *buffer, int order)
return 0;
error:
- buffer->subbuf_order = old_order;
+ WRITE_ONCE(buffer->subbuf_order, old_order);
atomic_dec(&buffer->record_disabled);
diff --git a/kernel/trace/ring_buffer_benchmark.c b/kernel/trace/ring_buffer_benchmark.c
index 593e3b59e42e9..c3d34c0e64e28 100644
--- a/kernel/trace/ring_buffer_benchmark.c
+++ b/kernel/trace/ring_buffer_benchmark.c
@@ -104,7 +104,7 @@ static enum event_status read_event(int cpu)
static enum event_status read_page(int cpu)
{
- struct buffer_data_read_page *bpage;
+ struct buffer_data_read_page *bpage = NULL;
struct ring_buffer_event *event;
struct rb_page *rpage;
unsigned long commit;
@@ -114,8 +114,8 @@ static enum event_status read_page(int cpu)
int inc;
int i;
- bpage = ring_buffer_alloc_read_page(buffer, cpu);
- if (IS_ERR(bpage))
+ ret = ring_buffer_alloc_read_page(buffer, cpu, &bpage);
+ if (ret < 0)
return EVENT_DROPPED;
page_size = ring_buffer_subbuf_size_get(buffer);
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index e6915fc7de832..fef4a7403f3e5 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7080,8 +7080,8 @@ ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf,
{
struct ftrace_buffer_info *info = filp->private_data;
struct trace_iterator *iter = &info->iter;
+ unsigned int spare_size;
void *trace_data;
- int page_size;
ssize_t ret = 0;
ssize_t size;
@@ -7091,36 +7091,22 @@ ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf,
if (iter->snapshot && tracer_uses_snapshot(iter->tr->current_trace))
return -EBUSY;
- page_size = ring_buffer_subbuf_size_get(iter->array_buffer->buffer);
+ spare_size = ring_buffer_read_page_size(info->spare);
- /* Make sure the spare matches the current sub buffer size */
- if (info->spare) {
- if (page_size != info->spare_size) {
- ring_buffer_free_read_page(iter->array_buffer->buffer,
- info->spare_cpu, info->spare);
- info->spare = NULL;
- }
- }
+again:
+ /* Do we have previous read data to read? */
+ if (info->read < spare_size)
+ goto read;
- if (!info->spare) {
- info->spare = ring_buffer_alloc_read_page(iter->array_buffer->buffer,
- iter->cpu_file);
- if (IS_ERR(info->spare)) {
- ret = PTR_ERR(info->spare);
- info->spare = NULL;
- } else {
- info->spare_cpu = iter->cpu_file;
- info->spare_size = page_size;
- }
- }
- if (!info->spare)
+ ret = ring_buffer_alloc_read_page(iter->array_buffer->buffer, iter->cpu_file,
+ &info->spare);
+ if (ret)
return ret;
- /* Do we have previous read data to read? */
- if (info->read < page_size)
- goto read;
+ spare_size = ring_buffer_read_page_size(info->spare);
+ info->read = spare_size;
+ info->spare_cpu = iter->cpu_file;
- again:
trace_access_lock(iter->cpu_file);
ret = ring_buffer_read_page(iter->array_buffer->buffer,
info->spare,
@@ -7146,8 +7132,9 @@ ssize_t tracing_buffers_read(struct file *filp, char __user *ubuf,
}
info->read = 0;
+
read:
- size = page_size - info->read;
+ size = spare_size - info->read;
if (size > count)
size = count;
trace_data = ring_buffer_read_page_data(info->spare);
@@ -7188,26 +7175,24 @@ int tracing_buffers_release(struct inode *inode, struct file *file)
__trace_array_put(iter->tr);
- if (info->spare)
- ring_buffer_free_read_page(iter->array_buffer->buffer,
- info->spare_cpu, info->spare);
+ ring_buffer_free_read_page(iter->array_buffer->buffer, info->spare_cpu, info->spare);
kvfree(info);
return 0;
}
struct buffer_ref {
- struct trace_buffer *buffer;
- void *page;
- int cpu;
- refcount_t refcount;
+ struct trace_buffer *buffer;
+ struct buffer_data_read_page *rpage;
+ int cpu;
+ refcount_t refcount;
};
static void buffer_ref_release(struct buffer_ref *ref)
{
if (!refcount_dec_and_test(&ref->refcount))
return;
- ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->page);
+ ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->rpage);
kfree(ref);
}
@@ -7266,25 +7251,15 @@ ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos,
.ops = &buffer_pipe_buf_ops,
.spd_release = buffer_spd_release,
};
+ unsigned int page_size = 0;
struct buffer_ref *ref;
bool woken = false;
- int page_size;
int entries, i;
ssize_t ret = 0;
if (iter->snapshot && tracer_uses_snapshot(iter->tr->current_trace))
return -EBUSY;
- page_size = ring_buffer_subbuf_size_get(iter->array_buffer->buffer);
- if (*ppos & (page_size - 1))
- return -EINVAL;
-
- if (len & (page_size - 1)) {
- if (len < page_size)
- return -EINVAL;
- len &= (~(page_size - 1));
- }
-
if (splice_grow_spd(pipe, &spd))
return -ENOMEM;
@@ -7304,25 +7279,37 @@ ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos,
refcount_set(&ref->refcount, 1);
ref->buffer = iter->array_buffer->buffer;
- ref->page = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file);
- if (IS_ERR(ref->page)) {
- ret = PTR_ERR(ref->page);
- ref->page = NULL;
+
+ ret = ring_buffer_alloc_read_page(ref->buffer, iter->cpu_file, &ref->rpage);
+ if (ret) {
kfree(ref);
break;
}
ref->cpu = iter->cpu_file;
- r = ring_buffer_read_page(ref->buffer, ref->page,
- len, iter->cpu_file, 1);
+ page_size = ring_buffer_read_page_size(ref->rpage);
+
+ r = -EINVAL;
+ if (IS_ALIGNED(*ppos, page_size) && len >= page_size) {
+ r = ring_buffer_read_page(ref->buffer, ref->rpage, len, iter->cpu_file, 1);
+ } else if (!i) {
+ /*
+ * We failed to read because the length is too small
+ * or unaligned. If this is the first iteration, it's
+ * an invalid userspace input. Otherwise, this is due
+ * to a subbuf order change. Do not report an error
+ * and just finish the read.
+ */
+ ret = -EINVAL;
+ }
+
if (r < 0) {
- ring_buffer_free_read_page(ref->buffer, ref->cpu,
- ref->page);
+ ring_buffer_free_read_page(ref->buffer, ref->cpu, ref->rpage);
kfree(ref);
break;
}
- page = virt_to_page(ring_buffer_read_page_data(ref->page));
+ page = virt_to_page(ring_buffer_read_page_data(ref->rpage));
spd.pages[i] = page;
spd.partial[i].len = page_size;
diff --git a/kernel/trace/trace.h b/kernel/trace/trace.h
index 3c111ca88e32d..5e76f94e7a80e 100644
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -745,11 +745,10 @@ static inline int tracing_get_cpu(struct inode *inode)
void tracing_reset_cpu(struct array_buffer *buf, int cpu);
struct ftrace_buffer_info {
- struct trace_iterator iter;
- void *spare;
- unsigned int spare_cpu;
- unsigned int spare_size;
- unsigned int read;
+ struct trace_iterator iter;
+ struct buffer_data_read_page *spare;
+ unsigned int spare_cpu;
+ unsigned int read;
};
/**
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 270/733] ring-buffer: Cap static ring buffer nr_pages
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (268 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 269/733] tracing: Fix subbuf resize races with trace_pipe_raw readers Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 271/733] tracing: Fix comment in tracing_buffers_splice_read() Greg Kroah-Hartman
` (474 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit f2b2b645595c82b4e824880f6cb987e077a8da19 ]
Static ring buffers (i.e. persistent, user-mapped and remote) rely on
the bpage::id field. The number of pages for those ring buffers must fit
into that variable. Enforce this limit on ring buffer creation or
user-mapping.
While at it, prevent nr_pages underflow when allocating a persistent
buffer.
Link: https://patch.msgid.link/20260904164450.1345852-4-vdonnefort@google.com
Fixes: be68d63a139b ("ring-buffer: Add ring_buffer_alloc_range()")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/ring_buffer.c | 22 ++++++++++++++++++++++
1 file changed, 22 insertions(+)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 8e4fb3bf309c6..66760542fce10 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -641,6 +641,15 @@ static bool rb_is_static(struct ring_buffer_per_cpu *cpu_buffer)
return cpu_buffer->user_mapped || cpu_buffer->remote || cpu_buffer->ring_meta;
}
+static unsigned long rb_static_max_pages(void)
+{
+ /*
+ * Static ring buffers are using bpage::id and must account for the
+ * reader page.
+ */
+ return (1UL << 30) - 1;
+}
+
struct ring_buffer_iter {
struct ring_buffer_per_cpu *cpu_buffer;
unsigned long head;
@@ -2825,6 +2834,8 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
size = end - buffers_start;
size = size / nr_cpu_ids;
+ if (size < sizeof(struct ring_buffer_cpu_meta))
+ goto fail_free_buffers;
/*
* The number of sub-buffers (nr_pages) is determined by the
* total size allocated minus the meta data size.
@@ -2834,6 +2845,10 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
*/
nr_pages = (size - sizeof(struct ring_buffer_cpu_meta)) /
(subbuf_size + sizeof(int));
+
+ if (nr_pages > rb_static_max_pages())
+ goto fail_free_buffers;
+
/* Need at least two pages plus the reader page */
if (nr_pages < 3)
goto fail_free_buffers;
@@ -2866,6 +2881,10 @@ static struct trace_buffer *alloc_buffer(unsigned long size, unsigned flags,
/* The writer is remote. This ring-buffer is read-only */
atomic_inc(&buffer->record_disabled);
nr_pages = desc->nr_page_va - 1;
+
+ if (nr_pages > rb_static_max_pages())
+ goto fail_free_buffers;
+
if (nr_pages < 2)
goto fail_free_buffers;
} else {
@@ -7826,6 +7845,9 @@ int ring_buffer_map(struct trace_buffer *buffer, int cpu,
/* prevent another thread from changing buffer/sub-buffer sizes */
guard(mutex)(&buffer->mutex);
+ if (cpu_buffer->nr_pages > rb_static_max_pages())
+ return -E2BIG;
+
err = rb_alloc_meta_page(cpu_buffer);
if (err)
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 271/733] tracing: Fix comment in tracing_buffers_splice_read()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (269 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 270/733] ring-buffer: Cap static ring buffer nr_pages Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 272/733] nexthop: Initialize extack in remove_nh_grp_entry() Greg Kroah-Hartman
` (473 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Steven Rostedt, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
[ Upstream commit 5cbea500775dd1944995f23320af030b9b24b24b ]
The comment about returning an error if the read fails on the first
iteration is slightly incorrect. It makes it sound like the only reason it
could fail on a later iteration is if the subbuf order changed. That is
incorrect, it could also fail if the length passed in was not a multiple
of the subbuf size. Fix the comment.
Link: https://lore.kernel.org/all/20260904143527.40e73d36@gandalf.local.home/
Link: https://patch.msgid.link/20260904144902.506862a1@gandalf.local.home
Fixes: dae8dda341d2 ("tracing: Fix subbuf resize races with trace_pipe_raw readers")
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/trace.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
diff --git a/kernel/trace/trace.c b/kernel/trace/trace.c
index fef4a7403f3e5..beb4c35519d3b 100644
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7294,11 +7294,13 @@ ssize_t tracing_buffers_splice_read(struct file *file, loff_t *ppos,
r = ring_buffer_read_page(ref->buffer, ref->rpage, len, iter->cpu_file, 1);
} else if (!i) {
/*
- * We failed to read because the length is too small
- * or unaligned. If this is the first iteration, it's
- * an invalid userspace input. Otherwise, this is due
- * to a subbuf order change. Do not report an error
- * and just finish the read.
+ * If this fails to read on the first iteration, it
+ * means the length was too small and an error should
+ * be returned to user space. Otherwise, at least
+ * one sub-buffer was successfully read but this failed
+ * due to either the length was unaligned or the
+ * subbuf order changed. Either case, do not report
+ * an error.
*/
ret = -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 272/733] nexthop: Initialize extack in remove_nh_grp_entry()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (270 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 271/733] tracing: Fix comment in tracing_buffers_splice_read() Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 273/733] bonding: use skb_cow_head() in bond_do_alb_xmit() and rlb_arp_xmit() Greg Kroah-Hartman
` (472 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Eric Dumazet,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
[ Upstream commit 5bd9e4e7cdaa03879e9b73b12ab52cceb1edd55b ]
remove_nh_grp_entry() prints the extack message when a listener fails
to replace the reduced nexthop group. However, extack is not
initialized and listeners are not required to set a message when
returning an error. Neither netdevsim nor mlxsw do so when an
allocation fails, resulting in the dereference of an uninitialized
stack pointer.
Fix by zero-initializing extack, as was done in commit 6347c5314cee
("nexthop: initialize extack in nh_res_bucket_migrate()").
Fixes: 833a1065eeb1 ("nexthop: Emit a notification when a nexthop group is reduced")
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260903080259.10378-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/nexthop.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/nexthop.c b/net/ipv4/nexthop.c
index 0f1e21a5c812e..901c353196828 100644
--- a/net/ipv4/nexthop.c
+++ b/net/ipv4/nexthop.c
@@ -2029,7 +2029,7 @@ remove_nh_grp_entry(struct net *net, struct nh_grp_entry *nhge,
{
struct nh_grp_entry *nhges, *new_nhges;
struct nexthop *nhp = nhge->nh_parent;
- struct netlink_ext_ack extack;
+ struct netlink_ext_ack extack = {};
struct nexthop *nh = nhge->nh;
struct nh_group *nhg, *newg;
int i, j, err;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 273/733] bonding: use skb_cow_head() in bond_do_alb_xmit() and rlb_arp_xmit()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (271 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 272/733] nexthop: Initialize extack in remove_nh_grp_entry() Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 274/733] net: dsa: bcm_sf2: bound the CFP rule dump by the callers buffer size Greg Kroah-Hartman
` (471 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Hangbin Liu,
Jay Vosburgh, Nikolay Aleksandrov, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit 1746ef2e2df2ad71c66eca56364d56bde284523b ]
In bond_do_alb_xmit() and rlb_arp_xmit(), make sure to unclone
skb head via skb_cow_head() before modifying the source MAC address
(Ethernet header and ARP payload) to avoid silent corruption if
the skb is shared or cloned. Avoid caching the header pointers
across skb_cow_head().
In rlb_arp_xmit(), only modify arp->mac_src if it differs from
tx_slave->dev->dev_addr to avoid an unnecessary copy and head
reallocation.
Also, we should not assume mac header is set in output path.
Use skb_eth_hdr() instead of eth_hdr() to fix the issue,
and remove now redundant skb_reset_mac_header() calls.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Cc: Jay Vosburgh <jv@jvosburgh.net>
Reviewed-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/20260903143940.1180513-1-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/bonding/bond_alb.c | 19 ++++++++++++-------
1 file changed, 12 insertions(+), 7 deletions(-)
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 654f051d00239..43ac8e28e4182 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -678,9 +678,15 @@ static struct slave *rlb_arp_xmit(struct sk_buff *skb, struct bonding *bond)
if (arp->op_code == htons(ARPOP_REPLY)) {
/* the arp must be sent on the selected rx channel */
tx_slave = rlb_choose_channel(skb, bond, arp);
- if (tx_slave)
+ if (tx_slave &&
+ !ether_addr_equal_64bits(arp->mac_src,
+ tx_slave->dev->dev_addr)) {
+ if (unlikely(skb_cow_head(skb, 0)))
+ return NULL;
+ arp = (struct arp_pkt *)skb_network_header(skb);
bond_hw_addr_copy(arp->mac_src, tx_slave->dev->dev_addr,
tx_slave->dev->addr_len);
+ }
netdev_dbg(bond->dev, "(slave %s): Server sent ARP Reply packet\n",
tx_slave ? tx_slave->dev->name : "NULL");
} else if (arp->op_code == htons(ARPOP_REQUEST)) {
@@ -1340,7 +1346,6 @@ static netdev_tx_t bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
struct slave *tx_slave)
{
struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
- struct ethhdr *eth_data = eth_hdr(skb);
if (!tx_slave) {
/* unbalanced or unassigned, send through primary */
@@ -1351,7 +1356,9 @@ static netdev_tx_t bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
if (tx_slave && bond_slave_can_tx(tx_slave)) {
if (tx_slave != rcu_access_pointer(bond->curr_active_slave)) {
- ether_addr_copy(eth_data->h_source,
+ if (unlikely(skb_cow_head(skb, 0)))
+ return bond_tx_drop(bond->dev, skb);
+ ether_addr_copy(skb_eth_hdr(skb)->h_source,
tx_slave->dev->dev_addr);
}
@@ -1375,8 +1382,7 @@ struct slave *bond_xmit_tlb_slave_get(struct bonding *bond,
struct ethhdr *eth_data;
u32 hash_index;
- skb_reset_mac_header(skb);
- eth_data = eth_hdr(skb);
+ eth_data = skb_eth_hdr(skb);
/* Do not TX balance any multicast or broadcast */
if (!is_multicast_ether_addr(eth_data->h_dest)) {
@@ -1428,8 +1434,7 @@ struct slave *bond_xmit_alb_slave_get(struct bonding *bond,
u32 hash_index = 0;
int hash_size = 0;
- skb_reset_mac_header(skb);
- eth_data = eth_hdr(skb);
+ eth_data = skb_eth_hdr(skb);
switch (ntohs(skb->protocol)) {
case ETH_P_IP: {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 274/733] net: dsa: bcm_sf2: bound the CFP rule dump by the callers buffer size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (272 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 273/733] bonding: use skb_cow_head() in bond_do_alb_xmit() and rlb_arp_xmit() Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 275/733] eth: nfp: bound the ntuple " Greg Kroah-Hartman
` (470 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jonas Gorski, Florian Fainelli,
Joe Damato, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit cdb719f4b8596d9ccee2d56d204c2c4dce982f46 ]
bcm_sf2_cfp_rule_get_all() walks the whole cfp.unique bitmap into
rule_locs[] without consulting nfc->rule_cnt, which is how many entries
the caller had room for. ETHTOOL_GRXCLSRLALL requires no CAP_NET_ADMIN
and the ioctl sizes the buffer from the rule_cnt userspace passes in, so
once an admin has installed CFP rules any user can ask for fewer slots
than there are rules and run off the end of the allocation. A rule_cnt
of 0 leaves the buffer pointer NULL and the walk dereferences it.
Fixes: 7318166cacad ("net: dsa: bcm_sf2: Add support for ethtool::rxnfc")
Reviewed-by: Jonas Gorski <jonas.gorski@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260903032611.3000029-2-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/bcm_sf2_cfp.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/dsa/bcm_sf2_cfp.c b/drivers/net/dsa/bcm_sf2_cfp.c
index 50d3a818eb1b7..84a086c3e99b4 100644
--- a/drivers/net/dsa/bcm_sf2_cfp.c
+++ b/drivers/net/dsa/bcm_sf2_cfp.c
@@ -1088,6 +1088,8 @@ static int bcm_sf2_cfp_rule_get_all(struct bcm_sf2_priv *priv,
unsigned int index = 1, rules_cnt = 0;
for_each_set_bit_from(index, priv->cfp.unique, priv->num_cfp_rules) {
+ if (rules_cnt == nfc->rule_cnt)
+ return -EMSGSIZE;
rule_locs[rules_cnt] = index;
rules_cnt++;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 275/733] eth: nfp: bound the ntuple rule dump by the callers buffer size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (273 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 274/733] net: dsa: bcm_sf2: bound the CFP rule dump by the callers buffer size Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 276/733] eth: nfp: drop the replaced rule from the list when reprogramming fails Greg Kroah-Hartman
` (469 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, VEGA, Joe Damato, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit f1986bf87b0709c95126fe196cf39e5b8c8453a1 ]
nfp_net_get_fs_loc() dumps every entry of nn->fs.list into rule_locs[]
without consulting cmd->rule_cnt, which is how many entries the caller
had room for. ETHTOOL_GRXCLSRLALL requires no CAP_NET_ADMIN and the
ioctl sizes the buffer from the rule_cnt userspace passes in, so once an
admin has installed flow steering rules any user can ask for fewer slots
than there are rules and run off the end of the allocation. A rule_cnt
of 0 leaves the buffer pointer NULL and the walk dereferences it.
Bail out with -EMSGSIZE when the buffer fills up, the way the other
ntuple capable drivers do, and report how many locations were filled so
a shrinking rule list does not leave the caller reading stale slots.
Reported-by: VEGA <vega@nebusec.ai>
Fixes: 9eb03bb1c035 ("nfp: add ethtool flow steering callbacks")
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260903032611.3000029-3-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index a2a89d48e3cac..9419e1ed84661 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -1421,7 +1421,8 @@ static int nfp_net_get_fs_rule(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
return -ENOENT;
}
-static int nfp_net_get_fs_loc(struct nfp_net *nn, u32 *rule_locs)
+static int nfp_net_get_fs_loc(struct nfp_net *nn, struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
{
struct nfp_fs_entry *entry;
u32 count = 0;
@@ -1429,8 +1430,12 @@ static int nfp_net_get_fs_loc(struct nfp_net *nn, u32 *rule_locs)
if (!(nn->cap_w1 & NFP_NET_CFG_CTRL_FLOW_STEER))
return -EOPNOTSUPP;
- list_for_each_entry(entry, &nn->fs.list, node)
+ list_for_each_entry(entry, &nn->fs.list, node) {
+ if (count == cmd->rule_cnt)
+ return -EMSGSIZE;
rule_locs[count++] = entry->loc;
+ }
+ cmd->rule_cnt = count;
return 0;
}
@@ -1455,7 +1460,7 @@ static int nfp_net_get_rxnfc(struct net_device *netdev,
return nfp_net_get_fs_rule(nn, cmd);
case ETHTOOL_GRXCLSRLALL:
cmd->data = NFP_FS_MAX_ENTRY;
- return nfp_net_get_fs_loc(nn, rule_locs);
+ return nfp_net_get_fs_loc(nn, cmd, rule_locs);
default:
return -EOPNOTSUPP;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 276/733] eth: nfp: drop the replaced rule from the list when reprogramming fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (274 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 275/733] eth: nfp: bound the ntuple " Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 277/733] net: dsa: mv88e6xxx: bound the policy rule dump by the callers buffer size Greg Kroah-Hartman
` (468 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Joe Damato, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit 108bb2142e3a12c9ad625ad662973127a113ddc6 ]
nfp_net_fs_add() replaces an existing rule by deleting it from the
hardware, decrementing nn->fs.count and programming the new one. If
nfp_net_fs_add_hw() fails the old entry stays on nn->fs.list - only the
success path reaches list_replace() - so the list is one longer than
nn->fs.count, and it advertises a rule whose hardware entry has already
been torn down.
nn->fs.count is what ETHTOOL_GRXCLSRLCNT reports, so userspace then sizes
its buffer one entry short of what the GRXCLSRLALL walk wants to write.
That used to overwrite one u32 past the allocation; since the walk is
bounded it is a permanent -EMSGSIZE instead, as nothing ever resyncs the
counter.
Fixes: 9eb03bb1c035 ("nfp: add ethtool flow steering callbacks")
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260903032611.3000029-4-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
index 9419e1ed84661..4e83637715e03 100644
--- a/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
+++ b/drivers/net/ethernet/netronome/nfp/nfp_net_ethtool.c
@@ -1703,8 +1703,14 @@ static int nfp_net_fs_add(struct nfp_net *nn, struct ethtool_rxnfc *cmd)
nn->fs.count--;
err = nfp_net_fs_add_hw(nn, new);
- if (err)
+ if (err) {
+ /* mbox broken, adding the old rule back will
+ * likely also fail.
+ */
+ list_del(&entry->node);
+ kfree(entry);
goto err;
+ }
nn->fs.count++;
list_replace(&entry->node, &new->node);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 277/733] net: dsa: mv88e6xxx: bound the policy rule dump by the callers buffer size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (275 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 276/733] eth: nfp: drop the replaced rule from the list when reprogramming fails Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 278/733] net: bridge: mcast: properly convert mglist to rcu Greg Kroah-Hartman
` (467 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Joe Damato, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit b1fffc273112e7284c5b705e186b43b5770cd3d5 ]
mv88e6xxx_get_rxnfc() uses rxnfc->rule_cnt as the write index while
dumping the policy IDR, clobbering the input value before it has been
looked at. That input is the number of entries the caller had room for.
ETHTOOL_GRXCLSRLALL requires no CAP_NET_ADMIN and the ioctl sizes the
buffer from the rule_cnt userspace passes in, so once an admin has
installed policy rules any user can ask for fewer slots than there are
rules and run off the end of the allocation. A rule_cnt of 0 leaves the
buffer pointer NULL and the walk dereferences it.
Count into a local so the caller's limit survives the walk, and stop with
-EMSGSIZE once it is reached.
Fixes: da7dc8755304 ("net: dsa: mv88e6xxx: add RXNFC support")
Reviewed-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260903032611.3000029-5-kuba@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/mv88e6xxx/chip.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 80b877c74513d..7f68a0c558026 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2438,6 +2438,7 @@ static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
struct ethtool_rx_flow_spec *fs = &rxnfc->fs;
struct mv88e6xxx_chip *chip = ds->priv;
struct mv88e6xxx_policy *policy;
+ u32 cnt = 0;
int err;
int id;
@@ -2463,11 +2464,18 @@ static int mv88e6xxx_get_rxnfc(struct dsa_switch *ds, int port,
break;
case ETHTOOL_GRXCLSRLALL:
rxnfc->data = 0;
- rxnfc->rule_cnt = 0;
- idr_for_each_entry(&chip->policies, policy, id)
- if (policy->port == port)
- rule_locs[rxnfc->rule_cnt++] = id;
err = 0;
+ idr_for_each_entry(&chip->policies, policy, id) {
+ if (policy->port != port)
+ continue;
+ if (cnt == rxnfc->rule_cnt) {
+ err = -EMSGSIZE;
+ break;
+ }
+ rule_locs[cnt++] = id;
+ }
+ if (!err)
+ rxnfc->rule_cnt = cnt;
break;
default:
err = -EOPNOTSUPP;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 278/733] net: bridge: mcast: properly convert mglist to rcu
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (276 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 277/733] net: dsa: mv88e6xxx: bound the policy rule dump by the callers buffer size Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 279/733] octeontx2-af: mcs: Clear stale X2P calibration state before calibration Greg Kroah-Hartman
` (466 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikolay Aleksandrov, Ido Schimmel,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikolay Aleksandrov <razor@blackwall.org>
[ Upstream commit 4b772869a1e5f9da5cef5b9c722ec0aa424ee0a0 ]
Sashiko reported a bug [1] that br_multicast_del_port_group unlists the
port group not using proper rcu helper that preserves the next pointer and
after that immediately frees the port group without waiting for rcu grace
period. The only rcu walker of mglist is br_multicast_list_adjacent() and
it turns out that function has always been buggy because mglist was never
properly converted to RCU. Fix it by converting it to rcu and moving its
initialization after eth_addr's. Initializing p->next can use
RCU_INIT_POINTER because we have a barrier from the hlist_add_head_rcu call
later, besides we're initializing an unpublished structure anyway.
[1] https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260826014200.362304-1-littleddfu%40gmail.com
Fixes: 07f8ac4a1e26 ("bridge: add export of multicast database adjacent to net_dev")
Signed-off-by: Nikolay Aleksandrov <razor@blackwall.org>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260903093851.1494297-1-razor@blackwall.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bridge/br_multicast.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/net/bridge/br_multicast.c b/net/bridge/br_multicast.c
index ec0339e204bda..2191d35d9fa07 100644
--- a/net/bridge/br_multicast.c
+++ b/net/bridge/br_multicast.c
@@ -1435,16 +1435,17 @@ struct net_bridge_port_group *br_multicast_new_port_group(
goto free_out;
}
- rcu_assign_pointer(p->next, next);
timer_setup(&p->timer, br_multicast_port_group_expired, 0);
timer_setup(&p->rexmit_timer, br_multicast_port_group_rexmit, 0);
- hlist_add_head(&p->mglist, &port->mglist);
if (src)
memcpy(p->eth_addr, src, ETH_ALEN);
else
eth_broadcast_addr(p->eth_addr);
+ RCU_INIT_POINTER(p->next, next);
+ hlist_add_head_rcu(&p->mglist, &port->mglist);
+
return p;
free_out:
@@ -1459,11 +1460,11 @@ void br_multicast_del_port_group(struct net_bridge_port_group *p)
struct net_bridge_port *port = p->key.port;
__u16 vid = p->key.addr.vid;
- hlist_del_init(&p->mglist);
+ hlist_del_init_rcu(&p->mglist);
if (!br_multicast_is_star_g(&p->key.addr))
rhashtable_remove_fast(&port->br->sg_port_tbl, &p->rhnode,
br_sg_port_rht_params);
- kfree(p);
+ kfree_rcu(p, rcu);
br_multicast_port_ngroups_dec(port, vid);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 279/733] octeontx2-af: mcs: Clear stale X2P calibration state before calibration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (277 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 278/733] net: bridge: mcast: properly convert mglist to rcu Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 280/733] ionic: use netif_txq_maybe_stop() in ionic_tx() Greg Kroah-Hartman
` (465 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nitin Shetty J, Viswajith Murali,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Viswajith Murali <viswajithm@marvell.com>
[ Upstream commit 1f29543126dde307e8b5fb6a740c54e59deaa2ff ]
Some firmware versions leave MCSX_MIL_GLOBAL bit 5 set on boot.
If the bit is already set when the driver attempts X2P calibration,
the hardware sees no rising edge and calibration never triggers.
Clear the bit and wait briefly before starting calibration to ensure
a clean rising edge.
Fixes: ca7f49ff8846 ("octeontx2-af: cn10k: Introduce driver for macsec block.")
Signed-off-by: Nitin Shetty J <nshettyj@marvell.com>
Signed-off-by: Viswajith Murali <viswajithm@marvell.com>
Link: https://patch.msgid.link/20260901094318.1395356-1-nshettyj@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/marvell/octeontx2/af/mcs.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
index a07e0b3d8d000..211c10aa5880f 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/mcs.c
@@ -1417,6 +1417,16 @@ static int mcs_x2p_calibration(struct mcs *mcs)
int i, err = 0;
u64 val;
+ /* Clear any stale calibration state left by firmware/bootloader.
+ * Some firmware versions may leave MCSX_MIL_GLOBAL bit 5 set,
+ * preventing the hardware from detecting the rising edge needed to
+ * trigger X2P calibration.
+ */
+ val = mcs_reg_read(mcs, MCSX_MIL_GLOBAL);
+ val &= ~BIT_ULL(5);
+ mcs_reg_write(mcs, MCSX_MIL_GLOBAL, val);
+ usleep_range(100, 200);
+
/* set X2P calibration */
val = mcs_reg_read(mcs, MCSX_MIL_GLOBAL);
val |= BIT_ULL(5);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 280/733] ionic: use netif_txq_maybe_stop() in ionic_tx()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (278 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 279/733] octeontx2-af: mcs: Clear stale X2P calibration state before calibration Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 281/733] net: usb: cx82310_eth: drop URB after 0xffff reboot sentinel to prevent partial_data heap overflow Greg Kroah-Hartman
` (464 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nikhil P. Rao, Brett Creeley,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil P. Rao <nikhil.rao@amd.com>
[ Upstream commit c91b4d6e5cc30ceea3f23ebe29aec012709a065f ]
Commit 061b9bedbef1 ("ionic: Rework Tx start/stop flow") replaced
ionic_maybe_stop_tx() with netif_txq_maybe_stop() to get the memory
barriers around the stop/start bits right, but did not cover the stop
in ionic_tx() added by commit 138506ab249b ("ionic: Check stop no
restart"). Convert the remaining site.
netif_txq_maybe_stop() requires the ring indexes to be updated before
it is invoked, so the post has to come first. But ring_dbell comes
from __netdev_tx_sent_queue(), which runs after that and reads the
stop bit, so it is not known in time to pass to ionic_txq_post(). Post
without the doorbell and ring it separately.
The stop condition is unchanged. The re-check only clears the stop bit
when space has become available, so the doorbell starvation fixed by
commit 138506ab249b ("ionic: Check stop no restart") cannot recur.
Fixes: 138506ab249b ("ionic: Check stop no restart")
Signed-off-by: Nikhil P. Rao <nikhil.rao@amd.com>
Reviewed-by: Brett Creeley <brett.creeley@amd.com>
Link: https://patch.msgid.link/20260901055627.1373129-1-nikhil.rao@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/pensando/ionic/ionic_txrx.c | 13 ++++++++++---
1 file changed, 10 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
index e436e3231e864..2543a8ff85476 100644
--- a/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
+++ b/drivers/net/ethernet/pensando/ionic/ionic_txrx.c
@@ -1672,15 +1672,22 @@ static int ionic_tx(struct net_device *netdev, struct ionic_queue *q,
stats->pkts++;
stats->bytes += skb->len;
+ ionic_txq_post(q, false);
+
if (likely(!ionic_txq_hwstamp_enabled(q))) {
struct netdev_queue *ndq = q_to_ndq(netdev, q);
- if (unlikely(!ionic_q_has_space(q, MAX_SKB_FRAGS + 1)))
- netif_tx_stop_queue(ndq);
+ netif_txq_maybe_stop(ndq, ionic_q_space_avail(q),
+ MAX_SKB_FRAGS + 1, MAX_SKB_FRAGS + 1);
ring_dbell = __netdev_tx_sent_queue(ndq, skb->len,
netdev_xmit_more());
}
- ionic_txq_post(q, ring_dbell);
+
+ if (ring_dbell) {
+ ionic_dbell_ring(q->lif->kern_dbpage, q->hw_type,
+ q->dbval | q->head_idx);
+ q->dbell_jiffies = jiffies;
+ }
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 281/733] net: usb: cx82310_eth: drop URB after 0xffff reboot sentinel to prevent partial_data heap overflow
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (279 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 280/733] ionic: use netif_txq_maybe_stop() in ionic_tx() Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 282/733] dibs: Unregister dibs_class after error Greg Kroah-Hartman
` (463 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Winter, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Winter <jjx@live.nl>
[ Upstream commit 5d50e90add8b4a978395e893e81954d19d58a7c5 ]
The 0xffff length sentinel detects a router reboot and schedules
re-enabling of ethernet mode, but then falls through to the rest
of the loop body. The next check is
} else if (len > CX82310_MTU) {
which is the else of the just-matched if -- it never fires for
len == 0xffff. The MTU bound that normally caps the
incomplete-packet save path is silently bypassed.
With 0xffff > skb->len always true (rx_urb_size is 4096), the
incomplete-packet branch saves dev->partial_len = skb->len bytes
into dev->partial_data. partial_data is kmalloc(hard_mtu) =
kmalloc(CX82310_MTU + 2) = 1516 bytes, but skb->len after the
2-byte header pull can be up to 4094. A device that sends a
4096-byte URB starting with [0xff 0xff] therefore copies 4094
device-provided bytes into a buffer allocated for 1516 bytes,
exceeding its requested size by 2578 bytes.
The next URB then reads dev->partial_len (4094) back from the same
1516-byte buffer and dev->partial_rem (65535 - 4094 = 61441) from
the new URB's ~4KB skb, both well past their allocations, and
delivers the spliced result as a 64KB "frame" to the network
stack.
Bail out of rx_fixup after scheduling the re-enable work; the
remainder of a reboot-marker URB is not meaningful packet data.
This restores the invariant that partial_len < CX82310_MTU + 2 on
the save path, since every other route there has already passed
the MTU check.
Fixes: ca139d76b0d9 ("cx82310_eth: re-enable ethernet mode after router reboot")
Signed-off-by: Jason Winter <jjx@live.nl>
Link: https://patch.msgid.link/BESP194MB283265DDDC63B6B78D8D34FBB8B72@BESP194MB2832.EURP194.PROD.OUTLOOK.COM
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/usb/cx82310_eth.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/usb/cx82310_eth.c b/drivers/net/usb/cx82310_eth.c
index 068acb052adb0..5df657acf3d55 100644
--- a/drivers/net/usb/cx82310_eth.c
+++ b/drivers/net/usb/cx82310_eth.c
@@ -282,6 +282,7 @@ static int cx82310_rx_fixup(struct usbnet *dev, struct sk_buff *skb)
if (len == 0xffff) {
netdev_info(dev->net, "router was rebooted, re-enabling ethernet mode");
schedule_work(&priv->reenable_work);
+ return 0;
} else if (len > CX82310_MTU) {
netdev_err(dev->net, "RX packet too long: %d B\n", len);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 282/733] dibs: Unregister dibs_class after error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (280 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 281/733] net: usb: cx82310_eth: drop URB after 0xffff reboot sentinel to prevent partial_data heap overflow Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 283/733] s390/ism: folio_put() " Greg Kroah-Hartman
` (462 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexandra Winter, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandra Winter <wintera@linux.ibm.com>
[ Upstream commit 1668a31e3b1ad358d981ddb6dbd3db1fe0533621 ]
In case dibs_loopback_init() fails, e.g. because of -ENOMEM, dibs_init()
must unregister dibs_class. Otherwise dibs_class and /sys/class/dibs exist
even though the functionality is not available. A retry to load the module
fails with -EEXIST.
Unregister dibs_class in the error path of dibs_init.
Note that before
commit ad3dfa80be76 ("dibs: change dibs_class to a const struct")
class_destroy(dibs_class) is required instead of
class_unregister(&dibs_class).
Fixes: 804737349813 ("dibs: Create class dibs")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Link: https://patch.msgid.link/20260902143438.426664-1-wintera@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/dibs/dibs_main.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/dibs/dibs_main.c b/drivers/dibs/dibs_main.c
index 2b53a9d277dca..20c50997a7cf2 100644
--- a/drivers/dibs/dibs_main.c
+++ b/drivers/dibs/dibs_main.c
@@ -251,13 +251,19 @@ static int __init dibs_init(void)
rc = class_register(&dibs_class);
if (rc)
- return rc;
+ goto err;
rc = dibs_loopback_init();
if (rc)
- pr_err("%s fails with %d\n", __func__, rc);
+ goto err_unregister;
return rc;
+
+err_unregister:
+ class_unregister(&dibs_class);
+err:
+ pr_err("%s fails with %d\n", __func__, rc);
+ return rc;
}
static void __exit dibs_exit(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 283/733] s390/ism: folio_put() after error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (281 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 282/733] dibs: Unregister dibs_class after error Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 284/733] vxlan: reject dynamic fdb entries that reference a nexthop id Greg Kroah-Hartman
` (461 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexandra Winter, Gerd Bayer,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexandra Winter <wintera@linux.ibm.com>
[ Upstream commit 907a56ab3eb8a58500a58daa76087f17bb2b6826 ]
dmb->cpu_addr was allocated via folio_alloc(). Use folio_put() instead of
kfree() in the error exit of ism_alloc_dmb() to avoid slab allocator
corruption.
While at it, reset dmb->cpu_addr after folio_put to avoid unintentional UAF
by future callers.
Fixes: 83781384a96b ("s390/ism: Properly fix receive message buffer allocation")
Signed-off-by: Alexandra Winter <wintera@linux.ibm.com>
Reviewed-by: Gerd Bayer <gbayer@linux.ibm.com>
Link: https://patch.msgid.link/20260902143733.433574-1-wintera@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/s390/net/ism_drv.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c
index 242da20f27e0e..035b233abb4e9 100644
--- a/drivers/s390/net/ism_drv.c
+++ b/drivers/s390/net/ism_drv.c
@@ -231,6 +231,7 @@ static void ism_free_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
dma_unmap_page(&ism->pdev->dev, dmb->dma_addr, dmb->dmb_len,
DMA_FROM_DEVICE);
folio_put(virt_to_folio(dmb->cpu_addr));
+ dmb->cpu_addr = NULL;
}
static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
@@ -274,7 +275,8 @@ static int ism_alloc_dmb(struct ism_dev *ism, struct dibs_dmb *dmb)
return 0;
out_free:
- kfree(dmb->cpu_addr);
+ folio_put(folio);
+ dmb->cpu_addr = NULL;
out_bit:
clear_bit(dmb->idx, ism->sba_bitmap);
return rc;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 284/733] vxlan: reject dynamic fdb entries that reference a nexthop id
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (282 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 283/733] s390/ism: folio_put() " Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 285/733] net: cap tx_queue_len at S16_MAX to prevent oversized ring allocations Greg Kroah-Hartman
` (460 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ido Schimmel, Seungwon Bae,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Seungwon Bae <qotmddnjs@ajou.ac.kr>
[ Upstream commit 98fc57d167446b95b4e719815fe79edef93f8e7a ]
The commit cited in the Fixes tag allowed VXLAN FDB entries to point to
FDB nexthops so that overlay traffic could be load balanced across
multiple VTEPs. Such entries can only be configured from user space,
cannot be learned and cannot roam. They only make sense with a user space
control plane such as E-VPN where data plane learning is disabled.
Despite that, the VXLAN driver does not currently prevent such entries
from being configured with the "dynamic" flag. The per-nexthop FDB list
is only protected by the per-device hash lock, which is not sufficient
when two VXLAN devices point to the same FDB nexthop and therefore share
the list. Aging runs in softirq context without RTNL, so an entry deleted
by one device can race with an addition or deletion from the other,
leading to list corruption:
list_del corruption. next->prev should be ffff8881069d9548, but was
dead000000000122. (next=ffff8881069d9448)
WARNING: CPU: 0 PID: 90 at lib/list_debug.c:65
__list_del_entry_valid_or_report+0x1aa/0x210
...
vxlan_fdb_destroy+0x5b8/0xad0
vxlan_cleanup+0x328/0x450
call_timer_fn+0x2a/0x1c0
run_timer_softirq+0x18c/0x210
BUG: KASAN: slab-use-after-free in vxlan_fdb_destroy
Fix this by rejecting the bogus configuration of dynamic FDB entries that
point to FDB nexthops, both when created and when an existing entry is
updated. As such, the per-nexthop FDB list is only ever mutated under the
RTNL lock. Add test cases to make sure that this does not regress in the
future.
Fixes: 1274e1cc4226 ("vxlan: ecmp support for mac fdb entries")
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Seungwon Bae <qotmddnjs@ajou.ac.kr>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/20260902155956.296699-1-qotmddnjs@ajou.ac.kr
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 11 ++++++++
tools/testing/selftests/net/fib_nexthops.sh | 28 +++++++++++++++++++++
2 files changed, 39 insertions(+)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 44ea8499e7877..1d76e1dbc41f2 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -996,6 +996,12 @@ static int vxlan_fdb_update_existing(struct vxlan_dev *vxlan,
return -EOPNOTSUPP;
}
+ if (rcu_access_pointer(f->nh) &&
+ !(state & (NUD_PERMANENT | NUD_NOARP))) {
+ NL_SET_ERR_MSG(extack, "Cannot make a nexthop fdb dynamic");
+ return -EOPNOTSUPP;
+ }
+
/* Do not allow an externally learned entry to take over an entry added
* by the user.
*/
@@ -1257,6 +1263,11 @@ static int vxlan_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
if (err)
return err;
+ if (nhid && !(ndm->ndm_state & (NUD_PERMANENT | NUD_NOARP))) {
+ NL_SET_ERR_MSG(extack, "A nexthop fdb cannot be dynamic");
+ return -EINVAL;
+ }
+
if (vxlan->default_dst.remote_ip.sa.sa_family != ip.sa.sa_family)
return -EAFNOSUPPORT;
diff --git a/tools/testing/selftests/net/fib_nexthops.sh b/tools/testing/selftests/net/fib_nexthops.sh
index ac868a7316946..daceb1ec592ab 100755
--- a/tools/testing/selftests/net/fib_nexthops.sh
+++ b/tools/testing/selftests/net/fib_nexthops.sh
@@ -522,6 +522,20 @@ ipv6_fdb_grp_fcnal()
run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 61 self"
log_test $? 255 "Fdb mac add with nexthop"
+ # fdb entries with a nexthop group cannot be aged out
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:15 dev vx10 nhid 102 self static"
+ log_test $? 0 "Fdb mac add with nexthop group and static state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:16 dev vx10 nhid 102 self dynamic"
+ log_test $? 255 "Fdb mac add with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self"
+ run_cmd "$BRIDGE fdb replace 02:02:00:00:00:17 dev vx10 dst 2001:db8:91::11 self dynamic"
+ log_test $? 255 "Fdb mac replace with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb append 02:02:00:00:00:17 dev vx10 dst 2001:db8:91::11 self dynamic"
+ log_test $? 255 "Fdb mac append with nexthop group and dynamic state"
+
run_cmd "$IP -6 ro add 2001:db8:101::1/128 nhid 66"
log_test $? 2 "Route add with fdb nexthop"
@@ -622,6 +636,20 @@ ipv4_fdb_grp_fcnal()
run_cmd "$BRIDGE fdb add 02:02:00:00:00:14 dev vx10 nhid 12 self"
log_test $? 255 "Fdb mac add with nexthop"
+ # fdb entries with a nexthop group cannot be aged out
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:15 dev vx10 nhid 102 self static"
+ log_test $? 0 "Fdb mac add with nexthop group and static state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:16 dev vx10 nhid 102 self dynamic"
+ log_test $? 255 "Fdb mac add with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb add 02:02:00:00:00:17 dev vx10 nhid 102 self"
+ run_cmd "$BRIDGE fdb replace 02:02:00:00:00:17 dev vx10 dst 10.0.0.3 self dynamic"
+ log_test $? 255 "Fdb mac replace with nexthop group and dynamic state"
+
+ run_cmd "$BRIDGE fdb append 02:02:00:00:00:17 dev vx10 dst 10.0.0.3 self dynamic"
+ log_test $? 255 "Fdb mac append with nexthop group and dynamic state"
+
run_cmd "$IP ro add 172.16.0.0/22 nhid 16"
log_test $? 2 "Route add with fdb nexthop"
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 285/733] net: cap tx_queue_len at S16_MAX to prevent oversized ring allocations
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (283 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 284/733] vxlan: reject dynamic fdb entries that reference a nexthop id Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 286/733] net: reject oversized tx_queue_len at netlink parse time Greg Kroah-Hartman
` (459 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 66ab4c59b74db7ab53a1c9083feaaede393a96a0 ]
Several subsystems allocate ring buffers sized by dev->tx_queue_len
with no upper bound. An unprivileged user (via unshare -Urn) can set a
huge tx_queue_len and exhaust global memory with ring allocations:
- pfifo_fast: pfifo_fast_init() and pfifo_fast_change_tx_queue_len()
allocate 3 skb_array rings of tx_queue_len entries each.
- tun: tun_queue_resize() and the queue-attach path resize ptr_rings
to tx_queue_len on the NETDEV_CHANGE_TX_QUEUE_LEN notifier.
- tap (macvtap/ipvtap): tap_queue_resize() and tap_init() resize/init
ptr_rings to tx_queue_len on the same notifier.
netif_change_tx_queue_len() is the single entry point for IFLA_TXQLEN,
sysfs, and the SIOCSIFTXQLEN ioctl. Cap new_len at S16_MAX (32767)
there so the oversized value is rejected at set time. This takes
effect whether the device is up or down, before dev->tx_queue_len is
written, before any notifier fires, and before any ring is allocated.
The "> S16_MAX" check also subsumes the previous unsigned-long
truncation test, and a negative ifr_qlen from the ioctl lands far
above the cap after conversion, so both old failure modes are covered
by the one comparison.
tx_queue_len is ambigious: both a per-ring sizing multiplier and a
default queue-length/limit knob for consumers that allocate
nothing at set time (pfifo/bfifo/gred/plug/sfb limits, htb
direct_qlen, qfq max_classes, teql). 32767 is chosen as the largest
value NLA_POLICY_FULL_RANGE can express for the u32 IFLA_TXQLEN
policy in patch 2/3 while staying a legitimate queue length on
high-BDP paths; the ring-memory trade-off of a shared knob is
disclosed below.
Conditions to recreate the bug:
- CONFIG_NET_SCHED=y, CONFIG_VETH=y, CONFIG_USER_NS=y, CONFIG_NET_NS=y.
- Unprivileged user in a fresh user+net namespace (unshare -Urn).
- pfifo_fast: create veth pairs, set tx_queue_len to 500000, attach
mq+pfifo_fast. ~28 iterations OOMs a 2GB guest.
- tun: create 50 tun devices with IFF_MULTI_QUEUE, set tx_queue_len to
500000, open 8 queues each. ~1.6GB of ptr_ring allocations OOMs a
512MB guest.
- tap: same as tun with IFF_TAP. ~960MB OOMs a 512MB guest.
- On the fixed kernel the oversized tx_queue_len is rejected with
-ERANGE at set time (all four paths: RTM_SETLINK, RTM_NEWLINK
create, sysfs, ioctl - the latter two via this check, the former
two via this check and the 2/3 parse policy respectively).
Fixes: 6a643ddb5624 ("net: introduce helper dev_change_tx_queue_len()")
Reported-by: Vega <vega@nebusec.ai>
Closes: https://lore.kernel.org/netdev/20260828121902.66837-1-jhs@mojatatu.com/
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-2899.v2.20260901233641@mojatatu.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/core/dev.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/core/dev.c b/net/core/dev.c
index 9ac8ac6004145..74dd9e25f4ff7 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -9932,7 +9932,7 @@ int netif_change_tx_queue_len(struct net_device *dev, unsigned long new_len)
unsigned int orig_len = dev->tx_queue_len;
int res;
- if (new_len != (unsigned int)new_len)
+ if (new_len > S16_MAX)
return -ERANGE;
if (new_len != orig_len) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 286/733] net: reject oversized tx_queue_len at netlink parse time
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (284 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 285/733] net: cap tx_queue_len at S16_MAX to prevent oversized ring allocations Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 287/733] pds_core: fix cmd_regs access racing BAR unmap on reset Greg Kroah-Hartman
` (458 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 1aa9e143bf51405665a793d4cc925e1c4f0c5922 ]
rtnl_create_link() assigns IFLA_TXQLEN directly to dev->tx_queue_len
without going through netif_change_tx_queue_len(), so a device created
with "ip link add ... txqueuelen 500000" bypasses the S16_MAX cap and
still triggers the oversized ring allocations in pfifo_fast, tun and
tap. The veth peer nest (rtnl_nla_parse_ifinfomsg()) and the
RTM_NEWLINK-on-existing-device path reach the same sinks.
Enforce the cap in ifla_policy instead: IFLA_TXQLEN becomes
NLA_POLICY_FULL_RANGE(NLA_U32, &txqlen_range) with
txqlen_range = { .min = 0, .max = S16_MAX }. All netlink consumers
parse against this policy - rtnl_setlink(), rtnl_newlink() (create
and change), and the veth peer nest - so every netlink path is capped
at parse time and rejects the attribute with -ERANGE plus a proper
"integer out of range" extack message before any device state is
modified (the RTM_SETLINK half-application wart is gone with it).
Document the bound in the rt-link.yaml netlink spec.
Conditions to recreate the bug:
- CONFIG_NET_SCHED=y, CONFIG_VETH=y, CONFIG_USER_NS=y, CONFIG_NET_NS=y.
- Unprivileged user in a fresh user+net namespace (unshare -Urn):
ip link add v0 txqueuelen 500000 type veth peer name v1
-> on the fixed kernel this is rejected with -ERANGE ("integer out
of range" extack) instead of installing an oversized tx_queue_len
that later inflates pfifo_fast/tun/tap ring allocations.
- ip link set v0 txqueuelen 500000 is likewise rejected at parse time.
Fixes: 38f7b870d4a6 ("[RTNETLINK]: Link creation API")
Reported-by: Vega <vega@nebusec.ai>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-2899.v2.20260901233641@mojatatu.com.2
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/netlink/specs/rt-link.yaml | 2 ++
net/core/rtnetlink.c | 7 ++++++-
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/Documentation/netlink/specs/rt-link.yaml b/Documentation/netlink/specs/rt-link.yaml
index 68c26a70bb649..c75731ecbe1af 100644
--- a/Documentation/netlink/specs/rt-link.yaml
+++ b/Documentation/netlink/specs/rt-link.yaml
@@ -898,6 +898,8 @@ attribute-sets:
-
name: txqlen
type: u32
+ checks:
+ max: 32767
-
name: map
type: binary
diff --git a/net/core/rtnetlink.c b/net/core/rtnetlink.c
index 12aa3aa1688b1..73101ec65c9af 100644
--- a/net/core/rtnetlink.c
+++ b/net/core/rtnetlink.c
@@ -2236,6 +2236,11 @@ static int rtnl_fill_ifinfo(struct sk_buff *skb,
return -EMSGSIZE;
}
+static const struct netlink_range_validation txqlen_range = {
+ .min = 0,
+ .max = S16_MAX,
+};
+
static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_UNSPEC] = { .strict_start_type = IFLA_DPLL_PIN },
[IFLA_IFNAME] = { .type = NLA_STRING, .len = IFNAMSIZ-1 },
@@ -2246,7 +2251,7 @@ static const struct nla_policy ifla_policy[IFLA_MAX+1] = {
[IFLA_LINK] = { .type = NLA_U32 },
[IFLA_MASTER] = { .type = NLA_U32 },
[IFLA_CARRIER] = { .type = NLA_U8 },
- [IFLA_TXQLEN] = { .type = NLA_U32 },
+ [IFLA_TXQLEN] = NLA_POLICY_FULL_RANGE(NLA_U32, &txqlen_range),
[IFLA_WEIGHT] = { .type = NLA_U32 },
[IFLA_OPERSTATE] = { .type = NLA_U8 },
[IFLA_LINKMODE] = { .type = NLA_U8 },
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 287/733] pds_core: fix cmd_regs access racing BAR unmap on reset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (285 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 286/733] net: reject oversized tx_queue_len at netlink parse time Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 288/733] pds_core: dont release PCI regions for VFs " Greg Kroah-Hartman
` (457 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Nikhil P. Rao,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil P. Rao <nikhil.rao@amd.com>
[ Upstream commit 7980325b2f71e3f65c1323c39792e2455da6fab6 ]
pdsc_reset_prepare() and pdsc_reset_done()'s pdsc_map_bars() error path
clear/iounmap cmd_regs without devcmd_lock, and
pdsc_legacy_firmware_update()'s download loop derefs cmd_regs after
dropping and retaking the lock without re-checking. An FLR concurrent
with a devlink flash can unmap cmd_regs under an in-flight devcmd,
causing a NULL deref or a write to unmapped MMIO.
Take devcmd_lock across the BAR unmap/remap, and re-check cmd_regs in
the download loop. Only the PF maps cmd_regs and runs devcmd, so skip
the unmap on a VF, as pdsc_remove() and pdsc_reset_done() already do.
A reset that completes entirely within the unlocked window is not a
correctness problem for the image: the device clears its update session,
so a resumed download is rejected, and it verifies the staged image
before writing a flash slot, reporting PDS_RC_BAD_FW rather than
activating it.
pdsc_unmap_bars() also clears info_regs, intr_status and intr_ctrl. The
interrupt and start/stop readers of those are quiesced before the unmap
by pdsc_fw_down(), which frees the interrupts and tears down the queues.
The debugfs readers are not, since those files outlive a reset; that is
pre-existing and out of scope here.
Fixes: e96094c1d11c ("pds_core: Clear BARs on reset")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260708212222.296202-1-nikhil.rao%40amd.com?part=3
Signed-off-by: Nikhil P. Rao <nikhil.rao@amd.com>
Link: https://patch.msgid.link/20260901044219.1361466-2-nikhil.rao@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/amd/pds_core/fw.c | 10 +++++++++-
drivers/net/ethernet/amd/pds_core/main.c | 8 +++++++-
2 files changed, 16 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/amd/pds_core/fw.c b/drivers/net/ethernet/amd/pds_core/fw.c
index fa626719e68d1..59d262b0d29c5 100644
--- a/drivers/net/ethernet/amd/pds_core/fw.c
+++ b/drivers/net/ethernet/amd/pds_core/fw.c
@@ -107,8 +107,10 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw,
dev_info(pdsc->dev, "Installing firmware\n");
- if (!pdsc->cmd_regs)
+ if (!pdsc->cmd_regs) {
+ NL_SET_ERR_MSG_MOD(extack, "BARs not mapped");
return -ENXIO;
+ }
dl = priv_to_devlink(pdsc);
devlink_flash_update_status_notify(dl, "Preparing to flash",
@@ -134,6 +136,12 @@ int pdsc_firmware_update(struct pdsc *pdsc, const struct firmware *fw,
copy_sz = min_t(unsigned int, buf_sz, fw->size - offset);
mutex_lock(&pdsc->devcmd_lock);
+ if (!pdsc->cmd_regs) {
+ mutex_unlock(&pdsc->devcmd_lock);
+ err = -ENXIO;
+ NL_SET_ERR_MSG_MOD(extack, "Device reset during flash");
+ goto err_out;
+ }
memcpy_toio(&pdsc->cmd_regs->data, fw->data + offset, copy_sz);
err = pdsc_devcmd_fw_download_locked(pdsc, data_addr,
offset, copy_sz);
diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c
index 9a2c64198d03b..1b960139de4e4 100644
--- a/drivers/net/ethernet/amd/pds_core/main.c
+++ b/drivers/net/ethernet/amd/pds_core/main.c
@@ -507,7 +507,11 @@ static void pdsc_reset_prepare(struct pci_dev *pdev)
pdsc_auxbus_dev_del(pdsc, pdsc, &pdsc->padev);
}
- pdsc_unmap_bars(pdsc);
+ if (!pdev->is_virtfn) {
+ mutex_lock(&pdsc->devcmd_lock);
+ pdsc_unmap_bars(pdsc);
+ mutex_unlock(&pdsc->devcmd_lock);
+ }
pci_release_regions(pdev);
if (pci_is_enabled(pdev))
pci_disable_device(pdev);
@@ -536,7 +540,9 @@ static void pdsc_reset_done(struct pci_dev *pdev)
return;
}
+ mutex_lock(&pdsc->devcmd_lock);
err = pdsc_map_bars(pdsc);
+ mutex_unlock(&pdsc->devcmd_lock);
if (err)
return;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 288/733] pds_core: dont release PCI regions for VFs on reset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (286 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 287/733] pds_core: fix cmd_regs access racing BAR unmap on reset Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 289/733] bpf: mark a NULL call argument precise Greg Kroah-Hartman
` (456 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Nikhil P. Rao,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil P. Rao <nikhil.rao@amd.com>
[ Upstream commit 73608de7e59246b4b533c1ffaee158a7048e186e ]
pdsc_reset_prepare() called pci_release_regions() unconditionally, but
only PFs call pci_request_regions() (pdsc_init_pf). On a VF FLR this
makes the kernel warn "Trying to free nonexistent resource".
Fixes: ffa55858330f ("pds_core: implement pci reset handlers")
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260804235946.177762-1-nikhil.rao%40amd.com
Signed-off-by: Nikhil P. Rao <nikhil.rao@amd.com>
Link: https://patch.msgid.link/20260901044219.1361466-3-nikhil.rao@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/amd/pds_core/main.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/amd/pds_core/main.c b/drivers/net/ethernet/amd/pds_core/main.c
index 1b960139de4e4..a19269f6b66c7 100644
--- a/drivers/net/ethernet/amd/pds_core/main.c
+++ b/drivers/net/ethernet/amd/pds_core/main.c
@@ -511,8 +511,8 @@ static void pdsc_reset_prepare(struct pci_dev *pdev)
mutex_lock(&pdsc->devcmd_lock);
pdsc_unmap_bars(pdsc);
mutex_unlock(&pdsc->devcmd_lock);
+ pci_release_regions(pdev);
}
- pci_release_regions(pdev);
if (pci_is_enabled(pdev))
pci_disable_device(pdev);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 289/733] bpf: mark a NULL call argument precise
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (287 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 288/733] pds_core: dont release PCI regions for VFs " Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 290/733] bpf: propagate mark_chain_precision() errors out of loop_flag_is_zero() Greg Kroah-Hartman
` (455 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eduard Zingerman, Alexei Starovoitov,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 1a3a10b030c96ea88868ccc060a16827c01eaa5a ]
check_func_arg() allows bpf_register_is_null() for nullable arguments
w/o marking the underlying scalar register precise. Hence a checkpoint
created on such a path would prune against arbitrary scalar value.
check_helper_call() enforces second parameter of the
bpf_get_local_storage() to be zero, w/o marking the underlying scalar
register precise. Hence a checkpoint created on such a path would
prune against arbitrary scalar value.
Grouping these two into one patch, as they share the same fixes tag.
Fixes: b5dc0163d8fd ("bpf: precise scalar_value tracking")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260904-register-is-null-precise-fixes-v1-1-0f5a360ff15d@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 9 ++++++++-
.../selftests/bpf/progs/verifier_subprog_precision.c | 12 ++++++------
2 files changed, 14 insertions(+), 7 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index be282185d5653..1b2df166e0849 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -8317,11 +8317,15 @@ static int check_func_arg(struct bpf_verifier_env *env, u32 arg,
return err;
}
- if (bpf_register_is_null(reg) && type_may_be_null(arg_type))
+ if (bpf_register_is_null(reg) && type_may_be_null(arg_type)) {
/* A NULL register has a SCALAR_VALUE type, so skip
* type checking.
*/
+ err = mark_chain_precision(env, regno);
+ if (err)
+ return err;
goto skip_type_check;
+ }
/* arg_btf_id and arg_size are in a union. */
if (base_type(arg_type) == ARG_PTR_TO_BTF_ID ||
@@ -10402,6 +10406,9 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
verbose(env, "get_local_storage() doesn't support non-zero flags\n");
return -EINVAL;
}
+ err = mark_chain_precision(env, BPF_REG_2);
+ if (err)
+ return err;
break;
case BPF_FUNC_for_each_map_elem:
err = push_callback_call(env, insn, insn_idx, meta.subprogno,
diff --git a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
index d21d32f6a6760..d990532e88b6d 100644
--- a/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
+++ b/tools/testing/selftests/bpf/progs/verifier_subprog_precision.c
@@ -287,9 +287,9 @@ __msg("17: (b7) r0 = 0")
__msg("18: (95) exit")
__msg("returning from callee:")
__msg("to caller at 9:")
-__msg("frame 0: propagating r1,r4")
+__msg("frame 0: propagating r1,r3,r4")
__msg("mark_precise: frame0: last_idx 9 first_idx 9 subseq_idx -1")
-__msg("mark_precise: frame0: regs=r1,r4 stack= before 18: (95) exit")
+__msg("mark_precise: frame0: regs=r1,r3,r4 stack= before 18: (95) exit")
__msg("from 18 to 9: safe")
__naked int callback_result_precise(void)
{
@@ -419,9 +419,9 @@ __msg("to caller at 9:")
/* r1, r4 are always precise for bpf_loop(),
* r6 was marked before backtracking to callback body.
*/
-__msg("frame 0: propagating r1,r4,r6")
+__msg("frame 0: propagating r1,r3,r4,r6")
__msg("mark_precise: frame0: last_idx 9 first_idx 9 subseq_idx -1")
-__msg("mark_precise: frame0: regs=r1,r4,r6 stack= before 16: (95) exit")
+__msg("mark_precise: frame0: regs=r1,r3,r4,r6 stack= before 16: (95) exit")
__msg("mark_precise: frame1: regs= stack= before 15: (b7) r0 = 0")
__msg("mark_precise: frame1: regs= stack= before 9: (85) call bpf_loop")
__msg("mark_precise: frame0: parent state regs= stack=:")
@@ -575,9 +575,9 @@ __msg("to caller at 10:")
/* r1, r4 are always precise for bpf_loop(),
* fp-8 was marked before backtracking to callback body.
*/
-__msg("frame 0: propagating r1,r4,fp-8")
+__msg("frame 0: propagating r1,r3,r4,fp-8")
__msg("mark_precise: frame0: last_idx 10 first_idx 10 subseq_idx -1")
-__msg("mark_precise: frame0: regs=r1,r4 stack=-8 before 18: (95) exit")
+__msg("mark_precise: frame0: regs=r1,r3,r4 stack=-8 before 18: (95) exit")
__msg("mark_precise: frame1: regs= stack= before 17: (b7) r0 = 0")
__msg("mark_precise: frame1: regs= stack= before 10: (85) call bpf_loop#181")
__msg("mark_precise: frame0: parent state regs= stack=:")
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 290/733] bpf: propagate mark_chain_precision() errors out of loop_flag_is_zero()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (288 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 289/733] bpf: mark a NULL call argument precise Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:09 ` [PATCH 7.2 291/733] powerpc/kexec_file: Use inclusive range checks in add_usable_mem() Greg Kroah-Hartman
` (454 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eduard Zingerman, Alexei Starovoitov,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eduard Zingerman <eddyz87@gmail.com>
[ Upstream commit 1d7f8f191c06f967a85922c4652dc33c132b585d ]
Stop verification if mark_chain_precision() fails when called from
loop_flag_is_zero(). No functional change intended for the paths where
backtracking succeeds.
Fixes: 1ade23711971 ("bpf: Inline calls to bpf_loop when callback is known")
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Link: https://lore.kernel.org/r/20260904-register-is-null-precise-fixes-v1-9-0f5a360ff15d@gmail.com
Signed-off-by: Alexei Starovoitov <ast@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/bpf/verifier.c | 36 +++++++++++++++++++++++++-----------
1 file changed, 25 insertions(+), 11 deletions(-)
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1b2df166e0849..54a4435f50fba 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -10188,33 +10188,45 @@ static struct bpf_insn_aux_data *cur_aux(const struct bpf_verifier_env *env)
return &env->insn_aux_data[env->insn_idx];
}
-static bool loop_flag_is_zero(struct bpf_verifier_env *env)
+/* Returns 1 if R4 is a known zero, 0 if it is not, a negative errno on error. */
+static int loop_flag_is_zero(struct bpf_verifier_env *env)
{
struct bpf_reg_state *reg = reg_state(env, BPF_REG_4);
- bool reg_is_null = bpf_register_is_null(reg);
+ int err;
- if (reg_is_null)
- mark_chain_precision(env, BPF_REG_4);
+ if (!bpf_register_is_null(reg))
+ return 0;
- return reg_is_null;
+ err = mark_chain_precision(env, BPF_REG_4);
+ if (err)
+ return err;
+ return 1;
}
-static void update_loop_inline_state(struct bpf_verifier_env *env, u32 subprogno)
+static int update_loop_inline_state(struct bpf_verifier_env *env, u32 subprogno)
{
struct bpf_loop_inline_state *state = &cur_aux(env)->loop_inline_state;
+ int flag_is_zero;
if (!state->initialized) {
+ flag_is_zero = loop_flag_is_zero(env);
+ if (flag_is_zero < 0)
+ return flag_is_zero;
state->initialized = 1;
- state->fit_for_inline = loop_flag_is_zero(env);
+ state->fit_for_inline = flag_is_zero;
state->callback_subprogno = subprogno;
- return;
+ return 0;
}
if (!state->fit_for_inline)
- return;
+ return 0;
- state->fit_for_inline = (loop_flag_is_zero(env) &&
+ flag_is_zero = loop_flag_is_zero(env);
+ if (flag_is_zero < 0)
+ return flag_is_zero;
+ state->fit_for_inline = (flag_is_zero &&
state->callback_subprogno == subprogno);
+ return 0;
}
/* Returns whether or not the given map can potentially elide
@@ -10426,7 +10438,9 @@ static int check_helper_call(struct bpf_verifier_env *env, struct bpf_insn *insn
err = check_bpf_snprintf_call(env, regs);
break;
case BPF_FUNC_loop:
- update_loop_inline_state(env, meta.subprogno);
+ err = update_loop_inline_state(env, meta.subprogno);
+ if (err)
+ return err;
/* Verifier relies on R1 value to determine if bpf_loop() iteration
* is finished, thus mark it precise.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 291/733] powerpc/kexec_file: Use inclusive range checks in add_usable_mem()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (289 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 290/733] bpf: propagate mark_chain_precision() errors out of loop_flag_is_zero() Greg Kroah-Hartman
@ 2026-09-17 15:09 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 292/733] powerpc/kexec_file: Use inclusive range checks for excluded memory Greg Kroah-Hartman
` (453 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:09 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Sourabh Jain,
Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit c6755be4838d6ccd641effbcdc3d917b82631ff9 ]
add_usable_mem() adds usable memory ranges for the kdump kernel.
The ranges are inclusive, but the partial overlap check uses exclusive
comparisons. This skips ranges with base == loc_end or end == loc_base.
Use inclusive comparisons instead.
Fixes: 7c64e21a1c5a ("powerpc/kexec_file: Restrict memory usage of kdump kernel")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260809162403.18142-2-thorsten.blum@linux.dev
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kexec/file_load_64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index 6075b1c88511a..c2ed0d1c92e75 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -113,7 +113,7 @@ static int add_usable_mem(struct umem_info *um_info, u64 base, u64 end)
loc_end = um_info->ranges[i].end;
if (loc_base >= base && loc_end <= end)
add = true;
- else if (base < loc_end && end > loc_base) {
+ else if (base <= loc_end && end >= loc_base) {
if (loc_base < base)
loc_base = base;
if (loc_end > end)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 292/733] powerpc/kexec_file: Use inclusive range checks for excluded memory
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (290 preceding siblings ...)
2026-09-17 15:09 ` [PATCH 7.2 291/733] powerpc/kexec_file: Use inclusive range checks in add_usable_mem() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 293/733] net: mctp: i3c: serialize probe with bus removal Greg Kroah-Hartman
` (452 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Sourabh Jain,
Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
[ Upstream commit 449f60f99f8f3cbe80a9bd2242945e827c5ed003 ]
arch_check_excluded_range() checks if a kexec segment overlaps an
excluded memory range.
Both ranges use inclusive end addresses, but the overlap check uses
exclusive comparisons. This skips ranges with start == ->ranges[i].end
or end == ->ranges[i].start. Use inclusive comparisons instead.
Fixes: 6e5250eaa665 ("powerpc/crash: use generic APIs to locate memory hole for kdump")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Reviewed-by: Sourabh Jain <sourabhjain@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260810145827.157972-3-thorsten.blum@linux.dev
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/kexec/file_load_64.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/kexec/file_load_64.c b/arch/powerpc/kexec/file_load_64.c
index c2ed0d1c92e75..d990880b77dfd 100644
--- a/arch/powerpc/kexec/file_load_64.c
+++ b/arch/powerpc/kexec/file_load_64.c
@@ -57,7 +57,7 @@ int arch_check_excluded_range(struct kimage *image, unsigned long start,
emem = image->arch.exclude_ranges;
for (i = 0; i < emem->nr_ranges; i++)
- if (start < emem->ranges[i].end && end > emem->ranges[i].start)
+ if (start <= emem->ranges[i].end && end >= emem->ranges[i].start)
return 1;
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 293/733] net: mctp: i3c: serialize probe with bus removal
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (291 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 292/733] powerpc/kexec_file: Use inclusive range checks for excluded memory Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 294/733] powerpc/entry: Fix irq_soft_mask corruption on replayed interrupt exit Greg Kroah-Hartman
` (451 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, XingWang Xiang, Matt Johnston,
David S. Miller, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: XingWang Xiang <v3rdant.xiang@gmail.com>
[ Upstream commit 2b4707a149a55e8fa75c9ef32b359d60f470a566 ]
mctp_i3c_probe() drops busdevs_lock after finding the matching bus. A
concurrent I3C_NOTIFY_BUS_REMOVE can then unregister and free the bus
netdev before probe passes its private data to mctp_i3c_add_device().
The latter consequently adds a list node through a freed mbus pointer.
Keep busdevs_lock held until the device has been added. This also
satisfies the __must_hold annotation on mctp_i3c_add_device().
Fixes: c8755b29b58e ("mctp i3c: MCTP I3C driver")
Signed-off-by: XingWang Xiang <v3rdant.xiang@gmail.com>
Acked-by: Matt Johnston <matt@codeconstruct.com.au>
Signed-off-by: David S. Miller <davem@davemloft.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/mctp/mctp-i3c.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/drivers/net/mctp/mctp-i3c.c b/drivers/net/mctp/mctp-i3c.c
index 88d9e36cd4a2b..4e857dd5df642 100644
--- a/drivers/net/mctp/mctp-i3c.c
+++ b/drivers/net/mctp/mctp-i3c.c
@@ -288,6 +288,7 @@ __must_hold(&busdevs_lock)
static int mctp_i3c_probe(struct i3c_device *i3c)
{
struct mctp_i3c_bus *b = NULL, *mbus = NULL;
+ int rc;
/* Look for a known bus */
mutex_lock(&busdevs_lock);
@@ -296,14 +297,16 @@ static int mctp_i3c_probe(struct i3c_device *i3c)
mbus = b;
break;
}
- mutex_unlock(&busdevs_lock);
if (!mbus) {
/* probably no "mctp-controller" property on the i3c bus */
- return -ENODEV;
+ rc = -ENODEV;
+ } else {
+ rc = mctp_i3c_add_device(mbus, i3c);
}
+ mutex_unlock(&busdevs_lock);
- return mctp_i3c_add_device(mbus, i3c);
+ return rc;
}
static void mctp_i3c_remove_device(struct mctp_i3c_device *mi)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 294/733] powerpc/entry: Fix irq_soft_mask corruption on replayed interrupt exit
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (292 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 293/733] net: mctp: i3c: serialize probe with bus removal Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 295/733] net/sched: defer qdisc freeing after failed creation Greg Kroah-Hartman
` (450 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Venkat Rao Bagalkote,
Shrikanth Hegde, Mukesh Kumar Chaurasiya (IBM),
Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
[ Upstream commit 63a7531ca31f9f097d9cc1cc3fe86ae683cdabdd ]
When __replay_soft_interrupts() replays a pending interrupt (e.g.
PACA_IRQ_DEC -> timer_interrupt), it calls the handler directly with a
synthetic pt_regs. The DEFINE_INTERRUPT_HANDLER_ASYNC wrapper around
each handler calls arch_interrupt_async_exit_prepare() on the way out,
which calls arch_interrupt_exit_prepare() -> local_irq_disable() ->
arch_local_irq_disable(), which does:
irq_soft_mask_set(IRQS_DISABLED) /* 0x1 */
This unconditionally overwrites irq_soft_mask with IRQS_DISABLED (0x1),
stripping the IRQS_PMI_DISABLED (0x2) bit. The result is that
irq_soft_mask is 0x1 instead of IRQS_ALL_DISABLED (0x3) when the
handler returns to __replay_soft_interrupts().
For a normally-taken interrupt this is harmless: the next interrupt
always enters through arch_interrupt_enter_prepare() which
unconditionally sets irq_soft_mask to IRQS_ALL_DISABLED. But during
replay, next_interrupt() is called directly between replayed handlers
without going back through arch_interrupt_enter_prepare(), so the
stripped bit is never restored. next_interrupt() then fires a WARNING:
WARNING: arch/powerpc/kernel/irq_64.c:75
WARN_ON(irq_soft_mask_return() != IRQS_ALL_DISABLED)
The warning was observed early in boot on a POWER10 pseries guest
during kmem_cache_init_late(), where a spinlock release triggers
interrupt replay that processes a pending timer interrupt.
Debugger state confirming the bug:
Before timer_interrupt(®s):
irq_soft_mask = 0x3 (IRQS_ALL_DISABLED) correct
irq_happened = 0x41 (HARD_DIS|REPLAYING) correct
After timer_interrupt(®s) returns:
irq_soft_mask = 0x1 (IRQS_DISABLED) WRONG - PMI bit stripped
irq_happened = 0x41 unchanged
The fix is to replace local_irq_disable() with hard_irq_disable().
hard_irq_disable() is the right primitive here for two reasons:
1. On PPC64 (hw_irq.h:301) it calls irq_soft_mask_set_return(IRQS_ALL_DISABLED),
setting the soft mask to 0x3 (both IRQS_DISABLED and IRQS_PMI_DISABLED),
which preserves the PMI bit and fixes the WARNING. The additional
work it does (__hard_irq_disable(), PACA_IRQ_HARD_DIS |=) is
redundant but safe since both are already set at this point in the
exit path; the trace_hardirqs_off() inside is guarded by
if (!arch_irqs_disabled_flags(flags)) so it will not double-fire.
2. On PPC32 (hw_irq.h:467) hard_irq_disable() maps to
arch_local_irq_disable() -> __hard_irq_disable(), which clears
MSR[EE] in hardware. This is exactly correct: PPC32 has no soft-mask
PACA mechanism, so the hardware disable is the right way to satisfy
irqentry_exit()'s requirement. This also fixes a build error on PPC32
where irq_soft_mask_set() is only defined under CONFIG_PPC64:
arch/powerpc/include/asm/entry-common.h:273: error: implicit
declaration of function 'irq_soft_mask_set'
Using hard_irq_disable() requires no #ifdef and is consistent with
how the rest of the entry code (e.g. entry-common.h:463) handles the
same PPC32/PPC64 split.
Fixes: 334f3f6d7a16 ("powerpc/entry: Disable interrupts before irqentry_exit")
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Closes: https://lore.kernel.org/all/6f9bfb0f-b14c-468e-bb9f-c157d120d0dc@linux.ibm.com/
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Reviewed-by: Shrikanth Hegde <sshegde@linux.ibm.com>
Signed-off-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260904090858.128563-1-mkchauras@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/include/asm/entry-common.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h
index 94083516df574..80b07750b531b 100644
--- a/arch/powerpc/include/asm/entry-common.h
+++ b/arch/powerpc/include/asm/entry-common.h
@@ -270,7 +270,7 @@ static inline void arch_interrupt_exit_prepare(struct pt_regs *regs)
}
/* irqentry_exit expects to be called with interrupts disabled */
- local_irq_disable();
+ hard_irq_disable();
}
static inline void arch_interrupt_async_enter_prepare(struct pt_regs *regs)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 295/733] net/sched: defer qdisc freeing after failed creation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (293 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 294/733] powerpc/entry: Fix irq_soft_mask corruption on replayed interrupt exit Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 296/733] net/mlx5e: Fix missing FEC mode mapping for RS_544_514_INTERLEAVED_QUAD Greg Kroah-Hartman
` (449 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiang Mei, Weiming Shi,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
[ Upstream commit e6662f2100f8d33b0f4d0047c219efd6bba186ea ]
An RTM_NEWQDISC request can make clsact bind a populated shared ingress
block during ->init(), publishing an embedded mini_Qdisc to lockless
readers. If the same request has an invalid TCA_RATE, estimator setup
fails after ->init(); the unwind removes the pointer but synchronously
frees its containing qdisc while tc_run() may still hold it.
Retire failed qdiscs through the same RCU helper as normal destruction.
Inline the synchronous free into the callback now that no direct callers
remain.
Fixes: 51ab2994c387 ("net: sched: allow ingress and clsact qdiscs to share filter blocks")
Reported-by: Xiang Mei <xmei5@asu.edu>
Link: https://lore.kernel.org/netdev/20260805102505.740806-1-david.lee@trailofbits.com/
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://patch.msgid.link/20260902155231.2149915-2-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/sch_generic.h | 2 +-
net/sched/sch_api.c | 2 +-
net/sched/sch_generic.c | 20 ++++++++++----------
3 files changed, 12 insertions(+), 12 deletions(-)
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index cbc2487765118..f35bd06a6bad6 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -793,7 +793,7 @@ void qdisc_offload_query_caps(struct net_device *dev,
struct Qdisc *qdisc_alloc(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops,
struct netlink_ext_ack *extack);
-void qdisc_free(struct Qdisc *qdisc);
+void qdisc_free_rcu(struct Qdisc *qdisc);
struct Qdisc *qdisc_create_dflt(struct netdev_queue *dev_queue,
const struct Qdisc_ops *ops, u32 parentid,
struct netlink_ext_ack *extack);
diff --git a/net/sched/sch_api.c b/net/sched/sch_api.c
index 90503e59e6e3b..463ededcdcfe0 100644
--- a/net/sched/sch_api.c
+++ b/net/sched/sch_api.c
@@ -1385,7 +1385,7 @@ static struct Qdisc *qdisc_create(struct net_device *dev,
err_out3:
qdisc_lock_uninit(sch, ops);
netdev_put(dev, &sch->dev_tracker);
- qdisc_free(sch);
+ qdisc_free_rcu(sch);
err_out2:
bpf_module_put(ops, ops->owner);
err_out:
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 4539dc2c6d380..6f6a6f0d5eb0d 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -1086,21 +1086,21 @@ void qdisc_reset(struct Qdisc *qdisc)
}
EXPORT_SYMBOL(qdisc_reset);
-void qdisc_free(struct Qdisc *qdisc)
+static void qdisc_free_cb(struct rcu_head *head)
{
- if (qdisc_is_percpu_stats(qdisc)) {
- free_percpu(qdisc->cpu_bstats);
- free_percpu(qdisc->cpu_qstats);
+ struct Qdisc *q = container_of(head, struct Qdisc, rcu);
+
+ if (qdisc_is_percpu_stats(q)) {
+ free_percpu(q->cpu_bstats);
+ free_percpu(q->cpu_qstats);
}
- kfree(qdisc);
+ kfree(q);
}
-static void qdisc_free_cb(struct rcu_head *head)
+void qdisc_free_rcu(struct Qdisc *qdisc)
{
- struct Qdisc *q = container_of(head, struct Qdisc, rcu);
-
- qdisc_free(q);
+ call_rcu(&qdisc->rcu, qdisc_free_cb);
}
static void __qdisc_destroy(struct Qdisc *qdisc)
@@ -1127,7 +1127,7 @@ static void __qdisc_destroy(struct Qdisc *qdisc)
trace_qdisc_destroy(qdisc);
- call_rcu(&qdisc->rcu, qdisc_free_cb);
+ qdisc_free_rcu(qdisc);
}
void qdisc_destroy(struct Qdisc *qdisc)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 296/733] net/mlx5e: Fix missing FEC mode mapping for RS_544_514_INTERLEAVED_QUAD
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (294 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 295/733] net/sched: defer qdisc freeing after failed creation Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 297/733] net/mlx5e: Fix setting RS FEC after remapping Greg Kroah-Hartman
` (448 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shahar Shitrit, Dragos Tatulea,
Yael Chemla, Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shahar Shitrit <shshitrit@nvidia.com>
[ Upstream commit 802eedcc0b25bb3e1b492f0600ab74325274d53b ]
MLX5E_FEC_RS_544_514_INTERLEAVED_QUAD is missing from
pplm_fec_2_ethtool_linkmodes[], leaving index 4 zero-initialized.
As a result, when this FEC mode is active, find_first_bit() returns
index 4, causing __set_bit() to set bit 0
(ETHTOOL_LINK_MODE_10baseT_Half_BIT) instead of
ETHTOOL_LINK_MODE_FEC_RS_BIT. Consequently, ethtool reports:
Advertised FEC modes: Not reported
Add the missing mapping to ETHTOOL_LINK_MODE_FEC_RS_BIT.
Fixes: 4e343c11efbb ("net/mlx5e: Support FEC settings for 200G per lane link modes")
Signed-off-by: Shahar Shitrit <shshitrit@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Yael Chemla <ychemla@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902164634.3657606-2-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index 112926d07634d..f285ad88b6d5a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1013,6 +1013,7 @@ static const u32 pplm_fec_2_ethtool_linkmodes[] = {
[MLX5E_FEC_NOFEC] = ETHTOOL_LINK_MODE_FEC_NONE_BIT,
[MLX5E_FEC_FIRECODE] = ETHTOOL_LINK_MODE_FEC_BASER_BIT,
[MLX5E_FEC_RS_528_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
+ [MLX5E_FEC_RS_544_514_INTERLEAVED_QUAD] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
[MLX5E_FEC_RS_544_514] = ETHTOOL_LINK_MODE_FEC_RS_BIT,
[MLX5E_FEC_LLRS_272_257_1] = ETHTOOL_LINK_MODE_FEC_LLRS_BIT,
};
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 297/733] net/mlx5e: Fix setting RS FEC after remapping
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (295 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 296/733] net/mlx5e: Fix missing FEC mode mapping for RS_544_514_INTERLEAVED_QUAD Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 298/733] net/mlx5e: Fix reporting support for all RS FEC variants Greg Kroah-Hartman
` (447 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shahar Shitrit, Dragos Tatulea,
Yael Chemla, Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shahar Shitrit <shshitrit@nvidia.com>
[ Upstream commit b9d755c5a37519fb1354034db1dfeb30e1ba6856 ]
When a user sets a FEC mode via ethtool, the driver maps the ethtool
FEC type to the lowest mlx5 bit of that type. For RS FEC, this is
MLX5E_FEC_RS_528_514 (bit 2). The driver then checks whether this
bit is supported by at least one link mode by inspecting the
fec_override_cap fields via mlx5e_fec_in_caps(), and returns
-EOPNOTSUPP if not.
This check is incorrect. RS FEC has three supported hardware variants:
RS_528_514 (bit 2), RS_544_514_INTERLEAVED_QUAD (bit 4), and
RS_544_514 (bit 7). mlx5e_remap_fec_conf_mode() already remaps bit 2
to the appropriate RS variant per link mode when writing the admin
fields, but the early capability check is done against the raw
unmapped bit. As a result, a device that supports RS_544_514 or
RS_544_514_INTERLEAVED_QUAD but not RS_528_514 will incorrectly reject
the user's RS FEC request.
Remove the early support check from mlx5e_set_fec_mode() and fold
it into the existing write loop, checking caps against the remapped
policy per link mode. Return -EOPNOTSUPP before the final register
write if no link mode accepted the policy.
Fixes: 2608a2f831c4 ("net/mlx5e: Fix return status when setting unsupported FEC mode")
Signed-off-by: Shahar Shitrit <shshitrit@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Yael Chemla <ychemla@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902164634.3657606-3-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en/port.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
index 6049ccf475bc4..a4c096a4fed25 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.c
@@ -557,6 +557,7 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
u32 in[MLX5_ST_SZ_DW(pplm_reg)] = {};
int sz = MLX5_ST_SZ_BYTES(pplm_reg);
u16 fec_policy_auto = 0;
+ bool fec_set = false;
int err;
int i;
@@ -569,9 +570,6 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
if (fec_policy >= (1 << MLX5E_FEC_LLRS_272_257_1) && !fec_50g_per_lane)
return -EOPNOTSUPP;
- if (fec_policy && !mlx5e_fec_in_caps(dev, fec_policy))
- return -EOPNOTSUPP;
-
MLX5_SET(pplm_reg, in, local_port, 1);
err = mlx5_core_access_reg(dev, in, sz, out, sz, MLX5_REG_PPLM, 0, 0);
if (err)
@@ -591,12 +589,17 @@ int mlx5e_set_fec_mode(struct mlx5_core_dev *dev, u16 fec_policy)
mlx5e_get_fec_cap_field(out, &fec_caps, i);
/* policy supported for link speed */
- if (fec_caps & conf_fec)
+ if (fec_caps & conf_fec) {
mlx5e_fec_admin_field(out, &conf_fec, 1, i);
- else
- /* set FEC to auto*/
+ fec_set = true;
+ } else {
+ /* set FEC to auto */
mlx5e_fec_admin_field(out, &fec_policy_auto, 1, i);
+ }
}
+ if (fec_policy && !fec_set)
+ return -EOPNOTSUPP;
+
return mlx5_core_access_reg(dev, out, sz, out, sz, MLX5_REG_PPLM, 0, 1);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 298/733] net/mlx5e: Fix reporting support for all RS FEC variants
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (296 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 297/733] net/mlx5e: Fix setting RS FEC after remapping Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 299/733] net/mlx5: LAG, use local tracker to update active ports Greg Kroah-Hartman
` (446 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shahar Shitrit, Dragos Tatulea,
Yael Chemla, Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shahar Shitrit <shshitrit@nvidia.com>
[ Upstream commit c84ce45a7a3f3f024502c7f53308db9c76e4ae71 ]
get_fec_supported_advertised() populates the FEC modes reported as
supported to userspace. The MLX5E_ADVERTISE_SUPPORTED_FEC macro only
checked MLX5E_FEC_RS_528_514, causing devices that support only the
other RS variants (RS_544_514_INTERLEAVED_QUAD or RS_544_514) to not
advertise RS as supported to ethtool at all.
Introduce MLX5E_FEC_RS_MASK covering all three RS bit positions,
update the macro to accept a bitmask directly rather than a single
enum value, and pass MLX5E_FEC_RS_MASK for the RS entry.
Fixes: b5ede32d3329 ("net/mlx5e: Add support for FEC modes based on 50G per lane links")
Fixes: 4e343c11efbb ("net/mlx5e: Support FEC settings for 200G per lane link modes")
Signed-off-by: Shahar Shitrit <shshitrit@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Reviewed-by: Yael Chemla <ychemla@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902164634.3657606-4-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en/port.h | 4 ++++
drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c | 12 ++++++------
2 files changed, 10 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h
index fa2283dd383b0..53dbdf77bccea 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/port.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/port.h
@@ -66,4 +66,8 @@ enum {
MLX5E_FEC_LLRS_272_257_1 = 9,
};
+#define MLX5E_FEC_RS_MASK (BIT(MLX5E_FEC_RS_528_514) | \
+ BIT(MLX5E_FEC_RS_544_514_INTERLEAVED_QUAD) | \
+ BIT(MLX5E_FEC_RS_544_514))
+
#endif
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
index f285ad88b6d5a..3ed59ced0407a 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_ethtool.c
@@ -1002,9 +1002,9 @@ static u32 pplm2ethtool_fec(u_long fec_mode, unsigned long size)
return 0;
}
-#define MLX5E_ADVERTISE_SUPPORTED_FEC(mlx5_fec, ethtool_fec) \
+#define MLX5E_ADVERTISE_SUPPORTED_FEC(fec_mask, ethtool_fec) \
do { \
- if (mlx5e_fec_in_caps(dev, 1 << (mlx5_fec))) \
+ if (mlx5e_fec_in_caps(dev, fec_mask)) \
__set_bit(ethtool_fec, \
link_ksettings->link_modes.supported);\
} while (0)
@@ -1030,13 +1030,13 @@ static int get_fec_supported_advertised(struct mlx5_core_dev *dev,
if (err)
return (err == -EOPNOTSUPP) ? 0 : err;
- MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_NOFEC,
+ MLX5E_ADVERTISE_SUPPORTED_FEC(BIT(MLX5E_FEC_NOFEC),
ETHTOOL_LINK_MODE_FEC_NONE_BIT);
- MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_FIRECODE,
+ MLX5E_ADVERTISE_SUPPORTED_FEC(BIT(MLX5E_FEC_FIRECODE),
ETHTOOL_LINK_MODE_FEC_BASER_BIT);
- MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_RS_528_514,
+ MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_RS_MASK,
ETHTOOL_LINK_MODE_FEC_RS_BIT);
- MLX5E_ADVERTISE_SUPPORTED_FEC(MLX5E_FEC_LLRS_272_257_1,
+ MLX5E_ADVERTISE_SUPPORTED_FEC(BIT(MLX5E_FEC_LLRS_272_257_1),
ETHTOOL_LINK_MODE_FEC_LLRS_BIT);
active_fec_long = active_fec;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 299/733] net/mlx5: LAG, use local tracker to update active ports
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (297 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 298/733] net/mlx5e: Fix reporting support for all RS FEC variants Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 300/733] net/mlx5e: Fix ETS zero BW reporting when one TC holds 100% Greg Kroah-Hartman
` (445 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Akiva Goldberger, Shay Drori,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akiva Goldberger <agoldberger@nvidia.com>
[ Upstream commit b3c79dee5038c5e8460c59d7d01cb1450bdf5ecb ]
The CREATE_LAG command is handled asynchronously by queuing a work,
which stores a local copy of ldev->tracker. When the work is processed,
it is possible that the values of the local copy and ldev->tracker have
diverged.
A single CREATE_LAG command programs two related fields into the
firmware: the v2p (virtual-to-physical) map, which selects the physical
egress port for each hash bucket, and the active_port bitmask, which
tells the firmware which physical ports are currently up so it can
redirect QP/TIS away from inactive ports. For the firmware to steer
traffic correctly, both must be derived from the same view of the ports'
link state.
The v2p map is computed by mlx5_infer_tx_affinity_mapping() from the
local tracker snapshot, but lag_active_port_bits() called
mlx5_infer_tx_enabled() on the live ldev->tracker instead. If
ldev->tracker changed between the snapshot and command execution, the
two fields reflect different port states: the v2p map may steer a bucket
to a port that the active_port mask marks as inactive (or vice versa).
The firmware then receives a self-contradictory configuration and can
redirect or drop traffic on a port the mapping still points at, until a
later event happens to reconcile the state.
Update lag_active_port_bits so that it receives the local version of the
tracker from when the work was queued, effectively closing the window
for injecting an inconsistency.
Fixes: c5c13b456cb8 ("net/mlx5: Lag, set active ports if support bypass port select flow table")
Signed-off-by: Akiva Goldberger <agoldberger@nvidia.com>
Reviewed-by: Shay Drori <shayd@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902192740.3665435-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/lag/lag.c | 19 +++++++++++--------
1 file changed, 11 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
index 2285c889c215e..c655f6e32e9b0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/lag/lag.c
@@ -63,14 +63,15 @@ static int get_port_sel_mode(enum mlx5_lag_mode mode, unsigned long flags)
return MLX5_LAG_PORT_SELECT_MODE_QUEUE_AFFINITY;
}
-static u8 lag_active_port_bits(struct mlx5_lag *ldev)
+static u8 lag_active_port_bits(struct mlx5_lag *ldev,
+ struct lag_tracker *tracker)
{
u8 enabled_ports[MLX5_MAX_PORTS] = {};
u8 active_port = 0;
int num_enabled;
int idx;
- mlx5_infer_tx_enabled(&ldev->tracker, ldev, enabled_ports,
+ mlx5_infer_tx_enabled(tracker, ldev, enabled_ports,
&num_enabled);
for (idx = 0; idx < num_enabled; idx++)
active_port |= BIT_MASK(enabled_ports[idx]);
@@ -79,7 +80,8 @@ static u8 lag_active_port_bits(struct mlx5_lag *ldev)
}
static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, struct mlx5_lag *ldev,
- int mode, unsigned long flags)
+ struct lag_tracker *tracker, int mode,
+ unsigned long flags)
{
bool fdb_sel_mode = test_bit(MLX5_LAG_MODE_FLAG_FDB_SEL_MODE_NATIVE,
&flags);
@@ -108,7 +110,7 @@ static int mlx5_cmd_create_lag(struct mlx5_core_dev *dev, struct mlx5_lag *ldev,
break;
MLX5_SET(lagc, lag_ctx, active_port,
- lag_active_port_bits(mlx5_lag_dev(dev)));
+ lag_active_port_bits(ldev, tracker));
break;
default:
break;
@@ -787,7 +789,8 @@ static int mlx5_cmd_modify_active_port(struct mlx5_core_dev *dev, u8 ports)
return mlx5_cmd_exec_in(dev, modify_lag, in);
}
-static int _mlx5_modify_lag(struct mlx5_lag *ldev, u8 *ports)
+static int _mlx5_modify_lag(struct mlx5_lag *ldev,
+ struct lag_tracker *tracker, u8 *ports)
{
int idx = mlx5_lag_get_dev_index_by_seq(ldev, MLX5_LAG_P1);
struct mlx5_core_dev *dev0;
@@ -804,7 +807,7 @@ static int _mlx5_modify_lag(struct mlx5_lag *ldev, u8 *ports)
!MLX5_CAP_PORT_SELECTION(dev0, port_select_flow_table_bypass))
return ret;
- active_ports = lag_active_port_bits(ldev);
+ active_ports = lag_active_port_bits(ldev, tracker);
return mlx5_cmd_modify_active_port(dev0, active_ports);
}
@@ -868,7 +871,7 @@ void mlx5_modify_lag(struct mlx5_lag *ldev,
idx = i * ldev->buckets + j;
if (ports[idx] == ldev->v2p_map[idx])
continue;
- err = _mlx5_modify_lag(ldev, ports);
+ err = _mlx5_modify_lag(ldev, tracker, ports);
if (err) {
mlx5_core_err(dev0,
"Failed to modify LAG (%d)\n",
@@ -976,7 +979,7 @@ static int mlx5_create_lag(struct mlx5_lag *ldev,
mlx5_core_info(dev0, "shared_fdb:%d mode:%s\n",
shared_fdb, mlx5_get_str_port_sel_mode(mode, flags));
- err = mlx5_cmd_create_lag(dev0, ldev, mode, flags);
+ err = mlx5_cmd_create_lag(dev0, ldev, tracker, mode, flags);
if (err) {
mlx5_core_err(dev0,
"Failed to create LAG (%d)\n",
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 300/733] net/mlx5e: Fix ETS zero BW reporting when one TC holds 100%
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (298 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 299/733] net/mlx5: LAG, use local tracker to update active ports Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 301/733] net/mlx5e: Fix use-after-free race in sample_restore_put() Greg Kroah-Hartman
` (444 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Carolina Jubran, Alex Lazar,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carolina Jubran <cjubran@nvidia.com>
[ Upstream commit e7ee89740800a1cf253713e9249c3ee9203ebe91 ]
When ETS TCs with zero bandwidth are configured, the driver programs the
firmware using an alternate representation. On get, it needs
to recognize that representation so those TCs can be translated back and
reported as 0% bandwidth.
The existing detection relied on the programmed bandwidth because it was
enough to identify this representation. However, when a single ETS TC
owns 100% of the bandwidth, its firmware representation becomes the
same as a strict-priority TC, causing zero-bandwidth ETS TCs to be
reported with non-zero bandwidth values.
Use the cached TSA instead to distinguish the ETS and strict-priority
cases.
Fixes: be0f161ef141 ("net/mlx5e: DCBNL, Implement tc with ets type and zero bandwidth")
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Alex Lazar <alazar@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902193224.3668743-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
index 00e706e1ede11..741f75b5bfec5 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_dcbnl.c
@@ -148,7 +148,7 @@ static int mlx5e_dcbnl_ieee_getets(struct net_device *netdev,
if (err)
return err;
- if (ets->tc_tx_bw[i] < MLX5E_MAX_BW_ALLOC &&
+ if (priv->dcbx.tc_tsa[i] == IEEE_8021QAZ_TSA_ETS &&
tc_group[i] == (MLX5E_LOWEST_PRIO_GROUP + 1))
is_zero_bw_ets_tc = true;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 301/733] net/mlx5e: Fix use-after-free race in sample_restore_put()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (299 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 300/733] net/mlx5e: Fix ETS zero BW reporting when one TC holds 100% Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 302/733] net/mlx5: E-Switch: fix use-after-free in mlx5_eswitch_termtbl_put Greg Kroah-Hartman
` (443 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Carolina Jubran, Shahar Shitrit,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carolina Jubran <cjubran@nvidia.com>
[ Upstream commit af3aef0245abbab5e9f6302e7a7d6407187afb71 ]
Concurrent teardown of TC sample rules sharing the same restore
context may re-read restore->count after dropping restore_lock.
At that point another thread may already have completed cleanup and
freed the restore object.
Use the result of the refcount decrement while holding restore_lock to
determine whether cleanup is needed.
Fixes: 36a3196256bf ("net/mlx5e: TC, Add sampler restore handle API")
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Shahar Shitrit <shshitrit@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902193341.3668809-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
index 89490f687a9c6..93c62d3f3e5bd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en/tc/sample.c
@@ -311,12 +311,15 @@ sample_restore_get(struct mlx5e_tc_psample *tc_psample, u32 obj_id,
static void
sample_restore_put(struct mlx5e_tc_psample *tc_psample, struct mlx5e_sample_restore *restore)
{
+ bool last;
+
mutex_lock(&tc_psample->restore_lock);
- if (--restore->count == 0)
+ last = --restore->count == 0;
+ if (last)
hash_del(&restore->hlist);
mutex_unlock(&tc_psample->restore_lock);
- if (!restore->count) {
+ if (last) {
mlx5_del_flow_rules(restore->rule);
mlx5_modify_header_dealloc(tc_psample->esw->dev, restore->modify_hdr);
kfree(restore);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 302/733] net/mlx5: E-Switch: fix use-after-free in mlx5_eswitch_termtbl_put
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (300 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 301/733] net/mlx5e: Fix use-after-free race in sample_restore_put() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 303/733] net/mlx5: E-Switch, prevent mc_list repopulation during vport disable Greg Kroah-Hartman
` (442 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yael Chemla, Dragos Tatulea,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yael Chemla <ychemla@nvidia.com>
[ Upstream commit 7ee07f601f8f507c9faf25c68a49396ab8950596 ]
In mlx5_eswitch_termtbl_put(), the zero-ref cleanup check reads
tt->ref_count after termtbl_mutex has been released. Two concurrent
callers on the same mlx5_termtbl_handle race: one decrements ref_count
to zero, removes the hash entry, and calls kfree(tt) while the other
has already dropped the mutex and is about to evaluate
if (!tt->ref_count), producing a use-after-free.
Fix this by capturing the result of the decrement into a stack-local
last variable before dropping the mutex. The cleanup decision is now
made entirely under termtbl_mutex, and tt is not touched after
kfree.
Fixes: 10caabdaad5a ("net/mlx5e: Use termination table for VLAN push actions")
Signed-off-by: Yael Chemla <ychemla@nvidia.com>
Reviewed-by: Dragos Tatulea <dtatulea@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902193514.3668880-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
index 19f65d4c4def9..d43f073601596 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch_offloads_termtbl.c
@@ -163,12 +163,15 @@ void
mlx5_eswitch_termtbl_put(struct mlx5_eswitch *esw,
struct mlx5_termtbl_handle *tt)
{
+ bool last;
+
mutex_lock(&esw->offloads.termtbl_mutex);
- if (--tt->ref_count == 0)
+ last = (--tt->ref_count == 0);
+ if (last)
hash_del(&tt->termtbl_hlist);
mutex_unlock(&esw->offloads.termtbl_mutex);
- if (!tt->ref_count) {
+ if (last) {
mlx5_del_flow_rules(tt->rule);
mlx5_destroy_flow_table(tt->termtbl);
kfree(tt);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 303/733] net/mlx5: E-Switch, prevent mc_list repopulation during vport disable
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (301 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 302/733] net/mlx5: E-Switch: fix use-after-free in mlx5_eswitch_termtbl_put Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 304/733] net/mlx5e: Keep HW timestamp stats monotonic across reconfiguration Greg Kroah-Hartman
` (441 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lama Kayal, Cosmin Ratiu,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lama Kayal <lkayal@nvidia.com>
[ Upstream commit c0c6f4ba8a37688f7b4d4044898d88f0450d44c2 ]
In mlx5_esw_vport_disable(), move esw_apply_vport_rx_mode() ahead
of esw_vport_change_handle_locked() so vport->allmulti_rule is
NULL before the change handler observes it.
During FW-fatal recovery the disable runs while dev->state ==
INTERNAL_ERROR. The promisc query inside esw_update_vport_rx_mode()
fails and returns early, leaving vport->allmulti_rule intact, so
esw_update_vport_mc_promisc() runs and adds MLX5_ACTION_ADD entries
to vport->mc_list whose flow rules are then installed in the FDB
by esw_add_mc_addr(). esw_destroy_legacy_table() tears down the
FDB with those refs still held, corrupting the sub-tree and
leaving dangling flow_rule pointers in vport->mc_list.
Two-stage failure on `echo 1 > /sys/bus/pci/devices/<bdf>/reset`:
refcount_t: underflow; use-after-free.
tree_put_node+0xef/0x110 [mlx5_core]
clean_tree+0x44/0xd0 [mlx5_core] (x5)
mlx5_fs_core_cleanup+0x57/0x1c0 [mlx5_core]
mlx5_unload+0x65/0xd0 [mlx5_core]
... mlx5_health_try_recover
BUG: unable to handle page fault for address: 0000000003000055
down_write+0x1c/0x60
mlx5_del_flow_rules+0x33/0x1f0 [mlx5_core]
esw_del_mc_addr+0x7b/0x170 [mlx5_core]
esw_apply_vport_addr_list+0x56/0xf0 [mlx5_core]
esw_vport_change_handle_locked+0x28b/0x310 [mlx5_core]
mlx5_esw_vport_enable+0x270/0x4a0 [mlx5_core]
... mlx5_load ... mlx5_health_try_recover
esw_apply_vport_rx_mode(false, false) clears vport->allmulti_rule
via its local state machine even when the FW del fails. With the
rule NULL the !IS_ERR_OR_NULL(allmulti_rule) gate in the change
handler closes, no rules are installed during disable, and the
reload starts with a clean mc_list.
Fixes: 922f56e9a795 ("net/mlx5: Fix steering rules cleanup")
Signed-off-by: Lama Kayal <lkayal@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902193854.3669035-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mellanox/mlx5/core/eswitch.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
index a0e2ca87b8d8f..eadc44119b1f4 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.c
@@ -1040,13 +1040,19 @@ void mlx5_esw_vport_disable(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
(vport->info.ipsec_crypto_enabled || vport->info.ipsec_packet_enabled))
esw->enabled_ipsec_vf_count--;
+ /* Clear rx-mode before esw_vport_change_handle_locked(): on
+ * MLX5_VPORT_PROMISC_CHANGE it calls esw_update_vport_mc_promisc()
+ * when vport->allmulti_rule is set, repopulating mc_list with FDB
+ * rules that dangle once the FDB is destroyed. NULL allmulti_rule
+ * here skips that path.
+ */
+ esw_apply_vport_rx_mode(esw, vport, false, false);
/* We don't assume VFs will cleanup after themselves.
* Calling vport change handler while vport is disabled will cleanup
* the vport resources.
*/
esw_vport_change_handle_locked(vport);
vport->enabled_events = 0;
- esw_apply_vport_rx_mode(esw, vport, false, false);
esw_vport_cleanup(esw, vport);
esw->enabled_vports--;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 304/733] net/mlx5e: Keep HW timestamp stats monotonic across reconfiguration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (302 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 303/733] net/mlx5: E-Switch, prevent mc_list repopulation during vport disable Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 305/733] net/sched: fq_pie: clamp quantum in change path Greg Kroah-Hartman
` (440 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Carolina Jubran, Shahar Shitrit,
Tariq Toukan, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carolina Jubran <cjubran@nvidia.com>
[ Upstream commit df99553f840e4c529c1ba4c29bd39396466ca11a ]
`mlx5e_stats_ts_get()` currently selects either DMA or port timestamp
counters based on `tx_ptp_opened`. This flag is intentionally kept set
once the PTP TX queues have been opened so their statistics remain
available after queue teardown. As a result, DMA timestamps are no
longer reported after switching from port timestamping back to DMA
timestamping.
The function also reads statistics only from the currently active
channels and TCs. Reducing the number of channels or TCs can therefore
drop previously accumulated timestamp counters from the reported value.
Read the persistent channel statistics instead and always include DMA
timestamp counters. Once the PTP TX queues have been opened, also
include the port timestamp counters.
This also drops state_lock. It previously protected live channel/PTP
pointers, the new code only reads persistent channel_stats and
ptp_stats via mlx5e_stats_nch_read(), which is already safe for
lockless stats access.
Fixes: 3579032c08c1 ("net/mlx5e: Implement ethtool hardware timestamping statistics")
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Shahar Shitrit <shshitrit@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Link: https://patch.msgid.link/20260902193731.3668958-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../ethernet/mellanox/mlx5/core/en_stats.c | 51 ++++++++-----------
1 file changed, 20 insertions(+), 31 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
index e7e6db7f6bf17..cd94bb44f6ab0 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_stats.c
@@ -1199,50 +1199,39 @@ void mlx5e_stats_rmon_get(struct mlx5e_priv *priv,
void mlx5e_stats_ts_get(struct mlx5e_priv *priv,
struct ethtool_ts_stats *ts_stats)
{
- int i, j;
+ u16 nch = mlx5e_stats_nch_read(priv);
+ int i, tc;
- mutex_lock(&priv->state_lock);
+ ts_stats->pkts = 0;
- if (priv->tx_ptp_opened) {
- struct mlx5e_ptp *ptp = priv->channels.ptp;
+ for (i = 0; i < nch; i++) {
+ struct mlx5e_channel_stats *channel_stats =
+ priv->channel_stats[i];
- ts_stats->pkts = 0;
+ for (tc = 0; tc < priv->max_opened_tc; tc++)
+ ts_stats->pkts += channel_stats->sq[tc].timestamps;
+ }
+
+ /* Accumulate DMA and port timestamp counters so values stay monotonic
+ * across channel teardown and mode switches.
+ */
+ if (priv->tx_ptp_opened) {
+ /* Err and Lost stats are only relevant for port timestamping,
+ * as the DMA layer will always successfully timestamp packets.
+ */
ts_stats->err = 0;
ts_stats->lost = 0;
- if (!ptp)
- goto out;
-
- /* Aggregate stats across all TCs */
- for (i = 0; i < ptp->num_tc; i++) {
+ for (tc = 0; tc < priv->max_opened_tc; tc++) {
struct mlx5e_ptp_cq_stats *stats =
- ptp->ptpsq[i].cq_stats;
+ &priv->ptp_stats.cq[tc];
ts_stats->pkts += stats->cqe;
ts_stats->err += stats->abort + stats->err_cqe +
- stats->late_cqe;
+ stats->late_cqe;
ts_stats->lost += stats->lost_cqe;
}
- } else {
- /* DMA layer will always successfully timestamp packets. Other
- * counters do not make sense for this layer.
- */
- ts_stats->pkts = 0;
-
- /* Aggregate stats across all SQs */
- for (j = 0; j < priv->channels.num; j++) {
- struct mlx5e_channel *c = priv->channels.c[j];
-
- for (i = 0; i < c->num_tc; i++) {
- struct mlx5e_sq_stats *stats = c->sq[i].stats;
-
- ts_stats->pkts += stats->timestamps;
- }
- }
}
-
-out:
- mutex_unlock(&priv->state_lock);
}
#define PPORT_PHY_LAYER_OFF(c) \
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 305/733] net/sched: fq_pie: clamp quantum in change path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (303 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 304/733] net/mlx5e: Keep HW timestamp stats monotonic across reconfiguration Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 306/733] net/sched: sfq: " Greg Kroah-Hartman
` (439 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 4864f58c53eb47257d55e01f47d4a9f355f7f970 ]
fq_pie_change() accepts any quantum value from userspace, including 1.
With a crafted size table qdisc_pkt_len reaches ~2 GiB, so quantum=1
makes the deficit-refill loop spin ~2^31 times under the qdisc lock
(a soft lockup / denial of service).
Add max(256U, ...) matching fq_codel_change().
Conditions to recreate the bug:
CONFIG_NET_SCH_FQ_PIE=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root fq_pie
tc qdisc change dev dummy0 root fq_pie quantum 1 stab data 32768 size_log 15 cell_log 0
Fixes: ec97ecf1ebe4 ("net: sched: add Flow Queue PIE packet scheduler")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.3
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_fq_pie.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_fq_pie.c b/net/sched/sch_fq_pie.c
index b27d95418707a..5982847df8f85 100644
--- a/net/sched/sch_fq_pie.c
+++ b/net/sched/sch_fq_pie.c
@@ -341,7 +341,8 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt,
nla_get_u32(tb[TCA_FQ_PIE_BETA]));
if (tb[TCA_FQ_PIE_QUANTUM])
- WRITE_ONCE(q->quantum, nla_get_u32(tb[TCA_FQ_PIE_QUANTUM]));
+ WRITE_ONCE(q->quantum,
+ max(256U, nla_get_u32(tb[TCA_FQ_PIE_QUANTUM])));
if (tb[TCA_FQ_PIE_MEMORY_LIMIT])
WRITE_ONCE(q->memory_limit,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 306/733] net/sched: sfq: clamp quantum in change path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (304 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 305/733] net/sched: fq_pie: clamp quantum in change path Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 307/733] net/sched: hhf: clamp quantum in change and init paths Greg Kroah-Hartman
` (438 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit fb9f88a33c516ea5c0bcd9a22ca288b246b34567 ]
sfq_change() accepts any non-negative quantum (only rejects
(int)ctl->quantum < 0). With a crafted size table qdisc_pkt_len reaches
~2 GiB, so quantum=1 makes the deficit-refill loop spin ~2^31 times
under the qdisc lock (a soft lockup / denial of service).
Add max(256U, ...) matching fq_codel_change(). Reject quantum > 1<<20
with -EINVAL, matching fq_codel_change() and the init clamp.
Conditions to recreate the bug:
CONFIG_NET_SCH_SFQ=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root sfq
tc qdisc change dev dummy0 root sfq quantum 1 stab data 32768 size_log 15 cell_log 0
Fixes: e4650d7ae425 ("net_sched: sch_sfq: handle bigger packets")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.4
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_sfq.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_sfq.c b/net/sched/sch_sfq.c
index 187d3ed578f26..8bbcfc9e85d94 100644
--- a/net/sched/sch_sfq.c
+++ b/net/sched/sch_sfq.c
@@ -660,6 +660,11 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
return -EINVAL;
}
+ if (ctl->quantum > 1 << 20) {
+ NL_SET_ERR_MSG_MOD(extack, "quantum too large");
+ return -EINVAL;
+ }
+
if (ctl->perturb_period < 0 ||
ctl->perturb_period > INT_MAX / HZ) {
NL_SET_ERR_MSG_MOD(extack, "invalid perturb period");
@@ -688,7 +693,7 @@ static int sfq_change(struct Qdisc *sch, struct nlattr *opt,
/* update and validate configuration */
if (ctl->quantum)
- quantum = ctl->quantum;
+ quantum = max(256U, ctl->quantum);
if (ctl->flows)
maxflows = min_t(u32, ctl->flows, SFQ_MAX_FLOWS);
if (ctl->divisor) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 307/733] net/sched: hhf: clamp quantum in change and init paths
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (305 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 306/733] net/sched: sfq: " Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 308/733] net/sched: dualpi2: clamp psched_mtu at all call sites Greg Kroah-Hartman
` (437 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit eb56a495f59baf6cad5ed80e3ffb9078098b1346 ]
hhf_change() accepts any quantum from userspace, including 1. With a
crafted size table qdisc_pkt_len reaches ~2 GiB, so quantum=1 makes
the deficit-refill loop spin ~2^31 times under the qdisc lock
(a soft lockup / denial of service).
Add max(256U, ...) in hhf_change() matching fq_codel_change(). Clamp
hhf_init() to [256, 1<<20] matching the siblings, and remove the old
fallback that only set quantum=256 on overflow.
Conditions to recreate the bug:
CONFIG_NET_SCH_HHF=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root hhf
tc qdisc change dev dummy0 root hhf quantum 1 stab data 32768 size_log 15 cell_log 0
Fixes: 10239edf86f1 ("net-qdisc-hhf: Heavy-Hitter Filter (HHF) qdisc")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.5
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_hhf.c | 8 ++------
1 file changed, 2 insertions(+), 6 deletions(-)
diff --git a/net/sched/sch_hhf.c b/net/sched/sch_hhf.c
index 96acab6a8da03..fc72f825fbd92 100644
--- a/net/sched/sch_hhf.c
+++ b/net/sched/sch_hhf.c
@@ -551,7 +551,7 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt,
return err;
if (tb[TCA_HHF_QUANTUM])
- new_quantum = nla_get_u32(tb[TCA_HHF_QUANTUM]);
+ new_quantum = max(256U, nla_get_u32(tb[TCA_HHF_QUANTUM]));
if (tb[TCA_HHF_NON_HH_WEIGHT])
new_hhf_non_hh_weight = nla_get_u32(tb[TCA_HHF_NON_HH_WEIGHT]);
@@ -613,7 +613,7 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
int i;
sch->limit = 1000;
- q->quantum = psched_mtu(qdisc_dev(sch));
+ q->quantum = clamp_t(u32, psched_mtu(qdisc_dev(sch)), 256, 1 << 20);
get_random_bytes(&q->perturbation, sizeof(q->perturbation));
INIT_LIST_HEAD(&q->new_buckets);
INIT_LIST_HEAD(&q->old_buckets);
@@ -624,10 +624,6 @@ static int hhf_init(struct Qdisc *sch, struct nlattr *opt,
q->hhf_evict_timeout = HZ; /* 1 sec */
q->hhf_non_hh_weight = 2;
- if ((int)q->quantum <= 0 ||
- (u64)q->quantum * q->hhf_non_hh_weight > INT_MAX)
- q->quantum = 256;
-
if (opt) {
int err = hhf_change(sch, opt, extack);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 308/733] net/sched: dualpi2: clamp psched_mtu at all call sites
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (306 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 307/733] net/sched: hhf: clamp quantum in change and init paths Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 309/733] net/sched: pie: clamp psched_mtu in pie_drop_early Greg Kroah-Hartman
` (436 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 3c01f1ca5dfc6d6911b0e5b37f5062b1dc451b94 ]
dualpi2_calculate_c_protection(), must_drop(), and get_memory_limit()
call psched_mtu() with no clamp. A huge MTU makes (s32)psched_mtu()
overflow in the signed multiply for c_protection_init, and 2 *
psched_mtu() wraps in get_memory_limit(). With a crafted size table
qdisc_pkt_len reaches ~2 GiB, causing a soft lockup / denial of service.
Clamp psched_mtu() to [1, 1<<20] at all three call sites.
Conditions to recreate the bug:
CONFIG_NET_SCH_DUALPI2=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root dualpi2
tc qdisc change dev dummy0 root dualpi2 stab data 32768 size_log 15 cell_log 0
Fixes: 320d031ad6e4 ("sched: Struct definition and parsing of dualpi2 qdisc")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.6
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_dualpi2.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/sched/sch_dualpi2.c b/net/sched/sch_dualpi2.c
index 4f678d4ff10ec..4947def7c49ef 100644
--- a/net/sched/sch_dualpi2.c
+++ b/net/sched/sch_dualpi2.c
@@ -208,9 +208,11 @@ static void dualpi2_reset_c_protection(struct dualpi2_sched_data *q)
static void dualpi2_calculate_c_protection(struct Qdisc *sch,
struct dualpi2_sched_data *q, u32 wc)
{
+ u32 mtu = clamp_t(u32, psched_mtu(qdisc_dev(sch)), 1, 1 << 20);
+
q->c_protection_wc = wc;
q->c_protection_wl = MAX_WC - wc;
- q->c_protection_init = (s32)psched_mtu(qdisc_dev(sch)) *
+ q->c_protection_init = (s32)mtu *
((int)q->c_protection_wc - (int)q->c_protection_wl);
dualpi2_reset_c_protection(q);
}
@@ -285,8 +287,9 @@ static bool must_drop(struct Qdisc *sch, struct dualpi2_sched_data *q,
u64 local_l_prob;
bool overload;
u32 prob;
+ u32 mtu = clamp_t(u32, psched_mtu(qdisc_dev(sch)), 1, 1 << 20);
- if (sch->qstats.backlog < 2 * psched_mtu(qdisc_dev(sch)))
+ if (sch->qstats.backlog < 2 * mtu)
return false;
prob = READ_ONCE(q->pi2_prob);
@@ -712,7 +715,8 @@ static u32 get_memory_limit(struct Qdisc *sch, u32 limit)
/* Apply rule of thumb, i.e., doubling the packet length,
* to further include per packet overhead in memory_limit.
*/
- u64 memlim = mul_u32_u32(limit, 2 * psched_mtu(qdisc_dev(sch)));
+ u64 memlim = mul_u32_u32(limit, 2 * clamp_t(u32, psched_mtu(qdisc_dev(sch)),
+ 1, 1 << 20));
if (upper_32_bits(memlim))
return U32_MAX;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 309/733] net/sched: pie: clamp psched_mtu in pie_drop_early
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (307 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 308/733] net/sched: dualpi2: clamp psched_mtu at all call sites Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 310/733] net/sched: drr: clamp quantum in change class Greg Kroah-Hartman
` (435 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 54370e44c002770ae61fc889f28f699e91616ffc ]
pie_drop_early() calls psched_mtu() with no clamp. With mtu=0x80000000
the bytemode divide silently zeroes the drop probability, disabling AQM.
Clamp to [1, 1<<20].
Conditions to recreate the bug:
CONFIG_NET_SCH_PIE=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root pie
tc qdisc change dev dummy0 root pie stab data 32768 size_log 15 cell_log 0
Fixes: d4b36210c2e6 ("net: pkt_sched: PIE AQM scheme")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.7
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_pie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index b41f2def2e2cc..3b7863ffd284c 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -35,7 +35,7 @@ bool pie_drop_early(struct Qdisc *sch, struct pie_params *params,
{
u64 rnd;
u64 local_prob = vars->prob;
- u32 mtu = psched_mtu(qdisc_dev(sch));
+ u32 mtu = clamp_t(u32, psched_mtu(qdisc_dev(sch)), 1, 1 << 20);
/* If there is still burst allowance left skip random early drop */
if (vars->burst_time > 0)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 310/733] net/sched: drr: clamp quantum in change class
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (308 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 309/733] net/sched: pie: clamp psched_mtu in pie_drop_early Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 311/733] net/sched: ets: clamp quantum in parse and fallback paths Greg Kroah-Hartman
` (434 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 8382abec0f1568d0a5590d75a3df92f23fcf5196 ]
drr_change_class() rejects explicit quantum==0 but falls back to
psched_mtu() with no floor. With a crafted size table qdisc_pkt_len
reaches ~2 GiB, so quantum=1 (or a zero psched_mtu on a headerless
device) makes the deficit-refill loop spin under the qdisc lock.
Add clamp_t(u32, quantum, 256, 1<<20) after the zero reject and on the
fallback path. The explicit-zero reject is preserved.
Conditions to recreate the bug:
CONFIG_NET_SCH_DRR=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root drr
tc class add dev dummy0 parent 1: classid 1:1 drr quantum 1
Fixes: 13d2a1d2b032 ("pkt_sched: add DRR scheduler")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.8
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_drr.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/net/sched/sch_drr.c b/net/sched/sch_drr.c
index 91b1ef824afaf..8621d057edd9f 100644
--- a/net/sched/sch_drr.c
+++ b/net/sched/sch_drr.c
@@ -82,8 +82,9 @@ static int drr_change_class(struct Qdisc *sch, u32 classid, u32 parentid,
NL_SET_ERR_MSG(extack, "Specified DRR quantum cannot be zero");
return -EINVAL;
}
+ quantum = clamp_t(u32, quantum, 256, 1 << 20);
} else
- quantum = psched_mtu(qdisc_dev(sch));
+ quantum = clamp_t(u32, (u32)psched_mtu(qdisc_dev(sch)), 256, 1 << 20);
if (cl != NULL) {
if (tca[TCA_RATE]) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 311/733] net/sched: ets: clamp quantum in parse and fallback paths
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (309 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 310/733] net/sched: drr: clamp quantum in change class Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 312/733] net: macb: fix NULL pointer dereference on unbind with fixed-link Greg Kroah-Hartman
` (433 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega,
Toke Høiland-Jørgensen, Victor Nogueira,
Jamal Hadi Salim, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamal Hadi Salim <jhs@mojatatu.com>
[ Upstream commit 1c38487f46b243bfeefec0c0c86023a3904f2214 ]
ets_qdisc_change() falls back to psched_mtu() with no floor for bands
without an explicit quantum. With a crafted size table qdisc_pkt_len
reaches ~2 GiB, so a zero psched_mtu on a headerless device makes the
deficit-refill loop spin under the qdisc lock.
Move the floor into ets_quantum_parse() so explicitly configured quanta
are also clamped to [256, 1<<20], not just the fallback path.
Conditions to recreate the bug:
CONFIG_NET_SCH_ETS=y. Requires CAP_NET_ADMIN (namespace-local via
unshare -Urn suffices).
tc qdisc add dev dummy0 root ets bands 3 strict 2 quanta 1 1
Fixes: dcc68b4d8084 ("net: sch_ets: Add a new Qdisc")
Reported-by: Vega <vega@nebusec.ai>
Reviewed-by: Toke Høiland-Jørgensen <toke@redhat.com>
Tested-by: Victor Nogueira <victor@mojatatu.com>
Signed-off-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/QDISC-0CFC.v3.20260901204856@mojatatu.com.9
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/sch_ets.c | 12 +++++-------
1 file changed, 5 insertions(+), 7 deletions(-)
diff --git a/net/sched/sch_ets.c b/net/sched/sch_ets.c
index 25fcf4079fece..6cc902a038387 100644
--- a/net/sched/sch_ets.c
+++ b/net/sched/sch_ets.c
@@ -83,11 +83,7 @@ static int ets_quantum_parse(struct Qdisc *sch, const struct nlattr *attr,
unsigned int *quantum,
struct netlink_ext_ack *extack)
{
- *quantum = nla_get_u32(attr);
- if (!*quantum) {
- NL_SET_ERR_MSG(extack, "ETS quantum cannot be zero");
- return -EINVAL;
- }
+ *quantum = clamp_t(u32, nla_get_u32(attr), 256, 1 << 20);
return 0;
}
@@ -632,11 +628,13 @@ static int ets_qdisc_change(struct Qdisc *sch, struct nlattr *opt,
return err;
}
/* If there are more bands than strict + quanta provided, the remaining
- * ones are ETS with quantum of MTU. Initialize the missing values here.
+ * ones are ETS with quantum of max(MTU, 256). Initialize the missing
+ * values here.
*/
for (i = nstrict; i < nbands; i++) {
if (!quanta[i])
- quanta[i] = psched_mtu(qdisc_dev(sch));
+ quanta[i] = clamp_t(u32, (u32)psched_mtu(qdisc_dev(sch)),
+ 256, 1 << 20);
}
/* Before commit, make sure we can allocate all new qdiscs */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 312/733] net: macb: fix NULL pointer dereference on unbind with fixed-link
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (310 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 311/733] net/sched: ets: clamp quantum in parse and fallback paths Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 313/733] bpf: Reject non-scalar bpf_loop iteration counts Greg Kroah-Hartman
` (432 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vineeth Karumanchi, Xuanqiang Luo,
Nicolai Buchwitz, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
[ Upstream commit 38b6be101006d3e7af972999f45d4f1e8250587a ]
When the device tree describes a fixed-link and has no "mdio" child
node, macb_mii_init() returns early without allocating the MDIO bus,
leaving bp->mii_bus as NULL.
Two cleanup paths then dereference this NULL bus:
1. On driver unbind, macb_remove() unconditionally calls
mdiobus_unregister(bp->mii_bus), which oopses:
Unable to handle kernel NULL pointer dereference at virtual address 00000000000004a8
pc : mdiobus_unregister+0x14/0xa4
lr : macb_remove+0x38/0xa4
Call trace:
mdiobus_unregister+0x14/0xa4 (P)
macb_remove+0x38/0xa4
platform_remove+0x20/0x30
device_release_driver_internal+0x1c8/0x224
unbind_store+0xb4/0xbc
2. On the probe error path in macb_probe(), reached when
macb_mii_init() has succeeded but a subsequent step fails, the
err_out_unregister_mdio label runs the same unconditional cleanup.
mdiobus_unregister() and mdiobus_free() do not guard against a NULL
bus, so guard the calls in both macb_remove() and the probe error
path.
Fixes: d0c3601f2c4e ("net: macb: Avoid 20s boot delay by skipping MDIO bus registration for fixed-link PHY")
Signed-off-by: Vineeth Karumanchi <vineeth.karumanchi@amd.com>
Reviewed-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260902102836.2019355-1-vineeth.karumanchi@amd.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb_main.c | 12 ++++++++----
1 file changed, 8 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 05eda2545597b..cd140f98cbc83 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5964,8 +5964,10 @@ static int macb_probe(struct platform_device *pdev)
return 0;
err_out_unregister_mdio:
- mdiobus_unregister(bp->mii_bus);
- mdiobus_free(bp->mii_bus);
+ if (bp->mii_bus) {
+ mdiobus_unregister(bp->mii_bus);
+ mdiobus_free(bp->mii_bus);
+ }
err_out_phy_exit:
phy_exit(bp->phy);
@@ -5993,8 +5995,10 @@ static void macb_remove(struct platform_device *pdev)
bp = netdev_priv(netdev);
unregister_netdev(netdev);
phy_exit(bp->phy);
- mdiobus_unregister(bp->mii_bus);
- mdiobus_free(bp->mii_bus);
+ if (bp->mii_bus) {
+ mdiobus_unregister(bp->mii_bus);
+ mdiobus_free(bp->mii_bus);
+ }
device_set_wakeup_enable(&bp->pdev->dev, 0);
cancel_delayed_work_sync(&bp->tx_lpi_work);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 313/733] bpf: Reject non-scalar bpf_loop iteration counts
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (311 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 312/733] net: macb: fix NULL pointer dereference on unbind with fixed-link Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 314/733] ALSA: caiaq: Decoupling ep1_in_urb in caiaq dev Greg Kroah-Hartman
` (431 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+7b47f87674e9a1569110,
Kumar Kartikeya Dwivedi, Eduard Zingerman, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kumar Kartikeya Dwivedi <memxor@gmail.com>
[ Upstream commit c3fd8e5fd100f122bad503bdc0e9277219533253 ]
bpf_loop() declares its nr_loops argument as ARG_ANYTHING. Privileged
programs may pass pointer values to such arguments, so check_func_arg()
lets a pointer-valued R1 reach the helper-specific checks.
Since commit bb124da69c47 ("bpf: keep track of max number of bpf_loop
callback iterations"), the verifier marks R1 precise and reads its upper
bound to limit callback simulation. Precision backtracking only accepts
scalar registers, so passing a pointer instead triggers the "backtracking
misuse" verifier warning. Kernels with panic_on_warn enabled subsequently
panic.
Introduce ARG_SCALAR for helper arguments that only accept scalar values
and use it for bpf_loop() nr_loops. Generic helper argument validation then
rejects pointers before loop inlining and precision processing.
Fixes: bb124da69c47 ("bpf: keep track of max number of bpf_loop callback iterations")
Reported-by: syzbot+7b47f87674e9a1569110@syzkaller.appspotmail.com
Signed-off-by: Kumar Kartikeya Dwivedi <memxor@gmail.com>
Link: https://patch.msgid.link/20260905014735.1452988-2-memxor@gmail.com
Closes: https://lore.kernel.org/bpf/6a9ad24c.b5d4176b.238c3e.0001.GAE@google.com/
Signed-off-by: Eduard Zingerman <eddyz87@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/bpf.h | 1 +
kernel/bpf/bpf_iter.c | 2 +-
kernel/bpf/verifier.c | 1 +
3 files changed, 3 insertions(+), 1 deletion(-)
diff --git a/include/linux/bpf.h b/include/linux/bpf.h
index 7798abc7d637b..c2c327dc0a72f 100644
--- a/include/linux/bpf.h
+++ b/include/linux/bpf.h
@@ -894,6 +894,7 @@ enum bpf_arg_type {
ARG_PTR_TO_CTX, /* pointer to context */
ARG_ANYTHING, /* any (initialized) argument is ok */
+ ARG_SCALAR, /* scalar argument */
ARG_PTR_TO_SPIN_LOCK, /* pointer to bpf_spin_lock */
ARG_PTR_TO_SOCK_COMMON, /* pointer to sock_common */
ARG_PTR_TO_SOCKET, /* pointer to bpf_sock (fullsock) */
diff --git a/kernel/bpf/bpf_iter.c b/kernel/bpf/bpf_iter.c
index f5eaeb2493d4a..9b4f5236c5ea3 100644
--- a/kernel/bpf/bpf_iter.c
+++ b/kernel/bpf/bpf_iter.c
@@ -754,7 +754,7 @@ const struct bpf_func_proto bpf_loop_proto = {
.func = bpf_loop,
.gpl_only = false,
.ret_type = RET_INTEGER,
- .arg1_type = ARG_ANYTHING,
+ .arg1_type = ARG_SCALAR,
.arg2_type = ARG_PTR_TO_FUNC,
.arg3_type = ARG_PTR_TO_STACK_OR_NULL,
.arg4_type = ARG_ANYTHING,
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 54a4435f50fba..1a0cd37b03cde 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -7877,6 +7877,7 @@ static const struct bpf_reg_types *compatible_reg_types[__BPF_ARG_TYPE_MAX] = {
[ARG_CONST_SIZE] = &scalar_types,
[ARG_CONST_SIZE_OR_ZERO] = &scalar_types,
[ARG_CONST_ALLOC_SIZE_OR_ZERO] = &scalar_types,
+ [ARG_SCALAR] = &scalar_types,
[ARG_CONST_MAP_PTR] = &const_map_ptr_types,
[ARG_PTR_TO_CTX] = &context_types,
[ARG_PTR_TO_SOCK_COMMON] = &sock_types,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 314/733] ALSA: caiaq: Decoupling ep1_in_urb in caiaq dev
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (312 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 313/733] bpf: Reject non-scalar bpf_loop iteration counts Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 315/733] erofs: delimit inode_share cache key components Greg Kroah-Hartman
` (430 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+832ce9fa3face1b7d44d,
Edward Adam Davis, Takashi Iwai, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <eadavis@sina.com>
[ Upstream commit 402a9d6aab7ac787ab075adeb562c3db8b8f564b ]
The epq_in_urb object belonging to the caiaq device is coupled within
the struct snd_usb_caiaqdev. After usb_submit_urb(epq_in_urb, GFP_KERNEL)
executes successfully, epq_in_urb is successfully added to the urbp_list
queue of the dummy HCD driver (userspace specifies dummy_hcd as the HCD
layer driver for the caiaq USB device).
When init_card() calls snd_usb_caiaq_send_command() which subsequently
fails due to a timeout, and proceeds to call snd_card_free() to release
the card, the embedded ep1_in_urb object is also freed. When the dummy
HCD driver detects that the URB has been unlinked, it returns the URB
(by usb_hcd_giveback_urb()), which triggers [1].
Decouple the ep1_in_urb object from the struct snd_usb_caiaqdev and switch
to using a pointer instead. Separately allocate and manage the memory for
ep1_in_urb to prevent the release of the snd_card memory object from
interfering with it.
midi_out_urb has the same issue as ep1_in_urb and is handled in the same
way.
[1]
BUG: KASAN: slab-use-after-free in usb_free_urb+0x24/0x120 drivers/usb/core/urb.c:96
Write of size 4 at addr ffff88803cee1050 by task ktimers/1/29
Call Trace:
usb_free_urb+0x24/0x120 drivers/usb/core/urb.c:96
dummy_timer+0xaac/0x4d50 drivers/usb/gadget/udc/dummy_hcd.c:2019
__run_hrtimer kernel/time/hrtimer.c:2067 [inline]
__hrtimer_run_queues+0x3eb/0xaf0 kernel/time/hrtimer.c:2124
hrtimer_run_softirq+0x1e1/0x2e0 kernel/time/hrtimer.c:2141
Allocated by task 36:
snd_card_new+0x7b/0x110 sound/core/init.c:184
create_card sound/usb/caiaq/device.c:429 [inline]
snd_probe+0x236/0x1af0 sound/usb/caiaq/device.c:544
Freed by task 36:
snd_card_free_when_closed sound/core/init.c:630 [inline]
snd_card_free+0x138/0x1d0 sound/core/init.c:662
snd_probe+0x162b/0x1af0 sound/usb/caiaq/device.c:553
Fixes: 523f1dce3743 ("[ALSA] Add Native Instrument usb audio device support")
Reported-by: syzbot+832ce9fa3face1b7d44d@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=832ce9fa3face1b7d44d
Tested-by: syzbot+832ce9fa3face1b7d44d@syzkaller.appspotmail.com
Signed-off-by: Edward Adam Davis <eadavis@sina.com>
Link: https://patch.msgid.link/20260903130521.554840-1-eadavis@sina.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/usb/caiaq/device.c | 36 ++++++++++++++++++++++++------------
sound/usb/caiaq/device.h | 4 ++--
sound/usb/caiaq/midi.c | 6 +++---
3 files changed, 29 insertions(+), 17 deletions(-)
diff --git a/sound/usb/caiaq/device.c b/sound/usb/caiaq/device.c
index a16e592484803..3d821fde45820 100644
--- a/sound/usb/caiaq/device.c
+++ b/sound/usb/caiaq/device.c
@@ -192,8 +192,8 @@ static void usb_ep1_command_reply_dispatch (struct urb* urb)
break;
}
- cdev->ep1_in_urb.actual_length = 0;
- ret = usb_submit_urb(&cdev->ep1_in_urb, GFP_ATOMIC);
+ cdev->ep1_in_urb->actual_length = 0;
+ ret = usb_submit_urb(cdev->ep1_in_urb, GFP_ATOMIC);
if (ret < 0)
dev_err(dev, "unable to submit urb. OOM!?\n");
}
@@ -408,6 +408,10 @@ static void card_free(struct snd_card *card)
#endif
snd_usb_caiaq_audio_free(cdev);
usb_put_dev(cdev->chip.dev);
+ usb_free_urb(cdev->ep1_in_urb);
+ cdev->ep1_in_urb = NULL;
+ usb_free_urb(cdev->midi_out_urb);
+ cdev->midi_out_urb = NULL;
}
static int create_card(struct usb_device *usb_dev,
@@ -457,22 +461,30 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
return -EIO;
}
- usb_init_urb(&cdev->ep1_in_urb);
- usb_init_urb(&cdev->midi_out_urb);
+ cdev->ep1_in_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!cdev->ep1_in_urb)
+ return -ENOMEM;
- usb_fill_bulk_urb(&cdev->ep1_in_urb, usb_dev,
+ cdev->midi_out_urb = usb_alloc_urb(0, GFP_KERNEL);
+ if (!cdev->midi_out_urb) {
+ usb_free_urb(cdev->ep1_in_urb);
+ cdev->ep1_in_urb = NULL;
+ return -ENOMEM;
+ }
+
+ usb_fill_bulk_urb(cdev->ep1_in_urb, usb_dev,
usb_rcvbulkpipe(usb_dev, 0x1),
cdev->ep1_in_buf, EP1_BUFSIZE,
usb_ep1_command_reply_dispatch, cdev);
- usb_fill_bulk_urb(&cdev->midi_out_urb, usb_dev,
+ usb_fill_bulk_urb(cdev->midi_out_urb, usb_dev,
usb_sndbulkpipe(usb_dev, 0x1),
cdev->midi_out_buf, EP1_BUFSIZE,
snd_usb_caiaq_midi_output_done, cdev);
/* sanity checks of EPs before actually submitting */
- if (usb_urb_ep_type_check(&cdev->ep1_in_urb) ||
- usb_urb_ep_type_check(&cdev->midi_out_urb)) {
+ if (usb_urb_ep_type_check(cdev->ep1_in_urb) ||
+ usb_urb_ep_type_check(cdev->midi_out_urb)) {
dev_err(dev, "invalid EPs\n");
return -EINVAL;
}
@@ -480,7 +492,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
init_waitqueue_head(&cdev->ep1_wait_queue);
init_waitqueue_head(&cdev->prepare_wait_queue);
- if (usb_submit_urb(&cdev->ep1_in_urb, GFP_KERNEL) != 0)
+ if (usb_submit_urb(cdev->ep1_in_urb, GFP_KERNEL) != 0)
return -EIO;
err = snd_usb_caiaq_send_command(cdev, EP1_CMD_GET_DEVICE_INFO, NULL, 0);
@@ -530,7 +542,7 @@ static int init_card(struct snd_usb_caiaqdev *cdev)
return 0;
err_kill_urb:
- usb_kill_urb(&cdev->ep1_in_urb);
+ usb_kill_urb(cdev->ep1_in_urb);
return err;
}
@@ -576,8 +588,8 @@ static void snd_disconnect(struct usb_interface *intf)
#endif
snd_usb_caiaq_audio_disconnect(cdev);
- usb_kill_urb(&cdev->ep1_in_urb);
- usb_kill_urb(&cdev->midi_out_urb);
+ usb_kill_urb(cdev->ep1_in_urb);
+ usb_kill_urb(cdev->midi_out_urb);
snd_card_free_when_closed(card);
}
diff --git a/sound/usb/caiaq/device.h b/sound/usb/caiaq/device.h
index 743eb0387b5fb..1c6f34693fa81 100644
--- a/sound/usb/caiaq/device.h
+++ b/sound/usb/caiaq/device.h
@@ -60,8 +60,8 @@ struct snd_usb_caiaq_cb_info;
struct snd_usb_caiaqdev {
struct snd_usb_audio chip;
- struct urb ep1_in_urb;
- struct urb midi_out_urb;
+ struct urb *ep1_in_urb;
+ struct urb *midi_out_urb;
struct urb **data_urbs_in;
struct urb **data_urbs_out;
struct snd_usb_caiaq_cb_info *data_cb_info;
diff --git a/sound/usb/caiaq/midi.c b/sound/usb/caiaq/midi.c
index c656d01624321..18529484c8dcc 100644
--- a/sound/usb/caiaq/midi.c
+++ b/sound/usb/caiaq/midi.c
@@ -43,7 +43,7 @@ static int snd_usb_caiaq_midi_output_close(struct snd_rawmidi_substream *substre
{
struct snd_usb_caiaqdev *cdev = substream->rmidi->private_data;
if (cdev->midi_out_active) {
- usb_kill_urb(&cdev->midi_out_urb);
+ usb_kill_urb(cdev->midi_out_urb);
cdev->midi_out_active = 0;
}
return 0;
@@ -64,9 +64,9 @@ static void snd_usb_caiaq_midi_send(struct snd_usb_caiaqdev *cdev,
return;
cdev->midi_out_buf[2] = len;
- cdev->midi_out_urb.transfer_buffer_length = len+3;
+ cdev->midi_out_urb->transfer_buffer_length = len+3;
- ret = usb_submit_urb(&cdev->midi_out_urb, GFP_ATOMIC);
+ ret = usb_submit_urb(cdev->midi_out_urb, GFP_ATOMIC);
if (ret < 0)
dev_err(dev,
"snd_usb_caiaq_midi_send(%p): usb_submit_urb() failed,"
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 315/733] erofs: delimit inode_share cache key components
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (313 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 314/733] ALSA: caiaq: Decoupling ep1_in_urb in caiaq dev Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 316/733] iommu/riscv: Add command queue lock Greg Kroah-Hartman
` (429 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengyu Zhu, Gao Xiang, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengyu Zhu <hudsonzhu@tencent.com>
[ Upstream commit 96bf9831fbf423b8104f7948cd8fe7007ecfb46c ]
Previously, inode_share keys were encoded as follows:
fingerprint || domain_id
It would be better to have a separator between the fingerprint and domain
ID so that the fingerprint won't be parsed as part of a domain ID.
Change the key encoding as follows:
domain_id || '\0' || fingerprint
Since domain_id is a NUL-terminated string, this makes the in-memory key
indices unambiguous.
Signed-off-by: Chengyu Zhu <hudsonzhu@tencent.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Fixes: e0bf7d1c074d ("erofs: support user-defined fingerprint name")
Signed-off-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/xattr.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/fs/erofs/xattr.c b/fs/erofs/xattr.c
index df7ea019526d7..57cfb75207824 100644
--- a/fs/erofs/xattr.c
+++ b/fs/erofs/xattr.c
@@ -620,8 +620,8 @@ int erofs_xattr_fill_inode_fingerprint(struct erofs_inode_fingerprint *fp,
{
struct erofs_sb_info *sbi = EROFS_SB(inode->i_sb);
struct erofs_xattr_prefix_item *prefix;
+ int domainlen, valuelen, base_index;
const char *infix;
- int valuelen, base_index;
if (!test_opt(&sbi->opt, INODE_SHARE))
return -EOPNOTSUPP;
@@ -633,17 +633,18 @@ int erofs_xattr_fill_inode_fingerprint(struct erofs_inode_fingerprint *fp,
valuelen = erofs_getxattr(inode, base_index, infix, NULL, 0);
if (valuelen <= 0 || valuelen > (1 << sbi->blkszbits))
return -EFSCORRUPTED;
- fp->size = valuelen + (domain_id ? strlen(domain_id) : 0);
+ domainlen = strlen(domain_id);
+ fp->size = domainlen + 1 + valuelen;
fp->opaque = kmalloc(fp->size, GFP_KERNEL);
if (!fp->opaque)
return -ENOMEM;
+ memcpy(fp->opaque, domain_id, domainlen + 1);
if (valuelen != erofs_getxattr(inode, base_index, infix,
- fp->opaque, valuelen)) {
+ fp->opaque + domainlen + 1, valuelen)) {
kfree(fp->opaque);
fp->opaque = NULL;
return -EFSCORRUPTED;
}
- memcpy(fp->opaque + valuelen, domain_id, fp->size - valuelen);
return 0;
}
#endif
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 316/733] iommu/riscv: Add command queue lock
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (314 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 315/733] erofs: delimit inode_share cache key components Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 317/733] iommu/riscv: Serialize command queue publishing Greg Kroah-Hartman
` (428 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fangyu Yu, Nutty Liu, Joerg Roedel,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
[ Upstream commit d5bcf9ccaa357396089bbfa47fc82b093f109b1e ]
Add a raw spinlock to the RISC-V IOMMU queue state so command queue
publishing can be serialized by a later change.
Fixes: 856c0cfe5c5f ("iommu/riscv: Command and fault queue support")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Reviewed-by: Nutty Liu <nutty.liu@hotmail.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/riscv/iommu.c | 1 +
drivers/iommu/riscv/iommu.h | 2 ++
2 files changed, 3 insertions(+)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index cec3ddd7ab103..2c0dcc90cf85b 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -1560,6 +1560,7 @@ int riscv_iommu_init(struct riscv_iommu_device *iommu)
int rc;
RISCV_IOMMU_QUEUE_INIT(&iommu->cmdq, CQ);
+ raw_spin_lock_init(&iommu->cmdq.lock);
RISCV_IOMMU_QUEUE_INIT(&iommu->fltq, FQ);
rc = riscv_iommu_init_check(iommu);
diff --git a/drivers/iommu/riscv/iommu.h b/drivers/iommu/riscv/iommu.h
index 46df79dd54957..5676001548cc7 100644
--- a/drivers/iommu/riscv/iommu.h
+++ b/drivers/iommu/riscv/iommu.h
@@ -12,6 +12,7 @@
#define _RISCV_IOMMU_H_
#include <linux/iommu.h>
+#include <linux/spinlock.h>
#include <linux/types.h>
#include <linux/iopoll.h>
@@ -23,6 +24,7 @@ struct riscv_iommu_queue {
atomic_t prod; /* unbounded producer allocation index */
atomic_t head; /* unbounded shadow ring buffer consumer index */
atomic_t tail; /* unbounded shadow ring buffer producer index */
+ raw_spinlock_t lock; /* serialize queue publishing */
unsigned int mask; /* index mask, queue length - 1 */
unsigned int irq; /* allocated interrupt number */
struct riscv_iommu_device *iommu; /* iommu device handling the queue when active */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 317/733] iommu/riscv: Serialize command queue publishing
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (315 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 316/733] iommu/riscv: Add command queue lock Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 318/733] iommu/riscv: Avoid waiting on failed command enqueue Greg Kroah-Hartman
` (427 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fangyu Yu, Joerg Roedel, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
[ Upstream commit ca58afa40946acd252a50fa4d4a86f15847a3d7d ]
Serialize command queue publishing so software producer state advances only
after a command is written and the hardware tail is updated. Wait for
hardware consumption outside the queue lock when the command queue is full
so other CPUs are not blocked behind a long poll.
Fixes: 856c0cfe5c5f ("iommu/riscv: Command and fault queue support")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/riscv/iommu.c | 100 +++++++++++++++++++++---------------
1 file changed, 58 insertions(+), 42 deletions(-)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index 2c0dcc90cf85b..e335beb70e422 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -382,77 +382,93 @@ static int riscv_iommu_queue_wait(struct riscv_iommu_queue *queue,
(int)(cons - index) > 0, 0, timeout_us);
}
-/* Enqueue an entry and wait to be processed if timeout_us > 0
- *
- * Error handling for IOMMU hardware not responding in reasonable time
- * will be added as separate patch series along with other RAS features.
- * For now, only report hardware failure and continue.
- */
+static int riscv_iommu_queue_wait_for_space(struct riscv_iommu_queue *queue,
+ unsigned int last)
+{
+ unsigned int head;
+ unsigned int tail;
+ unsigned int hw_head;
+ unsigned long flags;
+ int ret;
+
+ ret = riscv_iommu_readl_timeout(queue->iommu, Q_HEAD(queue), hw_head,
+ !(hw_head & ~queue->mask) && hw_head != last,
+ 0, RISCV_IOMMU_QUEUE_TIMEOUT);
+ if (ret)
+ return ret;
+
+ raw_spin_lock_irqsave(&queue->lock, flags);
+ head = atomic_read(&queue->head);
+ tail = atomic_read(&queue->tail);
+ if ((tail - head) >= queue->mask) {
+ last = Q_ITEM(queue, head);
+ /*
+ * Re-read hw_head under the lock so that it is consistent with
+ * the freshly computed 'last'. Using the pre-lock snapshot
+ * could produce a stale value that wraps around relative to the
+ * new 'last', advancing the shadow head past entries that have
+ * not yet been consumed by the hardware.
+ */
+ hw_head = riscv_iommu_readl(queue->iommu, Q_HEAD(queue));
+ if (!(hw_head & ~queue->mask) && hw_head != last)
+ atomic_add((hw_head - last) & queue->mask, &queue->head);
+ }
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
+
+ return 0;
+}
+
+/* Enqueue an entry and publish it to the hardware queue. */
static unsigned int riscv_iommu_queue_send(struct riscv_iommu_queue *queue,
void *entry, size_t entry_size)
{
unsigned int prod;
unsigned int head;
- unsigned int tail;
unsigned long flags;
+ int ret;
- /* Do not preempt submission flow. */
- local_irq_save(flags);
+ /* 1. Wait for space availability and reserve the next slot. */
+ for (;;) {
+ raw_spin_lock_irqsave(&queue->lock, flags);
- /* 1. Allocate some space in the queue */
- prod = atomic_inc_return(&queue->prod) - 1;
- head = atomic_read(&queue->head);
+ prod = atomic_read(&queue->tail);
+ head = atomic_read(&queue->head);
- /* 2. Wait for space availability. */
- if ((prod - head) > queue->mask) {
- if (readx_poll_timeout(atomic_read, &queue->head,
- head, (prod - head) < queue->mask,
- 0, RISCV_IOMMU_QUEUE_TIMEOUT))
- goto err_busy;
- } else if ((prod - head) == queue->mask) {
- const unsigned int last = Q_ITEM(queue, head);
+ if ((prod - head) < queue->mask)
+ break;
+
+ head = Q_ITEM(queue, head);
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
- if (riscv_iommu_readl_timeout(queue->iommu, Q_HEAD(queue), head,
- !(head & ~queue->mask) && head != last,
- 0, RISCV_IOMMU_QUEUE_TIMEOUT))
+ ret = riscv_iommu_queue_wait_for_space(queue, head);
+ if (ret)
goto err_busy;
- atomic_add((head - last) & queue->mask, &queue->head);
}
- /* 3. Store entry in the ring buffer */
+ /* 2. Store entry in the ring buffer. */
memcpy(queue->base + Q_ITEM(queue, prod) * entry_size, entry, entry_size);
- /* 4. Wait for all previous entries to be ready */
- if (readx_poll_timeout(atomic_read, &queue->tail, tail, prod == tail,
- 0, RISCV_IOMMU_QUEUE_TIMEOUT))
- goto err_busy;
-
- /*
- * 5. Make sure the ring buffer update (whether in normal or I/O memory) is
- * completed and visible before signaling the tail doorbell to fetch
- * the next command. 'fence ow, ow'
- */
+ /* 3. Make sure the entry is visible before updating the queue tail. */
dma_wmb();
riscv_iommu_writel(queue->iommu, Q_TAIL(queue), Q_ITEM(queue, prod + 1));
/*
- * 6. Make sure the doorbell write to the device has finished before updating
- * the shadow tail index in normal memory. 'fence o, w'
+ * 4. Make sure the doorbell write to the device has finished before
+ * updating the shadow tail index in normal memory. 'fence o, w'
*/
#ifdef CONFIG_MMIOWB
mmiowb();
#endif
- atomic_inc(&queue->tail);
+ atomic_set(&queue->tail, prod + 1);
+ atomic_set(&queue->prod, prod + 1);
- /* 7. Complete submission and restore local interrupts */
- local_irq_restore(flags);
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
return prod;
err_busy:
- local_irq_restore(flags);
+ /* Report the failure and continue; full RAS recovery is not implemented. */
dev_err_once(queue->iommu->dev, "Hardware error: command enqueue failed\n");
-
return prod;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 318/733] iommu/riscv: Avoid waiting on failed command enqueue
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (316 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 317/733] iommu/riscv: Serialize command queue publishing Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 319/733] iommu/amd: Do not reallocate GA log buffers on resume Greg Kroah-Hartman
` (426 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fangyu Yu, Joerg Roedel, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangyu Yu <fangyu.yu@linux.alibaba.com>
[ Upstream commit 4c50bec3d54288230aafb7fe3d2930d42beb14fd ]
Do not wait for IOFENCE.C completion when the command failed to enter the
queue. The command was not published to hardware, so waiting for its
producer index can only report a misleading execution timeout.
Fixes: 856c0cfe5c5f ("iommu/riscv: Command and fault queue support")
Signed-off-by: Fangyu Yu <fangyu.yu@linux.alibaba.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/riscv/iommu.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/iommu/riscv/iommu.c b/drivers/iommu/riscv/iommu.c
index e335beb70e422..fe8e6d0f8a23b 100644
--- a/drivers/iommu/riscv/iommu.c
+++ b/drivers/iommu/riscv/iommu.c
@@ -419,8 +419,9 @@ static int riscv_iommu_queue_wait_for_space(struct riscv_iommu_queue *queue,
}
/* Enqueue an entry and publish it to the hardware queue. */
-static unsigned int riscv_iommu_queue_send(struct riscv_iommu_queue *queue,
- void *entry, size_t entry_size)
+static int riscv_iommu_queue_send(struct riscv_iommu_queue *queue,
+ void *entry, size_t entry_size,
+ unsigned int *out_prod)
{
unsigned int prod;
unsigned int head;
@@ -462,14 +463,16 @@ static unsigned int riscv_iommu_queue_send(struct riscv_iommu_queue *queue,
atomic_set(&queue->tail, prod + 1);
atomic_set(&queue->prod, prod + 1);
- raw_spin_unlock_irqrestore(&queue->lock, flags);
+ if (out_prod)
+ *out_prod = prod;
- return prod;
+ raw_spin_unlock_irqrestore(&queue->lock, flags);
+ return 0;
err_busy:
/* Report the failure and continue; full RAS recovery is not implemented. */
dev_err_once(queue->iommu->dev, "Hardware error: command enqueue failed\n");
- return prod;
+ return ret;
}
/*
@@ -508,7 +511,7 @@ static irqreturn_t riscv_iommu_cmdq_process(int irq, void *data)
static void riscv_iommu_cmd_send(struct riscv_iommu_device *iommu,
struct riscv_iommu_command *cmd)
{
- riscv_iommu_queue_send(&iommu->cmdq, cmd, sizeof(*cmd));
+ riscv_iommu_queue_send(&iommu->cmdq, cmd, sizeof(*cmd), NULL);
}
/* Send IOFENCE.C command and wait for all scheduled commands to complete. */
@@ -517,9 +520,12 @@ static void riscv_iommu_cmd_sync(struct riscv_iommu_device *iommu,
{
struct riscv_iommu_command cmd;
unsigned int prod;
+ int ret;
riscv_iommu_cmd_iofence(&cmd);
- prod = riscv_iommu_queue_send(&iommu->cmdq, &cmd, sizeof(cmd));
+ ret = riscv_iommu_queue_send(&iommu->cmdq, &cmd, sizeof(cmd), &prod);
+ if (ret)
+ return;
if (!timeout_us)
return;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 319/733] iommu/amd: Do not reallocate GA log buffers on resume
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (317 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 318/733] iommu/riscv: Avoid waiting on failed command enqueue Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 320/733] iommu/amd: Fix premature break in init_iommu_one() again Greg Kroah-Hartman
` (425 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Vasant Hegde,
Ankit Soni, Joerg Roedel, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 00a7dd64888d6dd72110b40e2824a088cf7b7386 ]
Commit c5e1a1eb9279 ("iommu/amd: Simplify and Consolidate Virtual APIC
(AVIC) Enablement") moved the GA log allocation from iommu_init_pci()
to enable_iommus_vapic(), which is called on every resume.
iommu_init_ga_log() assigns iommu->ga_log and iommu->ga_log_tail
unconditionally. Each resume therefore replaces the boot-time pointers
and leaks both old allocations. The function also uses GFP_KERNEL from a
syscore resume callback, where interrupts are disabled and the non-boot
CPUs are offline.
Return early if both buffers are already allocated. Clear the pointers
in free_ga_log() so a partial allocation failure cannot leave ga_log
dangling.
Fixes: c5e1a1eb9279 ("iommu/amd: Simplify and Consolidate Virtual APIC (AVIC) Enablement")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Reviewed-by: Ankit Soni <Ankit.Soni@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/amd/init.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 2563ebe9f2461..16ffc75ef3f0d 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -906,7 +906,9 @@ static void free_ga_log(struct amd_iommu *iommu)
{
#ifdef CONFIG_IRQ_REMAP
iommu_free_pages(iommu->ga_log);
+ iommu->ga_log = NULL;
iommu_free_pages(iommu->ga_log_tail);
+ iommu->ga_log_tail = NULL;
#endif
}
@@ -953,6 +955,9 @@ static int iommu_init_ga_log(struct amd_iommu *iommu)
if (WARN_ON_ONCE(!AMD_IOMMU_GUEST_IR_VAPIC(amd_iommu_guest_ir)))
return -EINVAL;
+ if (iommu->ga_log && iommu->ga_log_tail)
+ return 0;
+
iommu->ga_log = iommu_alloc_pages_node_sz(nid, GFP_KERNEL, GA_LOG_SIZE);
if (!iommu->ga_log)
goto err_out;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 320/733] iommu/amd: Fix premature break in init_iommu_one() again
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (318 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 319/733] iommu/amd: Do not reallocate GA log buffers on resume Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 321/733] iommu/amd: Fix ineffective error check in nested domain allocation Greg Kroah-Hartman
` (424 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andreas Juch, Vasant Hegde,
Joerg Roedel, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasant Hegde <vasant.hegde@amd.com>
[ Upstream commit eb29b7bbc8ba28bbb0b9fdd655e931e1d1fa625c ]
Commit 283d245468a2 ("iommu/amd: Fix premature break in
init_iommu_one()") unintentionally broke older platforms - such as
the ASRockRack B550D4-4L - where the BIOS advertises incorrect IOMMU
features.
Move the HATDis check ahead of the GASup check, and re-introduce the
break inside the GASup check to restore correct behavior on affected
platforms.
This is a short-term fix to resolve the regression. Longer term, we
should rework how EFRs are tracked and prioritize the MMIO-advertised
EFR over the one reported via IVRS. That requires more extensive
changes and will be addressed separately.
Fixes: 283d245468a2 ("iommu/amd: Fix premature break in init_iommu_one()")
Reported-by: Andreas Juch <andreas@juch.cc>
Closes: https://lore.kernel.org/linux-iommu/07b2d390-f7a0-47e2-bc2c-eb0853acf52e@juch.cc/
Tested-by: Andreas Juch <andreas@juch.cc>
Signed-off-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/amd/init.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
diff --git a/drivers/iommu/amd/init.c b/drivers/iommu/amd/init.c
index 16ffc75ef3f0d..3509be3fc744e 100644
--- a/drivers/iommu/amd/init.c
+++ b/drivers/iommu/amd/init.c
@@ -1919,19 +1919,20 @@ static int __init init_iommu_one(struct amd_iommu *iommu, struct ivhd_header *h,
else
iommu->mmio_phys_end = MMIO_CNTR_CONF_OFFSET;
+ if (h->efr_attr & BIT(IOMMU_IVHD_ATTR_HATDIS_SHIFT)) {
+ pr_warn_once("Host Address Translation is not supported.\n");
+ amd_iommu_hatdis = true;
+ }
+
/* XT and GAM require GA mode. */
if ((h->efr_reg & (0x1 << IOMMU_EFR_GASUP_SHIFT)) == 0) {
amd_iommu_guest_ir = AMD_IOMMU_GUEST_IR_LEGACY;
+ break;
} else {
if (h->efr_reg & BIT(IOMMU_EFR_XTSUP_SHIFT))
amd_iommu_xt_mode = IRQ_REMAP_X2APIC_MODE;
}
- if (h->efr_attr & BIT(IOMMU_IVHD_ATTR_HATDIS_SHIFT)) {
- pr_warn_once("Host Address Translation is not supported.\n");
- amd_iommu_hatdis = true;
- }
-
early_iommu_features_init(iommu, h);
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 321/733] iommu/amd: Fix ineffective error check in nested domain allocation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (319 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 320/733] iommu/amd: Fix premature break in init_iommu_one() again Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 322/733] hwmon: (ltc4282) Make sure clk_init_data is fully initialized Greg Kroah-Hartman
` (423 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hemanth Selam, Vasant Hegde,
Joerg Roedel, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hemanth Selam <hemanth.selam@gmail.com>
[ Upstream commit fa5c0827f0b7bac6d0a188f10118151769ae68fd ]
amd_iommu_pdom_id_alloc() returns an int: a domain ID on success, or the
negative errno from ida_alloc_range() when the ID space is exhausted or
memory is short. amd_iommu_alloc_domain_nested() stores that return value
in gdom_info->hdom_id, which is a u32, and only then tests it:
gdom_info->hdom_id = amd_iommu_pdom_id_alloc();
if (gdom_info->hdom_id <= 0) {
The assignment discards the sign, so -ENOSPC becomes 0xffffffe4 and the
test never fires. The nested domain is then set up with a host domain ID
that was never allocated, instead of the allocation failing with -ENOSPC.
Keep the value in an int, test it there, and store it only once it is
known to be valid, which is what the other amd_iommu_pdom_id_alloc()
callers already do.
Fixes: 757d2b1fdf5b ("iommu/amd: Introduce gDomID-to-hDomID Mapping and handle parent domain invalidation")
Signed-off-by: Hemanth Selam <hemanth.selam@gmail.com>
Reviewed-by: Vasant Hegde <vasant.hegde@amd.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/iommu/amd/nested.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
diff --git a/drivers/iommu/amd/nested.c b/drivers/iommu/amd/nested.c
index 63b53b29e0298..f1c7987fc5859 100644
--- a/drivers/iommu/amd/nested.c
+++ b/drivers/iommu/amd/nested.c
@@ -96,7 +96,7 @@ struct iommu_domain *
amd_iommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
const struct iommu_user_data *user_data)
{
- int ret;
+ int ret, hdom_id;
unsigned long irqflags;
struct nested_domain *ndom;
struct guest_domain_mapping_info *gdom_info;
@@ -161,8 +161,8 @@ amd_iommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
}
/* The gDomID does not exist. We allocate new hdom_id */
- gdom_info->hdom_id = amd_iommu_pdom_id_alloc();
- if (gdom_info->hdom_id <= 0) {
+ hdom_id = amd_iommu_pdom_id_alloc();
+ if (hdom_id <= 0) {
__xa_cmpxchg(&aviommu->gdomid_array,
ndom->gdom_id, gdom_info, NULL, GFP_ATOMIC);
xa_unlock_irqrestore(&aviommu->gdomid_array, irqflags);
@@ -170,6 +170,7 @@ amd_iommu_alloc_domain_nested(struct iommufd_viommu *viommu, u32 flags,
goto out_err_gdom_info;
}
+ gdom_info->hdom_id = hdom_id;
ndom->gdom_info = gdom_info;
refcount_set(&gdom_info->users, 1);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 322/733] hwmon: (ltc4282) Make sure clk_init_data is fully initialized
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (320 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 321/733] iommu/amd: Fix ineffective error check in nested domain allocation Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 323/733] Documentation/hwmon: Document hwmon_notify_event() Greg Kroah-Hartman
` (422 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geert Uytterhoeven, Brian Masney,
Guenter Roeck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geert Uytterhoeven <geert+renesas@glider.be>
[ Upstream commit e317326d1755ea054b98e7a4833b929157461c35 ]
The clk_init_data structure contains several mutually-exclusive members
for different methods to specify the possible parents of a clock,
prompting drivers to initialize only the members they need. However,
not initializing all members may cause subtle issues, which are only
exposed when CONFIG_INIT_STACK_ALL_PATTERN or CONFIG_INIT_STACK_NONE is
enabled.
ltc428_clk_provider_setup() does not fill in any parent clocks, and
assumes that init.num_parents is NULL. However, the latter in
uninitialized, and thus may cause a crash.
Make sure all members are fully initialized, to fix such bugs, and to
avoid future breakage when converting drivers to a different method for
specifying the parents.
Fixes: cbc29538dbf7d740 ("hwmon: Add driver for LTC4282")
Signed-off-by: Geert Uytterhoeven <geert+renesas@glider.be>
Link: https://patch.msgid.link/8ec3c5cbd2df675a938f090470f5da5f22008517.1787165329.git.geert+renesas@glider.be
Reviewed-by: Brian Masney <bmasney@redhat.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/ltc4282.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/ltc4282.c b/drivers/hwmon/ltc4282.c
index b1675dc5b3c7f..54ba4b8542e94 100644
--- a/drivers/hwmon/ltc4282.c
+++ b/drivers/hwmon/ltc4282.c
@@ -1106,7 +1106,7 @@ static const struct clk_ops ltc4282_ops = {
static int ltc428_clk_provider_setup(struct ltc4282_state *st,
struct device *dev)
{
- struct clk_init_data init;
+ struct clk_init_data init = {};
int ret;
if (!IS_ENABLED(CONFIG_COMMON_CLK))
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 323/733] Documentation/hwmon: Document hwmon_notify_event()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (321 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 322/733] hwmon: (ltc4282) Make sure clk_init_data is fully initialized Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 324/733] hwmon: Fix potential UAF in pec_store Greg Kroah-Hartman
` (421 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kalesh AP, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit b4fffa75c1d6f87e6dc6191dec900f2b5bd23a1c ]
The hwmon core provides hwmon_notify_event() for drivers to report events
such as alarm or fault conditions to userspace via sysfs notifications
and uevents, as well as to the thermal subsystem for temperature sensors.
However, this function is not documented in the hwmon kernel API guide.
Add the function prototype and description of hwmon_notify_event() to
Documentation/hwmon/hwmon-kernel-api.rst.
Cc: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Reviewed-by: Kalesh AP <kalesh-anakkur.purayil@broadcom.com>
Fixes: 1597b374af222 ("hwmon: Add notification support")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/hwmon/hwmon-kernel-api.rst | 15 +++++++++++++++
1 file changed, 15 insertions(+)
diff --git a/Documentation/hwmon/hwmon-kernel-api.rst b/Documentation/hwmon/hwmon-kernel-api.rst
index 9fcde32a140df..c3eb433a78f61 100644
--- a/Documentation/hwmon/hwmon-kernel-api.rst
+++ b/Documentation/hwmon/hwmon-kernel-api.rst
@@ -42,6 +42,9 @@ register/unregister functions::
char *devm_hwmon_sanitize_name(struct device *dev, const char *name);
+ int hwmon_notify_event(struct device *dev, enum hwmon_sensor_types type,
+ u32 attr, int channel);
+
void hwmon_lock(struct device *dev);
void hwmon_unlock(struct device *dev);
@@ -90,6 +93,18 @@ implemented in the driver, or debugfs functions, hwmon_lock() and hwmon_unlock()
can be used to ensure that calls to those functions are serialized. Those
functions also support guard() and scoped_guard() variants.
+Drivers can call hwmon_notify_event() to notify userspace and the thermal
+subsystem when a hardware monitoring event (such as an alarm or a fault
+condition) occurs or clears. The parameters are the hwmon device, the sensor
+type, the attribute identifier associated with the event (such as
+hwmon_temp_max_alarm or hwmon_fan_fault), and the sensor channel number.
+hwmon_notify_event() generates a sysfs event (calling sysfs_notify()) and a
+udev event with the attribute name passed in the NAME environment property
+(e.g., "NAME=temp1_max_alarm"). If the event is for a temperature sensor and
+the sensor is attached to a thermal zone, it also notifies the thermal
+subsystem to update the thermal zone. hwmon_notify_event() returns 0 on
+success or a negative error code on failure.
+
Using devm_hwmon_device_register_with_info()
--------------------------------------------
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 324/733] hwmon: Fix potential UAF in pec_store
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (322 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 323/733] Documentation/hwmon: Document hwmon_notify_event() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 325/733] hwmon: (ina2xx) Acquire hwmon_lock in shunt_resistor_show() Greg Kroah-Hartman
` (420 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Guenter Roeck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 354ccc99b2dc8ba0cf6d4de34e520bcf6ecca5c2 ]
Sashiko reports:
In pec_store(), a guard(mutex)(&hwdev->lock) is taken. If the chip write
operation returns an error other than -EOPNOTSUPP, the code jumps to the
put label, which calls put_device(hdev). If this drops the final reference,
the device is freed. When the function then returns, the guard cleanup
function runs and attempts to unlock the freed mutex.
Use scoped_guard() instead of guard() to avoid the problem.
Fixes: 3ad2a7b9b15d5 ("hwmon: Serialize accesses in hwmon core")
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/hwmon.c | 21 ++++++++++-----------
1 file changed, 10 insertions(+), 11 deletions(-)
diff --git a/drivers/hwmon/hwmon.c b/drivers/hwmon/hwmon.c
index 29dc90a2c3fe7..8cf717ae8b1dd 100644
--- a/drivers/hwmon/hwmon.c
+++ b/drivers/hwmon/hwmon.c
@@ -371,18 +371,17 @@ static ssize_t pec_store(struct device *dev, struct device_attribute *devattr,
* handling is not required.
*/
hwdev = to_hwmon_device(hdev);
- guard(mutex)(&hwdev->lock);
- if (hwdev->chip->ops->write) {
- err = hwdev->chip->ops->write(hdev, hwmon_chip, hwmon_chip_pec, 0, val);
- if (err && err != -EOPNOTSUPP)
- goto put;
+ scoped_guard(mutex, &hwdev->lock) {
+ if (hwdev->chip->ops->write) {
+ err = hwdev->chip->ops->write(hdev, hwmon_chip, hwmon_chip_pec, 0, val);
+ if (err && err != -EOPNOTSUPP)
+ goto put;
+ }
+ if (!val)
+ client->flags &= ~I2C_CLIENT_PEC;
+ else
+ client->flags |= I2C_CLIENT_PEC;
}
-
- if (!val)
- client->flags &= ~I2C_CLIENT_PEC;
- else
- client->flags |= I2C_CLIENT_PEC;
-
err = count;
put:
put_device(hdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 325/733] hwmon: (ina2xx) Acquire hwmon_lock in shunt_resistor_show()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (323 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 324/733] hwmon: Fix potential UAF in pec_store Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 326/733] hwmon: (ina2xx) Parameterize ina2xx_data in ina226_alert_read() Greg Kroah-Hartman
` (419 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jared Kangas, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jared Kangas <jkangas@redhat.com>
[ Upstream commit 8afc94bfb0ffdfc4a168081785820aa4818d1d23 ]
shunt_resistor_store() currently acquires hwmon_lock to set
data->rshunt, but the corresponding access in shunt_resistor_show() is
unprotected. Acquire the lock in shunt_resistor_show() as well to ensure
proper synchronization.
Fixes: 3ad867001c91 ("hwmon: (ina2xx) fix sysfs shunt resistor read access")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260729162836.89BDF1F00A3A@smtp.kernel.org/
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-1-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/ina2xx.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 449a72c6b40bd..8dfe5da13cae5 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -868,8 +868,12 @@ static ssize_t shunt_resistor_show(struct device *dev,
struct device_attribute *da, char *buf)
{
struct ina2xx_data *data = dev_get_drvdata(dev);
+ long rshunt;
- return sysfs_emit(buf, "%li\n", data->rshunt);
+ scoped_guard(hwmon_lock, dev) {
+ rshunt = data->rshunt;
+ }
+ return sysfs_emit(buf, "%li\n", rshunt);
}
static ssize_t shunt_resistor_store(struct device *dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 326/733] hwmon: (ina2xx) Parameterize ina2xx_data in ina226_alert_read()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (324 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 325/733] hwmon: (ina2xx) Acquire hwmon_lock in shunt_resistor_show() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 327/733] hwmon: (ina2xx) Replace masks with enum in alert functions Greg Kroah-Hartman
` (418 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jared Kangas, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jared Kangas <jkangas@redhat.com>
[ Upstream commit 3d44ab826e0244a8b9eaf0f1f604f4cb8b890325 ]
Mirror ina226_alert_limit_read/write and use struct ina2xx_data instead
of struct regmap in ina226_alert_read's parameters.
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-2-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Stable-dep-of: 35760f5efd7b ("hwmon: (ina2xx) Decouple in0 and curr1 alarms")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/ina2xx.c | 14 +++++++-------
1 file changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 8dfe5da13cae5..6175fab8728e0 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -483,12 +483,12 @@ static int ina2xx_chip_read(struct device *dev, u32 attr, long *val)
return 0;
}
-static int ina226_alert_read(struct regmap *regmap, u32 mask, long *val)
+static int ina226_alert_read(struct ina2xx_data *data, u32 mask, long *val)
{
unsigned int regval;
int ret;
- ret = regmap_read_bypassed(regmap, INA226_MASK_ENABLE, ®val);
+ ret = regmap_read_bypassed(data->regmap, INA226_MASK_ENABLE, ®val);
if (ret)
return ret;
@@ -523,9 +523,9 @@ static int ina2xx_in_read(struct device *dev, u32 attr, int channel, long *val)
return ina226_alert_limit_read(data, over_voltage_mask,
voltage_reg, val);
case hwmon_in_lcrit_alarm:
- return ina226_alert_read(regmap, under_voltage_mask, val);
+ return ina226_alert_read(data, under_voltage_mask, val);
case hwmon_in_crit_alarm:
- return ina226_alert_read(regmap, over_voltage_mask, val);
+ return ina226_alert_read(data, over_voltage_mask, val);
default:
return -EOPNOTSUPP;
}
@@ -582,7 +582,7 @@ static int ina2xx_power_read(struct device *dev, u32 attr, long *val)
return ina226_alert_limit_read(data, INA226_POWER_OVER_LIMIT_MASK,
INA2XX_POWER, val);
case hwmon_power_crit_alarm:
- return ina226_alert_read(data->regmap, INA226_POWER_OVER_LIMIT_MASK, val);
+ return ina226_alert_read(data, INA226_POWER_OVER_LIMIT_MASK, val);
default:
return -EOPNOTSUPP;
}
@@ -624,9 +624,9 @@ static int ina2xx_curr_read(struct device *dev, u32 attr, long *val)
return ina226_alert_limit_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
INA2XX_CURRENT, val);
case hwmon_curr_lcrit_alarm:
- return ina226_alert_read(regmap, INA226_SHUNT_UNDER_VOLTAGE_MASK, val);
+ return ina226_alert_read(data, INA226_SHUNT_UNDER_VOLTAGE_MASK, val);
case hwmon_curr_crit_alarm:
- return ina226_alert_read(regmap, INA226_SHUNT_OVER_VOLTAGE_MASK, val);
+ return ina226_alert_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK, val);
default:
return -EOPNOTSUPP;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 327/733] hwmon: (ina2xx) Replace masks with enum in alert functions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (325 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 326/733] hwmon: (ina2xx) Parameterize ina2xx_data in ina226_alert_read() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 328/733] hwmon: (ina2xx) Decouple in0 and curr1 alarms Greg Kroah-Hartman
` (417 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jared Kangas, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jared Kangas <jkangas@redhat.com>
[ Upstream commit e92b9208415a90e9cc1d923c5d8c058dde77be68 ]
Instead of passing an explicit mask to alert/limit functions like
ina226_alert_read(), introduce an enum ina2xx_alert_type that can be
converted to a mask internally. This semantically separates current from
shunt voltage in helpers that use function masks, which previously saw
the same mask for the two functions.
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-3-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Stable-dep-of: 35760f5efd7b ("hwmon: (ina2xx) Decouple in0 and curr1 alarms")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/ina2xx.c | 90 +++++++++++++++++++++++++++++++-----------
1 file changed, 67 insertions(+), 23 deletions(-)
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index 6175fab8728e0..dec4e72be2f92 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -128,6 +128,17 @@ enum ina2xx_ids {
sy24655
};
+enum ina2xx_alert_type {
+ INA2XX_ALERT_NONE,
+ INA2XX_ALERT_CURRENT_LOW,
+ INA2XX_ALERT_CURRENT_HIGH,
+ INA2XX_ALERT_POWER_HIGH,
+ INA2XX_ALERT_BUS_VOLTAGE_LOW,
+ INA2XX_ALERT_BUS_VOLTAGE_HIGH,
+ INA2XX_ALERT_SHUNT_VOLTAGE_LOW,
+ INA2XX_ALERT_SHUNT_VOLTAGE_HIGH,
+};
+
struct ina2xx_config {
u16 config_default;
bool has_alerts; /* chip supports alerts and limits */
@@ -413,16 +424,43 @@ static u16 ina226_alert_to_reg(struct ina2xx_data *data, int reg, long val)
}
}
-static int ina226_alert_limit_read(struct ina2xx_data *data, u32 mask, int reg, long *val)
+static u32 ina2xx_alert_type_to_mask(enum ina2xx_alert_type alert)
+{
+ switch (alert) {
+ case INA2XX_ALERT_CURRENT_LOW:
+ case INA2XX_ALERT_SHUNT_VOLTAGE_LOW:
+ return INA226_SHUNT_UNDER_VOLTAGE_MASK;
+ case INA2XX_ALERT_CURRENT_HIGH:
+ case INA2XX_ALERT_SHUNT_VOLTAGE_HIGH:
+ return INA226_SHUNT_OVER_VOLTAGE_MASK;
+ case INA2XX_ALERT_BUS_VOLTAGE_LOW:
+ return INA226_BUS_UNDER_VOLTAGE_MASK;
+ case INA2XX_ALERT_BUS_VOLTAGE_HIGH:
+ return INA226_BUS_OVER_VOLTAGE_MASK;
+ case INA2XX_ALERT_POWER_HIGH:
+ return INA226_POWER_OVER_LIMIT_MASK;
+ case INA2XX_ALERT_NONE:
+ return 0;
+ default:
+ /* programmer error */
+ WARN_ON_ONCE(1);
+ return 0;
+ }
+}
+
+static int ina226_alert_limit_read(struct ina2xx_data *data, enum ina2xx_alert_type alert,
+ int reg, long *val)
{
struct regmap *regmap = data->regmap;
int regval;
+ u32 mask;
int ret;
ret = regmap_read(regmap, INA226_MASK_ENABLE, ®val);
if (ret)
return ret;
+ mask = ina2xx_alert_type_to_mask(alert);
if (regval & mask) {
ret = regmap_read(regmap, INA226_ALERT_LIMIT, ®val);
if (ret)
@@ -434,9 +472,11 @@ static int ina226_alert_limit_read(struct ina2xx_data *data, u32 mask, int reg,
return 0;
}
-static int ina226_alert_limit_write(struct ina2xx_data *data, u32 mask, int reg, long val)
+static int ina226_alert_limit_write(struct ina2xx_data *data, enum ina2xx_alert_type alert,
+ int reg, long val)
{
struct regmap *regmap = data->regmap;
+ u32 mask;
int ret;
if (val < 0)
@@ -457,9 +497,11 @@ static int ina226_alert_limit_write(struct ina2xx_data *data, u32 mask, int reg,
if (ret < 0)
return ret;
- if (val)
+ if (val) {
+ mask = ina2xx_alert_type_to_mask(alert);
return regmap_update_bits(regmap, INA226_MASK_ENABLE,
INA226_ALERT_CONFIG_MASK, mask);
+ }
return 0;
}
@@ -483,15 +525,17 @@ static int ina2xx_chip_read(struct device *dev, u32 attr, long *val)
return 0;
}
-static int ina226_alert_read(struct ina2xx_data *data, u32 mask, long *val)
+static int ina226_alert_read(struct ina2xx_data *data, enum ina2xx_alert_type alert, long *val)
{
unsigned int regval;
+ u32 mask;
int ret;
ret = regmap_read_bypassed(data->regmap, INA226_MASK_ENABLE, ®val);
if (ret)
return ret;
+ mask = ina2xx_alert_type_to_mask(alert);
*val = (regval & mask) && (regval & INA226_ALERT_FUNCTION_FLAG);
return 0;
@@ -500,10 +544,10 @@ static int ina226_alert_read(struct ina2xx_data *data, u32 mask, long *val)
static int ina2xx_in_read(struct device *dev, u32 attr, int channel, long *val)
{
int voltage_reg = channel ? INA2XX_BUS_VOLTAGE : INA2XX_SHUNT_VOLTAGE;
- u32 under_voltage_mask = channel ? INA226_BUS_UNDER_VOLTAGE_MASK
- : INA226_SHUNT_UNDER_VOLTAGE_MASK;
- u32 over_voltage_mask = channel ? INA226_BUS_OVER_VOLTAGE_MASK
- : INA226_SHUNT_OVER_VOLTAGE_MASK;
+ enum ina2xx_alert_type under_voltage_alert = channel ? INA2XX_ALERT_BUS_VOLTAGE_LOW
+ : INA2XX_ALERT_SHUNT_VOLTAGE_LOW;
+ enum ina2xx_alert_type over_voltage_alert = channel ? INA2XX_ALERT_BUS_VOLTAGE_HIGH
+ : INA2XX_ALERT_SHUNT_VOLTAGE_HIGH;
struct ina2xx_data *data = dev_get_drvdata(dev);
struct regmap *regmap = data->regmap;
unsigned int regval;
@@ -517,15 +561,15 @@ static int ina2xx_in_read(struct device *dev, u32 attr, int channel, long *val)
*val = ina2xx_get_value(data, voltage_reg, regval);
break;
case hwmon_in_lcrit:
- return ina226_alert_limit_read(data, under_voltage_mask,
+ return ina226_alert_limit_read(data, under_voltage_alert,
voltage_reg, val);
case hwmon_in_crit:
- return ina226_alert_limit_read(data, over_voltage_mask,
+ return ina226_alert_limit_read(data, over_voltage_alert,
voltage_reg, val);
case hwmon_in_lcrit_alarm:
- return ina226_alert_read(data, under_voltage_mask, val);
+ return ina226_alert_read(data, under_voltage_alert, val);
case hwmon_in_crit_alarm:
- return ina226_alert_read(data, over_voltage_mask, val);
+ return ina226_alert_read(data, over_voltage_alert, val);
default:
return -EOPNOTSUPP;
}
@@ -579,10 +623,10 @@ static int ina2xx_power_read(struct device *dev, u32 attr, long *val)
case hwmon_power_average:
return sy24655_average_power_read(data, SY24655_EIN, val);
case hwmon_power_crit:
- return ina226_alert_limit_read(data, INA226_POWER_OVER_LIMIT_MASK,
+ return ina226_alert_limit_read(data, INA2XX_ALERT_POWER_HIGH,
INA2XX_POWER, val);
case hwmon_power_crit_alarm:
- return ina226_alert_read(data, INA226_POWER_OVER_LIMIT_MASK, val);
+ return ina226_alert_read(data, INA2XX_ALERT_POWER_HIGH, val);
default:
return -EOPNOTSUPP;
}
@@ -618,15 +662,15 @@ static int ina2xx_curr_read(struct device *dev, u32 attr, long *val)
*val = ina2xx_get_value(data, INA2XX_CURRENT, regval);
return 0;
case hwmon_curr_lcrit:
- return ina226_alert_limit_read(data, INA226_SHUNT_UNDER_VOLTAGE_MASK,
+ return ina226_alert_limit_read(data, INA2XX_ALERT_CURRENT_LOW,
INA2XX_CURRENT, val);
case hwmon_curr_crit:
- return ina226_alert_limit_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
+ return ina226_alert_limit_read(data, INA2XX_ALERT_CURRENT_HIGH,
INA2XX_CURRENT, val);
case hwmon_curr_lcrit_alarm:
- return ina226_alert_read(data, INA226_SHUNT_UNDER_VOLTAGE_MASK, val);
+ return ina226_alert_read(data, INA2XX_ALERT_CURRENT_LOW, val);
case hwmon_curr_crit_alarm:
- return ina226_alert_read(data, INA226_SHUNT_OVER_VOLTAGE_MASK, val);
+ return ina226_alert_read(data, INA2XX_ALERT_CURRENT_HIGH, val);
default:
return -EOPNOTSUPP;
}
@@ -670,12 +714,12 @@ static int ina2xx_in_write(struct device *dev, u32 attr, int channel, long val)
switch (attr) {
case hwmon_in_lcrit:
return ina226_alert_limit_write(data,
- channel ? INA226_BUS_UNDER_VOLTAGE_MASK : INA226_SHUNT_UNDER_VOLTAGE_MASK,
+ channel ? INA2XX_ALERT_BUS_VOLTAGE_LOW : INA2XX_ALERT_SHUNT_VOLTAGE_LOW,
channel ? INA2XX_BUS_VOLTAGE : INA2XX_SHUNT_VOLTAGE,
val);
case hwmon_in_crit:
return ina226_alert_limit_write(data,
- channel ? INA226_BUS_OVER_VOLTAGE_MASK : INA226_SHUNT_OVER_VOLTAGE_MASK,
+ channel ? INA2XX_ALERT_BUS_VOLTAGE_HIGH : INA2XX_ALERT_SHUNT_VOLTAGE_HIGH,
channel ? INA2XX_BUS_VOLTAGE : INA2XX_SHUNT_VOLTAGE,
val);
default:
@@ -690,7 +734,7 @@ static int ina2xx_power_write(struct device *dev, u32 attr, long val)
switch (attr) {
case hwmon_power_crit:
- return ina226_alert_limit_write(data, INA226_POWER_OVER_LIMIT_MASK,
+ return ina226_alert_limit_write(data, INA2XX_ALERT_POWER_HIGH,
INA2XX_POWER, val);
default:
return -EOPNOTSUPP;
@@ -704,10 +748,10 @@ static int ina2xx_curr_write(struct device *dev, u32 attr, long val)
switch (attr) {
case hwmon_curr_lcrit:
- return ina226_alert_limit_write(data, INA226_SHUNT_UNDER_VOLTAGE_MASK,
+ return ina226_alert_limit_write(data, INA2XX_ALERT_CURRENT_LOW,
INA2XX_CURRENT, val);
case hwmon_curr_crit:
- return ina226_alert_limit_write(data, INA226_SHUNT_OVER_VOLTAGE_MASK,
+ return ina226_alert_limit_write(data, INA2XX_ALERT_CURRENT_HIGH,
INA2XX_CURRENT, val);
default:
return -EOPNOTSUPP;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 328/733] hwmon: (ina2xx) Decouple in0 and curr1 alarms
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (326 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 327/733] hwmon: (ina2xx) Replace masks with enum in alert functions Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 329/733] Documentation: hwmon: replace full-width colon by a standard ASCII colon Greg Kroah-Hartman
` (416 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jared Kangas, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jared Kangas <jkangas@redhat.com>
[ Upstream commit 35760f5efd7bfa7a44a3831f47e19fe9cbafc905 ]
INA2XX current limits are converted into shunt voltage limits internally
using the shunt resistor value. Once a current limit's corresponding
voltage limit is written to the hardware, shunt voltage and current
alarms are indistinguishable from each other.
This causes two issues:
1. in0/curr1 alarms may be unintentionally cleared by reading from the
opposite input's alarm.
2. When a limit for either in0 (shunt voltage) or curr1 (current) is
set, both of their alarms are triggered, and both of their limits
read nonzero.
An example of this behavior on an INA231:
# cd /sys/class/hwmon/hwmon0
# head {curr1,in0}_input
==> curr1_input <==
1713
==> in0_input <==
2
# echo 1800 >curr1_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
1
==> in0_lcrit_alarm <==
0
# head {in0,curr1}_lcrit_alarm
==> in0_lcrit_alarm <==
1
==> curr1_lcrit_alarm <==
0
# head {in0,curr1}_lcrit_alarm
==> in0_lcrit_alarm <==
1
==> curr1_lcrit_alarm <==
1
This is because curr1 uses the same underlying masks
(INA226_SHUNT_*_VOLTAGE_MASK) as in0 on the hardware. As a result,
ina2xx_{curr,in}_read() both read the shunt voltage alarms/limits
without considering whether the voltage or current is currently set.
To fix this, track the active alarm type in ina2xx_data and guard
alarm/limit reads with a check that returns zero if the active alarm is
for a different type. The new field is initialized based on the
MASK_ENABLE register's set function, assuming voltage instead of current
when the shunt voltage mask is set.
After this fix, the alarms only read back 1 if their corresponding limit
is set:
# echo 0 >curr1_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
0
==> in0_lcrit_alarm <==
0
# echo 9999 >curr1_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
1
==> in0_lcrit_alarm <==
0
# echo 9999 >in0_lcrit
# head {curr1,in0}_lcrit_alarm
==> curr1_lcrit_alarm <==
0
==> in0_lcrit_alarm <==
1
Fixes: 4d5c2d986757 ("hwmon: (ina2xx) Add support for current limits")
Signed-off-by: Jared Kangas <jkangas@redhat.com>
Link: https://patch.msgid.link/20260820-upstream-ina2xx-in0-curr1-alarms-v2-4-fdce35abc41e@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/ina2xx.c | 65 ++++++++++++++++++++++++++++++++++++++++--
1 file changed, 63 insertions(+), 2 deletions(-)
diff --git a/drivers/hwmon/ina2xx.c b/drivers/hwmon/ina2xx.c
index dec4e72be2f92..958a1e3ec728d 100644
--- a/drivers/hwmon/ina2xx.c
+++ b/drivers/hwmon/ina2xx.c
@@ -8,6 +8,7 @@
*/
#include <linux/bitfield.h>
+#include <linux/bitops.h>
#include <linux/bits.h>
#include <linux/delay.h>
#include <linux/device.h>
@@ -158,6 +159,7 @@ struct ina2xx_data {
const struct ina2xx_config *config;
enum ina2xx_ids chip;
+ enum ina2xx_alert_type active_alert;
long rshunt;
long current_lsb_uA;
long power_lsb_uW;
@@ -448,6 +450,35 @@ static u32 ina2xx_alert_type_to_mask(enum ina2xx_alert_type alert)
}
}
+static enum ina2xx_alert_type ina2xx_mask_to_alert_type(u32 mask)
+{
+ int top_bit = fls(mask & INA226_ALERT_CONFIG_MASK);
+
+ if (!top_bit)
+ return INA2XX_ALERT_NONE;
+
+ /*
+ * Multiple bits may be set, with the highest-set function taking
+ * precedence according to the datasheet. Shunt voltage masks are
+ * assumed to map to voltage monitoring rather than current monitoring,
+ * since the latter isn't directly implemented in the hardware.
+ */
+ switch (BIT(top_bit - 1)) {
+ case INA226_SHUNT_OVER_VOLTAGE_MASK:
+ return INA2XX_ALERT_SHUNT_VOLTAGE_HIGH;
+ case INA226_SHUNT_UNDER_VOLTAGE_MASK:
+ return INA2XX_ALERT_SHUNT_VOLTAGE_LOW;
+ case INA226_BUS_OVER_VOLTAGE_MASK:
+ return INA2XX_ALERT_BUS_VOLTAGE_HIGH;
+ case INA226_BUS_UNDER_VOLTAGE_MASK:
+ return INA2XX_ALERT_BUS_VOLTAGE_LOW;
+ case INA226_POWER_OVER_LIMIT_MASK:
+ return INA2XX_ALERT_POWER_HIGH;
+ default:
+ return INA2XX_ALERT_NONE;
+ }
+}
+
static int ina226_alert_limit_read(struct ina2xx_data *data, enum ina2xx_alert_type alert,
int reg, long *val)
{
@@ -456,6 +487,12 @@ static int ina226_alert_limit_read(struct ina2xx_data *data, enum ina2xx_alert_t
u32 mask;
int ret;
+ /* Avoid nonzero reads from inactive alerts caused by shared limit register */
+ if (data->active_alert != alert) {
+ *val = 0;
+ return 0;
+ }
+
ret = regmap_read(regmap, INA226_MASK_ENABLE, ®val);
if (ret)
return ret;
@@ -491,6 +528,7 @@ static int ina226_alert_limit_write(struct ina2xx_data *data, enum ina2xx_alert_
INA226_ALERT_CONFIG_MASK, 0);
if (ret < 0)
return ret;
+ data->active_alert = INA2XX_ALERT_NONE;
ret = regmap_write(regmap, INA226_ALERT_LIMIT,
ina226_alert_to_reg(data, reg, val));
@@ -499,9 +537,13 @@ static int ina226_alert_limit_write(struct ina2xx_data *data, enum ina2xx_alert_
if (val) {
mask = ina2xx_alert_type_to_mask(alert);
- return regmap_update_bits(regmap, INA226_MASK_ENABLE,
- INA226_ALERT_CONFIG_MASK, mask);
+ ret = regmap_update_bits(regmap, INA226_MASK_ENABLE,
+ INA226_ALERT_CONFIG_MASK, mask);
+ if (ret < 0)
+ return ret;
+ data->active_alert = alert;
}
+
return 0;
}
@@ -531,6 +573,15 @@ static int ina226_alert_read(struct ina2xx_data *data, enum ina2xx_alert_type al
u32 mask;
int ret;
+ /*
+ * With alert latching, reading alerts from hardware also clears the
+ * alert, so return early if the alert is inactive.
+ */
+ if (data->active_alert != alert) {
+ *val = 0;
+ return 0;
+ }
+
ret = regmap_read_bypassed(data->regmap, INA226_MASK_ENABLE, ®val);
if (ret)
return ret;
@@ -973,6 +1024,16 @@ static int ina2xx_init(struct device *dev, struct ina2xx_data *data)
if (data->config->has_alerts) {
bool active_high = device_property_read_bool(dev, "ti,alert-polarity-active-high");
+ unsigned int mask_enable;
+
+ /*
+ * Infer active alert from MASK_ENABLE in case it's already
+ * configured (e.g., by a past probe or firmware)
+ */
+ ret = regmap_read(regmap, INA226_MASK_ENABLE, &mask_enable);
+ if (ret < 0)
+ return ret;
+ data->active_alert = ina2xx_mask_to_alert_type(mask_enable);
regmap_update_bits(regmap, INA226_MASK_ENABLE,
INA226_ALERT_LATCH_ENABLE | INA226_ALERT_POLARITY,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 329/733] Documentation: hwmon: replace full-width colon by a standard ASCII colon
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (327 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 328/733] hwmon: (ina2xx) Decouple in0 and curr1 alarms Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 330/733] hwmon: (yogafan) fix non-kernel-doc comment Greg Kroah-Hartman
` (415 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Antonin Godard, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antonin Godard <antonin.godard@bootlin.com>
[ Upstream commit 013c5a93e8062014177d68af799e8867cf03958d ]
It prevented the pdfdocs target to complete, prompting the following
error:
Latexmk: ====Problematic refs and citations with line #s in .tex file:
Missing character: There is no : (U+FF1A) in font DejaVu Serif/OT:script=latn;l
Fixes: 69001f21ded78 ("hwmon: document: add gpd-fan")
Signed-off-by: Antonin Godard <antonin.godard@bootlin.com>
Link: https://patch.msgid.link/20260818-doc-hwmon-remove-confusable-v2-1-c1dff1ec01cd@bootlin.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
Documentation/hwmon/gpd-fan.rst | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/Documentation/hwmon/gpd-fan.rst b/Documentation/hwmon/gpd-fan.rst
index 29527a77fe882..b27657d330563 100644
--- a/Documentation/hwmon/gpd-fan.rst
+++ b/Documentation/hwmon/gpd-fan.rst
@@ -67,7 +67,7 @@ pwm1_enable
at full speed. Write "1" to set to manual, write "2" to let the EC control
decide fan speed. Read this attribute to see current status.
- NB:In consideration of the safety of the device, when setting to manual mode,
+ NB: In consideration of the safety of the device, when setting to manual mode,
the pwm speed will be set to the maximum value (255) by default. You can set
a different value by writing pwm1 later.
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 330/733] hwmon: (yogafan) fix non-kernel-doc comment
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (328 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 329/733] Documentation: hwmon: replace full-width colon by a standard ASCII colon Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 331/733] hwmon: (sht4x) Add missing locks Greg Kroah-Hartman
` (414 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, hanzhijian, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: hanzhijian <hanzhijian1991@gmail.com>
[ Upstream commit 100eb7c7d0b28c52ad1b25d51c316fdc46c27c71 ]
The file description comment starts with "/**" which is reserved for
kernel-doc comments, triggering a kernel-doc checker warning. Change
it to a plain "/*" comment since it does not document any function or
struct.
Fixes: c67c248ca406a ("hwmon: (yogafan) Add support for Lenovo Yoga/Legion fan monitoring")
Signed-off-by: hanzhijian <hanzhijian1991@gmail.com>
Link: https://patch.msgid.link/20260821115720.2017516-1-hanzhijian1991@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/yogafan.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/yogafan.c b/drivers/hwmon/yogafan.c
index 605cc928f21f3..314ee61955dd8 100644
--- a/drivers/hwmon/yogafan.c
+++ b/drivers/hwmon/yogafan.c
@@ -1,5 +1,5 @@
// SPDX-License-Identifier: GPL-2.0-only
-/**
+/*
* yoga_fan.c - Lenovo Yoga/Legion Fan Hardware Monitoring Driver
*
* Provides fan speed monitoring for Lenovo Yoga, Legion, and IdeaPad
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 331/733] hwmon: (sht4x) Add missing locks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (329 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 330/733] hwmon: (yogafan) fix non-kernel-doc comment Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 332/733] hwmon: (sht4x) Fix return value from heater_enable_store() Greg Kroah-Hartman
` (413 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alessandro Zini, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 06b7cf395b1fb652a50db39674a759658fbfba0d ]
Sashiko reports:
Heater sysfs callbacks (heater_enable_store, heater_power_store, and
heater_time_store) are exposed to data races without the hwmon lock.
If a user-space process reads hwmon data while another process enables
the heater, heater_enable_store() executes without holding
hwmon_lock(dev). This can interleave I2C commands and mutate shared
state (data->heating_complete and data->data_pending) concurrently
with sht4x_read_values(), leading to corrupted I2C sequences.
Fixes: 53dfa12299c1 ("hwmon: (sht4x) Rely on subsystem locking")
Cc: Alessandro Zini <alessandro.zini@siemens.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Link: https://patch.msgid.link/20260821144916.2889031-1-linux@roeck-us.net
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/sht4x.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
index 9cace0e8acdab..7a0dc2ed723d8 100644
--- a/drivers/hwmon/sht4x.c
+++ b/drivers/hwmon/sht4x.c
@@ -277,6 +277,8 @@ static ssize_t heater_enable_store(struct device *dev,
heating_time_bound = 1100;
}
+ guard(hwmon_lock)(dev);
+
if (time_before(jiffies, data->heating_complete))
return -EBUSY;
@@ -314,6 +316,8 @@ static ssize_t heater_power_store(struct device *dev,
if (power != 20 && power != 110 && power != 200)
return -EINVAL;
+ guard(hwmon_lock)(dev);
+
data->heater_power = power;
return count;
@@ -344,6 +348,8 @@ static ssize_t heater_time_store(struct device *dev,
if (time != 100 && time != 1000)
return -EINVAL;
+ guard(hwmon_lock)(dev);
+
data->heater_time = time;
return count;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 332/733] hwmon: (sht4x) Fix return value from heater_enable_store()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (330 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 331/733] hwmon: (sht4x) Add missing locks Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 333/733] ASoC: bcm: bcm63xx: Publish the OF module aliases Greg Kroah-Hartman
` (412 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Antoni Pokusinski, Alessandro Zini,
Guenter Roeck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guenter Roeck <linux@roeck-us.net>
[ Upstream commit 70c33e211b2b78830f76c908e5236b77ffde63a0 ]
Sashiko reports:
The return value in heater_enable_store() causes an unexpected write
failure in user-space.
When the heater is successfully enabled, the function returns 0
instead of count:
drivers/hwmon/sht4x.c:heater_enable_store() {
...
data->heating_complete = jiffies + msecs_to_jiffies(heating_time_bound);
data->data_pending = true;
return 0;
}
Returning 0 signals to VFS that no bytes were processed. Standard
user-space tools will retry the write with the remaining bytes. On the
retry, time_before(jiffies, data->heating_complete) evaluates to true,
and the function immediately fails with -EBUSY.
Return count as expected to fix the problem.
Fixes: 0eed6fc3d2b9e ("hwmon: (sht4x): add heater support")
Cc: Antoni Pokusinski <apokusinski01@gmail.com>
Cc: Alessandro Zini <alessandro.zini@siemens.com>
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Link: https://patch.msgid.link/20260821144916.2889031-2-linux@roeck-us.net
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/sht4x.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/hwmon/sht4x.c b/drivers/hwmon/sht4x.c
index 7a0dc2ed723d8..a97dda9e92dc5 100644
--- a/drivers/hwmon/sht4x.c
+++ b/drivers/hwmon/sht4x.c
@@ -288,7 +288,7 @@ static ssize_t heater_enable_store(struct device *dev,
data->heating_complete = jiffies + msecs_to_jiffies(heating_time_bound);
data->data_pending = true;
- return 0;
+ return count;
}
static ssize_t heater_power_show(struct device *dev,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 333/733] ASoC: bcm: bcm63xx: Publish the OF module aliases
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (331 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 332/733] hwmon: (sht4x) Fix return value from heater_enable_store() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 334/733] ASoC: Intel: SST: Publish the PCI " Greg Kroah-Hartman
` (411 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, hpp.iscas, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: hpp.iscas <hppiscas@163.com>
[ Upstream commit 32689f0fc54fd801f1cd11637666e534984cb04a ]
The BCM63xx I2S platform driver matches brcm,bcm63xx-i2s using
snd_soc_bcm_audio_match. With SND_BCM63XX_I2S_WHISTLER=m, the platform
bus emits an OF modalias but snd-soc-63xx does not publish that table.
Export the existing OF IDs for module autoloading. The PCM companion
and the probe path remain unchanged.
Fixes: 88eb404ccc3e ("ASoC: brcm: Add DSL/PON SoC audio driver")
Signed-off-by: hpp.iscas <hppiscas@163.com>
Link: https://patch.msgid.link/20260905133103.63432-1-hppiscas@163.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/bcm/bcm63xx-i2s-whistler.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/bcm/bcm63xx-i2s-whistler.c b/sound/soc/bcm/bcm63xx-i2s-whistler.c
index c47ed1e6ea2b6..14d111fe29d83 100644
--- a/sound/soc/bcm/bcm63xx-i2s-whistler.c
+++ b/sound/soc/bcm/bcm63xx-i2s-whistler.c
@@ -285,6 +285,7 @@ static const struct of_device_id snd_soc_bcm_audio_match[] = {
{.compatible = "brcm,bcm63xx-i2s"},
{ }
};
+MODULE_DEVICE_TABLE(of, snd_soc_bcm_audio_match);
#endif
static struct platform_driver bcm63xx_i2s_driver = {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 334/733] ASoC: Intel: SST: Publish the PCI module aliases
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (332 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 333/733] ASoC: bcm: bcm63xx: Publish the OF module aliases Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 335/733] btrfs: fix unnecessary transaction commit fallback from btrfs_log_all_parents() Greg Kroah-Hartman
` (410 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, hpp.iscas, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: hpp.iscas <hppiscas@163.com>
[ Upstream commit d112159df5c6cc5ee6ab91cc32bf6ed29939df38 ]
The legacy SST PCI driver matches Intel Tangier devices using
intel_sst_ids, but its only explicit module alias is "sst". That alias
does not match PCI modalias events when this driver is built as a module.
Publish its PCI table. The independently configurable SOF driver does
not provide aliases for the legacy SST module.
Fixes: f533a035e4da ("ASoC: Intel: mrfld - create separate module for pci part")
Signed-off-by: hpp.iscas <hppiscas@163.com>
Link: https://patch.msgid.link/20260905133133.63661-1-hppiscas@163.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/intel/atom/sst/sst_pci.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/intel/atom/sst/sst_pci.c b/sound/soc/intel/atom/sst/sst_pci.c
index 44bb11c694905..1a53c993b57fc 100644
--- a/sound/soc/intel/atom/sst/sst_pci.c
+++ b/sound/soc/intel/atom/sst/sst_pci.c
@@ -167,6 +167,7 @@ static const struct pci_device_id intel_sst_ids[] = {
{ PCI_DEVICE_DATA(INTEL, SST_TNG, 0) },
{ 0, }
};
+MODULE_DEVICE_TABLE(pci, intel_sst_ids);
static struct pci_driver sst_driver = {
.name = SST_DRV_NAME,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 335/733] btrfs: fix unnecessary transaction commit fallback from btrfs_log_all_parents()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (333 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 334/733] ASoC: Intel: SST: Publish the PCI " Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 336/733] netfilter: nfnetlink_log: cope with concurrent instance destruction Greg Kroah-Hartman
` (409 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Boris Burkov, Qu Wenruo,
Filipe Manana, David Sterba, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Filipe Manana <fdmanana@suse.com>
[ Upstream commit 36f9aafa46f5b9fecf92d9218c5574f1ef6b4907 ]
When btrfs_log_all_parents() returns without doing any work (because all
parent directories were already logged), it returns 1, which is propagated
up the fsync call chain up to btrfs_log_dentry_safe(), and that causes
btrfs_sync_file() to trigger am unnecessary transaction commit.
This all happens because the call to btrfs_search_slot() in
btrfs_log_all_parents() always returns 1, as there can not be any inode
ref keys with an offset 0 (an invalid inode number), so if the while loop
below it does not do any work because all parent directories were already
logged, the 'ret' variable remains with a value of 1, which is then
returned up the call chain to btrfs_sync_file().
Fix this by setting 'ret' to 0 after the call to btrfs_search_slot().
Fixes: 0f24ea456ae1 ("btrfs: tracepoints: add trace event for btrfs_log_all_parents()")
Reviewed-by: Boris Burkov <boris@bur.io>
Reviewed-by: Qu Wenruo <wqu@suse.com>
Signed-off-by: Filipe Manana <fdmanana@suse.com>
Signed-off-by: David Sterba <dsterba@suse.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/btrfs/tree-log.c | 16 ++++++++++++++++
1 file changed, 16 insertions(+)
diff --git a/fs/btrfs/tree-log.c b/fs/btrfs/tree-log.c
index 875e4ddc68eae..c87f6a7e8d612 100644
--- a/fs/btrfs/tree-log.c
+++ b/fs/btrfs/tree-log.c
@@ -7307,6 +7307,22 @@ static int btrfs_log_all_parents(struct btrfs_trans_handle *trans,
ret = btrfs_search_slot(NULL, root, &key, path, 0, 0);
if (ret < 0)
goto out;
+ /*
+ * There can't be an inode ref key with offset 0 because inode numbers
+ * start at BTRFS_FIRST_FREE_OBJECTID.
+ */
+ if (WARN_ON_ONCE(ret == 0)) {
+ btrfs_err(trans->fs_info,
+ "found inode ref key with offset 0 for root %llu inode %llu",
+ btrfs_root_id(root), ino);
+ ret = BTRFS_LOG_FORCE_COMMIT;
+ goto out;
+ }
+ /*
+ * Set to 0 so that in case we don't do any work below, we won't return
+ * 1 and trigger an unnecessary transaction commit.
+ */
+ ret = 0;
while (true) {
struct extent_buffer *leaf = path->nodes[0];
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 336/733] netfilter: nfnetlink_log: cope with concurrent instance destruction
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (334 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 335/733] btrfs: fix unnecessary transaction commit fallback from btrfs_log_all_parents() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 337/733] netfilter: ip6_tables: set F_PROTO when proto value is nonzero Greg Kroah-Hartman
` (408 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eulgyu Kim, Jaeyoung Chung,
Florian Westphal, Pablo Neira Ayuso, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit 387d744fa7e499d2c3748a4e60e02ebb24e7fb16 ]
Instances are refcounted. However, only memory release happens on the
1 -> 0 transition; the unlink from hashes can occur with any refcount.
Uncooperative userspace can force a situation where a queue is pending
for destruction from netlink event while a different socket with same
portid processes an UNBIND request.
With right timing, this will unhash the instance again:
Oops: general protection fault, [..]
Call Trace:
<TASK>
nfulnl_recv_config+0x31a/0xd50
nfnetlink_rcv_msg+0x7c2/0xeb0
Fixes: 0597f2680d66 ("[NETFILTER]: Add new "nfnetlink_log" userspace packet logging facility")
Reported-by: Eulgyu Kim <eulgyukim@snu.ac.kr>
Reported-by: Jaeyoung Chung <jjy600901@snu.ac.kr>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/netfilter/nfnetlink_log.c | 13 +++++++++----
1 file changed, 9 insertions(+), 4 deletions(-)
diff --git a/net/netfilter/nfnetlink_log.c b/net/netfilter/nfnetlink_log.c
index 6c7fa2ed34f5c..8fc002ae08bcd 100644
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -228,13 +228,18 @@ static void __nfulnl_flush(struct nfulnl_instance *inst);
static void
__instance_destroy(struct nfulnl_instance *inst)
{
+ spin_lock(&inst->lock);
+ if (inst->copy_mode == NFULNL_COPY_DISABLED) {
+ /* attempt to UNBIND a queue already pending
+ * destruction via netlink close event. Ignore.
+ */
+ spin_unlock(&inst->lock);
+ return;
+ }
+
/* first pull it out of the global list */
hlist_del_rcu(&inst->hlist);
- /* then flush all pending packets from skb */
-
- spin_lock(&inst->lock);
-
/* lockless readers wont be able to use us */
inst->copy_mode = NFULNL_COPY_DISABLED;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 337/733] netfilter: ip6_tables: set F_PROTO when proto value is nonzero
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (335 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 336/733] netfilter: nfnetlink_log: cope with concurrent instance destruction Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 338/733] regulator: pf1550: fix which regulator is notified Greg Kroah-Hartman
` (407 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhiling Zou, Florian Westphal,
Pablo Neira Ayuso, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Florian Westphal <fw@strlen.de>
[ Upstream commit da4afc5a956d407443988e97a4d4ca14c2e999c7 ]
The ip6tables traverser doesn't search the extension header chain unless
userspace did set the IP6T_F_PROTO flag.
This also means that userspace that sets the e->ipv6.proto flag can bypass
the protocol check for the rule by not setting this flag.
That in turn means that all ip6_tables modules and targets that want to
reject rules without '-p' flag MUST also check for that flag.
Not all do, likely because they got copied from iptables which lacks
this flag (no extension headers).
Instead of fixing up all the relevant targets, emulate ip6tables behaviour
in the kernel (like nft_compat.c) and set the flag if the protocol is set.
Reported-by: Zhiling Zou <zhilinz@nebusec.ai>
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/netfilter/ip6_tables.c | 5 +++++
1 file changed, 5 insertions(+)
diff --git a/net/ipv6/netfilter/ip6_tables.c b/net/ipv6/netfilter/ip6_tables.c
index f42fb96ef64b6..313c4aac377aa 100644
--- a/net/ipv6/netfilter/ip6_tables.c
+++ b/net/ipv6/netfilter/ip6_tables.c
@@ -647,6 +647,11 @@ check_entry_size_and_hooks(struct ip6t_entry *e,
/* Clear counters and comefrom */
e->counters = ((struct xt_counters) { 0, 0 });
e->comefrom = 0;
+
+ /* set F_PROTO, else ip6_packet_match won't do the right thing. */
+ if (e->ipv6.proto)
+ e->ipv6.flags |= IP6T_F_PROTO;
+
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 338/733] regulator: pf1550: fix which regulator is notified
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (336 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 337/733] netfilter: ip6_tables: set F_PROTO when proto value is nonzero Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 339/733] ASoC: mt6351: Publish the OF module alias Greg Kroah-Hartman
` (406 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Mark Brown,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
[ Upstream commit f3e6ef13e24c9f26dca0d35de57fcdf04f78e378 ]
The interrupt handler distinguishes the rail that reported the fault, but
the body ignores it. Every SW interrupt walks the regulator array looking
for the name "SW3" and every LDO interrupt looks for "LDO3", so an
over-current on SW1 is reported to the consumers of SW3 while the
consumers of SW1 hear nothing.
The lookup itself is unreliable as well. rdev_get_name() returns the
device tree regulator-name property whenever the board supplies one, and
only falls back to the name in the driver descriptor when it does not.
The binding example for this device sets regulator-name to "sw3" and
"ldo3", which strcmp() does not match against the upper case literals
used here, so a board that follows the documentation gets no over-current
notification at all. A board that names its rails after the schematic
does not match either. No other driver in the tree selects a notification
target this way.
Replace the name lookup with rdev_get_id(), which returns the descriptor
id set by the driver and cannot be overridden from the device tree, and
take both the id and the event from a table indexed by the interrupt.
The die temperature interrupts keep notifying every regulator since they
report a chip wide condition.
Fixes: 7320d41c29bb ("regulator: pf1550: Add support for regulator")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://patch.msgid.link/20260904105624.48577-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/regulator/pf1550-regulator.c | 82 ++++++++++++++--------------
1 file changed, 40 insertions(+), 42 deletions(-)
diff --git a/drivers/regulator/pf1550-regulator.c b/drivers/regulator/pf1550-regulator.c
index 610eac9bb9cb2..ceee553a84b23 100644
--- a/drivers/regulator/pf1550-regulator.c
+++ b/drivers/regulator/pf1550-regulator.c
@@ -283,63 +283,61 @@ static struct pf1550_desc pf1550_regulators[] = {
PF_LDO1(PF1550, "ldo3", LDO3, 0x1f, pf1550_ldo13_volts),
};
+/*
+ * The _LS interrupts indicate an over-current event. The _HS
+ * interrupts, which are more accurate and can detect catastrophic
+ * faults, issue an error event. The current limit FAULT interrupt is
+ * similar to the _HS.
+ */
+static const struct pf1550_regulator_irq {
+ unsigned int event;
+ u8 id;
+} pf1550_regulator_irqs[] = {
+ [PF1550_PMIC_IRQ_SW1_LS] = { REGULATOR_EVENT_OVER_CURRENT_WARN, PF1550_SW1 },
+ [PF1550_PMIC_IRQ_SW2_LS] = { REGULATOR_EVENT_OVER_CURRENT_WARN, PF1550_SW2 },
+ [PF1550_PMIC_IRQ_SW3_LS] = { REGULATOR_EVENT_OVER_CURRENT_WARN, PF1550_SW3 },
+ [PF1550_PMIC_IRQ_SW1_HS] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_SW1 },
+ [PF1550_PMIC_IRQ_SW2_HS] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_SW2 },
+ [PF1550_PMIC_IRQ_SW3_HS] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_SW3 },
+ [PF1550_PMIC_IRQ_LDO1_FAULT] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_LDO1 },
+ [PF1550_PMIC_IRQ_LDO2_FAULT] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_LDO2 },
+ [PF1550_PMIC_IRQ_LDO3_FAULT] = { REGULATOR_EVENT_OVER_CURRENT, PF1550_LDO3 },
+};
+
static irqreturn_t pf1550_regulator_irq_handler(int irq, void *data)
{
+ const struct pf1550_regulator_irq *map;
struct pf1550_regulator_info *info = data;
struct device *dev = info->dev;
struct platform_device *pdev = to_platform_device(dev);
int i, irq_type = -1;
- unsigned int event;
for (i = 0; i < PF1550_REGULATOR_IRQ_NR; i++)
if (irq == platform_get_irq(pdev, i))
irq_type = i;
- switch (irq_type) {
- /* The _LS interrupts indicate over-current event. The _HS interrupts
- * which are more accurate and can detect catastrophic faults, issue
- * an error event. The current limit FAULT interrupt is similar to the
- * _HS'
- */
- case PF1550_PMIC_IRQ_SW1_LS:
- case PF1550_PMIC_IRQ_SW2_LS:
- case PF1550_PMIC_IRQ_SW3_LS:
- event = REGULATOR_EVENT_OVER_CURRENT_WARN;
- for (i = 0; i < PF1550_MAX_REGULATOR; i++)
- if (!strcmp(rdev_get_name(info->rdevs[i]), "SW3"))
- regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- case PF1550_PMIC_IRQ_SW1_HS:
- case PF1550_PMIC_IRQ_SW2_HS:
- case PF1550_PMIC_IRQ_SW3_HS:
- event = REGULATOR_EVENT_OVER_CURRENT;
- for (i = 0; i < PF1550_MAX_REGULATOR; i++)
- if (!strcmp(rdev_get_name(info->rdevs[i]), "SW3"))
- regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- case PF1550_PMIC_IRQ_LDO1_FAULT:
- case PF1550_PMIC_IRQ_LDO2_FAULT:
- case PF1550_PMIC_IRQ_LDO3_FAULT:
- event = REGULATOR_EVENT_OVER_CURRENT;
- for (i = 0; i < PF1550_MAX_REGULATOR; i++)
- if (!strcmp(rdev_get_name(info->rdevs[i]), "LDO3"))
- regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- case PF1550_PMIC_IRQ_TEMP_110:
- case PF1550_PMIC_IRQ_TEMP_125:
- event = REGULATOR_EVENT_OVER_TEMP;
+ /* The die temperature concerns every rail. */
+ if (irq_type == PF1550_PMIC_IRQ_TEMP_110 ||
+ irq_type == PF1550_PMIC_IRQ_TEMP_125) {
for (i = 0; i < PF1550_MAX_REGULATOR; i++)
regulator_notifier_call_chain(info->rdevs[i],
- event, NULL);
- break;
- default:
- dev_err(dev, "regulator interrupt: irq %d occurred\n",
- irq_type);
+ REGULATOR_EVENT_OVER_TEMP,
+ NULL);
+ return IRQ_HANDLED;
+ }
+
+ if (irq_type < 0 || irq_type >= (int)ARRAY_SIZE(pf1550_regulator_irqs)) {
+ dev_err(dev, "regulator interrupt: irq %d occurred\n", irq_type);
+ return IRQ_HANDLED;
}
+ map = &pf1550_regulator_irqs[irq_type];
+
+ for (i = 0; i < PF1550_MAX_REGULATOR; i++)
+ if (rdev_get_id(info->rdevs[i]) == map->id)
+ regulator_notifier_call_chain(info->rdevs[i],
+ map->event, NULL);
+
return IRQ_HANDLED;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 339/733] ASoC: mt6351: Publish the OF module alias
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (337 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 338/733] regulator: pf1550: fix which regulator is notified Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 340/733] irqchip/gic-v5: Preserve ICC_CR0_EL1 state Greg Kroah-Hartman
` (405 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, hpp.iscas, Mark Brown, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: hpp.iscas <hppiscas@163.com>
[ Upstream commit 9c3882ec10399c14c59b7e4599d33c4395367c37 ]
The MT6351 codec platform driver uses mt6351_of_match to bind devices
with compatible mediatek,mt6351-sound. The codec can be a separate
module, but the OF table is not exported to module alias metadata.
Publish the existing table without changing codec matching, register
access or the machine-driver configuration.
Fixes: a74d51ba0e17 ("ASoC: add mt6351 codec driver")
Signed-off-by: hpp.iscas <hppiscas@163.com>
Link: https://patch.msgid.link/20260905133210.63803-1-hppiscas@163.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/soc/codecs/mt6351.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/sound/soc/codecs/mt6351.c b/sound/soc/codecs/mt6351.c
index 1768c249650d8..3be0491a2588c 100644
--- a/sound/soc/codecs/mt6351.c
+++ b/sound/soc/codecs/mt6351.c
@@ -1478,6 +1478,7 @@ static const struct of_device_id mt6351_of_match[] = {
{.compatible = "mediatek,mt6351-sound",},
{}
};
+MODULE_DEVICE_TABLE(of, mt6351_of_match);
static struct platform_driver mt6351_codec_driver = {
.driver = {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 340/733] irqchip/gic-v5: Preserve ICC_CR0_EL1 state
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (338 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 339/733] ASoC: mt6351: Publish the OF module alias Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 341/733] virtio_ring: fix stale descriptor flags after a failed packed add Greg Kroah-Hartman
` (404 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Sascha Bischoff,
Thomas Gleixner, Marc Zyngier, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sascha Bischoff <Sascha.Bischoff@arm.com>
[ Upstream commit 1017911fcc03584b6854b1b8f0aafeb25f5a8d25 ]
In addition to EN, ICC_CR0_EL1 contains other fields, such as LINK and
LINK_IDLE. The driver only needs to modify EN, and must preserve the
values of all other fields when enabling or disabling the CPU
interface.
Define the missing LINK and LINK_IDLE fields, and use read-modify-write
accesses to update EN without affecting the rest of ICC_CR0_EL1.
Fixes: 7ec80fb3f025 ("irqchip/gic-v5: Add GICv5 PPI support")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Signed-off-by: Sascha Bischoff <sascha.bischoff@arm.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://patch.msgid.link/20260907164945.714545-1-sascha.bischoff@arm.com
Closes: https://lore.kernel.org/r/20260807121703.D4B7A1F00A3A@smtp.kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/arm64/tools/sysreg | 4 +++-
drivers/irqchip/irq-gic-v5.c | 6 ++++--
2 files changed, 7 insertions(+), 3 deletions(-)
diff --git a/arch/arm64/tools/sysreg b/arch/arm64/tools/sysreg
index 7cb61aca3797f..03f5e1755a633 100644
--- a/arch/arm64/tools/sysreg
+++ b/arch/arm64/tools/sysreg
@@ -3736,7 +3736,9 @@ Sysreg ICC_CR0_EL1 3 1 12 0 1
Res0 63:39
Field 38 PID
Field 37:32 IPPT
-Res0 31:1
+Res0 31:3
+Field 2 LINK_IDLE
+Field 1 LINK
Field 0 EN
EndSysreg
diff --git a/drivers/irqchip/irq-gic-v5.c b/drivers/irqchip/irq-gic-v5.c
index d6f1c0c8b7473..21c34e7587323 100644
--- a/drivers/irqchip/irq-gic-v5.c
+++ b/drivers/irqchip/irq-gic-v5.c
@@ -974,7 +974,8 @@ static void gicv5_cpu_disable_interrupts(void)
{
u64 cr0;
- cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 0);
+ cr0 = read_sysreg_s(SYS_ICC_CR0_EL1);
+ cr0 &= ~ICC_CR0_EL1_EN_MASK;
write_sysreg_s(cr0, SYS_ICC_CR0_EL1);
isb();
}
@@ -991,7 +992,8 @@ static void gicv5_cpu_enable_interrupts(void)
pcr = FIELD_PREP(ICC_PCR_EL1_PRIORITY, GICV5_IRQ_PRI_MI);
write_sysreg_s(pcr, SYS_ICC_PCR_EL1);
- cr0 = FIELD_PREP(ICC_CR0_EL1_EN, 1);
+ cr0 = read_sysreg_s(SYS_ICC_CR0_EL1);
+ cr0 |= ICC_CR0_EL1_EN_MASK;
write_sysreg_s(cr0, SYS_ICC_CR0_EL1);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 341/733] virtio_ring: fix stale descriptor flags after a failed packed add
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (339 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 340/733] irqchip/gic-v5: Preserve ICC_CR0_EL1 state Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 342/733] virtio: fix use-after-free in unregister_virtio_device() Greg Kroah-Hartman
` (403 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Graf, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Graf <graf@amazon.com>
[ Upstream commit 75d276e5bb68778b2916f98a2bc30f142ebadc64 ]
In a packed ring the AVAIL and USED bits sit in the descriptor itself,
so writing them makes that descriptor available. Those bit combinations
flip meaning on every round of the ring, tracked by a wrap counter, so
invalidating or validating a descriptor means inverting both bits.
Commit 1ce9e6055fa0 ("virtio_ring: introduce packed ring support") has
virtqueue_add_packed() make every descriptor of a chain available as it
maps the chain, and write the head last. The device consumes the ring in
order and stops at a head that is not available yet, so it never reaches
the rest.
When vring_map_one_sg() fails partway, unmap_release unmaps the segments
and restores avail_used_flags, but the descriptors it wrote to in the
ring stay marked with AVAIL and USED bits. The head is now the only
entry that keeps the device from consuming these stale entries.
For example, the ring would look like this now.
Z - pre-previous command
A - previous command
B - aborted command
C - current command
[A1 DONE] [A2 DONE] <C1 EMPTY> [B2] [B3] [Z1 DONE]
When the driver now attempts to issue the C command, the next add starts
at the same head as B. If C spans less descriptors than B, there is no
end marker because AVAIL and USED bits were still in place. And that
means the device will start interpreting these stale entries (B2/B3) as
another command entry, which then blocks the queue.
This effect typically happens in swiotlb configurations under memory
pressure, because vring_map_one_sg() can then fail with larger I/O
requests which then leads to command abortions.
There are broadly 2 ways to avoid leaving those flags behind:
1) Defer those flags too until the chain is complete.
2) Rewrite those flags for the previous wrap counter.
Implement the second option in both packed add paths. The first option
traverses the chain a second time on every successful add. The second
option invalidates all added descriptors when any add fails.
With this patch applied, a packed virtqueue keeps completing requests
after a failed add.
Fixes: 1ce9e6055fa0 ("virtio_ring: introduce packed ring support")
Fixes: f6a15d854986 ("virtio_ring: add in order support")
Assisted-by: Kiro:claude-opus-5 checkpatch sparse
Signed-off-by: Alexander Graf <graf@amazon.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260817223229.28954-1-graf@amazon.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio_ring.c | 38 ++++++++++++++++++++++++++++++++----
1 file changed, 34 insertions(+), 4 deletions(-)
diff --git a/drivers/virtio/virtio_ring.c b/drivers/virtio/virtio_ring.c
index b438dc2ce1b80..a9e1ee9536b5b 100644
--- a/drivers/virtio/virtio_ring.c
+++ b/drivers/virtio/virtio_ring.c
@@ -1670,7 +1670,7 @@ static inline int virtqueue_add_packed(struct vring_virtqueue *vq,
struct scatterlist *sg;
unsigned int i, n, c, descs_used, err_idx, len;
__le16 head_flags, flags;
- u16 head, id, prev, curr, avail_used_flags;
+ u16 head, id, prev, curr, avail_used_flags, unpub_flags;
int err;
START_USE(vq);
@@ -1798,15 +1798,30 @@ static inline int virtqueue_add_packed(struct vring_virtqueue *vq,
curr = vq->free_head;
vq->packed.avail_used_flags = avail_used_flags;
+ unpub_flags = avail_used_flags ^ (1 << VRING_PACKED_DESC_F_AVAIL |
+ 1 << VRING_PACKED_DESC_F_USED);
for (n = 0; n < total_sg; n++) {
if (i == err_idx)
break;
+ /*
+ * The mapping loop made every descriptor but the head
+ * available. Stamp the previous wrap counter's AVAIL and USED
+ * bits on those, so that a later and shorter chain at this head
+ * does not leave one of them available beyond its own last
+ * descriptor. Marking them used instead would hand
+ * is_used_desc_packed() a completion we never made.
+ */
+ if (i != head)
+ desc[i].flags = cpu_to_le16(unpub_flags);
vring_unmap_extra_packed(vq, &vq->packed.desc_extra[curr]);
curr = vq->packed.desc_extra[curr].next;
i++;
- if (i >= vq->packed.vring.num)
+ if (i >= vq->packed.vring.num) {
i = 0;
+ unpub_flags ^= 1 << VRING_PACKED_DESC_F_AVAIL |
+ 1 << VRING_PACKED_DESC_F_USED;
+ }
}
END_USE(vq);
@@ -1828,7 +1843,7 @@ static inline int virtqueue_add_packed_in_order(struct vring_virtqueue *vq,
struct scatterlist *sg;
unsigned int i, n, sg_count, err_idx, total_in_len = 0;
__le16 head_flags, flags;
- u16 head, avail_used_flags;
+ u16 head, avail_used_flags, unpub_flags;
bool avail_wrap_counter;
int err;
@@ -1955,14 +1970,29 @@ static inline int virtqueue_add_packed_in_order(struct vring_virtqueue *vq,
i = head;
vq->packed.avail_used_flags = avail_used_flags;
vq->packed.avail_wrap_counter = avail_wrap_counter;
+ unpub_flags = avail_used_flags ^ (1 << VRING_PACKED_DESC_F_AVAIL |
+ 1 << VRING_PACKED_DESC_F_USED);
for (n = 0; n < total_sg; n++) {
if (i == err_idx)
break;
+ /*
+ * The mapping loop made every descriptor but the head
+ * available. Stamp the previous wrap counter's AVAIL and USED
+ * bits on those, so that a later and shorter chain at this head
+ * does not leave one of them available beyond its own last
+ * descriptor. Marking them used instead would hand
+ * is_used_desc_packed() a completion we never made.
+ */
+ if (i != head)
+ desc[i].flags = cpu_to_le16(unpub_flags);
vring_unmap_extra_packed(vq, &vq->packed.desc_extra[i]);
i++;
- if (i >= vq->packed.vring.num)
+ if (i >= vq->packed.vring.num) {
i = 0;
+ unpub_flags ^= 1 << VRING_PACKED_DESC_F_AVAIL |
+ 1 << VRING_PACKED_DESC_F_USED;
+ }
}
END_USE(vq);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 342/733] virtio: fix use-after-free in unregister_virtio_device()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (340 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 341/733] virtio_ring: fix stale descriptor flags after a failed packed add Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 343/733] virtio_console: do not free control-out buffers on remove Greg Kroah-Hartman
` (402 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 3f9a0fceb730f5107d52421ead5568eae25a0049 ]
device_unregister() is device_del() plus put_device(). When the caller
holds no extra reference, that drops the last one and runs the release
callback, which for several transports frees the memory the embedded
struct virtio_device sits in. unregister_virtio_device() then calls
virtio_debug_device_exit(), which reads dev->debugfs_dir out of the freed
object.
Affected transports are the ones whose release callback frees and whose
remove path takes no reference: virtio_mmio, virtio_vdpa, virtio_uml,
mlxbf-tmfifo and virtio_ccw. virtio_pci is unaffected because
virtio_pci_remove() brackets the call with get_device() and put_device().
Remove the debugfs entries before the device can go away. They are only
accessed through the protected debugfs interface, so
debugfs_remove_recursive() waits for in-progress file operations before
returning. Tearing them down while the device is still alive is therefore
safe.
Reproduced on User-Mode Linux with CONFIG_KASAN and CONFIG_VIRTIO_DEBUG
by unbinding a virtio-uml device:
BUG: KASAN: slab-use-after-free in virtio_debug_device_exit+0x36/0x4d
Read of size 8 at addr 00000000616e0b10 by task init/1
__asan_report_load8_noabort
virtio_debug_device_exit+0x36/0x4d
unregister_virtio_device+0x48/0x75
virtio_uml_remove
platform_remove
device_release_driver_internal
unbind_store
Freed by task 1:
kfree
virtio_uml_release_dev
device_release
kobject_put
put_device
device_unregister
With this applied, the report is gone and unbind is clean.
Fixes: 96a8326d69ff ("virtio: add debugfs infrastructure to allow to debug virtio features")
Assisted-by: Claude:claude-opus-5
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260821213953.76906-1-kmehltretter@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio.c b/drivers/virtio/virtio.c
index 75bb4ffe3b877..b6c9e927bef57 100644
--- a/drivers/virtio/virtio.c
+++ b/drivers/virtio/virtio.c
@@ -604,8 +604,8 @@ void unregister_virtio_device(struct virtio_device *dev)
{
int index = dev->index; /* save for after device release */
- device_unregister(&dev->dev);
virtio_debug_device_exit(dev);
+ device_unregister(&dev->dev);
ida_free(&virtio_index_ida, index);
}
EXPORT_SYMBOL_GPL(unregister_virtio_device);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 343/733] virtio_console: do not free control-out buffers on remove
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (341 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 342/733] virtio: fix use-after-free in unregister_virtio_device() Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 344/733] vhost/vdpa: reject VRING_NUM larger than device max Greg Kroah-Hartman
` (401 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jia Jia, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia Jia <physicalmtea@gmail.com>
[ Upstream commit 894f98e73983f37354214a89a3a7fd35bf9e3072 ]
__send_control_msg() publishes &portdev->cpkt as the control-out
virtqueue cookie. remove_vqs() walks every virtqueue and passes leftover
cookies to free_buf(), which treats them as struct port_buffer and
reads sgpages.
If a control message is still on c_ovq when the device is unbound,
free_buf() reads past the ports_device object.
KASAN reported slab-out-of-bounds in free_buf():
free_buf
remove_vqs
virtcons_remove
unbind_store
The object was the ports_device allocated in virtcons_probe().
Drain c_ovq without freeing. The packet lives in portdev and is released
with it.
Fixes: a7a69ec0d8e4 ("virtio_console: free buffers after reset")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260819021230.292696-1-physicalmtea@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/char/virtio_console.c | 21 ++++++++++++++++++---
1 file changed, 18 insertions(+), 3 deletions(-)
diff --git a/drivers/char/virtio_console.c b/drivers/char/virtio_console.c
index 198b973141680..1ec5b25d1a9ae 100644
--- a/drivers/char/virtio_console.c
+++ b/drivers/char/virtio_console.c
@@ -1891,13 +1891,28 @@ static const struct file_operations portdev_fops = {
static void remove_vqs(struct ports_device *portdev)
{
struct virtqueue *vq;
+ bool multiport = use_multiport(portdev);
virtio_device_for_each_vq(portdev->vdev, vq) {
struct port_buffer *buf;
+ unsigned int len;
- flush_bufs(vq, true);
- while ((buf = virtqueue_detach_unused_buf(vq)))
- free_buf(buf, true);
+ /*
+ * c_ovq cookies are &portdev->cpkt, not port_buffer.
+ * Detach them but do not free_buf().
+ */
+ if (multiport && vq == portdev->c_ovq) {
+ spin_lock(&portdev->c_ovq_lock);
+ while (virtqueue_get_buf(vq, &len))
+ ;
+ while (virtqueue_detach_unused_buf(vq))
+ ;
+ spin_unlock(&portdev->c_ovq_lock);
+ } else {
+ flush_bufs(vq, true);
+ while ((buf = virtqueue_detach_unused_buf(vq)))
+ free_buf(buf, true);
+ }
cond_resched();
}
portdev->vdev->config->del_vqs(portdev->vdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 344/733] vhost/vdpa: reject VRING_NUM larger than device max
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (342 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 343/733] virtio_console: do not free control-out buffers on remove Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 345/733] vhost-vdpa: dont install the eventfd_ctx_fdget() error in config_ctx Greg Kroah-Hartman
` (400 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jia Jia, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia Jia <physicalmtea@gmail.com>
[ Upstream commit ccb1dc7c527f8c925925cf92afc76ae590dac311 ]
vhost_vring_set_num() accepts any non-zero power-of-two queue size that
fits in 16 bits. vhost-vdpa then passes that value to set_vq_num()
without comparing it with get_vq_num_max().
A process with access to /dev/vhost-vdpa-* can therefore configure a
queue larger than the device advertises. With vdpa_sim, the worker can
walk descriptors beyond the mapped descriptor ring. KASAN reports a
16-byte out-of-bounds read, corresponding to one vring_desc, in the
vringh IOTLB path:
BUG: KASAN: out-of-bounds in _copy_from_iter
Read of size 16
copy_from_iotlb
copydesc_iotlb
vringh_getdesc_iotlb
vdpasim_net_work
Cache get_vq_num_max() immediately after reset. Some backends derive
it from writable queue-size state, so querying it after SET_NUM may
return the current size instead of the device capability. Invalidate
the cached value before reset so a failed reset leaves SET_NUM
disabled.
For VHOST_SET_VRING_NUM, copy the complete vring state once and use
the same index and size for validation, vq->num, and set_vq_num().
This ensures that validation and use operate on the same copied values.
Fixes: 4c8cf31885f6 ("vhost: introduce vDPA-based backend")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260810010300.132959-1-physicalmtea@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vdpa.c | 44 +++++++++++++++++++++++++++++++++++++-------
1 file changed, 37 insertions(+), 7 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index c3d913bd7cac7..4eb1eb5e5c79d 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -58,6 +58,7 @@ struct vhost_vdpa {
struct cdev cdev;
atomic_t opened;
u32 nvqs;
+ u16 vq_num_max;
int virtio_id;
int minor;
struct eventfd_ctx *config_ctx;
@@ -236,7 +237,9 @@ static void vhost_vdpa_unsetup_vq_irq(struct vhost_vdpa *v, u16 qid)
static int _compat_vdpa_reset(struct vhost_vdpa *v)
{
struct vdpa_device *vdpa = v->vdpa;
+ const struct vdpa_config_ops *ops = vdpa->config;
u32 flags = 0;
+ int ret;
v->suspended = false;
@@ -246,7 +249,14 @@ static int _compat_vdpa_reset(struct vhost_vdpa *v)
VDPA_RESET_F_CLEAN_MAP : 0;
}
- return vdpa_reset(vdpa, flags);
+ v->vq_num_max = 0;
+ ret = vdpa_reset(vdpa, flags);
+ if (!ret) {
+ /* Some backends derive the max from mutable queue state. */
+ v->vq_num_max = ops->get_vq_num_max(vdpa);
+ }
+
+ return ret;
}
static int vhost_vdpa_reset(struct vhost_vdpa *v)
@@ -648,9 +658,15 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
u32 idx;
long r;
- r = get_user(idx, (u32 __user *)argp);
- if (r < 0)
- return r;
+ if (cmd == VHOST_SET_VRING_NUM) {
+ if (copy_from_user(&s, argp, sizeof(s)))
+ return -EFAULT;
+ idx = s.index;
+ } else {
+ r = get_user(idx, (u32 __user *)argp);
+ if (r < 0)
+ return r;
+ }
if (idx >= v->nvqs)
return -ENOBUFS;
@@ -659,6 +675,23 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
vq = &v->vqs[idx];
switch (cmd) {
+ case VHOST_SET_VRING_NUM:
+ mutex_lock(&vq->mutex);
+ if (vq->private_data) {
+ r = -EBUSY;
+ } else if (!s.num || s.num > 0xffff ||
+ s.num > v->vq_num_max ||
+ (s.num & (s.num - 1))) {
+ r = -EINVAL;
+ } else {
+ vq->num = s.num;
+ r = 0;
+ }
+ mutex_unlock(&vq->mutex);
+ if (r)
+ return r;
+ ops->set_vq_num(vdpa, idx, s.num);
+ return 0;
case VHOST_VDPA_SET_VRING_ENABLE:
if (copy_from_user(&s, argp, sizeof(s)))
return -EFAULT;
@@ -772,9 +805,6 @@ static long vhost_vdpa_vring_ioctl(struct vhost_vdpa *v, unsigned int cmd,
ops->set_vq_cb(vdpa, idx, &cb);
break;
- case VHOST_SET_VRING_NUM:
- ops->set_vq_num(vdpa, idx, vq->num);
- break;
}
return r;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 345/733] vhost-vdpa: dont install the eventfd_ctx_fdget() error in config_ctx
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (343 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 344/733] vhost/vdpa: reject VRING_NUM larger than device max Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 346/733] vhost-vdpa: protect config_ctx from being freed under the config callback Greg Kroah-Hartman
` (399 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yu Zhang, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Zhang <yuz08559@gmail.com>
[ Upstream commit e74a9fa50749b9940b4fb13199652325e08d3c4a ]
vhost_vdpa_set_config_call() swaps the eventfd_ctx_fdget() return value
into v->config_ctx before checking it, so on failure the field briefly
holds an ERR_PTR:
ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
swap(ctx, v->config_ctx);
if (!IS_ERR_OR_NULL(ctx))
eventfd_ctx_put(ctx);
if (IS_ERR(v->config_ctx)) {
long ret = PTR_ERR(v->config_ctx);
v->config_ctx = NULL;
return ret;
}
Commit 0bde59c1723a ("vhost-vdpa: set v->config_ctx to NULL if
eventfd_ctx_fdget() fails") added that clearing, and spelled out the
invariant the rest of the file relies on: "we consider 'v->config_ctx'
valid if it is not NULL". The window between the swap and the clearing
still breaks it. vhost_vdpa_config_cb() only tests for NULL, so a config
interrupt delivered inside the window hands the ERR_PTR to
eventfd_signal().
Check the fd before installing it instead. That closes the window and
matches how vhost_vring_ioctl() handles the same failure for the vq call
fd.
It also stops a rejected fd from tearing down a config interrupt that was
working: until now the swap replaced the live context and put it, so
after an EBADF the device silently stopped delivering config interrupts
until userspace installed a new fd.
Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260807100025.19750-2-yuz08559@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vdpa.c | 12 ++++--------
1 file changed, 4 insertions(+), 8 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 4eb1eb5e5c79d..3e5165b7c094e 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -546,18 +546,14 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
return -EFAULT;
ctx = fd == VHOST_FILE_UNBIND ? NULL : eventfd_ctx_fdget(fd);
+ if (IS_ERR(ctx))
+ return PTR_ERR(ctx);
+
swap(ctx, v->config_ctx);
- if (!IS_ERR_OR_NULL(ctx))
+ if (ctx)
eventfd_ctx_put(ctx);
- if (IS_ERR(v->config_ctx)) {
- long ret = PTR_ERR(v->config_ctx);
-
- v->config_ctx = NULL;
- return ret;
- }
-
v->vdpa->config->set_config_cb(v->vdpa, &cb);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 346/733] vhost-vdpa: protect config_ctx from being freed under the config callback
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (344 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 345/733] vhost-vdpa: dont install the eventfd_ctx_fdget() error in config_ctx Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 347/733] vdpa_sim_blk: reject out-of-range sector starts Greg Kroah-Hartman
` (398 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yu Zhang, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yu Zhang <yuz08559@gmail.com>
[ Upstream commit 62be4e3e5f5f947fbf765b914cebdc478f715d12 ]
vhost_vdpa_config_cb() loads v->config_ctx and signals it without taking
a reference and without holding any lock:
struct eventfd_ctx *config_ctx = v->config_ctx;
if (config_ctx)
eventfd_signal(config_ctx);
VHOST_VDPA_SET_CONFIG_CALL replaces that field and drops what is normally
the last reference to the old context:
swap(ctx, v->config_ctx);
if (ctx)
eventfd_ctx_put(ctx);
eventfd_ctx_put() drops the last kref and frees the context immediately,
with no RCU grace period, so a callback that has already loaded the
pointer goes on to dereference freed memory. The two sides share no
lock: the ioctl runs under vhost_dev.mutex, while the parent invokes the
callback from its own interrupt or workqueue context.
This is not the reopen refcount underflow fixed by commit f6bbf0010ba0
("vhost-vdpa: fix use-after-free of v->config_ctx"), which was about
vhost_vdpa_config_put() leaving a stale pointer behind. Here the pointer
is maintained correctly and it is the read side that is unprotected.
With VDUSE as the parent this is reachable from userspace with access to
/dev/vduse (root by default). VDUSE_DEV_INJECT_CONFIG_IRQ queues
dev->inject, and vduse_dev_irq_inject() runs the callback under VDUSE's
own dev->irq_lock, which vhost does not hold. vduse_dev_reset() does
flush_work(&dev->inject), but VHOST_VDPA_SET_CONFIG_CALL never goes
through reset, so an inject already in flight is not waited for. A
process that injects config interrupts on the VDUSE fd while another
thread swaps the call fd on the vhost-vdpa fd hits it in seconds:
BUG: KASAN: slab-use-after-free in native_queued_spin_lock_slowpath
Read of size 4 at addr ffff888107d21808 by task kworker/u17:1/2993
Workqueue: vduse-irq vduse_dev_irq_inject
Call Trace:
native_queued_spin_lock_slowpath+0x97/0x5b0
_raw_spin_lock_irqsave+0xd4/0xe0
eventfd_signal_mask+0x69/0x120
vhost_vdpa_config_cb+0x34/0x50
vduse_dev_irq_inject+0x46/0x60
process_one_work+0x468/0x950
Allocated by task 2992:
do_eventfd+0x50/0x200
__x64_sys_eventfd2+0x2e/0x40
Freed by task 2992:
eventfd_ctx_put+0xb9/0xc0
vhost_vdpa_unlocked_ioctl+0x116c/0x2190
Add a spinlock covering every access to config_ctx, so the callback
either signals a context that is still alive or observes NULL, and the
put happens only once no callback can reach the old value.
Clearing the parent's callback before the put would not be enough: of the
in-tree set_config_cb() implementations only VDUSE takes a lock, the rest
store the pointer unlocked, so that would not order against an in-flight
invocation.
Fixes: 776f395004d8 ("vhost_vdpa: Support config interrupt in vdpa")
Signed-off-by: Yu Zhang <yuz08559@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260807100025.19750-3-yuz08559@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/vdpa.c | 32 +++++++++++++++++++++++++-------
1 file changed, 25 insertions(+), 7 deletions(-)
diff --git a/drivers/vhost/vdpa.c b/drivers/vhost/vdpa.c
index 3e5165b7c094e..a31786796d4ce 100644
--- a/drivers/vhost/vdpa.c
+++ b/drivers/vhost/vdpa.c
@@ -62,6 +62,8 @@ struct vhost_vdpa {
int virtio_id;
int minor;
struct eventfd_ctx *config_ctx;
+ /* Serialises vhost_vdpa_config_cb() against config_ctx being replaced. */
+ spinlock_t config_lock;
int in_batch;
struct vdpa_iova_range range;
u32 batch_asid;
@@ -195,10 +197,12 @@ static irqreturn_t vhost_vdpa_virtqueue_cb(void *private)
static irqreturn_t vhost_vdpa_config_cb(void *private)
{
struct vhost_vdpa *v = private;
- struct eventfd_ctx *config_ctx = v->config_ctx;
+ unsigned long flags;
- if (config_ctx)
- eventfd_signal(config_ctx);
+ spin_lock_irqsave(&v->config_lock, flags);
+ if (v->config_ctx)
+ eventfd_signal(v->config_ctx);
+ spin_unlock_irqrestore(&v->config_lock, flags);
return IRQ_HANDLED;
}
@@ -528,15 +532,22 @@ static long vhost_vdpa_get_vring_num(struct vhost_vdpa *v, u16 __user *argp)
static void vhost_vdpa_config_put(struct vhost_vdpa *v)
{
- if (v->config_ctx) {
- eventfd_ctx_put(v->config_ctx);
- v->config_ctx = NULL;
- }
+ struct eventfd_ctx *ctx;
+ unsigned long flags;
+
+ spin_lock_irqsave(&v->config_lock, flags);
+ ctx = v->config_ctx;
+ v->config_ctx = NULL;
+ spin_unlock_irqrestore(&v->config_lock, flags);
+
+ if (ctx)
+ eventfd_ctx_put(ctx);
}
static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
{
struct vdpa_callback cb;
+ unsigned long flags;
int fd;
struct eventfd_ctx *ctx;
@@ -549,8 +560,14 @@ static long vhost_vdpa_set_config_call(struct vhost_vdpa *v, u32 __user *argp)
if (IS_ERR(ctx))
return PTR_ERR(ctx);
+ spin_lock_irqsave(&v->config_lock, flags);
swap(ctx, v->config_ctx);
+ spin_unlock_irqrestore(&v->config_lock, flags);
+ /*
+ * The callback can no longer reach the old context, so this is the
+ * last reference to it.
+ */
if (ctx)
eventfd_ctx_put(ctx);
@@ -1639,6 +1656,7 @@ static int vhost_vdpa_probe(struct vdpa_device *vdpa)
}
atomic_set(&v->opened, 0);
+ spin_lock_init(&v->config_lock);
v->minor = minor;
v->vdpa = vdpa;
v->nvqs = vdpa->nvqs;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 347/733] vdpa_sim_blk: reject out-of-range sector starts
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (345 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 346/733] vhost-vdpa: protect config_ctx from being freed under the config callback Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 348/733] vdpa_sim_net: check TX pull result before RX copy Greg Kroah-Hartman
` (397 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linfeng Sun, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linfeng Sun <linfeng.sun.dev@gmail.com>
[ Upstream commit 0a8693f00c408d85f086ad85d29e7030bf1e2055 ]
vdpasim_blk_check_range() logs an invalid start sector but continues
validating the request. The subsequent unsigned capacity subtraction can
underflow and let an out-of-range buffer offset reach the data path.
The invalid offset is used by three request paths. VIRTIO_BLK_T_OUT
copies guest data to blk->buffer + offset through
vringh_iov_pull_iotlb(), causing an out-of-bounds write in
_copy_from_iter() or memcpy(). VIRTIO_BLK_T_IN copies from
blk->buffer + offset to the guest through vringh_iov_push_iotlb(),
causing an out-of-bounds read in _copy_to_iter().
VIRTIO_BLK_T_WRITE_ZEROES passes blk->buffer + offset to memset(),
causing an out-of-bounds write.
Reject starts at or beyond the capacity before the subtraction. Treat the
capacity boundary as invalid because the IN and OUT paths round byte counts
down to sectors for validation but later copy the original byte counts. A
sub-sector request at the capacity boundary would otherwise still access
past the end of the buffer.
I found this bug myself, though the patch was written with AI assistance.
Fixes: 7d189f617f83 ("vdpa_sim_blk: implement ramdisk behaviour")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260901094800.25475-1-linfeng.sun.dev@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/vdpa_sim/vdpa_sim_blk.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
index f70f454dde8eb..76dd5b0828d7a 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_blk.c
@@ -79,10 +79,11 @@ static void vdpasim_blk_buffer_unlock(struct vdpasim_blk *blk)
static bool vdpasim_blk_check_range(struct vdpasim *vdpasim, u64 start_sector,
u64 num_sectors, u64 max_sectors)
{
- if (start_sector > VDPASIM_BLK_CAPACITY) {
+ if (start_sector >= VDPASIM_BLK_CAPACITY) {
dev_dbg(&vdpasim->vdpa.dev,
"starting sector exceeds the capacity - start: 0x%llx capacity: 0x%x\n",
start_sector, VDPASIM_BLK_CAPACITY);
+ return false;
}
if (num_sectors > max_sectors) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 348/733] vdpa_sim_net: check TX pull result before RX copy
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (346 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 347/733] vdpa_sim_blk: reject out-of-range sector starts Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 349/733] virtio-pci: return IRQ_HANDLED after non-zero ISR Greg Kroah-Hartman
` (396 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linfeng Sun, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linfeng Sun <linfeng.sun.dev@gmail.com>
[ Upstream commit 0d195797a80b77f2ec56718cd26d3ee65d0093e8 ]
vringh_iov_pull_iotlb() returns a signed byte count. A failed TX pull is
currently added to the unsigned byte counter and then passed as a size_t
length to receive_filter() and vringh_iov_push_iotlb(). A negative error
can therefore become a large length in the RX path.
Handle non-positive pull results before every length use. Count the TX
error and complete the consumed TX descriptor with zero bytes.
I found this bug myself, though the patch was written with AI assistance.
Fixes: cfe226892913 ("vdpa_sim: filter destination mac address")
Assisted-by: OpenAI-Codex:GPT-5
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260901094842.25875-1-linfeng.sun.dev@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/vdpa_sim/vdpa_sim_net.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
diff --git a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
index 29fd14ce5860b..a6514b5ccd865 100644
--- a/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
+++ b/drivers/vdpa/vdpa_sim/vdpa_sim_net.c
@@ -225,10 +225,15 @@ static void vdpasim_net_work(struct vdpasim *vdpasim)
break;
}
- ++tx_pkts;
read = vringh_iov_pull_iotlb(&txq->vring, &txq->out_iov,
net->buffer, PAGE_SIZE);
+ if (read <= 0) {
+ ++tx_errors;
+ vdpasim_net_complete(txq, 0);
+ continue;
+ }
+ ++tx_pkts;
tx_bytes += read;
if (!receive_filter(vdpasim, read)) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 349/733] virtio-pci: return IRQ_HANDLED after non-zero ISR
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (347 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 348/733] vdpa_sim_net: check TX pull result before RX copy Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 350/733] vduse: validate virtqueue alignment Greg Kroah-Hartman
` (395 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael S. Tsirkin, Andrew Stellman,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Stellman <astellman@stellman-greene.com>
[ Upstream commit 93fa09455fb1a9624b73d42ac1f83771f4818e80 ]
vp_interrupt() reads the ISR before dispatching config-change and
vring handling. Reading the ISR also clears it, so once the read
returns non-zero the interrupt was from this device and has already
been consumed.
Currently vp_interrupt() returns the result of vp_vring_interrupt().
For a config-change interrupt with no vring work, that can return
IRQ_NONE even though the ISR was non-zero and the interrupt was
handled.
Call vp_vring_interrupt() for any queue work, but once the ISR is
non-zero return IRQ_HANDLED.
Tested with QEMU virtio-blk-pci forced to INTx using vectors=0 and
pci=nomsi. On an idle device, 200 config-change interrupts were
generated using QMP block_resize.
Before this change, irq_handler_exit reported ret=unhandled and
/proc/irq/11/spurious increased from 0 to 200 unhandled interrupts.
After this change, irq_handler_exit reported ret=handled and the
unhandled count remained at 0.
The issue was found during an LLM-assisted Quality Playbook review.
Fixes: 77cf524654a8 ("virtio_pci: split up vp_interrupt")
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Assisted-by: LLM
Signed-off-by: Andrew Stellman <astellman@stellman-greene.com>
Message-ID: <20260904141318.30278-1-astellman@stellman-greene.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio_pci_common.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/virtio/virtio_pci_common.c b/drivers/virtio/virtio_pci_common.c
index 10371ecbc054c..b90c174450b20 100644
--- a/drivers/virtio/virtio_pci_common.c
+++ b/drivers/virtio/virtio_pci_common.c
@@ -120,7 +120,9 @@ static irqreturn_t vp_interrupt(int irq, void *opaque)
if (isr & VIRTIO_PCI_ISR_CONFIG)
vp_config_changed(irq, opaque);
- return vp_vring_interrupt(irq, opaque);
+ vp_vring_interrupt(irq, opaque);
+
+ return IRQ_HANDLED;
}
static int vp_request_msix_vectors(struct virtio_device *vdev, int nvectors,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 350/733] vduse: validate virtqueue alignment
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (348 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 349/733] virtio-pci: return IRQ_HANDLED after non-zero ISR Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:10 ` [PATCH 7.2 351/733] vhost: invalidate vring access on IOTLB transitions Greg Kroah-Hartman
` (394 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jia Jia, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia Jia <physicalmtea@gmail.com>
[ Upstream commit fa2c25b4add57888acfa89e398389e267bff3dcf ]
vduse_validate_config() only checks the upper bound of vq_align. Invalid
values can therefore reach vring_create_virtqueue_map(). The split-ring
helpers use align - 1 as a bit mask, so the alignment must be a non-zero
power of two. A zero value makes vring_size() drop the descriptor and
available-ring part and vring_init() leave the used ring pointer NULL.
The VIRTIO spec requires the used ring to start at an address
aligned to at least 4 bytes. Reject values below VRING_USED_ALIGN_SIZE as
well as non-power-of-two values before they reach the virtio ring helpers.
Opening a virtio-net device created with vq_align=0 triggered:
BUG: KASAN: null-ptr-deref in virtqueue_kick_prepare_split+0xe3/0x100
Read of size 2 at addr 0000000000000000 by task systemd-network/1062
Call Trace (relevant frames):
dump_stack_lvl
print_report
kasan_report
__asan_load2
virtqueue_kick_prepare_split+0xe3/0x100
virtqueue_kick_prepare+0x40/0x60
try_fill_recv+0x857/0x1250
virtnet_open+0x189/0x460
__dev_open+0x225/0x390
__dev_change_flags+0x368/0x3b0
netif_change_flags+0x56/0xc0
do_setlink.isra.0+0x68c/0x1e30
Validate the value before it reaches the virtio ring helpers.
Fixes: c8a6153b6c59 ("vduse: Introduce VDUSE - vDPA Device in Userspace")
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260830023354.115333-1-physicalmtea@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/vdpa_user/vduse_dev.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
index 10dcf016bfb06..2ea30f85350d3 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -2094,7 +2094,9 @@ static bool vduse_validate_config(struct vduse_dev_config *config,
return false;
}
- if (config->vq_align > PAGE_SIZE)
+ if (config->vq_align < VRING_USED_ALIGN_SIZE ||
+ !is_power_of_2(config->vq_align) ||
+ config->vq_align > PAGE_SIZE)
return false;
if (config->config_size > PAGE_SIZE)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 351/733] vhost: invalidate vring access on IOTLB transitions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (349 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 350/733] vduse: validate virtqueue alignment Greg Kroah-Hartman
@ 2026-09-17 15:10 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 352/733] virtio_input: reset device if input_register_device() fails Greg Kroah-Hartman
` (393 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:10 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael S. Tsirkin, Jia Jia,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jia Jia <physicalmtea@gmail.com>
[ Upstream commit e4f4761879a230aa59e569102a6ab9851847d833 ]
When VIRTIO_F_ACCESS_PLATFORM changes, cached vring pointers and IOTLB
metadata are interpreted in a different address space. Keeping them
across the transition can leave stale ring mappings in use.
Clearing d->iotlb before taking the VQ locks also lets a worker observe
a transient NULL d->iotlb and fall back to d->umem while translating a
descriptor.
Add a common vhost_clear_device_iotlb() helper for vhost-net and
vhost-vsock. Take all VQ mutexes in index order before dropping the
device-wide IOTLB, invalidate each VQ's cached ring access and metadata,
clear pending IOTLB messages, and free the old table after the handoff.
This serializes the transition with workers and prevents mixed address
space mappings.
On the first direct-to-IOTLB transition, invalidate the cached vring
addresses. When an existing device IOTLB is replaced, preserve the
GIOVA ring addresses and reset only the metadata cache. After clearing
ACCESS_PLATFORM, userspace must configure the vring addresses for the
new address mode.
vhost_vq_invalidate_access() clears desc, avail, and used together.
Treat the VQ as invalidated only when all three are NULL, since a single
GIOVA address may legitimately be zero.
Fixes: 6b1e6cc7855b ("vhost: new device IOTLB API")
Fixes: e13a6915a03f ("vhost/vsock: add IOTLB API support")
Suggested-by: Michael S. Tsirkin <mst@redhat.com>
Signed-off-by: Jia Jia <physicalmtea@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260828085721.57816-1-physicalmtea@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vhost/net.c | 2 ++
drivers/vhost/vhost.c | 57 ++++++++++++++++++++++++++++++++++++++++++-
drivers/vhost/vhost.h | 1 +
drivers/vhost/vsock.c | 2 ++
4 files changed, 61 insertions(+), 1 deletion(-)
diff --git a/drivers/vhost/net.c b/drivers/vhost/net.c
index 38d9c184082d0..4d9d7c2216ed5 100644
--- a/drivers/vhost/net.c
+++ b/drivers/vhost/net.c
@@ -1696,6 +1696,8 @@ static int vhost_net_set_features(struct vhost_net *n, const u64 *features)
if (virtio_features_test_bit(features, VIRTIO_F_ACCESS_PLATFORM)) {
if (vhost_init_device_iotlb(&n->dev))
goto out_unlock;
+ } else {
+ vhost_clear_device_iotlb(&n->dev);
}
for (i = 0; i < VHOST_NET_VQ_MAX; ++i) {
diff --git a/drivers/vhost/vhost.c b/drivers/vhost/vhost.c
index 269efad90369e..f9511be1fa43f 100644
--- a/drivers/vhost/vhost.c
+++ b/drivers/vhost/vhost.c
@@ -344,6 +344,17 @@ static void __vhost_vq_meta_reset(struct vhost_virtqueue *vq)
vq->meta_iotlb[j] = NULL;
}
+/* Caller must hold the virtqueue mutex. */
+static void vhost_vq_invalidate_access(struct vhost_virtqueue *vq)
+{
+ vq->desc = NULL;
+ vq->avail = NULL;
+ vq->used = NULL;
+ vq->log_used = false;
+ vq->log_addr = -1ull;
+ __vhost_vq_meta_reset(vq);
+}
+
static void vhost_vq_meta_reset(struct vhost_dev *d)
{
int i;
@@ -1914,6 +1925,13 @@ int vq_meta_prefetch(struct vhost_virtqueue *vq)
{
unsigned int num = vq->num;
+ /*
+ * vhost_vq_invalidate_access() clears all three addresses together.
+ * A single zero address may be a valid GIOVA in IOTLB mode.
+ */
+ if (!vq->desc && !vq->avail && !vq->used)
+ return 0;
+
if (!vq->iotlb)
return 1;
@@ -2283,6 +2301,40 @@ long vhost_vring_ioctl(struct vhost_dev *d, unsigned int ioctl, void __user *arg
}
EXPORT_SYMBOL_GPL(vhost_vring_ioctl);
+/* Caller must hold the device mutex. */
+void vhost_clear_device_iotlb(struct vhost_dev *d)
+{
+ struct vhost_iotlb *iotlb;
+ int i;
+
+ iotlb = d->iotlb;
+ if (!iotlb)
+ return;
+
+ vhost_dev_lock_vqs(d);
+
+ /*
+ * vhost_dev_lock_vqs() takes all VQ mutexes in index order. Drop the
+ * device-wide view while they are held, then clear each per-VQ view
+ * and its cached ring access before releasing the locks. Workers
+ * cannot observe a mixed address-space state during this handoff.
+ */
+ d->iotlb = NULL;
+
+ for (i = 0; i < d->nvqs; ++i) {
+ struct vhost_virtqueue *vq = d->vqs[i];
+
+ vq->iotlb = NULL;
+ vhost_vq_invalidate_access(vq);
+ }
+
+ vhost_dev_unlock_vqs(d);
+ vhost_clear_msg(d);
+ vhost_iotlb_free(iotlb);
+ wake_up_interruptible_poll(&d->wait, EPOLLIN | EPOLLRDNORM);
+}
+EXPORT_SYMBOL_GPL(vhost_clear_device_iotlb);
+
int vhost_init_device_iotlb(struct vhost_dev *d)
{
struct vhost_iotlb *niotlb, *oiotlb;
@@ -2303,7 +2355,10 @@ int vhost_init_device_iotlb(struct vhost_dev *d)
mutex_lock(&vq->mutex);
vq->iotlb = niotlb;
- __vhost_vq_meta_reset(vq);
+ if (oiotlb)
+ __vhost_vq_meta_reset(vq);
+ else
+ vhost_vq_invalidate_access(vq);
mutex_unlock(&vq->mutex);
}
diff --git a/drivers/vhost/vhost.h b/drivers/vhost/vhost.h
index 0192ade6e7491..3c75e80893730 100644
--- a/drivers/vhost/vhost.h
+++ b/drivers/vhost/vhost.h
@@ -277,6 +277,7 @@ ssize_t vhost_chr_read_iter(struct vhost_dev *dev, struct iov_iter *to,
int noblock);
ssize_t vhost_chr_write_iter(struct vhost_dev *dev,
struct iov_iter *from);
+void vhost_clear_device_iotlb(struct vhost_dev *d);
int vhost_init_device_iotlb(struct vhost_dev *d);
void vhost_iotlb_map_free(struct vhost_iotlb *iotlb,
diff --git a/drivers/vhost/vsock.c b/drivers/vhost/vsock.c
index 9aaab6bb8061c..abed1fbcf66cc 100644
--- a/drivers/vhost/vsock.c
+++ b/drivers/vhost/vsock.c
@@ -868,6 +868,8 @@ static int vhost_vsock_set_features(struct vhost_vsock *vsock, u64 features)
if ((features & (1ULL << VIRTIO_F_ACCESS_PLATFORM))) {
if (vhost_init_device_iotlb(&vsock->dev))
goto err;
+ } else {
+ vhost_clear_device_iotlb(&vsock->dev);
}
vsock->seqpacket_allow = features & (1ULL << VIRTIO_VSOCK_F_SEQPACKET);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 352/733] virtio_input: reset device if input_register_device() fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (350 preceding siblings ...)
2026-09-17 15:10 ` [PATCH 7.2 351/733] vhost: invalidate vring access on IOTLB transitions Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 353/733] virtio_input: stop callbacks before unregistering input device Greg Kroah-Hartman
` (392 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xiong Weimin, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiong Weimin <xiongweimin@kylinos.cn>
[ Upstream commit 81489b32a21c9360f8750d1fb600155d27452e19 ]
Probe marks the device DRIVER_OK with virtio_device_ready() before
calling input_register_device(). If registration fails, the error path
cleared vi->ready and called del_vqs() while the device was still live,
so the device could keep DMA to queues that were already torn down.
Match remove/freeze: call virtio_reset_device() on that path before
tearing down the virtqueues.
Fixes: 271c865161c5 ("Add virtio-input driver.")
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260805032931.1606652-1-xiongweimin@kylinos.cn>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio_input.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
index deec24e8e6828..1a87be4c88cf5 100644
--- a/drivers/virtio/virtio_input.c
+++ b/drivers/virtio/virtio_input.c
@@ -331,6 +331,7 @@ static int virtinput_probe(struct virtio_device *vdev)
spin_lock_irqsave(&vi->lock, flags);
vi->ready = false;
spin_unlock_irqrestore(&vi->lock, flags);
+ virtio_reset_device(vdev);
err_mt_init_slots:
input_free_device(vi->idev);
err_input_alloc:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 353/733] virtio_input: stop callbacks before unregistering input device
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (351 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 352/733] virtio_input: reset device if input_register_device() fails Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 354/733] af_unix: Update last skb marker in manage_oob() Greg Kroah-Hartman
` (391 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit d7808b37da0a619cf1fa541c2384e783fecc2480 ]
virtinput_remove() unregisters the input device before resetting the
virtio device. virtinput_recv_events() drops vi->lock around input_event(),
so clearing vi->ready does not stop a callback that passed the entry check.
It can still use vi->idev, requeue buffers and kick the queue.
Reset first, as virtinput_freeze() already does. With the preceding core
change, reset waits for callbacks before input_unregister_device() can
free vi->idev. Recheck vi->ready after taking the lock again: keep draining
completed events so an input packet is not truncated, but stop requeueing
buffers and kicking the queue.
With evdev attached, input_unregister_handle() currently waits for an RCU
grace period, which also waits out IRQ callbacks. This masks the lifetime
bug on PCI and MMIO, but does not protect sleepable callbacks on other
transports.
Fixes: 271c865161c5 ("Add virtio-input driver.")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260905152059.89560-3-kmehltretter@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/virtio/virtio_input.c | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/drivers/virtio/virtio_input.c b/drivers/virtio/virtio_input.c
index 1a87be4c88cf5..e3bd0b9616f94 100644
--- a/drivers/virtio/virtio_input.c
+++ b/drivers/virtio/virtio_input.c
@@ -49,9 +49,12 @@ static void virtinput_recv_events(struct virtqueue *vq)
le16_to_cpu(event->code),
le32_to_cpu(event->value));
spin_lock_irqsave(&vi->lock, flags);
+ if (!vi->ready)
+ continue;
virtinput_queue_evtbuf(vi, event);
}
- virtqueue_kick(vq);
+ if (vi->ready)
+ virtqueue_kick(vq);
}
spin_unlock_irqrestore(&vi->lock, flags);
}
@@ -351,8 +354,9 @@ static void virtinput_remove(struct virtio_device *vdev)
vi->ready = false;
spin_unlock_irqrestore(&vi->lock, flags);
- input_unregister_device(vi->idev);
+ /* Callbacks use vi->idev. */
virtio_reset_device(vdev);
+ input_unregister_device(vi->idev);
while ((buf = virtqueue_detach_unused_buf(vi->sts)) != NULL)
kfree(buf);
vdev->config->del_vqs(vdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 354/733] af_unix: Update last skb marker in manage_oob().
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (352 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 353/733] virtio_input: stop callbacks before unregistering input device Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 355/733] af_unix: Return immediately when manage_oob() returns NULL for 0-length buffer Greg Kroah-Hartman
` (390 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fahad Alharbi, Kuniyuki Iwashima,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 94fd4debd2e3a69cf93e766c8b328a810c228119 ]
Fahad Alharbi reported that blocking recv(MSG_PEEK) could hog CPU
due to OOB skb.
In the following cases, manage_oob() skips OOB skb(s) and returns
NULL for the last recv(MSG_PEEK):
socketpair(AF_UNIX, SOCK_STREAM, 0, sk);
1) skb -> OOB skb -> NULL
send(sk[0], "ab", 2, MSG_OOB);
recv(sk[1], buf, 0, MSG_PEEK);
2) skb -> consumed OOB skb -> NULL
send(sk[0], "ab", 2, MSG_OOB);
recv(sk[1], buf, 1, MSG_OOB);
recv(sk[1], buf, 0, MSG_PEEK);
3) consumed OOB skb -> OOB skb -> NULL
send(sk[0], "a", 1, MSG_OOB);
recv(sk[1], buf, 0, MSG_OOB);
send(sk[0], "b", 1, MSG_OOB);
recv(sk[1], buf, 1, MSG_PEEK);
Then, @copied is 0 in unix_stream_read_generic() (zero-length buffer,
or non-OOB skb is not yet consumed), and unix_stream_data_wait() is
called.
However, it returns immediately because @last is not updated in
unix_stream_read_generic(), and the thread busy-waits for a new skb.
Let's update @last in manage_oob().
For MSG_PEEK, @last is updated with the skipped OOB, and for the
non-peek case, @last matches the returned value (when !copied)
because OOB is unlinked.
Note that manage_oob() is inlined and no stack canary is added.
Fixes: 22dd70eb2c3d ("af_unix: Don't peek OOB data without MSG_OOB.")
Reported-by: Fahad Alharbi <fahad@codepure.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260902202202.892676-2-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/unix/af_unix.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 10ed9421e43aa..4eb086992ae5e 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2805,8 +2805,8 @@ static int unix_stream_recv_urg(struct unix_stream_read_state *state)
return 1;
}
-static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
- int flags, int copied)
+static struct sk_buff *manage_oob(struct sk_buff *skb, struct sk_buff **last,
+ struct sock *sk, int flags, int copied)
{
struct sk_buff *read_skb = NULL, *unread_skb = NULL;
struct unix_sock *u = unix_sk(sk);
@@ -2820,11 +2820,13 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
if (copied && (!u->oob_skb || skb == u->oob_skb)) {
skb = NULL;
} else if (flags & MSG_PEEK) {
+ *last = skb;
skb = skb_peek_next(skb, &sk->sk_receive_queue);
} else {
read_skb = skb;
skb = skb_peek_next(skb, &sk->sk_receive_queue);
__skb_unlink(read_skb, &sk->sk_receive_queue);
+ *last = skb;
}
if (!skb)
@@ -2843,8 +2845,10 @@ static struct sk_buff *manage_oob(struct sk_buff *skb, struct sock *sk,
__skb_unlink(skb, &sk->sk_receive_queue);
unread_skb = skb;
skb = skb_peek(&sk->sk_receive_queue);
+ *last = skb;
}
} else if (!sock_flag(sk, SOCK_URGINLINE)) {
+ *last = skb;
skb = skb_peek_next(skb, &sk->sk_receive_queue);
}
@@ -2964,7 +2968,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
again:
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
if (skb) {
- skb = manage_oob(skb, sk, flags, copied);
+ skb = manage_oob(skb, &last, sk, flags, copied);
if (!skb && copied) {
unix_state_unlock(sk);
break;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 355/733] af_unix: Return immediately when manage_oob() returns NULL for 0-length buffer.
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (353 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 354/733] af_unix: Update last skb marker in manage_oob() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 356/733] net: ipv4: Fix UDP length overflow with PMTU discover and big MTU Greg Kroah-Hartman
` (389 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Fahad Alharbi, Kuniyuki Iwashima,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit 6e5ee08eb5858d175da6768d75d163817b6a9d4a ]
Fahad Alharbi reported that recv(0, MSG_PEEK) triggers busy-wait
in unix_stream_read_generic() if recv() is blocking and the last
skb in the queue is MSG_OOB skb.
In such a situation, TCP returns 0 immediately regardless of
blocking or non-blocking.
Let's follow the behaviour.
Fixes: 314001f0bf92 ("af_unix: Add OOB support")
Reported-by: Fahad Alharbi <fahad@codepure.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260902202202.892676-3-kuniyu@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/unix/af_unix.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/unix/af_unix.c b/net/unix/af_unix.c
index 4eb086992ae5e..c7a03b01119d7 100644
--- a/net/unix/af_unix.c
+++ b/net/unix/af_unix.c
@@ -2969,7 +2969,7 @@ static int unix_stream_read_generic(struct unix_stream_read_state *state,
#if IS_ENABLED(CONFIG_AF_UNIX_OOB)
if (skb) {
skb = manage_oob(skb, &last, sk, flags, copied);
- if (!skb && copied) {
+ if (!skb && (copied || !state->size)) {
unix_state_unlock(sk);
break;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 356/733] net: ipv4: Fix UDP length overflow with PMTU discover and big MTU
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (354 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 355/733] af_unix: Return immediately when manage_oob() returns NULL for 0-length buffer Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 357/733] net: ipv6: " Greg Kroah-Hartman
` (388 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ce13c07d96d04716eaa2,
Alice Mikityanska, Willem de Bruijn, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alice Mikityanska <alice@isovalent.com>
[ Upstream commit b83641e0ab8b20eefcc4cdc5a059f897375291a2 ]
This commit bounds cork->base.fragsize to IP_MAX_MTU to avoid a
possible overflow of UDP length that triggers a WARN in
udp_set_len_short when setsockopt IP_MTU_DISCOVER is set to
IP_PMTUDISC_PROBE, and a large packet is sent over a netdev with an
unusually large MTU.
Steps to reproduce:
1. Set device MTU bigger than IP_MAX_MTU + 20. cork->base.fragsize will
be set to that MTU in ip_setup_cork.
2. Set IP_MTU_DISCOVER to IP_PMTUDISC_PROBE. It lets maxnonfragsize be
set to device MTU (cork->fragsize) in __ip_append_data, rather than
to IP_MAX_MTU.
3. Send 65528 bytes of payload (+8 bytes of UDP header, +20 bytes of
IPv4 header). Device MTU allows it (it's only one byte bigger than
IP_MAX_MTU + IPv4 header, and the device MTU is bigger than that).
4. The UDP length in the built packet is 65536, which overflows the
16-bit length field and triggers the WARN in udp_set_len_short.
Note: IP_PMTUDISC_DO with IPv4 is safe, because ip_dst_mtu_maybe_forward
always clamps at IP_MAX_MTU, unlike ip6_dst_mtu_maybe_forward.
The Fixes tag points at the first commit where I could reproduce the
overflow with IPv4 and IP_PMTUDISC_PROBE.
Fixes: daba287b299e ("ipv4: fix DO and PROBE pmtu mode regarding local fragmentation with UFO/CORK")
Reported-by: syzbot+ce13c07d96d04716eaa2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a6a966c.86abc875.e5c3d.0054.GAE@google.com/
Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260901195714.673548-2-alice.kernel@fastmail.im
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv4/ip_output.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/ipv4/ip_output.c b/net/ipv4/ip_output.c
index 74e095b6b7ca0..a24cc8ee11d3e 100644
--- a/net/ipv4/ip_output.c
+++ b/net/ipv4/ip_output.c
@@ -1303,6 +1303,7 @@ static int ip_setup_cork(struct sock *sk, struct inet_cork *cork,
cork->fragsize = ip_sk_use_pmtu(sk) ?
dst4_mtu(&rt->dst) : READ_ONCE(rt->dst.dev->mtu);
+ cork->fragsize = min(cork->fragsize, IP_MAX_MTU);
if (!inetdev_valid_mtu(cork->fragsize))
return -ENETUNREACH;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 357/733] net: ipv6: Fix UDP length overflow with PMTU discover and big MTU
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (355 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 356/733] net: ipv4: Fix UDP length overflow with PMTU discover and big MTU Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 358/733] net: ipv6: Clamp to IP6_MAX_MTU in ip6_dst_mtu_maybe_forward Greg Kroah-Hartman
` (387 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+ce13c07d96d04716eaa2,
Alice Mikityanska, Willem de Bruijn, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alice Mikityanska <alice@isovalent.com>
[ Upstream commit 0ae10b6be49b425827659b23bcce498f80eb7182 ]
This commit bounds cork->base.fragsize to IP6_MAX_MTU for UDP sockets to
avoid a possible overflow of UDP length that triggers a WARN in
udp_set_len_short when setsockopt IPV6_MTU_DISCOVER is set to
IPV6_PMTUDISC_DO or IPV6_PMTUDISC_PROBE, and a large packet is sent over
a netdev with an unusually large MTU.
Steps to reproduce (included in the new selftest):
1. Set device MTU bigger than IP6_MAX_MTU. cork->base.fragsize will be
set to that MTU in ip6_setup_cork.
2. Set IPV6_MTU_DISCOVER to IPV6_PMTUDISC_PROBE or IPV6_PMTUDISC_DO. It
lets maxnonfragsize be set to device MTU (cork->fragsize) in
__ip6_append_data, rather than to IP6_MAX_MTU.
3. Send 65528 bytes of payload (+8 bytes of UDP header, +40 bytes of
IPv6 header). Device MTU allows it (it's only one byte bigger than
IP6_MAX_MTU, and the device MTU is bigger than that).
4. The UDP length in the built packet is 65536, which overflows the
16-bit length field and triggers the WARN in udp_set_len_short.
To avoid breaking sending UDP jumbograms over raw IPv6 sockets, limit
the change to UDP sockets only.
The original overflow bug with IPv6 and IPV6_PMTUDISC_DO seems to
predate git history (verified reproduction on 2.6.21), was fixed later,
and then reappeared in commit 427faee167bc ("net: ipv6: introduce
ip6_dst_mtu_maybe_forward"), which is chosen as the Fixes tag here. The
overflow with IPV6_PMTUDISC_PROBE reproduces since its introduction in
commit 628a5c561890 ("[INET]: Add IP(V6)_PMTUDISC_RPOBE").
Fixes: 427faee167bc ("net: ipv6: introduce ip6_dst_mtu_maybe_forward")
Reported-by: syzbot+ce13c07d96d04716eaa2@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a6a966c.86abc875.e5c3d.0054.GAE@google.com/
Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260901195714.673548-3-alice.kernel@fastmail.im
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/ip6_output.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 8fc4766c8da90..5509650589915 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1432,6 +1432,8 @@ static int ip6_setup_cork(struct sock *sk, struct inet_cork_full *cork,
if (frag_size && frag_size < mtu)
mtu = frag_size;
+ if (sk_is_udp(sk))
+ mtu = min(mtu, IP6_MAX_MTU);
cork->base.fragsize = mtu;
cork->base.gso_size = ipc6->gso_size;
cork->base.tx_flags = 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 358/733] net: ipv6: Clamp to IP6_MAX_MTU in ip6_dst_mtu_maybe_forward
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (356 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 357/733] net: ipv6: " Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 359/733] vduse: return compat ioctl results directly Greg Kroah-Hartman
` (386 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alice Mikityanska, Willem de Bruijn,
Willem de Bruijn, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alice Mikityanska <alice@isovalent.com>
[ Upstream commit 199271ebc71c1e0913b2fad988a7bff330a8828a ]
Commit 427faee167bc ("net: ipv6: introduce ip6_dst_mtu_maybe_forward")
dropped the IP6_MAX_MTU clamp that used to be present in ip6_mtu(). A
similar IPv4 commit ac6627a28dbf ("net: ipv4: Consolidate ipv4_mtu and
ip_dst_mtu_maybe_forward") preserves the IP_MAX_MTU clamp.
Restore the upper bound in the IPv6 flow to avoid potential 16-bit
overflows in forwarding paths.
Fixes: 427faee167bc ("net: ipv6: introduce ip6_dst_mtu_maybe_forward")
Signed-off-by: Alice Mikityanska <alice@isovalent.com>
Suggested-by: Willem de Bruijn <willemdebruijn.kernel@gmail.com>
Reviewed-by: Willem de Bruijn <willemb@google.com>
Link: https://patch.msgid.link/20260901195714.673548-5-alice.kernel@fastmail.im
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/net/ip6_route.h | 2 ++
1 file changed, 2 insertions(+)
diff --git a/include/net/ip6_route.h b/include/net/ip6_route.h
index ac1acc0b74368..745ab62154ace 100644
--- a/include/net/ip6_route.h
+++ b/include/net/ip6_route.h
@@ -382,6 +382,8 @@ static inline unsigned int ip6_dst_mtu_maybe_forward(const struct dst_entry *dst
rcu_read_unlock();
out:
+ mtu = min_t(unsigned int, mtu, IP6_MAX_MTU);
+
return mtu - lwtunnel_headroom(dst->lwtstate, mtu);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 359/733] vduse: return compat ioctl results directly
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (357 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 358/733] net: ipv6: Clamp to IP6_MAX_MTU in ip6_dst_mtu_maybe_forward Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 360/733] net: macb: zero the link settings taprio reads back Greg Kroah-Hartman
` (385 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Linfeng Sun, Michael S. Tsirkin,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linfeng Sun <linfeng.sun.dev@gmail.com>
[ Upstream commit 48a4ee65e677559776349128e6a81a6041986c99 ]
The compat handler handles VDUSE_IOTLB_GET_FD and VDUSE_VQ_GET_INFO, but
then calls the native handler. Their different command sizes make native
dispatch return -ENOIOCTLCMD.
For GET_FD, this overwrites receive_fd()'s return value after the
descriptor is installed, leaking one fd per call. Return handled compat
results directly and use native dispatch only for other commands.
Fixes: 455a2a1af926 ("vduse: fix compat handling for VDUSE_IOTLB_GET_FD/VDUSE_VQ_GET_INFO")
Signed-off-by: Linfeng Sun <linfeng.sun.dev@gmail.com>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260908-fix-vduse_dev_compat_ioctl-v1-1-62264d9bfb8d@gmail.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/vdpa/vdpa_user/vduse_dev.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/vdpa/vdpa_user/vduse_dev.c b/drivers/vdpa/vdpa_user/vduse_dev.c
index 2ea30f85350d3..ed71e5835e60c 100644
--- a/drivers/vdpa/vdpa_user/vduse_dev.c
+++ b/drivers/vdpa/vdpa_user/vduse_dev.c
@@ -1751,11 +1751,11 @@ static long vduse_dev_compat_ioctl(struct file *file, unsigned int cmd,
break;
}
default:
- ret = -ENOIOCTLCMD;
- break;
+ return vduse_dev_ioctl(file, cmd,
+ (unsigned long)compat_ptr(arg));
}
- return vduse_dev_ioctl(file, cmd, (unsigned long)compat_ptr(arg));
+ return ret;
}
#else
#define vduse_dev_compat_ioctl compat_ptr_ioctl
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 360/733] net: macb: zero the link settings taprio reads back
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (358 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 359/733] vduse: return compat ioctl results directly Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 361/733] net: macb: reject an unknown link speed in the taprio setup Greg Kroah-Hartman
` (384 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Sviridkin <f@lex.la>
[ Upstream commit 0523d5c52a450590bf5992bd6925394f3cc403e8 ]
macb_taprio_setup_replace() calls phylink_ethtool_ksettings_get() with
an uninitialised kset, and kset is not only an out-parameter. On a
fixed link, or an in-band link with no PHY, phylink writes speed and
duplex only if kset->base.rate_matching already reads RATE_MATCH_NONE,
a field it never writes itself; in PHY mode before the PHY is attached
it writes port and supported and nothing more. Either way the speed
read back afterwards can be stack garbage. The ethtool core zeroes the
structure on every path into the op, which is why its callers never
see this; taprio is the only in-kernel caller passing its own variable.
Fixes: 89934dbf169e ("net: macb: Add TAPRIO traffic scheduling support")
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260903123652.23900-2-f@lex.la
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index cd140f98cbc83..09fd83782ae3f 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4331,9 +4331,9 @@ static int macb_taprio_setup_replace(struct net_device *netdev,
u64 total_on_time = 0, start_time_sec = 0, start_time = conf->base_time;
u32 configured_queues = 0, speed = 0, start_time_nsec;
struct macb_queue_enst_config *enst_queue;
- struct tc_taprio_sched_entry *entry;
+ struct ethtool_link_ksettings kset = {};
struct macb *bp = netdev_priv(netdev);
- struct ethtool_link_ksettings kset;
+ struct tc_taprio_sched_entry *entry;
struct macb_queue *queue;
u32 queue_mask;
u8 queue_id;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 361/733] net: macb: reject an unknown link speed in the taprio setup
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (359 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 360/733] net: macb: zero the link settings taprio reads back Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 362/733] net: ethernet: cortina: Fix budget accounting Greg Kroah-Hartman
` (383 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Sviridkin <f@lex.la>
[ Upstream commit 2b6c0e25a3d713c4032e45f212bdd9e14c50f8a0 ]
speed is a u32, so SPEED_UNKNOWN arrives as 0xffffffff and passes the
"speed <= 0" check, which only ever catches zero. That is what an
autonegotiating link reports while it is down: the limit derived from
the speed collapses to a nanosecond at most and the first entry fails
with a misleading "exceeds hardware limit". Zero stays covered, it is
what an interface that was never opened reports, and
enst_max_hw_interval() divides by it. Say which case it was in the
error.
Fixes: 89934dbf169e ("net: macb: Add TAPRIO traffic scheduling support")
Assisted-by: LLM
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260903123652.23900-3-f@lex.la
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb_main.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 09fd83782ae3f..55ed40a0a6062 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -4360,8 +4360,8 @@ static int macb_taprio_setup_replace(struct net_device *netdev,
}
speed = kset.base.speed;
- if (unlikely(speed <= 0)) {
- netdev_err(netdev, "Invalid speed: %d\n", speed);
+ if (unlikely(speed == SPEED_UNKNOWN || !speed)) {
+ netdev_err(netdev, "Invalid speed %d, link-down?\n", speed);
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 362/733] net: ethernet: cortina: Fix budget accounting
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (360 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 361/733] net: macb: reject an unknown link speed in the taprio setup Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 363/733] net: ethernet: cortina: Finish RX updates before NAPI completion Greg Kroah-Hartman
` (382 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joe Damato, Linus Walleij,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit a0de06d0da78a3db53de65dfd7452cc6d111f703 ]
The gmac_rx() function returns the remaining NAPI budget, but its
caller treats the return value as the number of packets received. An
idle poll therefore reports a full budget and remains scheduled.
Return the number of received packets instead. Preserve the existing
free queue refill accounting by adding that count directly; continuing
to subtract it from the budget would invert the refill behavior.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Link: https://lore.kernel.org/r/20260509-gemini-ethernet-fixes-v1-4-6c5d20ddc35b@kernel.org
Link: https://lore.kernel.org/r/20260512131456.189452-1-pabeni@redhat.com
Assisted-by: LLM
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260903-gemini-ethernet-fixes-v2-1-2bbbd598ca6e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 4c762229ce420..1d9824d1716cf 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1450,6 +1450,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
unsigned int frame_len, frag_len;
struct gmac_rxdesc *rx = NULL;
struct gmac_queue_page *gpage;
+ unsigned int received = 0;
union gmac_rxdesc_0 word0;
union gmac_rxdesc_1 word1;
union gmac_rxdesc_3 word3;
@@ -1545,7 +1546,8 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
napi_gro_frags(&port->napi);
skb = NULL;
frag_nr = 0;
- --budget;
+ budget--;
+ received++;
}
continue;
@@ -1565,7 +1567,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
port->rx_skb = skb;
port->rx_frag_nr = frag_nr;
writew(r, ptr_reg);
- return budget;
+ return received;
}
static int gmac_napi_poll(struct napi_struct *napi, int budget)
@@ -1586,7 +1588,7 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget)
++port->rx_napi_exits;
}
- port->freeq_refill += (budget - received);
+ port->freeq_refill += received;
if (port->freeq_refill > freeq_threshold) {
port->freeq_refill -= freeq_threshold;
geth_fill_freeq(geth, true);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 363/733] net: ethernet: cortina: Finish RX updates before NAPI completion
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (361 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 362/733] net: ethernet: cortina: Fix budget accounting Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 364/733] net: ethernet: cortina: Count dropped frames as NAPI work Greg Kroah-Hartman
` (381 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joe Damato, Linus Walleij,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit baa26841cb9a2cdc7e0e99d6854a4e3359bf7393 ]
napi_complete_done() releases ownership of the NAPI instance, but the
Gemini poll keeps the RX statistics writer section open and updates the
free queue after calling it. A new poll can therefore start while the old
writer is still active.
Finish the statistics and free queue updates before releasing ownership.
Only re-enable RX interrupts when napi_complete_done() reports successful
completion.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Suggested-by: Joe Damato <joe@dama.to>
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260903-gemini-ethernet-fixes-v2-2-2bbbd598ca6e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 1d9824d1716cf..6502220362cbd 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1581,12 +1581,10 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget)
u64_stats_update_begin(&port->rx_stats_syncp);
received = gmac_rx(napi->dev, budget);
- if (received < budget) {
- napi_gro_flush(napi, false);
- napi_complete_done(napi, received);
- gmac_enable_rx_irq(napi->dev, 1);
+ if (received < budget)
++port->rx_napi_exits;
- }
+
+ u64_stats_update_end(&port->rx_stats_syncp);
port->freeq_refill += received;
if (port->freeq_refill > freeq_threshold) {
@@ -1594,7 +1592,9 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget)
geth_fill_freeq(geth, true);
}
- u64_stats_update_end(&port->rx_stats_syncp);
+ if (received < budget && napi_complete_done(napi, received))
+ gmac_enable_rx_irq(napi->dev, 1);
+
return received;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 364/733] net: ethernet: cortina: Count dropped frames as NAPI work
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (362 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 363/733] net: ethernet: cortina: Finish RX updates before NAPI completion Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 365/733] net: ethernet: cortina: Count RX drops once per frame Greg Kroah-Hartman
` (380 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Linus Walleij, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit b856c552f556bc0341c1dbe0bf88e630fd1dc4b7 ]
The RX loop only consumes budget when it successfully delivers a frame.
Error paths keep consuming descriptors without reducing the budget, so a
stream of bad frames can process the entire receive ring in one poll.
Move the budget accounting to a common end-of-frame path. This counts
each completed frame as NAPI work whether it was delivered or dropped,
matching the behavior of the vendor driver.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260903-gemini-ethernet-fixes-v2-3-2bbbd598ca6e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 6502220362cbd..33e9763b32fe8 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1501,7 +1501,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
skb = NULL;
frag_nr = 0;
}
- continue;
+ goto next_desc;
}
page = gpage->page;
@@ -1523,7 +1523,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
} else if (!skb) {
put_page(page);
- continue;
+ goto next_desc;
}
if (word3.bits32 & EOF_BIT)
@@ -1546,10 +1546,8 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
napi_gro_frags(&port->napi);
skb = NULL;
frag_nr = 0;
- budget--;
- received++;
}
- continue;
+ goto next_desc;
err_drop:
if (skb) {
@@ -1562,6 +1560,13 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
put_page(page);
port->stats.rx_dropped++;
+
+next_desc:
+ /* Final or single-descriptor fragment, advance things */
+ if (word3.bits32 & EOF_BIT) {
+ budget--;
+ received++;
+ }
}
port->rx_skb = skb;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 365/733] net: ethernet: cortina: Count RX drops once per frame
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (363 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 364/733] net: ethernet: cortina: Count dropped frames as NAPI work Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 366/733] net: ethernet: cortina: Count RX descriptors for freeq refill Greg Kroah-Hartman
` (379 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joe Damato, Linus Walleij,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit 6520198c430c81bcc367f0dd5e32f2fb740b9d51 ]
The absence of a partial skb means either that the driver is not
assembling a frame or that the current frame was already dropped.
Consequently, repeated descriptor errors can increment rx_dropped more
than once, while an orphaned descriptor chain can reach EOF without being
counted at all.
Track the dropping state across NAPI polls. Clear it at frame boundaries
and route mapping failures and orphaned continuations through the common
drop path so each discarded frame is counted exactly once.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Reported-by: Joe Damato <joe@dama.to>
Closes: https://lore.kernel.org/netdev/apdK5aMmvYssz35F@devvm20253.cco0.facebook.com/
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260903-gemini-ethernet-fixes-v2-4-2bbbd598ca6e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 41 +++++++++++++++------------
1 file changed, 23 insertions(+), 18 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 33e9763b32fe8..9ba8524fa3710 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -124,6 +124,7 @@ struct gemini_ethernet_port {
unsigned int rx_coalesce_nsecs;
struct sk_buff *rx_skb;
unsigned int rx_frag_nr;
+ bool rx_dropping;
unsigned int freeq_refill;
struct gmac_txq txq[TX_QUEUE_NUM];
@@ -1451,6 +1452,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
struct gmac_rxdesc *rx = NULL;
struct gmac_queue_page *gpage;
unsigned int received = 0;
+ bool dropping = port->rx_dropping;
union gmac_rxdesc_0 word0;
union gmac_rxdesc_1 word1;
union gmac_rxdesc_3 word3;
@@ -1472,6 +1474,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
w = rw.bits.wptr;
while (budget && w != r) {
+ page = NULL;
rx = port->rxq_ring + r;
word0 = rx->word0;
word1 = rx->word1;
@@ -1485,6 +1488,16 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
frame_len = word1.bits.byte_count;
page_offs = mapping & ~PAGE_MASK;
+ if (word3.bits32 & SOF_BIT) {
+ if (skb) {
+ napi_free_frags(&port->napi);
+ port->stats.rx_dropped++;
+ skb = NULL;
+ frag_nr = 0;
+ }
+ dropping = false;
+ }
+
if (!mapping) {
netdev_err(netdev,
"rxq[%u]: HW BUG: zero DMA desc\n", r);
@@ -1495,24 +1508,11 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE);
if (!gpage) {
dev_err(geth->dev, "could not find mapping\n");
- port->stats.rx_dropped++;
- if (skb) {
- napi_free_frags(&port->napi);
- skb = NULL;
- frag_nr = 0;
- }
- goto next_desc;
+ goto err_drop;
}
page = gpage->page;
if (word3.bits32 & SOF_BIT) {
- if (skb) {
- napi_free_frags(&port->napi);
- port->stats.rx_dropped++;
- skb = NULL;
- frag_nr = 0;
- }
-
skb = gmac_skb_if_good_frame(port, word0, frame_len);
if (!skb)
goto err_drop;
@@ -1522,8 +1522,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
frag_nr = 0;
} else if (!skb) {
- put_page(page);
- goto next_desc;
+ goto err_drop;
}
if (word3.bits32 & EOF_BIT)
@@ -1556,21 +1555,26 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
frag_nr = 0;
}
- if (mapping)
+ if (page)
put_page(page);
- port->stats.rx_dropped++;
+ if (!dropping) {
+ port->stats.rx_dropped++;
+ dropping = true;
+ }
next_desc:
/* Final or single-descriptor fragment, advance things */
if (word3.bits32 & EOF_BIT) {
budget--;
received++;
+ dropping = false;
}
}
port->rx_skb = skb;
port->rx_frag_nr = frag_nr;
+ port->rx_dropping = dropping;
writew(r, ptr_reg);
return received;
}
@@ -1900,6 +1904,7 @@ static int gmac_stop(struct net_device *netdev)
napi_disable(&port->napi);
port->rx_skb = NULL;
port->rx_frag_nr = 0;
+ port->rx_dropping = false;
gmac_enable_irq(netdev, 0);
gmac_cleanup_rxq(netdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 366/733] net: ethernet: cortina: Count RX descriptors for freeq refill
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (364 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 365/733] net: ethernet: cortina: Count RX drops once per frame Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 367/733] drm/adp: Drop the select of the nonexistent CONFIG_DRM_KMS_DMA_HELPER Greg Kroah-Hartman
` (378 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joe Damato, Linus Walleij,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linus Walleij <linusw@kernel.org>
[ Upstream commit e89e88ad41d9f31c829c2af39c48313e8e48d5b0 ]
The software free queue provides one buffer fragment for every descriptor
moved to an RX queue. The refill heuristic instead advances by NAPI work,
which counts frames. A fragmented or discarded frame can consume several
queue entries while adding only one to the refill count.
Count the RX descriptors as they are consumed and report that separately
from NAPI work. Use the descriptor count to drive free queue refills.
Fixes: 4d5ae32f5e1e ("net: ethernet: Add a driver for Gemini gigabit ethernet")
Assisted-by: LLM
Reviewed-by: Joe Damato <joe@dama.to>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260903-gemini-ethernet-fixes-v2-5-2bbbd598ca6e@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cortina/gemini.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/cortina/gemini.c b/drivers/net/ethernet/cortina/gemini.c
index 9ba8524fa3710..f08de623e6f7c 100644
--- a/drivers/net/ethernet/cortina/gemini.c
+++ b/drivers/net/ethernet/cortina/gemini.c
@@ -1440,7 +1440,8 @@ static struct sk_buff *gmac_skb_if_good_frame(struct gemini_ethernet_port *port,
return skb;
}
-static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
+static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget,
+ unsigned int *freeq_consumed)
{
struct gemini_ethernet_port *port = netdev_priv(netdev);
unsigned short m = (1 << port->rxq_order) - 1;
@@ -1448,6 +1449,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
void __iomem *ptr_reg = port->rxq_rwptr;
unsigned int frag_nr = port->rx_frag_nr;
struct sk_buff *skb = port->rx_skb;
+ unsigned int consumed = 0;
unsigned int frame_len, frag_len;
struct gmac_rxdesc *rx = NULL;
struct gmac_queue_page *gpage;
@@ -1483,6 +1485,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
r++;
r &= m;
+ consumed++;
frag_len = word0.bits.buffer_size;
frame_len = word1.bits.byte_count;
@@ -1575,6 +1578,7 @@ static unsigned int gmac_rx(struct net_device *netdev, unsigned int budget)
port->rx_skb = skb;
port->rx_frag_nr = frag_nr;
port->rx_dropping = dropping;
+ *freeq_consumed = consumed;
writew(r, ptr_reg);
return received;
}
@@ -1584,18 +1588,19 @@ static int gmac_napi_poll(struct napi_struct *napi, int budget)
struct gemini_ethernet_port *port = netdev_priv(napi->dev);
struct gemini_ethernet *geth = port->geth;
unsigned int freeq_threshold;
+ unsigned int freeq_consumed;
unsigned int received;
freeq_threshold = 1 << (geth->freeq_order - 1);
u64_stats_update_begin(&port->rx_stats_syncp);
- received = gmac_rx(napi->dev, budget);
+ received = gmac_rx(napi->dev, budget, &freeq_consumed);
if (received < budget)
++port->rx_napi_exits;
u64_stats_update_end(&port->rx_stats_syncp);
- port->freeq_refill += received;
+ port->freeq_refill += freeq_consumed;
if (port->freeq_refill > freeq_threshold) {
port->freeq_refill -= freeq_threshold;
geth_fill_freeq(geth, true);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 367/733] drm/adp: Drop the select of the nonexistent CONFIG_DRM_KMS_DMA_HELPER
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (365 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 366/733] net: ethernet: cortina: Count RX descriptors for freeq refill Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 368/733] drm/logicvc: " Greg Kroah-Hartman
` (377 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Thomas Zimmermann,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit fedf002d7d08bee36693aacd1ade2ba39351ea91 ]
There is no Kconfig symbol CONFIG_DRM_KMS_DMA_HELPER. The former
CONFIG_DRM_KMS_CMA_HELPER was removed by commit 09717af7d13d ("drm:
Remove CONFIG_DRM_KMS_CMA_HELPER option") before this driver was added,
so the select does nothing. The driver already selects
CONFIG_DRM_GEM_DMA_HELPER, which is what it needs.
Remove the dead line.
Fixes: 332122eba628 ("drm: adp: Add Apple Display Pipe driver")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260905080426.34224-1-kmehltretter@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/adp/Kconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/adp/Kconfig b/drivers/gpu/drm/adp/Kconfig
index 9fcc27eb200db..acfa21ee06d22 100644
--- a/drivers/gpu/drm/adp/Kconfig
+++ b/drivers/gpu/drm/adp/Kconfig
@@ -6,7 +6,6 @@ config DRM_ADP
select DRM_KMS_HELPER
select DRM_BRIDGE_CONNECTOR
select DRM_DISPLAY_HELPER
- select DRM_KMS_DMA_HELPER
select DRM_GEM_DMA_HELPER
select DRM_PANEL_BRIDGE
select VIDEOMODE_HELPERS
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 368/733] drm/logicvc: Drop the select of the nonexistent CONFIG_DRM_KMS_DMA_HELPER
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (366 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 367/733] drm/adp: Drop the select of the nonexistent CONFIG_DRM_KMS_DMA_HELPER Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 369/733] s390/debug: Fix NULL pointer dereference in debug_set_level() Greg Kroah-Hartman
` (376 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Thomas Zimmermann,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit f97802dd98b27e45c04293f9926f07642578b23f ]
CONFIG_DRM_KMS_CMA_HELPER was removed by commit 09717af7d13d ("drm:
Remove CONFIG_DRM_KMS_CMA_HELPER option"). When commit 6bcfe8eaeef0
("drm/fb: rename FB CMA helpers to FB DMA helpers") later renamed the
select in this Kconfig to CONFIG_DRM_KMS_DMA_HELPER, no symbol of that
name existed, and git log -S finds no Kconfig file that has defined one
since. The select is silently ignored. The driver already selects
CONFIG_DRM_GEM_DMA_HELPER, which is what it needs.
Remove the dead line.
Fixes: 6bcfe8eaeef0 ("drm/fb: rename FB CMA helpers to FB DMA helpers")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Thomas Zimmermann <tzimmermann@suse.de>
Signed-off-by: Thomas Zimmermann <tzimmermann@suse.de>
Link: https://patch.msgid.link/20260905080344.34077-1-kmehltretter@gmail.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/logicvc/Kconfig | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/gpu/drm/logicvc/Kconfig b/drivers/gpu/drm/logicvc/Kconfig
index 579a358ed5cf3..11aae1626199b 100644
--- a/drivers/gpu/drm/logicvc/Kconfig
+++ b/drivers/gpu/drm/logicvc/Kconfig
@@ -4,7 +4,6 @@ config DRM_LOGICVC
depends on OF || COMPILE_TEST
select DRM_CLIENT_SELECTION
select DRM_KMS_HELPER
- select DRM_KMS_DMA_HELPER
select DRM_GEM_DMA_HELPER
select REGMAP
select REGMAP_MMIO
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 369/733] s390/debug: Fix NULL pointer dereference in debug_set_level()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (367 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 368/733] drm/logicvc: " Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 370/733] ALSA: hda: Report a change when only the channel status bytes move Greg Kroah-Hartman
` (375 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mikhail Zaslonko,
Peter Oberparleiter, Heiko Carstens, Vasily Gorbik, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mikhail Zaslonko <zaslonko@linux.ibm.com>
[ Upstream commit b1eb31d533cdfcae1011ed53850d52f36afe5774 ]
Commit a2cec6863709 ("s390/debug: Add s390dbf kernel parameter")
incorrectly removed a null-id check from debug_set_level(), introducing
a possible NULL pointer dereference for debug-API users that put
debug_register() results unchecked into debug_set_level().
Fix this by moving the check from the internal _debug_set_level()
variant back to the external debug_set_level() wrapper.
Fixes: a2cec6863709 ("s390/debug: Add s390dbf kernel parameter")
Signed-off-by: Mikhail Zaslonko <zaslonko@linux.ibm.com>
Reviewed-by: Peter Oberparleiter <oberpar@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/s390/kernel/debug.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/arch/s390/kernel/debug.c b/arch/s390/kernel/debug.c
index 14d2b58ad0930..e06abf1dbc218 100644
--- a/arch/s390/kernel/debug.c
+++ b/arch/s390/kernel/debug.c
@@ -1074,9 +1074,6 @@ static void _debug_set_level(debug_info_t *id, int new_level)
{
unsigned long flags;
- if (!id)
- return;
-
if (new_level == DEBUG_OFF_LEVEL) {
pr_info("%s: switched off\n", id->name);
} else if ((new_level > DEBUG_MAX_LEVEL) || (new_level < 0)) {
@@ -1101,6 +1098,9 @@ static void _debug_set_level(debug_info_t *id, int new_level)
*/
void debug_set_level(debug_info_t *id, int new_level)
{
+ if (!id)
+ return;
+
/* Level specified via kernel parameter takes precedence */
debug_get_param(id->name, &new_level, NULL);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 370/733] ALSA: hda: Report a change when only the channel status bytes move
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (368 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 369/733] s390/debug: Fix NULL pointer dereference in debug_set_level() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 371/733] platform/x86: x86-android-tablets: fix gpio_secondary_fwnode_init() not working Greg Kroah-Hartman
` (374 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, HyeongJun An, Takashi Iwai,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: HyeongJun An <sammiee5311@gmail.com>
[ Upstream commit 7284788743121ec8bed556b00f830dc52ad9955d ]
The put() callback of "IEC958 Playback Default" returns whether the
converted register value moved. The convert_from_spdif_status() helper
reads part of the first two channel status bytes and none of the last
two, while the get() callback returns all four. So a write that lands
only in the bits it does not read changes what userspace reads back and
reports no change. Of the 31 bits above the mode bit, 20 are such bits
in consumer mode and 29 in professional mode. The core notifies only on
a positive return.
Toggling status[2] bit 0 on an HDA HDMI codec moves the read-back from
04 00 00 00 to 04 00 01 00 with no event. Toggling the non-audio bit
in status[0] gives one.
Compare the stored status as well, the way the ac97 code does. The
write to the codec stays gated on the converted value.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Signed-off-by: HyeongJun An <sammiee5311@gmail.com>
Assisted-by: Claude:claude-opus-5
Link: https://patch.msgid.link/20260908134153.1614273-1-sammiee5311@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
sound/hda/common/codec.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/sound/hda/common/codec.c b/sound/hda/common/codec.c
index ef533770179b4..33dbe21fa165c 100644
--- a/sound/hda/common/codec.c
+++ b/sound/hda/common/codec.c
@@ -2271,6 +2271,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
int idx = kcontrol->private_value;
struct hda_spdif_out *spdif;
hda_nid_t nid;
+ unsigned int old_status;
unsigned short val;
int change;
@@ -2279,6 +2280,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
guard(mutex)(&codec->spdif_mutex);
spdif = snd_array_elem(&codec->spdif_out, idx);
nid = spdif->nid;
+ old_status = spdif->status;
spdif->status = ucontrol->value.iec958.status[0] |
((unsigned int)ucontrol->value.iec958.status[1] << 8) |
((unsigned int)ucontrol->value.iec958.status[2] << 16) |
@@ -2289,7 +2291,7 @@ static int snd_hda_spdif_default_put(struct snd_kcontrol *kcontrol,
spdif->ctls = val;
if (change && nid != (u16)-1)
set_dig_out_convert(codec, nid, val & 0xff, (val >> 8) & 0xff);
- return change;
+ return change || spdif->status != old_status;
}
#define snd_hda_spdif_out_switch_info snd_ctl_boolean_mono_info
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 371/733] platform/x86: x86-android-tablets: fix gpio_secondary_fwnode_init() not working
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (369 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 370/733] ALSA: hda: Report a change when only the channel status bytes move Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 372/733] idpf: account for VLAN header when parsing RSC packet header Greg Kroah-Hartman
` (373 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dmitry Torokhov, Hans de Goede,
Ilpo Järvinen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <johannes.goede@oss.qualcomm.com>
[ Upstream commit dd519eb8f66eaa205bbbdcb753588138a1d18414 ]
acpi_bus_find_device_by_name() call returns a pointer to the device object
on the ACPI bus, aka the ACPI companion device.
gpio_secondary_fwnode_init() then continues with setting the secondary
fwnode on this device. But this is not the actual physical device for
the GPIO controller (e.g. the GPIO controller platform bus device).
This mismatch is causing GPIO lookups by secondary fwnode to not work.
Modify gpio_secondary_fwnode_init() to instead set the secondary fwnode
of the first physical device associated with the ACPI companion device.
This fixes the GPIO lookups not working.
Fixes: 1448c2d2ca5c ("platform/x86: x86-android-tablets: enable fwnode matching of GPIO chips")
Reviewed-by: Dmitry Torokhov <dmitry.torokhov@gmail.com>
Signed-off-by: Hans de Goede <johannes.goede@oss.qualcomm.com>
Link: https://patch.msgid.link/20260908185517.49047-1-johannes.goede@oss.qualcomm.com
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/platform/x86/x86-android-tablets/core.c | 11 +++++++++--
1 file changed, 9 insertions(+), 2 deletions(-)
diff --git a/drivers/platform/x86/x86-android-tablets/core.c b/drivers/platform/x86/x86-android-tablets/core.c
index 722c0ae4ecd12..7751261f4b7cf 100644
--- a/drivers/platform/x86/x86-android-tablets/core.c
+++ b/drivers/platform/x86/x86-android-tablets/core.c
@@ -381,6 +381,7 @@ static int gpio_secondary_fwnode_init(struct device *parent)
{
const struct software_node *const *swnode;
struct fwnode_handle *fwnode;
+ struct device *phys_dev;
int ret;
if (!gpiochip_node_group)
@@ -408,9 +409,15 @@ static int gpio_secondary_fwnode_init(struct device *parent)
if (WARN_ON(!fwnode))
return -ENOENT;
- set_secondary_fwnode(dev, fwnode);
+ phys_dev = acpi_get_first_physical_node(to_acpi_device(dev));
+ if (!phys_dev)
+ return dev_err_probe(parent, -ENODEV,
+ "No physical device for ACPI GPIO dev: %pfwP\n",
+ fwnode);
- ret = devm_add_action_or_reset(parent, gpio_secondary_unset, get_device(dev));
+ set_secondary_fwnode(phys_dev, fwnode);
+
+ ret = devm_add_action_or_reset(parent, gpio_secondary_unset, get_device(phys_dev));
if (ret)
return ret;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 372/733] idpf: account for VLAN header when parsing RSC packet header
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (370 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 371/733] platform/x86: x86-android-tablets: fix gpio_secondary_fwnode_init() not working Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 373/733] ice: add missing xa_destroy for sched_node_ids Greg Kroah-Hartman
` (372 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Joshua Hay, Emil Tantilov,
Aleksandr Loktionov, Samuel Salin, Tony Nguyen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joshua Hay <joshua.a.hay@intel.com>
[ Upstream commit cc6d60ef92278a31ffc2e94966a0921b9646af18 ]
While parsing the header of a Receive Side Coalesced (RSC) packet, check
if a VLAN tag is present and adjust the header parsing accordingly.
Otherwise, Rx TCP traffic is completely broken for any VLAN interface
whose underlying interface has RSC (rx-gro-hw) enabled.
We only need to worry about one VLAN header since Rx packets with
multiple VLAN headers are not candidates for RSC.
Fixes: 3a8845af66edb ("idpf: add RX splitq napi poll support")
Signed-off-by: Joshua Hay <joshua.a.hay@intel.com>
Reviewed-by: Emil Tantilov <emil.s.tantilov@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
diff --git a/drivers/net/ethernet/intel/idpf/idpf_txrx.c b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
index 91ca75e454630..0b4e3d075fb05 100644
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -3299,6 +3299,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
struct libeth_rx_pt decoded)
{
u16 rsc_segments, rsc_seg_len;
+ u16 l3_start = 0;
bool ipv4, ipv6;
int len;
@@ -3321,7 +3322,10 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
NAPI_GRO_CB(skb)->count = rsc_segments;
skb_shinfo(skb)->gso_size = rsc_seg_len;
- skb_reset_network_header(skb);
+ if (unlikely(eth_type_vlan(skb->protocol)))
+ l3_start = VLAN_HLEN;
+
+ skb_set_network_header(skb, l3_start);
if (ipv4) {
struct iphdr *ipv4h = ip_hdr(skb);
@@ -3329,7 +3333,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV4;
/* Reset and set transport header offset in skb */
- skb_set_transport_header(skb, sizeof(struct iphdr));
+ skb_set_transport_header(skb, l3_start + sizeof(struct iphdr));
len = skb->len - skb_transport_offset(skb);
/* Compute the TCP pseudo header checksum*/
@@ -3339,7 +3343,7 @@ static int idpf_rx_rsc(struct idpf_rx_queue *rxq, struct sk_buff *skb,
struct ipv6hdr *ipv6h = ipv6_hdr(skb);
skb_shinfo(skb)->gso_type = SKB_GSO_TCPV6;
- skb_set_transport_header(skb, sizeof(struct ipv6hdr));
+ skb_set_transport_header(skb, l3_start + sizeof(struct ipv6hdr));
len = skb->len - skb_transport_offset(skb);
tcp_hdr(skb)->check =
~tcp_v6_check(len, &ipv6h->saddr, &ipv6h->daddr, 0);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 373/733] ice: add missing xa_destroy for sched_node_ids
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (371 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 372/733] idpf: account for VLAN header when parsing RSC packet header Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 374/733] eth: ice: dont dereference pointers from TP_printk() Greg Kroah-Hartman
` (371 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jacob Keller, Aleksandr Loktionov,
Tony Nguyen, Sasha Levin, Rinitha S
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jacob Keller <jacob.e.keller@intel.com>
[ Upstream commit 53432c4c3e869076350aef319534431af8ba99c1 ]
Commit 16dfa49406bc ("ice: Introduce new parameters in ice_sched_node")
added a sched_node_ids xarray to the port info structure, but never called
xa_destroy on it.
Since xarrays can allocate internal memory, this can result in a memory
leak even if every element in the xarray has been removed.
The xarray is currently embedded in the port_info structure. This appears
to have been done because its use is within functions that take the
port_info as a primary argument.
However, this complicates managing the lifecycle of the field. The
port_info structure is allocated in ice_init_hw() using devm, and it is
not released until the devm cleanup when the driver is unloaded.
The ice_init_hw() function is called in many places, including devlink
reload, and possibly during DDP load after updating the Tx scheduler
layout.
Adding a call of xa_destroy to the ice_deinit_hw() causes Sashiko to raise
multiple concerns due to potential ordering issues and possible ways that
port_info could be a dangling reference.
To handle this, move the sched_node_ids out of port_info and into the hw
structure. All users of the array already have a pointer to hw anyways, and
there is only one sched_node_ids per adapter. While here, remove the overly
verbose comment explaining the nature of the sched_node_ids xarray.
Add the missing xa_destroy to the cleanup path and to ice_deinit_hw(),
ensuring that we properly release the xarray memory.
This was caught by Sashiko during development of unrelated code.
Fixes: 16dfa49406bc ("ice: Introduce new parameters in ice_sched_node")
Signed-off-by: Jacob Keller <jacob.e.keller@intel.com>
Reviewed-by: Aleksandr Loktionov <aleksandr.loktionov@intel.com>
Tested-by: Rinitha S <sx.rinitha@intel.com> (A Contingent worker at Intel)
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_common.c | 9 ++++++---
drivers/net/ethernet/intel/ice/ice_sched.c | 4 ++--
drivers/net/ethernet/intel/ice/ice_type.h | 2 +-
3 files changed, 9 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_common.c b/drivers/net/ethernet/intel/ice/ice_common.c
index ef1ce106f81b5..04633103e3e61 100644
--- a/drivers/net/ethernet/intel/ice/ice_common.c
+++ b/drivers/net/ethernet/intel/ice/ice_common.c
@@ -1051,14 +1051,13 @@ int ice_init_hw(struct ice_hw *hw)
hw->evb_veb = true;
- /* init xarray for identifying scheduling nodes uniquely */
- xa_init_flags(&hw->port_info->sched_node_ids, XA_FLAGS_ALLOC);
+ xa_init_flags(&hw->sched_node_ids, XA_FLAGS_ALLOC);
/* Query the allocated resources for Tx scheduler */
status = ice_sched_query_res_alloc(hw);
if (status) {
ice_debug(hw, ICE_DBG_SCHED, "Failed to get scheduler allocated resources\n");
- goto err_unroll_alloc;
+ goto err_unroll_xarray;
}
ice_sched_get_psm_clk_freq(hw);
@@ -1146,6 +1145,8 @@ int ice_init_hw(struct ice_hw *hw)
ice_cleanup_fltr_mgmt_struct(hw);
err_unroll_sched:
ice_sched_cleanup_all(hw);
+err_unroll_xarray:
+ xa_destroy(&hw->sched_node_ids);
err_unroll_alloc:
devm_kfree(ice_hw_to_dev(hw), hw->port_info);
err_unroll_cqinit:
@@ -1186,6 +1187,8 @@ void ice_deinit_hw(struct ice_hw *hw)
/* Clear VSI contexts if not already cleared */
ice_clear_all_vsi_ctx(hw);
+
+ xa_destroy(&hw->sched_node_ids);
}
/**
diff --git a/drivers/net/ethernet/intel/ice/ice_sched.c b/drivers/net/ethernet/intel/ice/ice_sched.c
index fff0c1afdb414..ffa18d86729a0 100644
--- a/drivers/net/ethernet/intel/ice/ice_sched.c
+++ b/drivers/net/ethernet/intel/ice/ice_sched.c
@@ -371,7 +371,7 @@ void ice_free_sched_node(struct ice_port_info *pi, struct ice_sched_node *node)
devm_kfree(ice_hw_to_dev(hw), node->children);
kfree(node->name);
- xa_erase(&pi->sched_node_ids, node->id);
+ xa_erase(&hw->sched_node_ids, node->id);
devm_kfree(ice_hw_to_dev(hw), node);
}
@@ -977,7 +977,7 @@ ice_sched_add_elems(struct ice_port_info *pi, struct ice_sched_node *tc_node,
if (!new_node->name)
return -ENOMEM;
- status = xa_alloc(&pi->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX),
+ status = xa_alloc(&hw->sched_node_ids, &new_node->id, NULL, XA_LIMIT(0, UINT_MAX),
GFP_KERNEL);
if (status) {
ice_debug(hw, ICE_DBG_SCHED, "xa_alloc failed for sched node status =%d\n",
diff --git a/drivers/net/ethernet/intel/ice/ice_type.h b/drivers/net/ethernet/intel/ice/ice_type.h
index d9a5c1aae7c23..cf147a2127071 100644
--- a/drivers/net/ethernet/intel/ice/ice_type.h
+++ b/drivers/net/ethernet/intel/ice/ice_type.h
@@ -765,7 +765,6 @@ struct ice_port_info {
/* List contain profile ID(s) and other params per layer */
struct list_head rl_prof_list[ICE_AQC_TOPO_MAX_LEVEL_NUM];
struct ice_qos_cfg qos_cfg;
- struct xarray sched_node_ids;
u8 is_vf:1;
u8 is_custom_tx_enabled:1;
};
@@ -930,6 +929,7 @@ struct ice_hw {
u8 sw_entry_point_layer;
u16 max_children[ICE_AQC_TOPO_MAX_LEVEL_NUM];
struct list_head agg_list; /* lists all aggregator */
+ struct xarray sched_node_ids;
struct ice_vsi_ctx *vsi_ctx[ICE_MAX_VSI];
u8 evb_veb; /* true for VEB, false for VEPA */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 374/733] eth: ice: dont dereference pointers from TP_printk()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (372 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 373/733] ice: add missing xa_destroy for sched_node_ids Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 375/733] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform Greg Kroah-Hartman
` (370 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jakub Kicinski, Alexander Nowlin,
Tony Nguyen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <kuba@kernel.org>
[ Upstream commit b8bf9bfda5f62e11444e483c2b4aaff90c5cfc6b ]
After forwarding net-next during the v7.3 merge window we started
seeing:
TRACE EVENT ERROR: Event ice_tx_dim_work has double dereference in TP_printk: REC->q_vector->tx.tx_ring->q_index
WARNING: kernel/trace/trace_events.c:420 at test_double_dereference.cold+0x39/0x4b
this is due to extra checks added in tracing subsystem in
commit b5cc230af5e5 ("tracing: Warn when an event dereferences a pointer in TP_printk()").
Printing happens long after the event was recorded, by which point
the pointers may be invalid (the ring or the dim instance).
Copy the eight scalars into the event instead.
Fixes: 3089cf6d3caa ("ice: add tracepoints")
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Tested-by: Alexander Nowlin <alexander.nowlin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/intel/ice/ice_trace.h | 64 ++++++++++++++--------
1 file changed, 42 insertions(+), 22 deletions(-)
diff --git a/drivers/net/ethernet/intel/ice/ice_trace.h b/drivers/net/ethernet/intel/ice/ice_trace.h
index 4f35ef8d6b299..7568c917cdbe1 100644
--- a/drivers/net/ethernet/intel/ice/ice_trace.h
+++ b/drivers/net/ethernet/intel/ice/ice_trace.h
@@ -63,23 +63,33 @@
DECLARE_EVENT_CLASS(ice_rx_dim_template,
TP_PROTO(struct ice_q_vector *q_vector, struct dim *dim),
TP_ARGS(q_vector, dim),
- TP_STRUCT__entry(__field(struct ice_q_vector *, q_vector)
- __field(struct dim *, dim)
+ TP_STRUCT__entry(__field(u16, q_index)
+ __field(u8, state)
+ __field(u8, profile_ix)
+ __field(u8, tune_state)
+ __field(u8, steps_right)
+ __field(u8, steps_left)
+ __field(u8, tired)
__string(devname, q_vector->rx.rx_ring->netdev->name)),
- TP_fast_assign(__entry->q_vector = q_vector;
- __entry->dim = dim;
+ TP_fast_assign(__entry->q_index = q_vector->rx.rx_ring->q_index;
+ __entry->state = dim->state;
+ __entry->profile_ix = dim->profile_ix;
+ __entry->tune_state = dim->tune_state;
+ __entry->steps_right = dim->steps_right;
+ __entry->steps_left = dim->steps_left;
+ __entry->tired = dim->tired;
__assign_str(devname);),
TP_printk("netdev: %s Rx-Q: %d dim-state: %d dim-profile: %d dim-tune: %d dim-st-right: %d dim-st-left: %d dim-tired: %d",
__get_str(devname),
- __entry->q_vector->rx.rx_ring->q_index,
- __entry->dim->state,
- __entry->dim->profile_ix,
- __entry->dim->tune_state,
- __entry->dim->steps_right,
- __entry->dim->steps_left,
- __entry->dim->tired)
+ __entry->q_index,
+ __entry->state,
+ __entry->profile_ix,
+ __entry->tune_state,
+ __entry->steps_right,
+ __entry->steps_left,
+ __entry->tired)
);
DEFINE_EVENT(ice_rx_dim_template, ice_rx_dim_work,
@@ -90,23 +100,33 @@ DEFINE_EVENT(ice_rx_dim_template, ice_rx_dim_work,
DECLARE_EVENT_CLASS(ice_tx_dim_template,
TP_PROTO(struct ice_q_vector *q_vector, struct dim *dim),
TP_ARGS(q_vector, dim),
- TP_STRUCT__entry(__field(struct ice_q_vector *, q_vector)
- __field(struct dim *, dim)
+ TP_STRUCT__entry(__field(u16, q_index)
+ __field(u8, state)
+ __field(u8, profile_ix)
+ __field(u8, tune_state)
+ __field(u8, steps_right)
+ __field(u8, steps_left)
+ __field(u8, tired)
__string(devname, q_vector->tx.tx_ring->netdev->name)),
- TP_fast_assign(__entry->q_vector = q_vector;
- __entry->dim = dim;
+ TP_fast_assign(__entry->q_index = q_vector->tx.tx_ring->q_index;
+ __entry->state = dim->state;
+ __entry->profile_ix = dim->profile_ix;
+ __entry->tune_state = dim->tune_state;
+ __entry->steps_right = dim->steps_right;
+ __entry->steps_left = dim->steps_left;
+ __entry->tired = dim->tired;
__assign_str(devname);),
TP_printk("netdev: %s Tx-Q: %d dim-state: %d dim-profile: %d dim-tune: %d dim-st-right: %d dim-st-left: %d dim-tired: %d",
__get_str(devname),
- __entry->q_vector->tx.tx_ring->q_index,
- __entry->dim->state,
- __entry->dim->profile_ix,
- __entry->dim->tune_state,
- __entry->dim->steps_right,
- __entry->dim->steps_left,
- __entry->dim->tired)
+ __entry->q_index,
+ __entry->state,
+ __entry->profile_ix,
+ __entry->tune_state,
+ __entry->steps_right,
+ __entry->steps_left,
+ __entry->tired)
);
DEFINE_EVENT(ice_tx_dim_template, ice_tx_dim_work,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 375/733] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (373 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 374/733] eth: ice: dont dereference pointers from TP_printk() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 376/733] Bluetooth: btusb: Fix UAF of btusb_data by rx_work Greg Kroah-Hartman
` (369 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Rafael Passos, Rong Zhang,
Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rong Zhang <i@rong.moe>
[ Upstream commit dcaf83ead130d3067862599089b0999b3da140a4 ]
It is reported that a remote wakeup could cause MT7922/MT7925's btusb
interface completely unresponsive. Resetting the xHCI root hub doesn't
help at all, and recovering from such a state needs a power cycle.
All reports seen to be relevant to Ryzen-based laptops. These NICs are
usually used as OEM components thanks to some sort of reference designs.
Their popularity on other platforms is unclear. While there is still a
chance that the quirk may exist on other platforms, be cautious and only
apply the quirk to direct children of Ryzen platforms's root hubs for
the time being. In most cases the root hub is on the SoC or PCH, which
needs the quirk. Unfortunately, this can't distinguish root hubs on PCIe
add-in cards. Such roughness should be acceptable, as PCIe USB
controller add-in cards are less commonly used nowadays. On the other
hand, applying the quirk doesn't hurt any functionalities either, as the
device can still be used as a wakeup source if desired. Theoretically,
we could retrieve the root hub's PCI vendor ID with some hierarchy
magic, but that's too intrusive...
Meanwhile, though device_set_wakeup_capable(false) is the correct fix
for other NICs with fake remote wakeup capabilities, doing so for
MT7922/MT7925 effectively prevents it from being used as wakeup
sources as per userspace requests. Hence, return -EBUSY on runtime
suspend to prevent the interface from being autosuspended while it's
still opened, which has the same effect as
device_set_wakeup_capable(false), since disabling remote wakeup simply
causes the USB core to gate runtime autosuspend as well due to
needs_remote_wakeup == 1. The interface can be safely autosuspended as
long as remote wakeup is disabled, i.e., after closing the HCI device.
Specifically, the interface may still take the advantage of remote
wakeup in order to wake up the system from sleep if userspace has
enabled it as a wakeup source.
Fixes: e31d761628ad ("Bluetooth: btmtk: Disable remote wakeup for MT7922/MT7925")
Tested-by: Rafael Passos <rafael@rcpassos.me>
Signed-off-by: Rong Zhang <i@rong.moe>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btmtk.c | 10 ------
drivers/bluetooth/btusb.c | 73 ++++++++++++++++++++++++++++++++++++---
2 files changed, 69 insertions(+), 14 deletions(-)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index c0ed51567ed4d..9589caff925de 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1374,16 +1374,6 @@ int btmtk_usb_setup(struct hci_dev *hdev)
break;
case 0x7922:
case 0x7925:
- /*
- * A remote wakeup could cause the device completely unresponsive, and
- * recovering from such a state needs a power cycle.
- *
- * Since the remote wakeup capability is super broken, just disable it
- * to get rid of the troubles. The device can still be autosuspended
- * when the bluetooth interface is closed.
- */
- device_set_wakeup_capable(&btmtk_data->udev->dev, false);
- fallthrough;
case 0x7961:
case 0x7902:
case 0x6639:
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index a3d6d3194b15b..ed4bf9a478087 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -6,6 +6,7 @@
* Copyright (C) 2005-2008 Marcel Holtmann <marcel@holtmann.org>
*/
+#include <linux/cpufeature.h>
#include <linux/dmi.h>
#include <linux/module.h>
#include <linux/usb.h>
@@ -968,6 +969,7 @@ struct qca_dump_info {
#define BTUSB_USE_ALT3_FOR_WBS 15
#define BTUSB_ALT6_CONTINUOUS_TX 16
#define BTUSB_HW_SSR_ACTIVE 17
+#define BTUSB_WAKEUP_BROKEN 18
struct btusb_data {
struct hci_dev *hdev;
@@ -2950,10 +2952,25 @@ static int btusb_send_frame_mtk(struct hci_dev *hdev, struct sk_buff *skb)
}
}
+static inline bool platform_is_ryzen(void)
+{
+#ifdef CONFIG_X86
+ return boot_cpu_has(X86_FEATURE_ZEN);
+#else
+ return false;
+#endif
+}
+
+static inline bool is_direct_child_of_root_hub(struct usb_device *udev)
+{
+ return udev->parent == udev->bus->root_hub;
+}
+
static int btusb_mtk_setup(struct hci_dev *hdev)
{
struct btusb_data *data = hci_get_drvdata(hdev);
struct btmtk_data *btmtk_data = hci_get_priv(hdev);
+ int err;
/* MediaTek WMT vendor cmd requiring below USB resources to
* complete the handshake.
@@ -2970,7 +2987,40 @@ static int btusb_mtk_setup(struct hci_dev *hdev)
btusb_mtk_claim_iso_intf(data);
}
- return btmtk_usb_setup(hdev);
+ err = btmtk_usb_setup(hdev);
+ if (err)
+ return err;
+
+ switch (btmtk_data->dev_id) {
+ case 0x7922:
+ case 0x7925:
+ /*
+ * All reports seen to be relevant to Ryzen-based laptops. These
+ * NICs are usually used as OEM components thanks to some sort
+ * of reference designs.
+ *
+ * Their popularity on other platforms is unclear. While there
+ * is still a chance that the quirk may exist on other
+ * platforms, be cautious and only apply the quirk to direct
+ * children of Ryzen platforms's root hubs for the time being.
+ *
+ * In most cases the root hub is on the SoC or PCH, which needs
+ * the quirk. Unfortunately, this can't distinguish root hubs on
+ * PCIe add-in cards. Such roughness should be acceptable, as
+ * PCIe USB controller add-in cards are less commonly used
+ * nowadays. On the other hand, applying the quirk doesn't hurt
+ * any functionalities either, as the device can still be used
+ * as a wakeup source if desired.
+ *
+ * Theoretically, we could retrieve the root hub's PCI vendor ID
+ * with some hierarchy magic, but that's too intrusive...
+ */
+ if (platform_is_ryzen() && is_direct_child_of_root_hub(data->udev))
+ set_bit(BTUSB_WAKEUP_BROKEN, &data->flags);
+ break;
+ }
+
+ return 0;
}
static int btusb_mtk_shutdown(struct hci_dev *hdev)
@@ -4541,11 +4591,26 @@ static int btusb_suspend(struct usb_interface *intf, pm_message_t message)
BT_DBG("intf %p", intf);
- /* Don't auto-suspend if there are connections or discovery in
- * progress; external suspend calls shall never fail.
+ /*
+ * It is reported that remote wakeup events could sometimes cause some
+ * adapters completely unresponsive. Resetting the xHCI root hub doesn't
+ * help at all, and recovering from such a state needs a power cycle.
+ * Since disabling remote wakeup simply causes the USB core to gate
+ * runtime autosuspend as well due to needs_remote_wakeup == 1, let's do
+ * this ourselves to make our life easier. The interface can be safely
+ * autosuspended as long as remote wakeup is disabled, i.e., after
+ * closing the HCI device.
+ *
+ * Don't auto-suspend if there are connections or discovery in progress.
+ *
+ * External suspend calls shall never fail. Specifically, a device with
+ * broken remote wakeup may still take the advantage of remote wakeup in
+ * order to wake up the system from sleep if userspace has enabled it as
+ * a wakeup source.
*/
if (PMSG_IS_AUTO(message) &&
- (hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
+ ((test_bit(BTUSB_WAKEUP_BROKEN, &data->flags) && data->intf->needs_remote_wakeup) ||
+ hci_conn_count(data->hdev) || hci_discovery_active(data->hdev)))
return -EBUSY;
if (data->suspend_count++)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 376/733] Bluetooth: btusb: Fix UAF of btusb_data by rx_work
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (374 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 375/733] Bluetooth: Properly disable remote wakeup for MT7922/MT7925 on Ryzen platform Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 377/733] Bluetooth: btintel_pcie: validate packet_len before skb_put_data Greg Kroah-Hartman
` (368 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
[ Upstream commit 1c12c3117639e78940959d956519c758c57d0849 ]
btusb_close() and btusb_flush() cancel data->rx_work with the
asynchronous cancel_delayed_work(), so if btusb_rx_work() is already
running on another CPU it keeps running after the cancel returns.
btusb_disconnect() calls hci_unregister_dev(), which invokes
btusb_close(), and then frees the btusb_data. A still running
btusb_rx_work() then dereferences the freed data:
while ((skb = skb_dequeue(&data->acl_q)))
data->recv_acl(data->hdev, skb);
Use cancel_delayed_work_sync() instead. In btusb_close() the cancel also
has to happen after btusb_stop_traffic(), otherwise an URB completion
racing with the cancel can requeue the work right after it has been
waited for.
Fixes: 800fe5ec302e ("Bluetooth: btusb: Add support for queuing during polling interval")
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btusb.c | 14 ++++++++++----
1 file changed, 10 insertions(+), 4 deletions(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index ed4bf9a478087..53baf56b9dd96 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -2074,18 +2074,24 @@ static int btusb_close(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
- cancel_delayed_work(&data->rx_work);
cancel_work_sync(&data->work);
cancel_work_sync(&data->waker);
- skb_queue_purge(&data->acl_q);
-
clear_bit(BTUSB_ISOC_RUNNING, &data->flags);
clear_bit(BTUSB_BULK_RUNNING, &data->flags);
clear_bit(BTUSB_INTR_RUNNING, &data->flags);
clear_bit(BTUSB_DIAG_RUNNING, &data->flags);
btusb_stop_traffic(data);
+
+ /* rx_work must only be canceled once the URBs that can rearm it are
+ * gone, and it must be canceled synchronously since btusb_disconnect()
+ * frees the btusb_data it dereferences right after hci_unregister_dev().
+ */
+ cancel_delayed_work_sync(&data->rx_work);
+
+ skb_queue_purge(&data->acl_q);
+
btusb_free_frags(data);
err = usb_autopm_get_interface(data->intf);
@@ -2111,7 +2117,7 @@ static int btusb_flush(struct hci_dev *hdev)
BT_DBG("%s", hdev->name);
- cancel_delayed_work(&data->rx_work);
+ cancel_delayed_work_sync(&data->rx_work);
skb_queue_purge(&data->acl_q);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 377/733] Bluetooth: btintel_pcie: validate packet_len before skb_put_data
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (375 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 376/733] Bluetooth: btusb: Fix UAF of btusb_data by rx_work Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 378/733] Bluetooth: btintel_pcie: fix tx_handle bounds off-by-one Greg Kroah-Hartman
` (367 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiran K, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiran K <kiran.k@intel.com>
[ Upstream commit 6436e1b5331b1aebf905c13e0880a37032719b75 ]
btintel_pcie_submit_rx_work() reads packet_len from rfh_hdr without
checking if it exceeds the RX buffer size. An oversized packet_len
can lead to an out-of-bounds read in skb_put_data().
Validate packet_len to ensure it is non-zero and does not exceed
BTINTEL_PCIE_BUFFER_SIZE - sizeof(*rfh_hdr), logging an error when
invalid.
This issue was reported by Claude Mythos. It can be simulated either by
using customized firmware configured to return an invalid packet_len or
by modifying rfh_hdr->packet_len in the driver before calling
btintel_pcie_submit_rx_work().
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index 6b6258d03dd84..da46fb39d53ea 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1537,7 +1537,9 @@ static int btintel_pcie_submit_rx_work(struct btintel_pcie_data *data, u8 status
rfh_hdr = buf;
len = rfh_hdr->packet_len;
- if (len <= 0) {
+ if (len == 0 || len > BTINTEL_PCIE_BUFFER_SIZE - sizeof(*rfh_hdr)) {
+ bt_dev_err(data->hdev, "Invalid packet_len %d (max %zu)", len,
+ BTINTEL_PCIE_BUFFER_SIZE - sizeof(*rfh_hdr));
ret = -EINVAL;
goto resubmit;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 378/733] Bluetooth: btintel_pcie: fix tx_handle bounds off-by-one
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (376 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 377/733] Bluetooth: btintel_pcie: validate packet_len before skb_put_data Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 379/733] Bluetooth: btmtk: Declare MT7920 (MT7961 1a) Bluetooth firmware Greg Kroah-Hartman
` (366 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kiran K, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kiran K <kiran.k@intel.com>
[ Upstream commit 3dd1b41f96aad08444be1b7626c89de2b9f2abd4 ]
Valid indices into txq->urbd0s/tfds/bufs are 0..txq->count-1, so
tfd_index == txq->count is already out of range. Change the guard in
btintel_pcie_msix_tx_handle() from '> txq->count' to '>= txq->count'.
This issue was reported by Claude Mythos.
Fixes: c2b636b3f788 ("Bluetooth: btintel_pcie: Add support for PCIe transport")
Signed-off-by: Kiran K <kiran.k@intel.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btintel_pcie.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btintel_pcie.c b/drivers/bluetooth/btintel_pcie.c
index da46fb39d53ea..c64e96fe88976 100644
--- a/drivers/bluetooth/btintel_pcie.c
+++ b/drivers/bluetooth/btintel_pcie.c
@@ -1099,7 +1099,7 @@ static void btintel_pcie_msix_tx_handle(struct btintel_pcie_data *data)
urbd0 = &txq->urbd0s[cr_tia];
- if (urbd0->tfd_index > txq->count)
+ if (urbd0->tfd_index >= txq->count)
return;
cr_tia = (cr_tia + 1) % txq->count;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 379/733] Bluetooth: btmtk: Declare MT7920 (MT7961 1a) Bluetooth firmware
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (377 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 378/733] Bluetooth: btintel_pcie: fix tx_handle bounds off-by-one Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 380/733] Bluetooth: hci_sysfs: Fix NULL pointer dereference in device_del() Greg Kroah-Hartman
` (365 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ivan Hu, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Hu <ivan.hu@canonical.com>
[ Upstream commit 3d8a8e81ea8ad8813d4c82a12ba53ecb597b217d ]
btmtk_fw_get_filename() constructs the firmware name at runtime, so for
the MT7920 variant (dev_id 0x7961 with fw_flavor set) it requests
"mediatek/BT_RAM_CODE_MT7961_1a_2_hdr.bin" without ever declaring it via
MODULE_FIRMWARE(). Tools that select firmware from module metadata (e.g.
"modinfo -F firmware") therefore omit this blob, so request_firmware()
fails and Bluetooth does not initialise on MT7920, even though the file
is present in linux-firmware.
Declare it with MODULE_FIRMWARE(), as the mt76 driver already does for
the corresponding MT7920 wifi firmware.
Fixes: 1cb63d80fff6 ("Bluetooth: btusb: Add support Mediatek MT7920")
Signed-off-by: Ivan Hu <ivan.hu@canonical.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btmtk.c | 1 +
drivers/bluetooth/btmtk.h | 1 +
2 files changed, 2 insertions(+)
diff --git a/drivers/bluetooth/btmtk.c b/drivers/bluetooth/btmtk.c
index 9589caff925de..26d525acd6590 100644
--- a/drivers/bluetooth/btmtk.c
+++ b/drivers/bluetooth/btmtk.c
@@ -1577,5 +1577,6 @@ MODULE_FIRMWARE(FIRMWARE_MT7663);
MODULE_FIRMWARE(FIRMWARE_MT7668);
MODULE_FIRMWARE(FIRMWARE_MT7922);
MODULE_FIRMWARE(FIRMWARE_MT7961);
+MODULE_FIRMWARE(FIRMWARE_MT7920);
MODULE_FIRMWARE(FIRMWARE_MT7925);
MODULE_FIRMWARE(FIRMWARE_MT7927);
diff --git a/drivers/bluetooth/btmtk.h b/drivers/bluetooth/btmtk.h
index c83c24897c954..bc26148ec5442 100644
--- a/drivers/bluetooth/btmtk.h
+++ b/drivers/bluetooth/btmtk.h
@@ -7,6 +7,7 @@
#define FIRMWARE_MT7922 "mediatek/BT_RAM_CODE_MT7922_1_1_hdr.bin"
#define FIRMWARE_MT7902 "mediatek/BT_RAM_CODE_MT7902_1_1_hdr.bin"
#define FIRMWARE_MT7961 "mediatek/BT_RAM_CODE_MT7961_1_2_hdr.bin"
+#define FIRMWARE_MT7920 "mediatek/BT_RAM_CODE_MT7961_1a_2_hdr.bin"
#define FIRMWARE_MT7925 "mediatek/mt7925/BT_RAM_CODE_MT7925_1_1_hdr.bin"
#define FIRMWARE_MT7927 "mediatek/mt7927/BT_RAM_CODE_MT6639_2_1_hdr.bin"
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 380/733] Bluetooth: hci_sysfs: Fix NULL pointer dereference in device_del()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (378 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 379/733] Bluetooth: btmtk: Declare MT7920 (MT7961 1a) Bluetooth firmware Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 381/733] Bluetooth: btusb: mediatek: Fix leaked runtime PM reference in reset Greg Kroah-Hartman
` (364 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6df45dd3d03e1a9aca96,
Krystian Kaniewski, Luiz Augusto von Dentz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krystian Kaniewski <krystianmkaniewski@gmail.com>
[ Upstream commit 9b851b09b392da68bd715601f10a5adb2d8d19b8 ]
A NULL pointer dereference in klist_put() occurs when a child device (such
as a BNEP network device in bnep_session) is concurrently being
unregistered while hci_conn_del_sysfs() reparents child devices.
This is caused by a race condition between hci_conn_del_sysfs() and
concurrent child device unregistration (e.g. bnep_session calling
unregister_netdev()). During device unregistration, device_del() snapshots
a non-NULL parent pointer. Concurrently, hci_conn_del_sysfs() finds the
child device using device_find_any_child() and calls device_move() to
reparent it to NULL, which removes the node from its parent's klist and
clears knode_parent. Subsequently, device_del() calls
klist_del(&dev->p->knode_parent) using the stale parent snapshot, causing
klist_put() to dereference knode_klist(n)->put on an already removed node,
resulting in a NULL pointer dereference.
This race was introduced by commit 27aabf27fd01 ("Bluetooth: fix
use-after-free in device_for_each_child()"), which replaced
device_find_child(..., __match_tty) with device_find_any_child() in
hci_conn_del_sysfs(). That change was intended to avoid a use-after-free
where conn->dev outlived its parent hdev->dev when child devices held
references to conn->dev, because conn->dev only held a reference to
hdev->dev while registered in sysfs.
Fix the issue properly by taking an explicit reference to the parent device
with get_device(&hdev->dev) in hci_conn_init_sysfs() and dropping it with
put_device(parent) in bt_link_release() when the conn device is freed. This
ensures that hdev->dev remains valid for the entire lifecycle of conn->dev,
resolving the underlying use-after-free. With the parent reference held
properly, restore the __match_tty filter in hci_conn_del_sysfs() so that
device_move() is only invoked on persistent RFCOMM TTY devices as
originally intended, eliminating the race condition with unregistering
network devices.
Fixes: 27aabf27fd01 ("Bluetooth: fix use-after-free in device_for_each_child()")
Assisted-by: Gemini:gemini-3.7-flash syzbot
Reported-by: syzbot+6df45dd3d03e1a9aca96@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6df45dd3d03e1a9aca96
Link: https://syzkaller.appspot.com/ai_job?id=f1c0e740-db21-40af-a9ff-84db0fd8b8bd
Signed-off-by: Krystian Kaniewski <krystianmkaniewski@gmail.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/bluetooth/hci_sysfs.c | 17 +++++++++++++++--
1 file changed, 15 insertions(+), 2 deletions(-)
diff --git a/net/bluetooth/hci_sysfs.c b/net/bluetooth/hci_sysfs.c
index 8957ce7c21b76..c2065abf753e0 100644
--- a/net/bluetooth/hci_sysfs.c
+++ b/net/bluetooth/hci_sysfs.c
@@ -13,7 +13,10 @@ static const struct class bt_class = {
static void bt_link_release(struct device *dev)
{
struct hci_conn *conn = to_hci_conn(dev);
+ struct device *parent = dev->parent;
+
kfree(conn);
+ put_device(parent);
}
static const struct device_type bt_link = {
@@ -21,6 +24,16 @@ static const struct device_type bt_link = {
.release = bt_link_release,
};
+/*
+ * The rfcomm tty device will possibly retain even when conn
+ * is down, and sysfs doesn't support move zombie device,
+ * so we should move the device before conn device is destroyed.
+ */
+static int __match_tty(struct device *dev, const void *data)
+{
+ return !strncmp(dev_name(dev), "rfcomm", 6);
+}
+
void hci_conn_init_sysfs(struct hci_conn *conn)
{
struct hci_dev *hdev = conn->hdev;
@@ -29,7 +42,7 @@ void hci_conn_init_sysfs(struct hci_conn *conn)
conn->dev.type = &bt_link;
conn->dev.class = &bt_class;
- conn->dev.parent = &hdev->dev;
+ conn->dev.parent = get_device(&hdev->dev);
device_initialize(&conn->dev);
}
@@ -69,7 +82,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn)
while (1) {
struct device *dev;
- dev = device_find_any_child(&conn->dev);
+ dev = device_find_child(&conn->dev, NULL, __match_tty);
if (!dev)
break;
device_move(dev, NULL, DPM_ORDER_DEV_LAST);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 381/733] Bluetooth: btusb: mediatek: Fix leaked runtime PM reference in reset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (379 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 380/733] Bluetooth: hci_sysfs: Fix NULL pointer dereference in device_del() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 382/733] Bluetooth: btusb: Fix leaked runtime PM reference in btusb_reset Greg Kroah-Hartman
` (363 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiajia Liu, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiajia Liu <liujiajia@kylinos.cn>
[ Upstream commit e486a891c412d9d82ee865987f4eead6196e1f96 ]
MT7925 on HP Pro Mini 260 sometimes timed out during reloading driver
and reset usb device. btusb_suspend is not called again after closing
bluetooth interface.
usbcore: registered new interface driver btusb
Bluetooth: hci0: HW/SW Version: 0x00000000, Build Time: 20260605184935
Bluetooth: hci0: Execution of wmt command timed out
Bluetooth: hci0: Failed to send wmt patch dwnld (-110)
Bluetooth: hci0: Failed to set up firmware (-110)
usb 3-10: reset high-speed USB device number 4 using xhci_hcd
Bluetooth: hci0: HW/SW Version: 0x00000000, Build Time: 20260605184935
Bluetooth: hci0: Device setup in 1856545 usecs
Bluetooth: hci0: AOSP extensions version v1.00
Bluetooth: hci0: AOSP quality report is supported
Bluetooth: MGMT ver 1.23
btusb_mtk_reset calls usb_autopm_get_interface to resume the device
before driving the hardware reset, but never calls the matching
usb_autopm_put_interface. Every hardware reset therefore leaks a PM
usage reference of the interface, preventing the device from being
runtime suspended again until it is unbound.
Add the BTUSB_RESET flag. It is set before usb_queue_reset_device
and is cleared in btusb_disconnect, which drops the reference as well.
If the flag is already set when a new reset is requested, drop one
reference.
Also clear BTMTK_HW_RESET_ACTIVE if usb_autopm_get_interface fails,
otherwise no further reset could ever be attempted.
Fixes: 25b6d7593a3a ("Bluetooth: btmtk: introduce btmtk reset work")
Assisted-by: Claude:qwen3.8-max
Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btusb.c | 14 +++++++++++++-
1 file changed, 13 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index 53baf56b9dd96..f91a828f4b23b 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -970,6 +970,7 @@ struct qca_dump_info {
#define BTUSB_ALT6_CONTINUOUS_TX 16
#define BTUSB_HW_SSR_ACTIVE 17
#define BTUSB_WAKEUP_BROKEN 18
+#define BTUSB_RESET 19
struct btusb_data {
struct hci_dev *hdev;
@@ -2911,8 +2912,11 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
}
err = usb_autopm_get_interface(data->intf);
- if (err < 0)
+ if (err < 0) {
+ bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
+ clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
return err;
+ }
/* Release MediaTek ISO data interface */
btusb_mtk_release_iso_intf(hdev);
@@ -2935,6 +2939,11 @@ static int btusb_mtk_reset(struct hci_dev *hdev, void *rst_data)
err = btmtk_usb_subsys_reset(hdev, btmtk_data->dev_id);
+ if (test_and_set_bit(BTUSB_RESET, &data->flags)) {
+ bt_dev_err(hdev, "last usb reset failed? Resetting again");
+ usb_autopm_put_interface_no_suspend(data->intf);
+ }
+
usb_queue_reset_device(data->intf);
clear_bit(BTMTK_HW_RESET_ACTIVE, &btmtk_data->flags);
@@ -4572,6 +4581,9 @@ static void btusb_disconnect(struct usb_interface *intf)
if (data->reset_gpio)
gpiod_put(data->reset_gpio);
+ if (test_and_clear_bit(BTUSB_RESET, &data->flags))
+ usb_autopm_put_interface_no_suspend(data->intf);
+
if (intf == data->intf) {
if (data->isoc)
usb_driver_release_interface(&btusb_driver, data->isoc);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 382/733] Bluetooth: btusb: Fix leaked runtime PM reference in btusb_reset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (380 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 381/733] Bluetooth: btusb: mediatek: Fix leaked runtime PM reference in reset Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 383/733] net: mana: Clear RDMA teardown and suspend state in mana_rdma_probe() Greg Kroah-Hartman
` (362 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiajia Liu, Luiz Augusto von Dentz,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiajia Liu <liujiajia@kylinos.cn>
[ Upstream commit c93922dd316b7273a8667d29084632066fa8a2d3 ]
btusb_reset calls usb_autopm_get_interface to resume the device
before queuing a reset of it, but never calls the matching
usb_autopm_put_interface.
usb_queue_reset_device ends up in usb_reset_device(), and since
btusb provides no pre_reset/post_reset callbacks the interface is
merely unbound and rebound: the interface device object survives
this cycle, and so does its PM usage count, which is not cleared
when the driver is unbound.
As a result every reset permanently leaks a PM usage reference,
preventing the interface from being runtime suspended again until
it is unbound.
Set BTUSB_RESET flag before usb_queue_reset_device so that
btusb_disconnect drops the reference. If the flag is already set,
drop one reference.
Fixes: c9209b269afd ("Bluetooth: btusb: Introduce generic USB reset")
Assisted-by: Claude:qwen3.8-max
Signed-off-by: Jiajia Liu <liujiajia@kylinos.cn>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/bluetooth/btusb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/bluetooth/btusb.c b/drivers/bluetooth/btusb.c
index f91a828f4b23b..84f55f67523e0 100644
--- a/drivers/bluetooth/btusb.c
+++ b/drivers/bluetooth/btusb.c
@@ -1047,13 +1047,15 @@ static void btusb_reset(struct hci_dev *hdev)
int err;
data = hci_get_drvdata(hdev);
- /* This is not an unbalanced PM reference since the device will reset */
err = usb_autopm_get_interface(data->intf);
if (err) {
bt_dev_err(hdev, "Failed usb_autopm_get_interface: %d", err);
return;
}
+ if (test_and_set_bit(BTUSB_RESET, &data->flags))
+ usb_autopm_put_interface_no_suspend(data->intf);
+
bt_dev_err(hdev, "Resetting usb device.");
usb_queue_reset_device(data->intf);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 383/733] net: mana: Clear RDMA teardown and suspend state in mana_rdma_probe()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (381 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 382/733] Bluetooth: btusb: Fix leaked runtime PM reference in btusb_reset Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 384/733] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings() Greg Kroah-Hartman
` (361 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Long Li, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <longli@microsoft.com>
[ Upstream commit f6d61fe4c19cf448e5cba6d8767b4e6966f58606 ]
mana_rdma_remove() sets gd->rdma_teardown to stop
mana_rdma_service_handle() from acting on servicing events, but nothing
ever clears it. A hardware service reset (GDMA_EQE_HWC_RESET_REQUEST)
goes through mana_gd_suspend() -> mana_rdma_remove() and mana_gd_resume()
-> mana_rdma_probe(), so from the first reset onwards every
GDMA_EQE_HWC_SOC_SERVICE event returns early and RDMA suspend/resume
servicing is silently dropped for the life of the device.
gd->is_suspended has the same problem: it is set when servicing removes
the adev and is cleared only by a matching resume. A reset while RDMA is
suspended re-adds the adev but leaves is_suspended set, so a later resume
event calls add_adev() on top of a live gd->adev and leaks it. This is
currently masked by the rdma_teardown bug.
Clear both in mana_rdma_probe(). On the reset path mana_rdma_remove()
has closed the gate and drained the service workqueue, so clear
is_suspended first and re-open the gate with smp_store_release(), paired
with smp_load_acquire() in the handler, so the handler cannot observe an
open gate with a stale is_suspended. On the initial probe path the gate
was never closed and both flags are already clear.
This does not order gd->adev, which add_adev() publishes afterwards. A
servicing event arriving in that window is still dropped, as it is in
mainline today on the initial probe path; closing it needs probe and the
handler to be serialized and is left to a separate change.
Fixes: 505cc26bcae0 ("net: mana: Add support for auxiliary device servicing events")
Signed-off-by: Long Li <longli@microsoft.com>
Link: https://patch.msgid.link/20260902175153.3410560-1-longli@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/microsoft/mana/mana_en.c | 18 +++++++++++++++++-
1 file changed, 17 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/microsoft/mana/mana_en.c b/drivers/net/ethernet/microsoft/mana/mana_en.c
index 92bb55935c1c4..b2a6f6369bc3c 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -3728,7 +3728,8 @@ static void mana_rdma_service_handle(struct work_struct *work)
struct device *dev = gd->gdma_context->dev;
int ret;
- if (READ_ONCE(gd->rdma_teardown))
+ /* Pairs with the smp_store_release() in mana_rdma_probe(). */
+ if (smp_load_acquire(&gd->rdma_teardown))
goto out;
switch (serv_work->event) {
@@ -4024,6 +4025,21 @@ int mana_rdma_probe(struct gdma_dev *gd)
if (err)
return err;
+ /* Clear the state left by a previous mana_rdma_remove() so servicing
+ * events are handled again after a reset cycle.
+ */
+ gd->is_suspended = false;
+
+ /* Publish is_suspended before re-opening the gate, so the handler
+ * cannot observe an open gate with a stale is_suspended. Pairs
+ * with the smp_load_acquire() in mana_rdma_service_handle(). This
+ * matters on the reset path, where mana_rdma_remove() closed the
+ * gate and drained the workqueue; on the initial probe path the
+ * gate was never closed and both flags are already clear. It does
+ * not order gd->adev, which add_adev() publishes below.
+ */
+ smp_store_release(&gd->rdma_teardown, false);
+
err = add_adev(gd, "rdma");
if (err)
mana_gd_deregister_device(gd);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 384/733] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (382 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 383/733] net: mana: Clear RDMA teardown and suspend state in mana_rdma_probe() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 385/733] net: macb: destroy the phylink instance on the probe error path Greg Kroah-Hartman
` (360 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+a73e5ee0fd534fed75bd,
Naman Gulati, Kuniyuki Iwashima, Ido Schimmel,
Fernando Fernandez Mancera, Eric Dumazet, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naman Gulati <namangulati@google.com>
[ Upstream commit cdca92eddc025fdb90071be97738f7d55a65f8dd ]
syzbot reported a null-ptr-deref in __ip6_del_rt_siblings() [0].
The stack trace hinted towards a null dereference of rt->fib6_node when
fn->leaf is accessed in __ip6_del_rt_siblings(). With
RTNL_FLAG_DOIT_UNLOCKED set, inet6_rtm_delroute() operations run
concurrently without acquiring the RTNL lock. In ip6_route_del(), the
route lookup happens under rcu_read_lock() without acquiring
table->tb6_lock.
Between ip6_route_del() looking up the route and __ip6_del_rt_siblings()
acquiring table->tb6_lock, another thread can modify the routing table.
For example, when an ECMP route is replaced via RTM_NEWROUTE with
NLM_F_REPLACE, fib6_add_rt2node() unlinks all old siblings and sets
iter->fib6_node = NULL. A reproducer was found that triggers this [1].
Add a check to ensure rt->fib6_node is non-null before accessing it.
[0]
KASAN: null-ptr-deref in range [0x0000000000000020-0x0000000000000027]
RIP: 0010:__ip6_del_rt_siblings+0x31e/0x7c0 net/ipv6/route.c:4056
Call Trace:
<TASK>
ip6_route_del+0x1054/0x1110 net/ipv6/route.c:4232
inet6_rtm_delroute+0x5d7/0x6d0 net/ipv6/route.c:5669
rtnetlink_rcv_msg+0x802/0xc00 net/core/rtnetlink.c:7132
netlink_rcv_skb+0x226/0x4a0 net/netlink/af_netlink.c:2556
netlink_unicast_kernel net/netlink/af_netlink.c:1319 [inline]
netlink_unicast+0x7f5/0x990 net/netlink/af_netlink.c:1345
netlink_sendmsg+0x813/0xb40 net/netlink/af_netlink.c:1900
sock_sendmsg_nosec+0x13a/0x180 net/socket.c:800
__sock_sendmsg net/socket.c:815 [inline]
____sys_sendmsg+0x565/0x870 net/socket.c:2713
___sys_sendmsg+0x2a5/0x360 net/socket.c:2767
__sys_sendmsg net/socket.c:2799 [inline]
__do_sys_sendmsg net/socket.c:2804 [inline]
__se_sys_sendmsg net/socket.c:2802 [inline]
__x64_sys_sendmsg+0x1b7/0x290 net/socket.c:2802
do_syscall_x64 arch/x86/entry/syscall_64.c:61 [inline]
do_syscall_64+0x166/0x520 arch/x86/entry/syscall_64.c:84
entry_SYSCALL_64_after_hwframe+0x77/0x7f
</TASK>
[1] https://gist.github.com/NamanGulati/0766a1159b6ca61928faaf87425ff899
Fixes: bd11ff421d36 ("ipv6: Get rid of RTNL for SIOCDELRT and RTM_DELROUTE.")
Reported-by: syzbot+a73e5ee0fd534fed75bd@syzkaller.appspotmail.com
Closes: https://lore.kernel.org/netdev/6a9b03f9.04649fcc.10325f.0003.GAE@google.com
Signed-off-by: Naman Gulati <namangulati@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260904180645.706425-1-namangulati@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/ipv6/route.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
diff --git a/net/ipv6/route.c b/net/ipv6/route.c
index dc9060af5bb1e..ee707e48f4efa 100644
--- a/net/ipv6/route.c
+++ b/net/ipv6/route.c
@@ -4010,6 +4010,7 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
struct net *net = info->nl_net;
struct sk_buff *skb = NULL;
struct fib6_table *table;
+ struct fib6_node *fn;
int err = -ENOENT;
if (rt == net->ipv6.fib6_null_entry)
@@ -4017,9 +4018,13 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
table = rt->fib6_table;
spin_lock_bh(&table->tb6_lock);
+ fn = rcu_dereference_protected(rt->fib6_node,
+ lockdep_is_held(&table->tb6_lock));
+ if (!fn)
+ goto out_unlock;
+
if (rt->fib6_nsiblings && cfg->fc_delete_all_nh) {
struct fib6_info *sibling, *next_sibling;
- struct fib6_node *fn;
/* prefer to send a single notification with all hops */
skb = nlmsg_new(rt6_nlmsg_size(rt), GFP_ATOMIC);
@@ -4041,8 +4046,6 @@ static int __ip6_del_rt_siblings(struct fib6_info *rt, struct fib6_config *cfg)
* and emit a replace or delete notification, respectively.
*/
info->skip_notify_kernel = 1;
- fn = rcu_dereference_protected(rt->fib6_node,
- lockdep_is_held(&table->tb6_lock));
if (rcu_access_pointer(fn->leaf) == rt) {
struct fib6_info *last_sibling, *replace_rt;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 385/733] net: macb: destroy the phylink instance on the probe error path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (383 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 384/733] ipv6: null-check fib6_node before accessing in __ip6_del_rt_siblings() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 386/733] net: macb: put the "mdio" child node reference on success Greg Kroah-Hartman
` (359 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolai Buchwitz <nb@tipi-net.de>
[ Upstream commit 7d059f390750152b9bd69df934198651b94fc26d ]
macb_mii_init() creates a phylink instance on both of its success paths,
but the probe unwind frees the netdev without destroying it, so a failing
macb_alloc_tieoff() or register_netdev() leaks the instance.
Destroy it at err_out_unregister_mdio, which is only reachable once
macb_mii_init() has succeeded, so bp->phylink is valid there.
Fixes: 7897b071ac3b ("net: macb: convert to phylink")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260907210856.1673589-2-nb@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb_main.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 55ed40a0a6062..404aebe01ed01 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5968,6 +5968,7 @@ static int macb_probe(struct platform_device *pdev)
mdiobus_unregister(bp->mii_bus);
mdiobus_free(bp->mii_bus);
}
+ phylink_destroy(bp->phylink);
err_out_phy_exit:
phy_exit(bp->phy);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 386/733] net: macb: put the "mdio" child node reference on success
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (384 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 385/733] net: macb: destroy the phylink instance on the probe error path Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 387/733] nstree: check listing permission before taking a namespace reference Greg Kroah-Hartman
` (358 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolai Buchwitz, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolai Buchwitz <nb@tipi-net.de>
[ Upstream commit 382a373d9ea7a6ac4de9c022385b6217f65ae3cc ]
macb_mii_init() holds the reference returned by of_get_child_by_name()
for macb_mdiobus_register() and drops it only on the error paths, so
every successful probe leaks a node reference. On a CM5, overlay
removal after four bind cycles reports
OF: ERROR: memory leak, expected refcount 1 instead of 5
Drop the reference after registration, where __mdiobus_register() has
already taken its own for the lifetime of the bus.
Fixes: 8a6631f1cece ("net: macb: avoid redundant lookup for "mdio" child node in MDIO setup")
Signed-off-by: Nicolai Buchwitz <nb@tipi-net.de>
Link: https://patch.msgid.link/20260907210856.1673589-3-nb@tipi-net.de
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/cadence/macb_main.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/cadence/macb_main.c b/drivers/net/ethernet/cadence/macb_main.c
index 404aebe01ed01..9a59dd0df61a9 100644
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -1164,6 +1164,8 @@ static int macb_mii_init(struct macb *bp)
if (err)
goto err_out_unregister_bus;
+ of_node_put(mdio_np);
+
return 0;
err_out_unregister_bus:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 387/733] nstree: check listing permission before taking a namespace reference
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (385 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 386/733] net: macb: put the "mdio" child node reference on success Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 388/733] drm/xe: Guard page-fault worker with runtime PM check Greg Kroah-Hartman
` (357 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Bradley Morgan,
Christian Brauner (Amutable), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
[ Upstream commit 56ea4e86832d8abe8930394473566c194d189f85 ]
legitimize_ns() takes a reference on the candidate namespace before
may_list_ns() has decided whether the caller may see it. The
__free(ns_put) cleanup on the denied path can drop the last reference to a
mount namespace while we still hold the rcu read lock, and put_mnt_ns()
may sleep there. This is the same problem commit 2ec2aff3c8e2 ("ns: make
sure reference are dropped outside of rcu lock") fixed for the put_user()
path. Neither ns_requested() nor may_list_ns() needs a reference, both
only look at the namespace type and at the caller's own namespaces, so do
the checks first and take the reference last.
Splat:
Voluntary context switch within RCU read-side critical section!
WARNING: kernel/rcu/tree_plugin.h:332 at rcu_note_context_switch+0x238/0x2a0, CPU#5: a/3442
CPU: 5 UID: 1000 PID: 3442 Comm: a Not tainted 7.0.0-30-generic #30-Ubuntu PREEMPT(lazy)
RIP: 0010:rcu_note_context_switch+0x238/0x2a0
Call Trace:
<TASK>
__schedule+0xcf/0x650
schedule+0x27/0x90
schedule_preempt_disabled+0x15/0x30
__mutex_lock.constprop.0+0x550/0xaf0
__mutex_lock_slowpath+0x13/0x20
mutex_lock+0x3b/0x50
exp_funnel_lock+0xb2/0x260
synchronize_rcu_expedited+0xe7/0x220
namespace_unlock+0x26a/0x320
put_mnt_ns+0xd3/0x120
mntns_put+0xe/0x20
do_listns+0x13e/0x560
__do_sys_listns+0x126/0x2d0
__x64_sys_listns+0x20/0x30
x64_sys_call+0x2366/0x2390
do_syscall_64+0x105/0x5a0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
</TASK>
Fixes: 76b6f5dfb3fd ("nstree: add listns()")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Link: https://patch.msgid.link/ABA32239-733B-438C-B95A-B13ED69FF0F3@doyensec.com
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/nstree.c | 10 ++--------
1 file changed, 2 insertions(+), 8 deletions(-)
diff --git a/kernel/nstree.c b/kernel/nstree.c
index 6d12e5900ac01..831f279d174a3 100644
--- a/kernel/nstree.c
+++ b/kernel/nstree.c
@@ -533,19 +533,13 @@ DEFINE_FREE(ns_put, struct ns_common *, if (!IS_ERR_OR_NULL(_T)) ns_put(_T))
static inline struct ns_common *__must_check legitimize_ns(const struct klistns *kls,
struct ns_common *candidate)
{
- struct ns_common *ns __free(ns_put) = NULL;
-
if (!ns_requested(kls, candidate))
return NULL;
- ns = ns_get_unless_inactive(candidate);
- if (!ns)
- return NULL;
-
- if (!may_list_ns(kls, ns))
+ if (!may_list_ns(kls, candidate))
return NULL;
- return no_free_ptr(ns);
+ return ns_get_unless_inactive(candidate);
}
static ssize_t do_listns_userns(struct klistns *kls)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 388/733] drm/xe: Guard page-fault worker with runtime PM check
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (386 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 387/733] nstree: check listing permission before taking a namespace reference Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 389/733] mptcp: remove unneeded READ_ONCE() annotation Greg Kroah-Hartman
` (356 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Varun Gupta, Matthew Brost,
Tejas Upadhyay, Rodrigo Vivi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varun Gupta <varun.gupta@intel.com>
[ Upstream commit 20fce5b34b21a995839743b4917a1edd2fd503ba ]
During VM teardown, the VM's runtime PM reference is dropped
asynchronously, allowing the device to autosuspend while stale page
faults belonging to the now-dead VM are still queued. When the
page-fault worker later tries to ack one of these, it calls into
guc_ct_send_locked() on an already-suspended device, tripping:
Assertion `!xe_pm_runtime_suspended(xe)` failed!
WARNING at xe_device.c:1267 xe_device_assert_mem_access+0x11c/0x140 [xe]
A live VM/exec queue always holds a PM reference while it has
outstanding work, so if the device is suspended at ack time, the
owning context is already gone and the fault is stale.
Take a runtime PM reference across the entire pagefault
queue worker to safely deliver acks for torn-down VMs.
v3:
- Move PM ref to the generic xe_pagefault_queue_work using
guard(xe_pm_runtime)(xe) instead of tracking it in the GuC
backend(Matt Brost).
v2:
- Hold PM ref across the entire batch (begin/end) instead of per-ack.
This prevents the device from autosuspending mid-batch, which would
leave write_only acks written but the end flush skipped, and skip
counter++, desyncing the cadence check.(Himal)
- Add a comment explaining stale faults.(Himal)
Fixes: f289f7807119 ("drm/xe: Add xe_guc_pagefault layer")
Signed-off-by: Varun Gupta <varun.gupta@intel.com>
Reviewed-by: Matthew Brost <matthew.brost@intel.com>
Reviewed-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
Link: https://patch.msgid.link/20260907050011.497181-2-varun.gupta@intel.com
Signed-off-by: Tejas Upadhyay <tejas.upadhyay@intel.com>
(cherry picked from commit fcc2431d2213dc4d04250c4f1ae87d9c3ae0d455)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
[Rodrigo: Added xe_device struct for compatibility while cherry-picking]
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/gpu/drm/xe/xe_pagefault.c | 10 ++++++++++
drivers/gpu/drm/xe/xe_pagefault_types.h | 3 +++
2 files changed, 13 insertions(+)
diff --git a/drivers/gpu/drm/xe/xe_pagefault.c b/drivers/gpu/drm/xe/xe_pagefault.c
index dbf8f71d3328a..a4986df8328d6 100644
--- a/drivers/gpu/drm/xe/xe_pagefault.c
+++ b/drivers/gpu/drm/xe/xe_pagefault.c
@@ -16,6 +16,7 @@
#include "xe_hw_engine.h"
#include "xe_pagefault.h"
#include "xe_pagefault_types.h"
+#include "xe_pm.h"
#include "xe_svm.h"
#include "xe_trace_bo.h"
#include "xe_vm.h"
@@ -292,9 +293,17 @@ static void xe_pagefault_queue_work(struct work_struct *w)
{
struct xe_pagefault_queue *pf_queue =
container_of(w, typeof(*pf_queue), worker);
+ struct xe_device *xe = pf_queue->xe;
struct xe_pagefault pf;
unsigned long threshold;
+ /*
+ * A live VM holds a PM reference, but a torn-down VM does not.
+ * Guard the entire worker loop to safely drain stale faults and
+ * prevent autosuspends from desyncing batched CT flushes.
+ */
+ guard(xe_pm_runtime)(xe);
+
#define USM_QUEUE_MAX_RUNTIME_MS 20
threshold = jiffies + msecs_to_jiffies(USM_QUEUE_MAX_RUNTIME_MS);
@@ -365,6 +374,7 @@ static int xe_pagefault_queue_init(struct xe_device *xe,
drm_dbg(&xe->drm, "xe_pagefault_entry_size=%d, total_num_eus=%d, pf_queue->size=%u",
xe_pagefault_entry_size(), total_num_eus, pf_queue->size);
+ pf_queue->xe = xe;
spin_lock_init(&pf_queue->lock);
INIT_WORK(&pf_queue->worker, xe_pagefault_queue_work);
diff --git a/drivers/gpu/drm/xe/xe_pagefault_types.h b/drivers/gpu/drm/xe/xe_pagefault_types.h
index c4ee625b93ddd..f63a12aa0d4f7 100644
--- a/drivers/gpu/drm/xe/xe_pagefault_types.h
+++ b/drivers/gpu/drm/xe/xe_pagefault_types.h
@@ -8,6 +8,7 @@
#include <linux/workqueue.h>
+struct xe_device;
struct xe_gt;
struct xe_pagefault;
@@ -118,6 +119,8 @@ struct xe_pagefault {
* queue to absorb the device’s worst-case number of outstanding faults.
*/
struct xe_pagefault_queue {
+ /** @xe: Back-pointer to the Xe device */
+ struct xe_device *xe;
/**
* @data: Data in queue containing struct xe_pagefault, protected by
* @lock
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 389/733] mptcp: remove unneeded READ_ONCE() annotation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (387 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 388/733] drm/xe: Guard page-fault worker with runtime PM check Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 390/733] watchdog: fix hrtimer start when pretimeout is zero Greg Kroah-Hartman
` (355 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Matthieu Baerts (NGI0),
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <pabeni@redhat.com>
[ Upstream commit caa4a79f74f32084ce28aee8653bc04df745970d ]
The subflow->fully_established flag is always written under the subflow
socket lock. Reading such value under the same lock does not require any
ONCE annotation.
Fixes: 581c8cbfa934 ("mptcp: annotate data-races around subflow->fully_established")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-10-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/mptcp/options.c | 4 ++--
net/mptcp/protocol.c | 2 +-
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 1057d500577b0..6e208b4e024a6 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -529,7 +529,7 @@ static bool mptcp_established_options_mp(struct sock *sk, struct sk_buff *skb,
return false;
/* MPC/MPJ needed only on 3rd ack packet, DATA_FIN and TCP shutdown take precedence */
- if (READ_ONCE(subflow->fully_established) || snd_data_fin_enable ||
+ if (subflow->fully_established || snd_data_fin_enable ||
subflow->snd_isn != TCP_SKB_CB(skb)->seq ||
sk->sk_state != TCP_ESTABLISHED)
return false;
@@ -980,7 +980,7 @@ static bool check_fully_established(struct mptcp_sock *msk, struct sock *ssk,
/* here we can process OoO, in-window pkts, only in-sequence 4th ack
* will make the subflow fully established
*/
- if (likely(READ_ONCE(subflow->fully_established))) {
+ if (likely(subflow->fully_established)) {
/* on passive sockets, check for 3rd ack retransmission
* note that msk is always set by subflow_syn_recv_sock()
* for mp_join subflows
diff --git a/net/mptcp/protocol.c b/net/mptcp/protocol.c
index 8adf699894e32..5c6923fdcad08 100644
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3743,7 +3743,7 @@ static void schedule_3rdack_retransmission(struct sock *ssk)
struct tcp_sock *tp = tcp_sk(ssk);
unsigned long timeout;
- if (READ_ONCE(mptcp_subflow_ctx(ssk)->fully_established))
+ if (mptcp_subflow_ctx(ssk)->fully_established)
return;
/* reschedule with a timeout above RTT, as we must look only for drop */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 390/733] watchdog: fix hrtimer start when pretimeout is zero
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (388 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 389/733] mptcp: remove unneeded READ_ONCE() annotation Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 391/733] watchdog: msc313e: Avoid division by zero Greg Kroah-Hartman
` (354 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Arcari, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Arcari <darcari@redhat.com>
[ Upstream commit 0fa37512eb747e4ffdcf367274f9e72845f1bca4 ]
Per the watchdog API, a pretimeout value of 0 disables the feature.
However, watchdog_hrtimer_pretimeout_start() fails to verify if the
pretimeout is non-zero before arming the timer.
This omission inadvertently starts the software pretimeout timer,
which could result in the pretimeout handler executing incorrectly
when the watchdog timeout is reached.
Fix this by adding a check for wdd->pretimeout before calling
hrtimer_start(), ensuring the disabled state is respected.
Fixes: 7b7d2fdc8c3e ("watchdog: Add hrtimer-based pretimeout feature")
Signed-off-by: David Arcari <darcari@redhat.com>
Link: https://patch.msgid.link/20260903182029.936030-1-darcari@redhat.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/watchdog_hrtimer_pretimeout.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/watchdog/watchdog_hrtimer_pretimeout.c b/drivers/watchdog/watchdog_hrtimer_pretimeout.c
index fbc7eecd8b203..49a05ea60c979 100644
--- a/drivers/watchdog/watchdog_hrtimer_pretimeout.c
+++ b/drivers/watchdog/watchdog_hrtimer_pretimeout.c
@@ -30,6 +30,7 @@ void watchdog_hrtimer_pretimeout_init(struct watchdog_device *wdd)
void watchdog_hrtimer_pretimeout_start(struct watchdog_device *wdd)
{
if (!(wdd->info->options & WDIOF_PRETIMEOUT) &&
+ wdd->pretimeout &&
!watchdog_pretimeout_invalid(wdd, wdd->pretimeout))
hrtimer_start(&wdd->wd_data->pretimeout_timer,
ktime_set(wdd->timeout - wdd->pretimeout, 0),
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 391/733] watchdog: msc313e: Avoid division by zero
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (389 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 390/733] watchdog: fix hrtimer start when pretimeout is zero Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 392/733] watchdog: msc313e: Fix clock leak and spurious timer in settimeout() Greg Kroah-Hartman
` (353 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 3c73a37f5e40972ce26d8eeb98e8b938d719b069 ]
clk_get_rate() could return 0. Avoid a division by zero panic.
Fixes: e9800b799464 ("watchdog: Add Mstar MSC313e WDT driver")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260828161348.13212-3-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index f69d66971c41d..c3018b9701641 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -97,6 +97,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
{
struct device *dev = &pdev->dev;
struct msc313e_wdt_priv *priv;
+ unsigned long rate;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -116,7 +117,10 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
priv->wdev.ops = &msc313e_wdt_ops,
priv->wdev.parent = dev;
priv->wdev.min_timeout = MSC313E_WDT_MIN_TIMEOUT;
- priv->wdev.max_timeout = U32_MAX / clk_get_rate(priv->clk);
+ rate = clk_get_rate(priv->clk);
+ if (!rate)
+ return -EINVAL;
+ priv->wdev.max_timeout = U32_MAX / rate;
priv->wdev.timeout = MSC313E_WDT_DEFAULT_TIMEOUT;
/* If the period is non-zero the WDT is running */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 392/733] watchdog: msc313e: Fix clock leak and spurious timer in settimeout()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (390 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 391/733] watchdog: msc313e: Avoid division by zero Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 393/733] watchdog: msc313e: Enable clock before accessing hardware registers Greg Kroah-Hartman
` (352 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 3db30f315935c2fb0d95f46b7a593b5b4d3ec3d0 ]
msc313e_wdt_settimeout() unconditionally calls msc313e_wdt_start() which
introduces two severe bugs:
1. If the watchdog is already active, calling start() again will
increase the reference count of the clock again. However stop() is
only called once, the reference count is unbalance.
2. If the watchdog is stopped, calling settimeout() will start
the hardware timer accidentally.
Factor out the register-writing logic into a helper function. Only call
it in settimeout() if the watchdog is running. Otherwise, simply update
`wdev->timeout`.
Fixes: e9800b799464 ("watchdog: Add Mstar MSC313e WDT driver")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260828161348.13212-4-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 22 ++++++++++++++++------
1 file changed, 16 insertions(+), 6 deletions(-)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index c3018b9701641..8ce24df8e338b 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -31,20 +31,26 @@ struct msc313e_wdt_priv {
struct clk *clk;
};
+static void msc313e_wdt_set_hw_timeout(struct msc313e_wdt_priv *priv,
+ unsigned int timeout)
+{
+ u32 t = timeout * clk_get_rate(priv->clk);
+
+ writew(t & 0xffff, priv->base + REG_WDT_MAX_PRD_L);
+ writew((t >> 16) & 0xffff, priv->base + REG_WDT_MAX_PRD_H);
+ writew(1, priv->base + REG_WDT_CLR);
+}
+
static int msc313e_wdt_start(struct watchdog_device *wdev)
{
struct msc313e_wdt_priv *priv = watchdog_get_drvdata(wdev);
- u32 timeout;
int err;
err = clk_prepare_enable(priv->clk);
if (err)
return err;
- timeout = wdev->timeout * clk_get_rate(priv->clk);
- writew(timeout & 0xffff, priv->base + REG_WDT_MAX_PRD_L);
- writew((timeout >> 16) & 0xffff, priv->base + REG_WDT_MAX_PRD_H);
- writew(1, priv->base + REG_WDT_CLR);
+ msc313e_wdt_set_hw_timeout(priv, wdev->timeout);
return 0;
}
@@ -69,9 +75,13 @@ static int msc313e_wdt_stop(struct watchdog_device *wdev)
static int msc313e_wdt_settimeout(struct watchdog_device *wdev, unsigned int new_time)
{
+ struct msc313e_wdt_priv *priv = watchdog_get_drvdata(wdev);
+
wdev->timeout = new_time;
- return msc313e_wdt_start(wdev);
+ if (watchdog_hw_running(wdev) || watchdog_active(wdev))
+ msc313e_wdt_set_hw_timeout(priv, wdev->timeout);
+ return 0;
}
static const struct watchdog_info msc313e_wdt_ident = {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 393/733] watchdog: msc313e: Enable clock before accessing hardware registers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (391 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 392/733] watchdog: msc313e: Fix clock leak and spurious timer in settimeout() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 394/733] watchdog: msc313e: Fix spurious reset on suspend Greg Kroah-Hartman
` (351 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 3db2df24e7f11fb117718f6abe326628d91bc500 ]
msc313e_wdt_probe() reads from hardware registers without ensuring the
required clock is enabled. Furthermore, if the bootloader leaves the
watchdog running, msc313e_wdt_probe() sets WDOG_HW_RUNNING without
increasing the clock's reference count.
While the clock is currently supplied as a fixed clock by the device
tree (`xtal_div2` in arch/arm/boot/dts/sigmastar/mstar-v7.dtsi) which
masks the physical issue, this still violates the API usage.
Call clk_prepare_enable() before reading WDT registers. If the WDT is
running, leave the clock enabled so the CCF reference counter is
balanced.
Fixes: ffd264bd152c ("watchdog: msc313e: Check if the WDT was running at boot")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260828161348.13212-5-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 23 +++++++++++++++++++++--
1 file changed, 21 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index 8ce24df8e338b..7c45935667818 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -108,6 +108,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
struct device *dev = &pdev->dev;
struct msc313e_wdt_priv *priv;
unsigned long rate;
+ int ret;
priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
@@ -133,9 +134,21 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
priv->wdev.max_timeout = U32_MAX / rate;
priv->wdev.timeout = MSC313E_WDT_DEFAULT_TIMEOUT;
+ ret = clk_prepare_enable(priv->clk);
+ if (ret)
+ return ret;
+
/* If the period is non-zero the WDT is running */
- if (readw(priv->base + REG_WDT_MAX_PRD_L) | (readw(priv->base + REG_WDT_MAX_PRD_H) << 16))
+ if (readw(priv->base + REG_WDT_MAX_PRD_L) | (readw(priv->base + REG_WDT_MAX_PRD_H) << 16)) {
set_bit(WDOG_HW_RUNNING, &priv->wdev.status);
+ /*
+ * Keep the clock enabled. The watchdog core will skip the next
+ * start() and a future stop() will balance the CCF reference
+ * count.
+ */
+ } else {
+ clk_disable_unprepare(priv->clk);
+ }
watchdog_set_drvdata(&priv->wdev, priv);
platform_set_drvdata(pdev, priv);
@@ -144,7 +157,13 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
watchdog_stop_on_reboot(&priv->wdev);
watchdog_stop_on_unregister(&priv->wdev);
- return devm_watchdog_register_device(dev, &priv->wdev);
+ ret = devm_watchdog_register_device(dev, &priv->wdev);
+
+ /* If the WDT is running and anything goes wrong, disable the clock. */
+ if (ret && test_bit(WDOG_HW_RUNNING, &priv->wdev.status))
+ clk_disable_unprepare(priv->clk);
+
+ return ret;
}
static int __maybe_unused msc313e_wdt_suspend(struct device *dev)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 394/733] watchdog: msc313e: Fix spurious reset on suspend
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (392 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 393/733] watchdog: msc313e: Enable clock before accessing hardware registers Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 395/733] watchdog: msc313e: Fix undefined behavior Greg Kroah-Hartman
` (350 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 4f6817c9eff4aa1078e16652d82e4b7ef4ffae3e ]
If the hardware watchdog was started by the bootloader and the device is
suspended before userspace opens it, the ping worker (from watchdog
core) is frozen and the active hardware timer continues running. This
leads to a spurious system reset.
Check both watchdog_active() and watchdog_hw_running() when deciding
whether to start or stop the watchdog during suspend and resume.
Additionally, call watchdog_stop_ping_on_suspend() to ensure the ping
worker be correctly paused and restarted during suspend and resume.
Fixes: ffd264bd152c ("watchdog: msc313e: Check if the WDT was running at boot")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260828161348.13212-6-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index 7c45935667818..c7d558fefc860 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -156,6 +156,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
watchdog_init_timeout(&priv->wdev, timeout, dev);
watchdog_stop_on_reboot(&priv->wdev);
watchdog_stop_on_unregister(&priv->wdev);
+ watchdog_stop_ping_on_suspend(&priv->wdev);
ret = devm_watchdog_register_device(dev, &priv->wdev);
@@ -170,7 +171,7 @@ static int __maybe_unused msc313e_wdt_suspend(struct device *dev)
{
struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);
- if (watchdog_active(&priv->wdev))
+ if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev))
msc313e_wdt_stop(&priv->wdev);
return 0;
@@ -180,7 +181,7 @@ static int __maybe_unused msc313e_wdt_resume(struct device *dev)
{
struct msc313e_wdt_priv *priv = dev_get_drvdata(dev);
- if (watchdog_active(&priv->wdev))
+ if (watchdog_active(&priv->wdev) || watchdog_hw_running(&priv->wdev))
msc313e_wdt_start(&priv->wdev);
return 0;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 395/733] watchdog: msc313e: Fix undefined behavior
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (393 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 394/733] watchdog: msc313e: Fix spurious reset on suspend Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 396/733] watchdog: msc313e: Sync timeout value if WDT was running at boot Greg Kroah-Hartman
` (349 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit ab390021b2a3bb4cc875f28a6f76d13de90d7457 ]
readw() returns a u16. Left shifting a u16 by 16 bits yields undefined
behavior.
Cast to u32 explicitly before the shift.
Fixes: ffd264bd152c ("watchdog: msc313e: Check if the WDT was running at boot")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260828161348.13212-7-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 12 +++++++++++-
1 file changed, 11 insertions(+), 1 deletion(-)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index c7d558fefc860..e28261c7a8d4c 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -31,6 +31,16 @@ struct msc313e_wdt_priv {
struct clk *clk;
};
+static u32 msc313e_wdt_get_hw_timeout(struct msc313e_wdt_priv *priv)
+{
+ u16 low, high;
+
+ low = readw(priv->base + REG_WDT_MAX_PRD_L);
+ high = readw(priv->base + REG_WDT_MAX_PRD_H);
+
+ return ((u32)high << 16) | low;
+}
+
static void msc313e_wdt_set_hw_timeout(struct msc313e_wdt_priv *priv,
unsigned int timeout)
{
@@ -139,7 +149,7 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
return ret;
/* If the period is non-zero the WDT is running */
- if (readw(priv->base + REG_WDT_MAX_PRD_L) | (readw(priv->base + REG_WDT_MAX_PRD_H) << 16)) {
+ if (msc313e_wdt_get_hw_timeout(priv)) {
set_bit(WDOG_HW_RUNNING, &priv->wdev.status);
/*
* Keep the clock enabled. The watchdog core will skip the next
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 396/733] watchdog: msc313e: Sync timeout value if WDT was running at boot
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (394 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 395/733] watchdog: msc313e: Fix undefined behavior Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 397/733] net: dsa: lantiq_gswip: fix GSWIP_MDIO_PHY_FCONTX_EN value Greg Kroah-Hartman
` (348 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tzung-Bi Shih, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tzung-Bi Shih <tzungbi@kernel.org>
[ Upstream commit 01504d14e47b34779911250dd308a03f6ef681c2 ]
If WDT was running at boot, the hardware timeout might be set to values
other than the final software timeout.
To be consistent, set the hardware timeout to match the final software
timeout (i.e., after watchdog_init_timeout()) if WDT was running.
Fixes: ffd264bd152c ("watchdog: msc313e: Check if the WDT was running at boot")
Signed-off-by: Tzung-Bi Shih <tzungbi@kernel.org>
Link: https://patch.msgid.link/20260828161348.13212-8-tzungbi@kernel.org
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/watchdog/msc313e_wdt.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
diff --git a/drivers/watchdog/msc313e_wdt.c b/drivers/watchdog/msc313e_wdt.c
index e28261c7a8d4c..4a5cce2a16b18 100644
--- a/drivers/watchdog/msc313e_wdt.c
+++ b/drivers/watchdog/msc313e_wdt.c
@@ -144,12 +144,21 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
priv->wdev.max_timeout = U32_MAX / rate;
priv->wdev.timeout = MSC313E_WDT_DEFAULT_TIMEOUT;
+ watchdog_set_drvdata(&priv->wdev, priv);
+ platform_set_drvdata(pdev, priv);
+
+ watchdog_init_timeout(&priv->wdev, timeout, dev);
+ watchdog_stop_on_reboot(&priv->wdev);
+ watchdog_stop_on_unregister(&priv->wdev);
+ watchdog_stop_ping_on_suspend(&priv->wdev);
+
ret = clk_prepare_enable(priv->clk);
if (ret)
return ret;
/* If the period is non-zero the WDT is running */
if (msc313e_wdt_get_hw_timeout(priv)) {
+ msc313e_wdt_set_hw_timeout(priv, priv->wdev.timeout);
set_bit(WDOG_HW_RUNNING, &priv->wdev.status);
/*
* Keep the clock enabled. The watchdog core will skip the next
@@ -160,14 +169,6 @@ static int msc313e_wdt_probe(struct platform_device *pdev)
clk_disable_unprepare(priv->clk);
}
- watchdog_set_drvdata(&priv->wdev, priv);
- platform_set_drvdata(pdev, priv);
-
- watchdog_init_timeout(&priv->wdev, timeout, dev);
- watchdog_stop_on_reboot(&priv->wdev);
- watchdog_stop_on_unregister(&priv->wdev);
- watchdog_stop_ping_on_suspend(&priv->wdev);
-
ret = devm_watchdog_register_device(dev, &priv->wdev);
/* If the WDT is running and anything goes wrong, disable the clock. */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 397/733] net: dsa: lantiq_gswip: fix GSWIP_MDIO_PHY_FCONTX_EN value
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (395 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 396/733] watchdog: msc313e: Sync timeout value if WDT was running at boot Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 398/733] net: ks8851: Fix receiver error in 100BASE-TX mode following software power-down Greg Kroah-Hartman
` (347 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jan Havran (Advantech Czech),
Daniel Golle, Maxime Chevallier, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jan Havran (Advantech Czech) <havran.jan@email.cz>
[ Upstream commit 59fb389ad6bf50916189e56dafcd225ab977f874 ]
Per the GSW145 data sheet, the FCONTX (bits 8:7) and FCONRX (bits 6:5)
flow-control fields of the PHY_ADDR_n register both encode 00 = AUTO,
01 = EN, 10 = reserved, 11 = DIS. GSWIP_MDIO_PHY_FCONTX_EN was 0x0100,
i.e. field value 10 (the reserved encoding), instead of 0x0080 (01 = EN);
FCONRX_EN is already 0x0020 (01). Enabling tx flow control therefore wrote
the reserved value.
Set FCONTX_EN to 0x0080. The register is shared by all supported parts.
Fixes: 14fceff4771e ("net: dsa: Add Lantiq / Intel DSA driver for vrx200")
Signed-off-by: Jan Havran (Advantech Czech) <havran.jan@email.cz>
Reviewed-by: Daniel Golle <daniel@makrotopia.org>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260907134818.16670-4-havran.jan@email.cz
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/lantiq/lantiq_gswip.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/dsa/lantiq/lantiq_gswip.h b/drivers/net/dsa/lantiq/lantiq_gswip.h
index bc3686faad0d6..0b75be14dc109 100644
--- a/drivers/net/dsa/lantiq/lantiq_gswip.h
+++ b/drivers/net/dsa/lantiq/lantiq_gswip.h
@@ -42,7 +42,7 @@
#define GSWIP_MDIO_PHY_FDUP_DIS 0x0600
#define GSWIP_MDIO_PHY_FCONTX_MASK 0x0180
#define GSWIP_MDIO_PHY_FCONTX_AUTO 0x0000
-#define GSWIP_MDIO_PHY_FCONTX_EN 0x0100
+#define GSWIP_MDIO_PHY_FCONTX_EN 0x0080
#define GSWIP_MDIO_PHY_FCONTX_DIS 0x0180
#define GSWIP_MDIO_PHY_FCONRX_MASK 0x0060
#define GSWIP_MDIO_PHY_FCONRX_AUTO 0x0000
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 398/733] net: ks8851: Fix receiver error in 100BASE-TX mode following software power-down
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (396 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 397/733] net: dsa: lantiq_gswip: fix GSWIP_MDIO_PHY_FCONTX_EN value Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 399/733] hwmon: (corsair-cpro) Create debugfs entries after hwmon registration Greg Kroah-Hartman
` (346 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sebastian Andrzej Siewior,
Marek Vasut, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <marex@nabladev.com>
[ Upstream commit 66ef5adb75446627f8b6c26cd04f2adc86d4de56 ]
KSZ8851 errata sheet DS80000716D-page 4 Module 3 [1] states that,
when issuing a software power-down (PMECR[1:0] = 10) followed by a
power-on (PMECR[1:0] = 00), the receiver circuit can fail to start
properly preventing communication. The Transmitter will still send
data, but no data will be received.
The errata sheet also includes a workaround, which states that,
it is recommended that the software power-down feature not be used.
Implement that workaround and drop the entry into software power-down
mode. The ks8851_write_mac_addr() calls entry into normal power-on
mode at the very beginning of the function, therefore dropping the
second call to enter software power-down mode is sufficient here.
The ks8851_net_stop() can only be called after ks8851_net_start()
was already called, and ks8851_net_start() also makes the MAC enter
normal power-on mode, therefore it is also fine to drop the call to
enter software power-down mode from ks8851_net_stop().
This will lead to a slight increase in power consumption, but it also
fixes a sporadic reliability problem on at least KSZ8851-16MLL, which
is where the problem was reported and this fix was tested.
[1] https://ww1.microchip.com/downloads/en/DeviceDoc/80000716D.pdf
Fixes: 3ba81f3ece3c ("net: Micrel KS8851 SPI network driver")
Reviewed-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Marek Vasut <marex@nabladev.com>
Link: https://patch.msgid.link/20260905130327.203851-1-marex@nabladev.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/micrel/ks8851_common.c | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
diff --git a/drivers/net/ethernet/micrel/ks8851_common.c b/drivers/net/ethernet/micrel/ks8851_common.c
index 4afbb40bc0e4a..d49f281c78676 100644
--- a/drivers/net/ethernet/micrel/ks8851_common.c
+++ b/drivers/net/ethernet/micrel/ks8851_common.c
@@ -143,9 +143,6 @@ static int ks8851_write_mac_addr(struct net_device *dev)
ks8851_wrreg16(ks, KS_MAR(i), val);
}
- if (!netif_running(dev))
- ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
-
ks8851_unlock(ks);
return 0;
@@ -478,8 +475,7 @@ static int ks8851_net_open(struct net_device *dev)
* @dev: The device being closed.
*
* Called to close down a network device which has been active. Cancel any
- * work, shutdown the RX and TX process and then place the chip into a low
- * power state whilst it is not being used.
+ * work and shutdown the RX and TX process.
*/
static int ks8851_net_stop(struct net_device *dev)
{
@@ -506,8 +502,6 @@ static int ks8851_net_stop(struct net_device *dev)
/* shutdown TX process */
ks8851_wrreg16(ks, KS_TXCR, 0x0000);
- /* set powermode to soft power down to save power */
- ks8851_set_powermode(ks, PMECR_PM_SOFTDOWN);
ks8851_unlock(ks);
/* ensure any queued tx buffers are dumped */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 399/733] hwmon: (corsair-cpro) Create debugfs entries after hwmon registration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (397 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 398/733] net: ks8851: Fix receiver error in 100BASE-TX mode following software power-down Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 400/733] hwmon: (gpio-fan) take fan_data->lock in gpio_fan_shutdown() Greg Kroah-Hartman
` (345 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Guenter Roeck, Linmao Li,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linmao Li <lilinmao@kylinos.cn>
[ Upstream commit 508baf1713f32f287bfb4f85d759403ec8ba35a3 ]
ccp_debugfs_init() registers debugfs files whose private data is the devm
allocated ccp. It runs before hwmon_device_register_with_info(), so when
that registration fails, ccp_probe() returns with the files still in
place. The HID core then frees ccp, and ccp_remove() is not called for a
failed probe, so nothing removes them later either. Reading one of the
files dereferences the freed pointer.
Create the debugfs entries only after the hwmon device has been
registered, so no failing path can leave them behind.
The two version queries stay where they are. They send USB commands
without holding ccp->mutex, which is only safe as long as nothing else
can call send_usb_cmd(); once the hwmon device is registered its
callbacks can do so concurrently. Only the debugfs creation moves, and
it is told which queries succeeded.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-hwmon/20260708031612.BD7E61F000E9@smtp.kernel.org/
Suggested-by: Guenter Roeck <linux@roeck-us.net>
Fixes: 5997eb60f896 ("hwmon: (corsair-cpro) Add firmware and bootloader information")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Link: https://patch.msgid.link/20260831014509.3352442-1-lilinmao@kylinos.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/corsair-cpro.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
diff --git a/drivers/hwmon/corsair-cpro.c b/drivers/hwmon/corsair-cpro.c
index 8354a002f4c5e..56de0fe0f544c 100644
--- a/drivers/hwmon/corsair-cpro.c
+++ b/drivers/hwmon/corsair-cpro.c
@@ -566,21 +566,18 @@ static int bootloader_show(struct seq_file *seqf, void *unused)
}
DEFINE_SHOW_ATTRIBUTE(bootloader);
-static void ccp_debugfs_init(struct ccp_device *ccp)
+static void ccp_debugfs_init(struct ccp_device *ccp, bool fw_valid, bool bl_valid)
{
char name[32];
- int ret;
scnprintf(name, sizeof(name), "corsaircpro-%s", dev_name(&ccp->hdev->dev));
ccp->debugfs = debugfs_create_dir(name, NULL);
- ret = get_fw_version(ccp);
- if (!ret)
+ if (fw_valid)
debugfs_create_file("firmware_version", 0444,
ccp->debugfs, ccp, &firmware_fops);
- ret = get_bl_version(ccp);
- if (!ret)
+ if (bl_valid)
debugfs_create_file("bootloader_version", 0444,
ccp->debugfs, ccp, &bootloader_fops);
}
@@ -588,6 +585,7 @@ static void ccp_debugfs_init(struct ccp_device *ccp)
static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
{
struct ccp_device *ccp;
+ bool fw_valid, bl_valid;
int ret;
ccp = devm_kzalloc(&hdev->dev, sizeof(*ccp), GFP_KERNEL);
@@ -632,7 +630,13 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
if (ret)
goto out_hw_close;
- ccp_debugfs_init(ccp);
+ /*
+ * Query the versions before registering the hwmon device: they send
+ * USB commands without holding ccp->mutex, which is only safe while
+ * nothing else can call send_usb_cmd().
+ */
+ fw_valid = !get_fw_version(ccp);
+ bl_valid = !get_bl_version(ccp);
ccp->hwmon_dev = hwmon_device_register_with_info(&hdev->dev, "corsaircpro",
ccp, &ccp_chip_info, NULL);
@@ -641,6 +645,8 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
goto out_hw_close;
}
+ ccp_debugfs_init(ccp, fw_valid, bl_valid);
+
return 0;
out_hw_close:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 400/733] hwmon: (gpio-fan) take fan_data->lock in gpio_fan_shutdown()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (398 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 399/733] hwmon: (corsair-cpro) Create debugfs entries after hwmon registration Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 401/733] hwmon: (aspeed-pwm-tacho) Propagate reset deassert errors Greg Kroah-Hartman
` (344 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI review, Cong Nguyen,
Guenter Roeck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Nguyen <congnt264@gmail.com>
[ Upstream commit bb2424c3502cc72292eedade46960c331d5f28fb ]
set_fan_speed() writes the control GPIOs one bit at a time. Every
other caller locks around it; gpio_fan_shutdown() doesn't. If it races
a locked caller, the GPIO writes can interleave and leave the fan at a
speed neither caller asked for.
Fixes: b95579cd8795 ("hwmon: (gpio-fan) Add a shutdown handler to poweroff the fans")
Reported-by: Sashiko AI review <sashiko-bot@kernel.org>
Link: https://lore.kernel.org/r/20260830152150.27F5F1F000E9@smtp.kernel.org
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Link: https://patch.msgid.link/20260901155404.1532092-1-congnt264@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/gpio-fan.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/gpio-fan.c b/drivers/hwmon/gpio-fan.c
index 084828e1e2817..10c91bc33b020 100644
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -606,8 +606,11 @@ static void gpio_fan_shutdown(struct platform_device *pdev)
{
struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
- if (fan_data->gpios)
+ if (fan_data->gpios) {
+ mutex_lock(&fan_data->lock);
set_fan_speed(fan_data, 0);
+ mutex_unlock(&fan_data->lock);
+ }
}
static int gpio_fan_runtime_suspend(struct device *dev)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 401/733] hwmon: (aspeed-pwm-tacho) Propagate reset deassert errors
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (399 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 400/733] hwmon: (gpio-fan) take fan_data->lock in gpio_fan_shutdown() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 402/733] hwmon: (corsair-cpro) Remove debugfs entries when probe fails Greg Kroah-Hartman
` (343 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Pengpeng Hou, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pengpeng Hou <pengpeng@iscas.ac.cn>
[ Upstream commit 09a9e1746a87845d7d8e2b4e23bb613306effdff ]
aspeed_pwm_tacho_probe() installs its reset cleanup action and configures
the
controller after an unchecked reset deassertion.
Stop probing when the reset controller rejects the transition, before the
hwmon device becomes visible.
Fixes: 18c514cc0e02 ("hwmon: (aspeed-pwm-tacho) Deassert reset in probe")
Signed-off-by: Pengpeng Hou <pengpeng@iscas.ac.cn>
Link: https://patch.msgid.link/20260830125044.97718-1-pengpeng@iscas.ac.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/aspeed-pwm-tacho.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/aspeed-pwm-tacho.c b/drivers/hwmon/aspeed-pwm-tacho.c
index 1c5945d4ba377..bfce589c3fb1f 100644
--- a/drivers/hwmon/aspeed-pwm-tacho.c
+++ b/drivers/hwmon/aspeed-pwm-tacho.c
@@ -934,7 +934,9 @@ static int aspeed_pwm_tacho_probe(struct platform_device *pdev)
"missing or invalid reset controller device tree entry");
return PTR_ERR(priv->rst);
}
- reset_control_deassert(priv->rst);
+ ret = reset_control_deassert(priv->rst);
+ if (ret)
+ return ret;
ret = devm_add_action_or_reset(dev, aspeed_pwm_tacho_remove, priv);
if (ret)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 402/733] hwmon: (corsair-cpro) Remove debugfs entries when probe fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (400 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 401/733] hwmon: (aspeed-pwm-tacho) Propagate reset deassert errors Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 403/733] hwmon: (nct6694) do not expose enable on DTIN temperature channels Greg Kroah-Hartman
` (342 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Linmao Li, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Linmao Li <lilinmao@kylinos.cn>
[ Upstream commit 4ee875c423c66c45d7ef7bbff403cd0e3971e0a2 ]
ccp_debugfs_init() registers debugfs files whose private data is the devm
allocated ccp. If hwmon_device_register_with_info() fails right after it,
ccp_probe() returns without removing them: the HID core then frees ccp,
and ccp_remove() is not called for a failed probe, so the files stay
behind. Reading one of them dereferences the freed pointer.
Remove the debugfs entries on that error path. debugfs_remove_recursive()
waits for readers already inside the show callbacks, so ccp is no longer
reachable through debugfs by the time probe returns.
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-hwmon/20260708031612.BD7E61F000E9@smtp.kernel.org/
Fixes: 5997eb60f896 ("hwmon: (corsair-cpro) Add firmware and bootloader information")
Signed-off-by: Linmao Li <lilinmao@kylinos.cn>
Link: https://patch.msgid.link/20260828061949.3151191-1-lilinmao@kylinos.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/corsair-cpro.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/hwmon/corsair-cpro.c b/drivers/hwmon/corsair-cpro.c
index 56de0fe0f544c..c096451526132 100644
--- a/drivers/hwmon/corsair-cpro.c
+++ b/drivers/hwmon/corsair-cpro.c
@@ -642,13 +642,15 @@ static int ccp_probe(struct hid_device *hdev, const struct hid_device_id *id)
ccp, &ccp_chip_info, NULL);
if (IS_ERR(ccp->hwmon_dev)) {
ret = PTR_ERR(ccp->hwmon_dev);
- goto out_hw_close;
+ goto out_debugfs_remove;
}
ccp_debugfs_init(ccp, fw_valid, bl_valid);
return 0;
+out_debugfs_remove:
+ debugfs_remove_recursive(ccp->debugfs);
out_hw_close:
hid_hw_close(hdev);
hid_device_io_stop(hdev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 403/733] hwmon: (nct6694) do not expose enable on DTIN temperature channels
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (401 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 402/733] hwmon: (corsair-cpro) Remove debugfs entries when probe fails Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 404/733] octeontx2-pf: reset HTB scheduler topology before freeing queues Greg Kroah-Hartman
` (341 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ming Yu, Ali Ahmet Memis,
Guenter Roeck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
[ Upstream commit c88a6338ae485e4d6210cc74cdb7664d6476c925 ]
The driver registers 26 temperature channels, all advertising
HWMON_T_ENABLE, and indexes the enable bitmap with the raw channel:
data->hwmon_en.tin_en[channel / 8] |= BIT(channel % 8);
tin_en is two bytes and only covers the 5 THR and 5 TDP channels
(index 0-9). The 16 DTIN channels (index 10-25) are enabled by the
firmware and were never meant to carry an enable bit. Because the
control structure is packed, writing temp17_enable and above indexes
past tin_en into the fin_en bytes that follow it, so it toggles fan
enable state instead; nct6694_hwmon_init() then sends the whole
structure back to the device, and reads report fan state as temperature
state. It stays within the structure, so this is not a memory safety
problem, but on a board that uses the fan channels it is not harmless.
Give the DTIN channels a temperature config without HWMON_T_ENABLE so
the core never creates their enable attribute. The enable path is then
reachable only for the first 10 channels, which stay within tin_en, and
fin_en is left alone. The DTIN input and limit attributes are unchanged.
Fixes: 197e779d29d8 ("hwmon: Add Nuvoton NCT6694 HWMON support")
Suggested-by: Ming Yu <tmyu0@nuvoton.com>
Link: https://lore.kernel.org/all/20260802124730.20387-1-ali@iusegentoo.com/
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260803102148.14196-1-ali@iusegentoo.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/hwmon/nct6694-hwmon.c | 35 +++++++++++++++++++----------------
1 file changed, 19 insertions(+), 16 deletions(-)
diff --git a/drivers/hwmon/nct6694-hwmon.c b/drivers/hwmon/nct6694-hwmon.c
index 6dcf22ca5018a..9a9a4db434c4f 100644
--- a/drivers/hwmon/nct6694-hwmon.c
+++ b/drivers/hwmon/nct6694-hwmon.c
@@ -159,6 +159,9 @@ static inline s8 temp_to_reg(long val)
#define NCT6694_HWMON_TEMP_CONFIG (HWMON_T_INPUT | HWMON_T_ENABLE | \
HWMON_T_MAX | HWMON_T_MAX_HYST | \
HWMON_T_MAX_ALARM)
+#define NCT6694_HWMON_DTIN_CONFIG (HWMON_T_INPUT | \
+ HWMON_T_MAX | HWMON_T_MAX_HYST | \
+ HWMON_T_MAX_ALARM)
#define NCT6694_HWMON_FAN_CONFIG (HWMON_F_INPUT | HWMON_F_ENABLE | \
HWMON_F_MIN | HWMON_F_MIN_ALARM)
#define NCT6694_HWMON_PWM_CONFIG (HWMON_PWM_INPUT | HWMON_PWM_ENABLE | \
@@ -193,22 +196,22 @@ static const struct hwmon_channel_info *nct6694_info[] = {
NCT6694_HWMON_TEMP_CONFIG, /* TDP2 */
NCT6694_HWMON_TEMP_CONFIG, /* TDP3 */
NCT6694_HWMON_TEMP_CONFIG, /* TDP4 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN0 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN1 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN2 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN3 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN4 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN5 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN6 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN7 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN8 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN9 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN10 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN11 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN12 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN13 */
- NCT6694_HWMON_TEMP_CONFIG, /* DTIN14 */
- NCT6694_HWMON_TEMP_CONFIG), /* DTIN15 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN0 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN1 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN2 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN3 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN4 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN5 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN6 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN7 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN8 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN9 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN10 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN11 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN12 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN13 */
+ NCT6694_HWMON_DTIN_CONFIG, /* DTIN14 */
+ NCT6694_HWMON_DTIN_CONFIG), /* DTIN15 */
HWMON_CHANNEL_INFO(fan,
NCT6694_HWMON_FAN_CONFIG, /* FIN0 */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 404/733] octeontx2-pf: reset HTB scheduler topology before freeing queues
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (402 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 403/733] hwmon: (nct6694) do not expose enable on DTIN temperature channels Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 405/733] vxlan: initialize _md in vxlan_xmit_one() Greg Kroah-Hartman
` (340 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ratheesh Kannoth, Simon Horman,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ratheesh Kannoth <rkannoth@marvell.com>
[ Upstream commit ef39fca8508597fa565cf2be72a884a712fb98af ]
HTB offload programs NIX_AF_TLxX_TOPOLOGY on QoS-allocated scheduler
queues via otx2_qos_txschq_set_parent_topology(), but teardown freed
those queues without clearing TOPOLOGY. The AF only restores PARENT and
SCHEDULE on free, so PRIO_ANCHOR/RR_PRIO settings can survive in the
shared scheduler pool and affect later allocations.
Add otx2_qos_reset_schq_topology() and otx2_qos_free_hw_schq() to zero
TL4 through TL2 TOPOLOGY before each schq is returned to the AF during
hierarchy teardown and cfg rollback. Skip the aggregation level (TL1):
it is a per-tx-link queue shared by the PF, default Tx hierarchy and VFs,
and is not freed back to the AF by nix_txschq_free_one().
Fixes: 5e6808b4c68d ("octeontx2-pf: Add support for HTB offload")
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260903020533.3068041-1-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/marvell/octeontx2/nic/qos.c | 60 +++++++++++++++++--
1 file changed, 55 insertions(+), 5 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
index 69c0911e28e91..f160b1618efa2 100644
--- a/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
+++ b/drivers/net/ethernet/marvell/octeontx2/nic/qos.c
@@ -235,13 +235,63 @@ static int otx2_qos_txschq_set_parent_topology(struct otx2_nic *pfvf,
return rc;
}
+static int otx2_qos_reset_schq_topology(struct otx2_nic *pfvf, u16 lvl,
+ u16 schq)
+{
+ struct mbox *mbox = &pfvf->mbox;
+ struct nix_txschq_config *cfg;
+ int rc;
+
+ if (lvl < NIX_TXSCH_LVL_TL4 || lvl >= NIX_TXSCH_LVL_TL1)
+ return 0;
+
+ mutex_lock(&mbox->lock);
+
+ cfg = otx2_mbox_alloc_msg_nix_txschq_cfg(mbox);
+ if (!cfg) {
+ mutex_unlock(&mbox->lock);
+ return -ENOMEM;
+ }
+
+ cfg->lvl = lvl;
+ cfg->num_regs = 1;
+
+ if (lvl == NIX_TXSCH_LVL_TL4)
+ cfg->reg[0] = NIX_AF_TL4X_TOPOLOGY(schq);
+ else if (lvl == NIX_TXSCH_LVL_TL3)
+ cfg->reg[0] = NIX_AF_TL3X_TOPOLOGY(schq);
+ else if (lvl == NIX_TXSCH_LVL_TL2)
+ cfg->reg[0] = NIX_AF_TL2X_TOPOLOGY(schq);
+
+ cfg->regval[0] = 0;
+
+ rc = otx2_sync_mbox_msg(mbox);
+
+ mutex_unlock(&mbox->lock);
+
+ return rc;
+}
+
+static void otx2_qos_free_hw_schq(struct otx2_nic *pfvf, u16 lvl, u16 schq)
+{
+ int err;
+
+ err = otx2_qos_reset_schq_topology(pfvf, lvl, schq);
+ if (err)
+ netdev_warn(pfvf->netdev,
+ "QoS: failed to reset topology for schq %u at level %u: %d\n",
+ schq, lvl, err);
+
+ otx2_txschq_free_one(pfvf, lvl, schq);
+}
+
static void otx2_qos_free_hw_node_schq(struct otx2_nic *pfvf,
struct otx2_qos_node *parent)
{
struct otx2_qos_node *node;
list_for_each_entry_reverse(node, &parent->child_schq_list, list)
- otx2_txschq_free_one(pfvf, node->level, node->schq);
+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
}
static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
@@ -252,7 +302,7 @@ static void otx2_qos_free_hw_node(struct otx2_nic *pfvf,
list_for_each_entry_safe(node, tmp, &parent->child_list, list) {
otx2_qos_free_hw_node(pfvf, node);
otx2_qos_free_hw_node_schq(pfvf, node);
- otx2_txschq_free_one(pfvf, node->level, node->schq);
+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
}
}
@@ -266,7 +316,7 @@ static void otx2_qos_free_hw_cfg(struct otx2_nic *pfvf,
otx2_qos_free_hw_node_schq(pfvf, node);
/* free node hw mappings */
- otx2_txschq_free_one(pfvf, node->level, node->schq);
+ otx2_qos_free_hw_schq(pfvf, node->level, node->schq);
mutex_unlock(&pfvf->qos.qos_lock);
}
@@ -913,7 +963,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
for (lvl = 0; lvl < NIX_TXSCH_LVL_CNT; lvl++) {
for (idx = 0; idx < cfg->schq[lvl]; idx++) {
schq = cfg->schq_list[lvl][idx];
- otx2_txschq_free_one(pfvf, lvl, schq);
+ otx2_qos_free_hw_schq(pfvf, lvl, schq);
}
}
@@ -921,7 +971,7 @@ static void otx2_qos_free_cfg(struct otx2_nic *pfvf, struct otx2_qos_cfg *cfg)
for (idx = 0; idx < cfg->schq_contig[lvl]; idx++) {
if (cfg->schq_index_used[lvl][idx]) {
schq = cfg->schq_contig_list[lvl][idx];
- otx2_txschq_free_one(pfvf, lvl, schq);
+ otx2_qos_free_hw_schq(pfvf, lvl, schq);
}
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 405/733] vxlan: initialize _md in vxlan_xmit_one()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (403 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 404/733] octeontx2-pf: reset HTB scheduler topology before freeing queues Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 406/733] ppp_synctty: ensure a writeable skb header Greg Kroah-Hartman
` (339 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Dumazet, Kuniyuki Iwashima,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <edumazet@google.com>
[ Upstream commit be83178bfc44588f6e3adb827ed874c683193466 ]
If a VXLAN device is configured with both VXLAN_F_COLLECT_METADATA and
VXLAN_F_GBP, and a packet is transmitted through it using an external
ip_tunnel_info that lacks the IP_TUNNEL_VXLAN_OPT_BIT flag, md is left
pointing to the uninitialized _md stack variable:
if (test_bit(IP_TUNNEL_VXLAN_OPT_BIT, info->key.tun_flags)) {
if (info->options_len < sizeof(*md))
goto drop;
md = ip_tunnel_info_opts(info);
}
Because IP_TUNNEL_VXLAN_OPT_BIT is not set, md is not updated and remains
pointing to _md. Later, vxlan_build_skb() is called with md, which
eventually calls vxlan_build_gbp_hdr():
if (vxflags & VXLAN_F_GBP)
vxlan_build_gbp_hdr(vxh, md);
Inside vxlan_build_gbp_hdr(), md->gbp is read:
if (!md->gbp)
return;
gbp = (struct vxlanhdr_gbp *)vxh;
...
if (md->gbp & VXLAN_GBP_DONT_LEARN)
gbp->dont_learn = 1;
If the stack contains garbage, this causes:
1) VXLAN_HF_GBP flag to be spuriously set in the VXLAN header.
2) gbp->dont_learn and gbp->policy_applied to be set from stack bits.
3) gbp->policy_id to receive 16 bits of uninitialized kernel stack data,
leaking it onto the wire.
Fix this by zero-initializing _md. If IP_TUNNEL_VXLAN_OPT_BIT is not
present, md->gbp remains 0, and vxlan_build_gbp_hdr() returns early
without modifying the VXLAN header.
Fixes: ee122c79d422 ("vxlan: Flow based tunneling")
Signed-off-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Kuniyuki Iwashima <kuniyu@google.com>
Link: https://patch.msgid.link/20260906180111.1973188-2-edumazet@google.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/vxlan/vxlan_core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/vxlan/vxlan_core.c b/drivers/net/vxlan/vxlan_core.c
index 1d76e1dbc41f2..e045e1ee9e594 100644
--- a/drivers/net/vxlan/vxlan_core.c
+++ b/drivers/net/vxlan/vxlan_core.c
@@ -2373,7 +2373,7 @@ void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct ip_tunnel_key key;
struct vxlan_dev *vxlan = netdev_priv(dev);
const struct iphdr *old_iph;
- struct vxlan_metadata _md;
+ struct vxlan_metadata _md = {};
struct vxlan_metadata *md = &_md;
unsigned int pkt_len = skb->len;
__be16 src_port = 0, dst_port;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 406/733] ppp_synctty: ensure a writeable skb header
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (404 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 405/733] vxlan: initialize _md in vxlan_xmit_one() Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 407/733] net: phylink: initialise link_state before a forced major config Greg Kroah-Hartman
` (338 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qingfang Deng, Eric Dumazet,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <qingfang.deng@linux.dev>
[ Upstream commit 8aaeb56aff2a557a88f83ae866da2c91ad247e59 ]
ppp_sync_txmunge() checks headroom before prepending the address and
control bytes, but does not ensure that the skb header is writable.
A received skb can reach this function through PPP channel bridging
without passing through ppp_start_xmit(), which calls skb_cow_head().
For example, a PPPoE frame may share its buffer with a clone queued to
an AF_PACKET socket. If it is bridged to a synchronous tty channel, the
address/control bytes can overwrite data still visible to that socket.
Use skb_cow_head() to ensure both sufficient headroom and a writable
header.
Fixes: 4cf476ced45d ("ppp: add PPPIOCBRIDGECHAN and PPPIOCUNBRIDGECHAN ioctls")
Signed-off-by: Qingfang Deng <qingfang.deng@linux.dev>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Link: https://patch.msgid.link/20260908072135.877364-1-qingfang.deng@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ppp/ppp_synctty.c | 14 +++-----------
1 file changed, 3 insertions(+), 11 deletions(-)
diff --git a/drivers/net/ppp/ppp_synctty.c b/drivers/net/ppp/ppp_synctty.c
index 0208e752ef1eb..1b64e610f9609 100644
--- a/drivers/net/ppp/ppp_synctty.c
+++ b/drivers/net/ppp/ppp_synctty.c
@@ -457,17 +457,9 @@ ppp_sync_txmunge(struct syncppp *ap, struct sk_buff *skb)
/* prepend address/control fields if necessary */
if ((ap->flags & SC_COMP_AC) == 0 || islcp) {
- if (skb_headroom(skb) < 2) {
- struct sk_buff *npkt = dev_alloc_skb(skb->len + 2);
- if (npkt == NULL) {
- kfree_skb(skb);
- return NULL;
- }
- skb_reserve(npkt,2);
- skb_copy_from_linear_data(skb,
- skb_put(npkt, skb->len), skb->len);
- consume_skb(skb);
- skb = npkt;
+ if (skb_cow_head(skb, 2)) {
+ kfree_skb(skb);
+ return NULL;
}
skb_push(skb,2);
skb->data[0] = PPP_ALLSTATIONS;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 407/733] net: phylink: initialise link_state before a forced major config
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (405 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 406/733] ppp_synctty: ensure a writeable skb header Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 408/733] net: stmmac: initialize ptp_lock at probe time Greg Kroah-Hartman
` (337 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Sviridkin <f@lex.la>
[ Upstream commit 113998aa372f4869bf62cfc75c28a2849e8487be ]
phylink_resolve() leaves link_state on the stack unpopulated on its
disable and link-failed branches, which set only link_state.link.
phylink_apply_manual_flow() then reads the struct's advertising on
every mode but MLO_AN_FIXED, and has done so since long before
force_major_config existed.
force_major_config turns that into a write to the hardware. It is the
only trigger for the major-config block that does not require
mac_config, so phylink_major_config() programs the MAC for whatever
the stack held, a zeroed interface is PHY_INTERFACE_MODE_NA, and the
write-back stores it in pl->link_config.interface.
phylink_replay_link_end() is the only in-tree setter, and
sja1105_static_config_reload() calls it for every port that has a
phylink instance, regardless of admin state. On a stopped port
phylink_run_resolve() no-ops, so the flag outlives the call. The next
resolve consumes it whatever branch it takes; an unpopulated branch is
where that does damage.
Found while developing a series that attaches a late PHY from a
delayed work item and sets this flag there, so the PHY attached after
its port was already up. The link stayed down until the port was
cycled 29 minutes later. With this patch on the same board the same
attach programs the MAC for 2500base-x rather than unknown, and the
PHY's interrupt fires without a port bounce where it had stayed at
zero throughout the failure.
Fixes: 96969b132bf1 ("net: phylink: introduce helpers for replaying link callbacks")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260904185540.2844261-1-f@lex.la
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/phy/phylink.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/phy/phylink.c b/drivers/net/phy/phylink.c
index 7397169236fdf..27fd9aa2027a4 100644
--- a/drivers/net/phy/phylink.c
+++ b/drivers/net/phy/phylink.c
@@ -1630,8 +1630,10 @@ static void phylink_resolve(struct work_struct *w)
if (pl->phylink_disable_state) {
pl->link_failed = false;
+ link_state = pl->link_config;
link_state.link = false;
} else if (pl->link_failed) {
+ link_state = pl->link_config;
link_state.link = false;
retrigger = true;
} else if (pl->act_link_an_mode == MLO_AN_FIXED) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 408/733] net: stmmac: initialize ptp_lock at probe time
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (406 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 407/733] net: phylink: initialise link_state before a forced major config Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 409/733] net/mlx5e: Move representor vnic reporter to eswitch devlink port Greg Kroah-Hartman
` (336 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Maxime Chevallier,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit 0338c68e22abd2ee509ec2e32508a50896618c32 ]
priv->ptp_lock is only initialized in stmmac_ptp_register(), which runs
during __stmmac_open(). However, the lock is also used while the
interface is down and has never been opened: tc_taprio_configure()
invokes the PTP gettime64() callback to compute the EST base time when
offloading a TAPRIO schedule, and stmmac_get_time() takes
priv->ptp_lock. Using an uninitialized rwlock is undefined behaviour.
Move the rwlock_init() to __stmmac_dvr_probe(), together with the other
private locks, so that ptp_lock is always valid regardless of the
interface state.
Fixes: b60189e0392f ("net: stmmac: Integrate EST with TAPRIO scheduler API")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Reviewed-by: Maxime Chevallier <maxime.chevallier@bootlin.com>
Link: https://patch.msgid.link/20260904-stmmac-fix-ptp-clock-init-v1-1-df70eb1eb04d@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 1 +
drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c | 1 -
2 files changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index 1e88575fdddbb..aa05160c22e35 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -8032,6 +8032,7 @@ static int __stmmac_dvr_probe(struct device *device,
stmmac_napi_add(ndev);
mutex_init(&priv->lock);
+ rwlock_init(&priv->ptp_lock);
stmmac_fpe_init(priv);
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
index 960249960004c..3bfcc9760dce7 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_ptp.c
@@ -365,7 +365,6 @@ void stmmac_ptp_register(struct stmmac_priv *priv)
if (priv->plat->crosststamp)
priv->ptp_clock_ops.getcrosststamp = stmmac_getcrosststamp;
- rwlock_init(&priv->ptp_lock);
mutex_init(&priv->aux_ts_lock);
priv->ptp_clock = ptp_clock_register(&priv->ptp_clock_ops,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 409/733] net/mlx5e: Move representor vnic reporter to eswitch devlink port
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (407 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 408/733] net: stmmac: initialize ptp_lock at probe time Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 410/733] powerpc/entry: Fix double accounting of user time on interrupt entry Greg Kroah-Hartman
` (335 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Carolina Jubran, Cosmin Ratiu,
Tariq Toukan, Simon Horman, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Carolina Jubran <cjubran@nvidia.com>
[ Upstream commit 7f26a5e8040b4957ef4dbdfcde6cc7ba2db53937 ]
The representor vnic devlink health reporter is created and destroyed
along the representor netdev (un)load path, which is not serialized by
the devlink instance lock. Destroying the reporter from there triggers
a devl_assert_locked() splat on driver unbind:
WARNING: net/devlink/core.c:259 at devl_assert_locked+0x54/0x70, CPU#2: bash/3758
Modules linked in: mlx5_vdpa vringh vdpa mlx5_ib mlx5_fwctl mlx5_core ...
CPU: 2 UID: 0 PID: 3758 Comm: bash Tainted: G W 6.19.0+ #1 PREEMPT
Tainted: [W]=WARN
Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), ...
RIP: 0010:devl_assert_locked+0x54/0x70
Call Trace:
<TASK>
devl_health_reporter_destroy+0x3a/0x1b0
mlx5e_vport_rep_unload+0x12d/0x2b0 [mlx5_core]
mlx5_eswitch_unregister_vport_reps+0x1b8/0x220 [mlx5_core]
? __esw_offloads_unload_rep+0x190/0x190 [mlx5_core]
? kernfs_remove_by_name_ns+0xc3/0xf0
device_release_driver_internal+0x3b2/0x560
unbind_store+0xce/0xf0
Move the reporter's lifecycle to the eswitch devlink port (un)register
paths, which are already serialized by the devlink instance lock, and
store the handle on mlx5_devlink_port. Use the port's mlx5_vport as the
reporter priv since the diagnose callback only needs a device handle and
a vport number, and mlx5_vport carries both and is initialized before
any representor driver probes.
Fixes: cf14af140a5a ("net/mlx5e: Add vnic devlink health reporter to representors")
Signed-off-by: Carolina Jubran <cjubran@nvidia.com>
Reviewed-by: Cosmin Ratiu <cratiu@nvidia.com>
Signed-off-by: Tariq Toukan <tariqt@nvidia.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260906090700.3761260-1-tariqt@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/mellanox/mlx5/core/en_rep.c | 52 +------------------
.../net/ethernet/mellanox/mlx5/core/en_rep.h | 1 -
.../mellanox/mlx5/core/esw/devlink_port.c | 37 +++++++++++++
.../net/ethernet/mellanox/mlx5/core/eswitch.h | 1 +
4 files changed, 39 insertions(+), 52 deletions(-)
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
index 3d544fe4e6f73..eb3160bfbb29d 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.c
@@ -56,7 +56,6 @@
#include "lib/vxlan.h"
#define CREATE_TRACE_POINTS
#include "diag/en_rep_tracepoint.h"
-#include "diag/reporter_vnic.h"
#include "en_accel/ipsec.h"
#include "en/tc/int_port.h"
#include "en/ptp.h"
@@ -1435,51 +1434,6 @@ static unsigned int mlx5e_ul_rep_stats_grps_num(struct mlx5e_priv *priv)
return ARRAY_SIZE(mlx5e_ul_rep_stats_grps);
}
-static int
-mlx5e_rep_vnic_reporter_diagnose(struct devlink_health_reporter *reporter,
- struct devlink_fmsg *fmsg,
- struct netlink_ext_ack *extack)
-{
- struct mlx5e_rep_priv *rpriv = devlink_health_reporter_priv(reporter);
- struct mlx5_eswitch_rep *rep = rpriv->rep;
-
- mlx5_reporter_vnic_diagnose_counters(rep->esw->dev, fmsg, rep->vport,
- true);
- return 0;
-}
-
-static const struct devlink_health_reporter_ops mlx5_rep_vnic_reporter_ops = {
- .name = "vnic",
- .diagnose = mlx5e_rep_vnic_reporter_diagnose,
-};
-
-static void mlx5e_rep_vnic_reporter_create(struct mlx5e_priv *priv,
- struct devlink_port *dl_port)
-{
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
- struct devlink_health_reporter *reporter;
-
- reporter = devl_port_health_reporter_create(dl_port,
- &mlx5_rep_vnic_reporter_ops,
- rpriv);
- if (IS_ERR(reporter)) {
- mlx5_core_err(priv->mdev,
- "Failed to create representor vnic reporter, err = %pe\n",
- reporter);
- return;
- }
-
- rpriv->rep_vnic_reporter = reporter;
-}
-
-static void mlx5e_rep_vnic_reporter_destroy(struct mlx5e_priv *priv)
-{
- struct mlx5e_rep_priv *rpriv = priv->ppriv;
-
- if (!IS_ERR_OR_NULL(rpriv->rep_vnic_reporter))
- devl_health_reporter_destroy(rpriv->rep_vnic_reporter);
-}
-
static const struct mlx5e_profile mlx5e_rep_profile = {
.init = mlx5e_init_rep,
.cleanup = mlx5e_cleanup_rep,
@@ -1603,10 +1557,8 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
dl_port = mlx5_esw_offloads_devlink_port(dev->priv.eswitch,
rpriv->rep->vport);
- if (!IS_ERR(dl_port)) {
+ if (!IS_ERR(dl_port))
SET_NETDEV_DEVLINK_PORT(netdev, dl_port);
- mlx5e_rep_vnic_reporter_create(priv, dl_port);
- }
err = register_netdev(netdev);
if (err) {
@@ -1619,7 +1571,6 @@ mlx5e_vport_vf_rep_load(struct mlx5_core_dev *dev, struct mlx5_eswitch_rep *rep)
return 0;
err_detach_netdev:
- mlx5e_rep_vnic_reporter_destroy(priv);
mlx5e_detach_netdev(netdev_priv(netdev));
err_cleanup_profile:
priv->profile->cleanup(priv);
@@ -1677,7 +1628,6 @@ mlx5e_vport_rep_unload(struct mlx5_eswitch_rep *rep)
}
unregister_netdev(netdev);
- mlx5e_rep_vnic_reporter_destroy(priv);
mlx5e_detach_netdev(priv);
priv->profile->cleanup(priv);
mlx5e_destroy_netdev(netdev);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
index 70640fa1ad7bc..bcd7b4e814d06 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/en_rep.h
@@ -118,7 +118,6 @@ struct mlx5e_rep_priv {
struct rtnl_link_stats64 prev_vf_vport_stats;
struct mlx5_flow_handle *send_to_vport_meta_rule;
struct rhashtable tc_ht;
- struct devlink_health_reporter *rep_vnic_reporter;
};
static inline
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
index 6e50311faa27f..2e7eac4bca3dd 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
+++ b/drivers/net/ethernet/mellanox/mlx5/core/esw/devlink_port.c
@@ -4,6 +4,26 @@
#include <linux/mlx5/driver.h>
#include "eswitch.h"
#include "devlink.h"
+#include "diag/reporter_vnic.h"
+
+static int
+mlx5_esw_rep_vnic_reporter_diagnose(struct devlink_health_reporter *reporter,
+ struct devlink_fmsg *fmsg,
+ struct netlink_ext_ack *extack)
+{
+ struct mlx5_vport *vport = devlink_health_reporter_priv(reporter);
+
+ mlx5_reporter_vnic_diagnose_counters(vport->dev, fmsg, vport->vport,
+ true);
+
+ return 0;
+}
+
+static const
+struct devlink_health_reporter_ops mlx5_esw_rep_vnic_reporter_ops = {
+ .name = "vnic",
+ .diagnose = mlx5_esw_rep_vnic_reporter_diagnose,
+};
static void
mlx5_esw_get_port_parent_id(struct mlx5_core_dev *dev, struct netdev_phys_item_id *ppid)
@@ -217,6 +237,7 @@ static void mlx5_esw_devlink_port_res_unregister(struct devlink_port *dl_port)
int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, struct mlx5_vport *vport)
{
+ struct devlink_health_reporter *reporter;
struct mlx5_core_dev *dev = esw->dev;
const struct devlink_port_ops *ops;
struct mlx5_devlink_port *dl_port;
@@ -252,6 +273,16 @@ int mlx5_esw_offloads_devlink_port_register(struct mlx5_eswitch *esw, struct mlx
mlx5_core_dbg(dev, "Failed to register port resources: %d\n",
err);
+ reporter = devl_port_health_reporter_create(
+ &dl_port->dl_port, &mlx5_esw_rep_vnic_reporter_ops,
+ vport);
+ if (IS_ERR(reporter))
+ mlx5_core_err(dev,
+ "Failed to create vnic health reporter for vport %d: %pe\n",
+ vport_num, reporter);
+ else
+ dl_port->vnic_reporter = reporter;
+
return 0;
rate_err:
@@ -266,6 +297,12 @@ void mlx5_esw_offloads_devlink_port_unregister(struct mlx5_vport *vport)
if (!vport->dl_port)
return;
dl_port = vport->dl_port;
+
+ if (dl_port->vnic_reporter) {
+ devl_health_reporter_destroy(dl_port->vnic_reporter);
+ dl_port->vnic_reporter = NULL;
+ }
+
mlx5_esw_devlink_port_res_unregister(&dl_port->dl_port);
mlx5_esw_qos_vport_update_parent(vport, NULL, NULL);
diff --git a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
index fea72b1dedab9..e8817d45763a6 100644
--- a/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
+++ b/drivers/net/ethernet/mellanox/mlx5/core/eswitch.h
@@ -189,6 +189,7 @@ struct mlx5_vport;
struct mlx5_devlink_port {
struct devlink_port dl_port;
struct mlx5_vport *vport;
+ struct devlink_health_reporter *vnic_reporter;
};
static inline void mlx5_devlink_port_init(struct mlx5_devlink_port *dl_port,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 410/733] powerpc/entry: Fix double accounting of user time on interrupt entry
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (408 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 409/733] net/mlx5e: Move representor vnic reporter to eswitch devlink port Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:11 ` [PATCH 7.2 411/733] selftests/powerpc/tm: Fix tcheck() reading uninitialised CR value Greg Kroah-Hartman
` (334 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mukesh Kumar Chaurasiya (IBM),
Aboorva Devarajan, Venkat Rao Bagalkote, Amit Machhiwal,
Ritesh Harjani (IBM), Christophe Leroy (CS GROUP),
Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aboorva Devarajan <aboorvad@linux.ibm.com>
[ Upstream commit 11ae2e1dc58304a48816fc8ca4afa8f2ef9d1bdf ]
Since the switch to generic entry, an interrupt from user mode
accounts user time twice: once in arch_interrupt_enter_prepare()
and again in arch_enter_from_user_mode(), which irqentry_enter()
invokes for the same interrupt:
arch_interrupt_enter_prepare()
account_cpu_user_entry() /* first */
irqentry_enter()
arch_enter_from_user_mode()
account_cpu_user_entry() /* second */
The second call charges the same interval again, because
account_cpu_user_entry() accumulates the time spent in user mode
since the last return to user space.
The two calls come from the GENERIC_ENTRY preparation series,
where each step was a no-op on its own. Commit 09a9d3a8499d
("powerpc: introduce arch_enter_from_user_mode") added the hook
with the user-time accounting in it, but nothing called it yet.
Commit 893082ac769b ("powerpc: Prepare for IRQ entry exit")
copied interrupt_enter_prepare() verbatim into entry-common.h as
arch_interrupt_enter_prepare(); that copy was equally unused, as
handlers still called interrupt_enter_prepare().
Commit bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature")
made both live. On the syscall side it did the full conversion:
system_call_exception() now accounts once through the hook via
syscall_enter_from_user_mode(), rather than calling
account_cpu_user_entry() directly. On the interrupt side it
switched the handler macros to arch_interrupt_enter_prepare()
followed by irqentry_enter(), which also runs the hook, but the
accounting in arch_interrupt_enter_prepare() was not removed to
match. The double accounting starts with that commit.
With CONFIG_VIRT_CPU_ACCOUNTING_NATIVE=y this roughly doubles the
reported user time of any workload that takes interrupts. The
other accounting modes compile account_cpu_user_entry() to an
empty stub, so they are not affected.
Remove the accounting from arch_interrupt_enter_prepare() and rely
on arch_enter_from_user_mode(), which already runs for both
syscalls and interrupts. The duplicate account_stolen_time() call
is removed the same way.
On a pseries LPAR a busy loop reports 6s user time in 3s elapsed
(~210% CPU) before the fix, and 3s (~105% CPU) after it:
$ python3 -c 'while True: pass' &
$ sleep 3; ps -p $! -o etime,time,pcpu
ELAPSED TIME %CPU
Before 00:03 00:00:06 210
After 00:03 00:00:03 105
A 50% load reports ~70% usr / 30% idle before the fix, and
~49% usr / 51% idle after it:
$ taskset -c 6 stress-ng --cpu 1 --cpu-load 50 &
$ mpstat -P 6 1
CPU %usr %idle
Before 6 69.74 30.26
After 6 48.51 50.50
Fixes: bee25f97ad24 ("powerpc: Enable GENERIC_ENTRY feature")
Reviewed-by: Mukesh Kumar Chaurasiya (IBM) <mkchauras@gmail.com>
Signed-off-by: Aboorva Devarajan <aboorvad@linux.ibm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Reviewed-by: Christophe Leroy (CS GROUP) <chleroy@kernel.org>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260904025831.3439809-1-aboorvad@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/powerpc/include/asm/entry-common.h | 2 --
1 file changed, 2 deletions(-)
diff --git a/arch/powerpc/include/asm/entry-common.h b/arch/powerpc/include/asm/entry-common.h
index 80b07750b531b..8e91489fdf2bb 100644
--- a/arch/powerpc/include/asm/entry-common.h
+++ b/arch/powerpc/include/asm/entry-common.h
@@ -222,8 +222,6 @@ static inline void arch_interrupt_enter_prepare(struct pt_regs *regs)
if (user_mode(regs)) {
kuap_lock();
- account_cpu_user_entry();
- account_stolen_time();
} else {
kuap_save_and_lock(regs);
/*
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 411/733] selftests/powerpc/tm: Fix tcheck() reading uninitialised CR value
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (409 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 410/733] powerpc/entry: Fix double accounting of user time on interrupt entry Greg Kroah-Hartman
@ 2026-09-17 15:11 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 412/733] drm/i915/dp: Gate UHBR SST SDP splitting on sink capability Greg Kroah-Hartman
` (333 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:11 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thibault Ferrante,
Venkat Rao Bagalkote, Madhavan Srinivasan, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thibault Ferrante <thibault.ferrante@canonical.com>
[ Upstream commit ed28b16eab705071d28edaace47189c2eb3aa108 ]
tcheck() is used to check the current transaction state (active,
suspended, doomed) via the "tcheck" instruction, which writes its
result into CR field 0. The inline asm declared a GPR output operand
for this result but never actually moved the CR into it.
Every caller (tcheck_doomed(), tcheck_active(), tcheck_suspended(),
tcheck_transactional()) has effectively been testing bits of an unrelated,
arbitrary register value since this helper was introduced.
The "& 4" mask discards the TDOOMED and TS_lsb (suspended) bits before
they ever reach the callers, so tcheck_doomed() and tcheck_suspended()
can never return true, and tcheck_transactional() degrades to being
equivalent to tcheck_active().
Fix tcheck() to actually move CR into the output register with mfcr,
and widen the mask from "& 4" to "& 0xf" so the full CR0 nibble
(TDOOMED | TS_msb | TS_lsb | reserved) is preserved for the callers.
This bug has been present since tcheck() was introduced.
Link: https://bugs.launchpad.net/bugs/2107442
Fixes: 8e03bd4e70b6 ("selftests/powerpc: Add TM tcheck helpers in C")
Signed-off-by: Thibault Ferrante <thibault.ferrante@canonical.com>
Reported-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Tested-by: Venkat Rao Bagalkote <venkat88@linux.ibm.com>
Closes: https://lore.kernel.org/all/364996ce-aba2-4213-8d20-7dd481b43fe6@linux.ibm.com/
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260907215420.1258678-1-thibault.ferrante@canonical.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
tools/testing/selftests/powerpc/tm/tm.h | 8 ++++++--
1 file changed, 6 insertions(+), 2 deletions(-)
diff --git a/tools/testing/selftests/powerpc/tm/tm.h b/tools/testing/selftests/powerpc/tm/tm.h
index c03c6e7788767..6024ce4ba6ffd 100644
--- a/tools/testing/selftests/powerpc/tm/tm.h
+++ b/tools/testing/selftests/powerpc/tm/tm.h
@@ -105,8 +105,12 @@ static inline bool failure_is_nesting(void)
static inline int tcheck(void)
{
long cr;
- asm volatile ("tcheck 0" : "=r"(cr) : : "cr0");
- return (cr >> 28) & 4;
+ asm volatile("tcheck 0;"
+ "mfcr %0;"
+ : "=r"(cr)
+ :
+ : "cr0");
+ return (cr >> 28) & 0xf;
}
static inline bool tcheck_doomed(void)
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 412/733] drm/i915/dp: Gate UHBR SST SDP splitting on sink capability
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (410 preceding siblings ...)
2026-09-17 15:11 ` [PATCH 7.2 411/733] selftests/powerpc/tm: Fix tcheck() reading uninitialised CR value Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 413/733] perf/core: Allow list_del during perf_event_overflow() Greg Kroah-Hartman
` (332 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mitul Golani, Suraj Kandpal,
Jani Nikula, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
[ Upstream commit a894f97318366d12102c15937aa6b63c21aa82b5 ]
SDP splitting for 128b/132b (UHBR) SST audio must only be enabled when
the sink advertises support for it. Previously sdp_split_enable
was set for every UHBR SST stream carrying audio, regardless of sink
capability.
In MST mode SDP splitting is inherently supported, so the sink
capability check (DP_SST_SPLIT_SDP_CAP) is applied only to the SST path.
Fixes: 8853750dbad8 ("drm/i915: Enable SDP split for DP2.0")
Assisted-by: Claude:claude-opus-4-8
Signed-off-by: Mitul Golani <mitulkumar.ajitkumar.golani@intel.com>
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
Signed-off-by: Suraj Kandpal <suraj.kandpal@intel.com>
Link: https://patch.msgid.link/20260825073204.872441-1-mitulkumar.ajitkumar.golani@intel.com
(cherry picked from commit b37921c9f533ca936c5b5a484c1299680c570a7e)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../drm/i915/display/intel_display_types.h | 2 +
drivers/gpu/drm/i915/display/intel_dp.c | 44 ++++++++++++++++---
2 files changed, 40 insertions(+), 6 deletions(-)
diff --git a/drivers/gpu/drm/i915/display/intel_display_types.h b/drivers/gpu/drm/i915/display/intel_display_types.h
index c21e0c0ef0b12..96422641ae441 100644
--- a/drivers/gpu/drm/i915/display/intel_display_types.h
+++ b/drivers/gpu/drm/i915/display/intel_display_types.h
@@ -1947,6 +1947,8 @@ struct intel_dp {
bool colorimetry_support;
+ bool sst_split_sdp_support;
+
struct {
enum transcoder transcoder;
struct mutex lock;
diff --git a/drivers/gpu/drm/i915/display/intel_dp.c b/drivers/gpu/drm/i915/display/intel_dp.c
index 5733d2e7ac7f1..ba0b19d1163cf 100644
--- a/drivers/gpu/drm/i915/display/intel_dp.c
+++ b/drivers/gpu/drm/i915/display/intel_dp.c
@@ -3518,12 +3518,22 @@ intel_dp_audio_compute_config(struct intel_encoder *encoder,
struct intel_crtc_state *pipe_config,
struct drm_connector_state *conn_state)
{
+ struct intel_dp *intel_dp = enc_to_intel_dp(encoder);
+
pipe_config->has_audio =
intel_dp_has_audio(encoder, conn_state) &&
intel_audio_compute_config(encoder, pipe_config, conn_state);
pipe_config->sdp_split_enable = pipe_config->has_audio &&
intel_dp_is_uhbr(pipe_config);
+
+ /*
+ * SDP splitting for UHBR audio requires explicit sink capability in
+ * SST mode, whereas in MST mode it is inherently supported.
+ */
+ if (pipe_config->sdp_split_enable &&
+ !intel_crtc_has_type(pipe_config, INTEL_OUTPUT_DP_MST))
+ pipe_config->sdp_split_enable = intel_dp->sst_split_sdp_support;
}
void
@@ -4566,16 +4576,25 @@ void intel_dp_configure_protocol_converter(struct intel_dp *intel_dp,
str_enable_disable(tmp));
}
-static bool intel_dp_get_colorimetry_status(struct intel_dp *intel_dp)
+static u8 intel_dp_read_dprx_feature_enum(struct intel_dp *intel_dp)
{
u8 dprx = 0;
- if (drm_dp_dpcd_readb(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
- &dprx) != 1)
- return false;
+ drm_dp_dpcd_read_data(&intel_dp->aux, DP_DPRX_FEATURE_ENUMERATION_LIST,
+ &dprx, sizeof(dprx));
+ return dprx;
+}
+
+static bool intel_dp_get_colorimetry_status(u8 dprx)
+{
return dprx & DP_VSC_SDP_EXT_FOR_COLORIMETRY_SUPPORTED;
}
+static bool intel_dp_get_sst_split_sdp_status(u8 dprx)
+{
+ return dprx & DP_SST_SPLIT_SDP_CAP;
+}
+
static int intel_dp_read_dsc_dpcd(struct drm_dp_aux *aux,
u8 dsc_dpcd[DP_DSC_RECEIVER_CAP_SIZE])
{
@@ -4875,6 +4894,7 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
{
struct intel_display *display = to_intel_display(intel_dp);
int ret;
+ u8 dprx;
/* this function is meant to be called only once */
drm_WARN_ON(display->drm, intel_dp->dpcd[DP_DPCD_REV] != 0);
@@ -4886,8 +4906,13 @@ intel_edp_init_dpcd(struct intel_dp *intel_dp, struct intel_connector *connector
drm_dp_is_branch(intel_dp->dpcd));
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
+ dprx = intel_dp_read_dprx_feature_enum(intel_dp);
+
intel_dp->colorimetry_support =
- intel_dp_get_colorimetry_status(intel_dp);
+ intel_dp_get_colorimetry_status(dprx);
+
+ intel_dp->sst_split_sdp_support =
+ intel_dp_get_sst_split_sdp_status(dprx);
/*
* Read the eDP display control registers.
@@ -4978,13 +5003,20 @@ intel_dp_get_dpcd(struct intel_dp *intel_dp)
* the OUI/ID since we know it won't change.
*/
if (!intel_dp_is_edp(intel_dp)) {
+ u8 dprx;
+
drm_dp_read_desc(&intel_dp->aux, &intel_dp->desc,
drm_dp_is_branch(intel_dp->dpcd));
intel_init_dpcd_quirks(intel_dp, &intel_dp->desc.ident);
+ dprx = intel_dp_read_dprx_feature_enum(intel_dp);
+
intel_dp->colorimetry_support =
- intel_dp_get_colorimetry_status(intel_dp);
+ intel_dp_get_colorimetry_status(dprx);
+
+ intel_dp->sst_split_sdp_support =
+ intel_dp_get_sst_split_sdp_status(dprx);
intel_dp_update_sink_caps(intel_dp);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 413/733] perf/core: Allow list_del during perf_event_overflow()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (411 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 412/733] drm/i915/dp: Gate UHBR SST SDP splitting on sink capability Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 414/733] perf/x86/intel: Correct pt_regs->flags update for PEBS path Greg Kroah-Hartman
` (331 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Richter,
Peter Zijlstra (Intel), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <tmricht@linux.ibm.com>
[ Upstream commit 59e63416f5153e7d58652c616fbdcb7d5e01fff7 ]
A PMU might use perf_sched_cb_inc() and perf_sched_cb_dec()
interface to get the PMU call back function pmu::sched_task
invoked at schedule in and schedule out. This is achieved
by walking along the list anchored by sched_cb_list.
The following scenario might lead to a list corruption.
perf_pmu_sched_task()
for_each_list_entry(..., &sched_cb_list)
+--> __perf_pmu_sched_task()
+--> event->pmu->sched_task())
+--> PMU_push_sample()
+--> perf_event_overflow()
+--> __perf_event_overflow()
+--> pmu->stop()
+--> perf_sched_cb_dec()
remove entry from sched_cb_list
while list node in use.
This happens when ioctl(fd, PERF_EVENT_IOC_REFRESH, xxx) has been
invoked and perf_event::event_limit hits zero.
Prevent the list corruption and convert for_each_list_entry()
to for_each_list_entry_safe().
Fixes: bd2756811766 ("perf: Rewrite core context handling")
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260908105637.627004-1-tmricht@linux.ibm.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/events/core.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/kernel/events/core.c b/kernel/events/core.c
index ed3b62b0f948f..bd8c1acf59e2e 100644
--- a/kernel/events/core.c
+++ b/kernel/events/core.c
@@ -3925,13 +3925,13 @@ static void perf_pmu_sched_task(struct task_struct *prev,
bool sched_in)
{
struct perf_cpu_context *cpuctx = this_cpu_ptr(&perf_cpu_context);
- struct perf_cpu_pmu_context *cpc;
+ struct perf_cpu_pmu_context *cpc, *cpc2;
/* cpuctx->task_ctx will be handled in perf_event_context_sched_in/out */
if (prev == next || cpuctx->task_ctx)
return;
- list_for_each_entry(cpc, this_cpu_ptr(&sched_cb_list), sched_cb_entry)
+ list_for_each_entry_safe(cpc, cpc2, this_cpu_ptr(&sched_cb_list), sched_cb_entry)
__perf_pmu_sched_task(cpc, sched_in ? next : prev, sched_in);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 414/733] perf/x86/intel: Correct pt_regs->flags update for PEBS path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (412 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 413/733] perf/core: Allow list_del during perf_event_overflow() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 415/733] perf/x86/intel: Prevent drain_pebs() reentry Greg Kroah-Hartman
` (330 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dapeng Mi <dapeng1.mi@linux.intel.com>
[ Upstream commit 88aa1223bfffb1a0a98c639e9e1f71058f0d9178 ]
pt_regs->flags holds the saved CPU FLAGS register. In the PEBS path,
it was incorrectly set to PERF_EFLAGS_EXACT instead of being populated
from the PEBS flags snapshot.
Update pt_regs->flags from PEBS GPR flags if GPRs group is present.
Fixes: c22497f5838c ("perf/x86/intel: Support adaptive PEBS v4")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260908075102.540715-1-dapeng1.mi@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/ds.c | 10 +++++++++-
1 file changed, 9 insertions(+), 1 deletion(-)
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index 91a093d8cf2e7..e71cca7bbe77b 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -2445,7 +2445,7 @@ static inline void __setup_pebs_basic_group(struct perf_event *event,
{
/* The ip in basic is EventingIP */
set_linear_ip(regs, ip);
- regs->flags = PERF_EFLAGS_EXACT;
+ regs->flags |= PERF_EFLAGS_EXACT;
setup_pebs_time(event, data, tsc);
if (sample_type & PERF_SAMPLE_WEIGHT_STRUCT)
@@ -2457,9 +2457,17 @@ static inline void __setup_pebs_gpr_group(struct perf_event *event,
struct pebs_gprs *gprs,
u64 sample_type)
{
+ /*
+ * Update flags with PEBS data. PERF_EFLAGS_EXACT must be set
+ * in previous basic group handling.
+ */
+ regs->flags = gprs->flags | PERF_EFLAGS_EXACT;
+
if (event->attr.precise_ip < 2) {
set_linear_ip(regs, gprs->ip);
regs->flags &= ~PERF_EFLAGS_EXACT;
+ } else if (regs->flags & X86_VM_MASK) {
+ regs->flags ^= (PERF_EFLAGS_VM | X86_VM_MASK);
}
if (sample_type & (PERF_SAMPLE_REGS_INTR | PERF_SAMPLE_REGS_USER))
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 415/733] perf/x86/intel: Prevent drain_pebs() reentry
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (413 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 414/733] perf/x86/intel: Correct pt_regs->flags update for PEBS path Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 416/733] sched/eevdf: Fix augmented max_slice Greg Kroah-Hartman
` (329 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dapeng Mi, Peter Zijlstra (Intel),
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dapeng Mi <dapeng1.mi@linux.intel.com>
[ Upstream commit a56c03a397e2cd0c4cf8da96dcd6214f7d0e7d8c ]
The PEBS buffer is shared by all events on a CPU, so drain_pebs() must
not be reentered. If so, one instance may observe stale buffer state and
potentially access out-of-bound memory.
Most invocations happen in NMI context, which naturally prevents reentry.
However, drain_pebs() is also reachable from process context via
intel_pmu_drain_pebs_buffer().
In those paths, the PMU is often already disabled, but not guaranteed.
For example, __intel_pmu_pebs_disable() only disables the target counter,
so other active counters can still raise a PMI and interrupt an in-flight
drain_pebs(). Here is an example,
__perf_addr_filters_adjust()
perf_event_stop()
__perf_event_stop()
x86_pmu_stop() (event->pmu->stop)
intel_pmu_disable_event()
intel_pmu_pebs_disable()
__intel_pmu_pebs_disable()
intel_pmu_drain_large_pebs()
intel_pmu_drain_pebs_buffer()
Introduce __intel_pmu_quiesce() and __intel_pmu_resume() helpers and
use them in intel_pmu_drain_large_pebs() to disable the full PMU
around the intel_pmu_drain_pebs_buffer() call, preventing reentry.
Also add a warning in intel_pmu_drain_pebs_buffer() when the full PMU is
not disabled.
Fixes: b752ea0c28e3 ("perf/x86/intel/ds: Flush PEBS DS when changing PEBS_DATA_CFG")
Signed-off-by: Dapeng Mi <dapeng1.mi@linux.intel.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260813064346.335458-1-dapeng1.mi@linux.intel.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
arch/x86/events/intel/core.c | 33 ++++++++++++++++++++++++---------
arch/x86/events/intel/ds.c | 8 +++++++-
arch/x86/events/perf_event.h | 3 +++
3 files changed, 34 insertions(+), 10 deletions(-)
diff --git a/arch/x86/events/intel/core.c b/arch/x86/events/intel/core.c
index 5116b15438a21..24c1f40595449 100644
--- a/arch/x86/events/intel/core.c
+++ b/arch/x86/events/intel/core.c
@@ -3125,6 +3125,27 @@ static void intel_pmu_del_event(struct perf_event *event)
this_cpu_ptr(&cpu_hw_events)->n_late_setup--;
}
+int __intel_pmu_quiesce(void)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+ int pmu_enabled = cpuc->enabled;
+
+ cpuc->enabled = 0;
+ if (pmu_enabled)
+ intel_pmu_disable_all();
+
+ return pmu_enabled;
+}
+
+void __intel_pmu_resume(int pmu_enabled)
+{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
+
+ cpuc->enabled = pmu_enabled;
+ if (pmu_enabled)
+ intel_pmu_enable_all(0);
+}
+
static int icl_set_topdown_event_period(struct perf_event *event)
{
struct hw_perf_event *hwc = &event->hw;
@@ -3316,16 +3337,13 @@ static void intel_pmu_read_event(struct perf_event *event)
if (event->hw.flags & (PERF_X86_EVENT_AUTO_RELOAD | PERF_X86_EVENT_TOPDOWN) ||
is_pebs_counter_event_group(event)) {
struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
- bool pmu_enabled = cpuc->enabled;
+ int pmu_enabled;
/* Only need to call update_topdown_event() once for group read. */
if (is_metric_event(event) && (cpuc->txn_flags & PERF_PMU_TXN_READ))
return;
- cpuc->enabled = 0;
- if (pmu_enabled)
- intel_pmu_disable_all();
-
+ pmu_enabled = __intel_pmu_quiesce();
/*
* If the PEBS counters snapshotting is enabled,
* the topdown event is available in PEBS records.
@@ -3334,10 +3352,7 @@ static void intel_pmu_read_event(struct perf_event *event)
static_call(intel_pmu_update_topdown_event)(event, NULL);
else
intel_pmu_drain_pebs_buffer();
-
- cpuc->enabled = pmu_enabled;
- if (pmu_enabled)
- intel_pmu_enable_all(0);
+ __intel_pmu_resume(pmu_enabled);
return;
}
diff --git a/arch/x86/events/intel/ds.c b/arch/x86/events/intel/ds.c
index e71cca7bbe77b..3dcd7dfc92b1c 100644
--- a/arch/x86/events/intel/ds.c
+++ b/arch/x86/events/intel/ds.c
@@ -1242,8 +1242,11 @@ int intel_pmu_drain_bts_buffer(void)
void intel_pmu_drain_pebs_buffer(void)
{
+ struct cpu_hw_events *cpuc = this_cpu_ptr(&cpu_hw_events);
struct perf_sample_data data;
+ WARN_ON_ONCE(cpuc->enabled);
+
static_call(x86_pmu_drain_pebs)(NULL, &data);
}
@@ -1877,8 +1880,11 @@ static void intel_pmu_pebs_via_pt_enable(struct perf_event *event)
static inline void intel_pmu_drain_large_pebs(struct cpu_hw_events *cpuc)
{
if (cpuc->n_pebs == cpuc->n_large_pebs &&
- cpuc->n_pebs != cpuc->n_pebs_via_pt)
+ cpuc->n_pebs != cpuc->n_pebs_via_pt) {
+ int enabled = __intel_pmu_quiesce();
intel_pmu_drain_pebs_buffer();
+ __intel_pmu_resume(enabled);
+ }
}
static void __intel_pmu_pebs_enable(struct perf_event *event)
diff --git a/arch/x86/events/perf_event.h b/arch/x86/events/perf_event.h
index a8afea8d38f0c..680220d311a71 100644
--- a/arch/x86/events/perf_event.h
+++ b/arch/x86/events/perf_event.h
@@ -1644,6 +1644,9 @@ static __always_inline void __intel_pmu_lbr_disable(void)
wrmsrq(MSR_IA32_DEBUGCTLMSR, debugctl);
}
+extern int __intel_pmu_quiesce(void);
+extern void __intel_pmu_resume(int pmu_enabled);
+
int intel_pmu_save_and_restart(struct perf_event *event);
struct event_constraint *
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 416/733] sched/eevdf: Fix augmented max_slice
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (414 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 415/733] perf/x86/intel: Prevent drain_pebs() reentry Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 417/733] sched/eevdf: Fix rb augmented with multi fields Greg Kroah-Hartman
` (328 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Guittot,
Peter Zijlstra (Intel), K Prateek Nayak, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Guittot <vincent.guittot@linaro.org>
[ Upstream commit 9a8bc9bb4c3fb3218b4f151f98a722fbeb5b5c34 ]
Similarly to se->min_slice, init se->max_slice with se->slice before
enqueueing the entity so the augmented callback computes it correctly
at parent level.
Fixes: 6e3c0a4e1ad1 ("sched/fair: Fix lag clamp")
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://patch.msgid.link/20260907123855.1297976-1-vincent.guittot@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/fair.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 4c7bb4b7018e2..83fe5319e2ccd 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1042,6 +1042,8 @@ static void __enqueue_entity(struct cfs_rq *cfs_rq, struct sched_entity *se)
sum_w_vruntime_add(cfs_rq, se);
se->min_vruntime = se->vruntime;
se->min_slice = se->slice;
+ se->max_slice = se->slice;
+
rb_add_augmented_cached(&se->run_node, &cfs_rq->tasks_timeline,
__entity_less, &min_vruntime_cb);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 417/733] sched/eevdf: Fix rb augmented with multi fields
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (415 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 416/733] sched/eevdf: Fix augmented max_slice Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 418/733] sched: Account cgroup CPU time to the execution context Greg Kroah-Hartman
` (327 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Guittot,
Peter Zijlstra (Intel), K Prateek Nayak, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Guittot <vincent.guittot@linaro.org>
[ Upstream commit 51b0e68cfa0ac69e3c3ea9d6753af7e15dfaab22 ]
The eevdf rb tree maintains 3 augmented fields but only one is currently
copied when balancing the tree.
Add a more generic define that can be used when there are several augmented
fields. In this case, we provide a function that takes care of copying all
fields.
Fixes: aef6987d8954 ("sched/eevdf: Propagate min_slice up the cgroup hierarchy")
Signed-off-by: Vincent Guittot <vincent.guittot@linaro.org>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Reviewed-by: K Prateek Nayak <kprateek.nayak@amd.com>
Tested-by: K Prateek Nayak <kprateek.nayak@amd.com>
Link: https://patch.msgid.link/20260909150522.858312-1-vincent.guittot@linaro.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/rbtree_augmented.h | 35 +++++++++++++++++++++++++-------
kernel/sched/fair.c | 12 +++++++++--
2 files changed, 38 insertions(+), 9 deletions(-)
diff --git a/include/linux/rbtree_augmented.h b/include/linux/rbtree_augmented.h
index 6dbc5a1bf6a8c..d2fa1c41bfd2b 100644
--- a/include/linux/rbtree_augmented.h
+++ b/include/linux/rbtree_augmented.h
@@ -87,18 +87,18 @@ rb_add_augmented_cached(struct rb_node *node, struct rb_root_cached *tree,
}
/*
- * Template for declaring augmented rbtree callbacks (generic case)
+ * Template for declaring augmented rbtree callbacks (generic multi fields)
*
* RBSTATIC: 'static' or empty
* RBNAME: name of the rb_augment_callbacks structure
* RBSTRUCT: struct type of the tree nodes
* RBFIELD: name of struct rb_node field within RBSTRUCT
- * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
- * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
+ * RBCOPY: name of function that copies the RBAUGMENTED datas
+ * RBCOMPUTE: name of function that recomputes the RBAUGMENTED datas
*/
-#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
- RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
+#define RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
+ RBSTRUCT, RBFIELD, RBCOPY, RBCOMPUTE) \
static inline void \
RBNAME ## _propagate(struct rb_node *rb, struct rb_node *stop) \
{ \
@@ -114,14 +114,14 @@ RBNAME ## _copy(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
- new->RBAUGMENTED = old->RBAUGMENTED; \
+ RBCOPY(new, old); \
} \
static void \
RBNAME ## _rotate(struct rb_node *rb_old, struct rb_node *rb_new) \
{ \
RBSTRUCT *old = rb_entry(rb_old, RBSTRUCT, RBFIELD); \
RBSTRUCT *new = rb_entry(rb_new, RBSTRUCT, RBFIELD); \
- new->RBAUGMENTED = old->RBAUGMENTED; \
+ RBCOPY(new, old); \
RBCOMPUTE(old, false); \
} \
RBSTATIC const struct rb_augment_callbacks RBNAME = { \
@@ -130,6 +130,27 @@ RBSTATIC const struct rb_augment_callbacks RBNAME = { \
.rotate = RBNAME ## _rotate \
};
+/*
+ * Template for declaring augmented rbtree callbacks (generic single field)
+ *
+ * RBSTATIC: 'static' or empty
+ * RBNAME: name of the rb_augment_callbacks structure
+ * RBSTRUCT: struct type of the tree nodes
+ * RBFIELD: name of struct rb_node field within RBSTRUCT
+ * RBAUGMENTED: name of field within RBSTRUCT holding data for subtree
+ * RBCOMPUTE: name of function that recomputes the RBAUGMENTED data
+ */
+
+#define RB_DECLARE_CALLBACKS(RBSTATIC, RBNAME, \
+ RBSTRUCT, RBFIELD, RBAUGMENTED, RBCOMPUTE) \
+static inline void \
+RBNAME ## _copy_single(RBSTRUCT *new, RBSTRUCT *old) \
+{ \
+ new->RBAUGMENTED = old->RBAUGMENTED; \
+} \
+RB_DECLARE_CALLBACKS_MULTI(RBSTATIC, RBNAME, \
+ RBSTRUCT, RBFIELD, RBNAME ## _copy_single, RBCOMPUTE)
+
/*
* Template for declaring augmented rbtree callbacks,
* computing RBAUGMENTED scalar as max(RBCOMPUTE(node)) for all subtree nodes.
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 83fe5319e2ccd..a30d539a3f054 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1004,6 +1004,13 @@ static inline void __max_slice_update(struct sched_entity *se, struct rb_node *n
}
}
+static inline void min_vruntime_copy(struct sched_entity *new, struct sched_entity *old)
+{
+ new->min_vruntime = old->min_vruntime;
+ new->min_slice = old->min_slice;
+ new->max_slice = old->max_slice;
+}
+
/*
* se->min_vruntime = min(se->vruntime, {left,right}->min_vruntime)
*/
@@ -1031,8 +1038,9 @@ static inline bool min_vruntime_update(struct sched_entity *se, bool exit)
se->max_slice == old_max_slice;
}
-RB_DECLARE_CALLBACKS(static, min_vruntime_cb, struct sched_entity,
- run_node, min_vruntime, min_vruntime_update);
+
+RB_DECLARE_CALLBACKS_MULTI(static, min_vruntime_cb, struct sched_entity,
+ run_node, min_vruntime_copy, min_vruntime_update);
/*
* Enqueue an entity into the rb-tree:
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 418/733] sched: Account cgroup CPU time to the execution context
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (416 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 417/733] sched/eevdf: Fix rb augmented with multi fields Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 419/733] sched/core: Call wq_worker_tick() for " Greg Kroah-Hartman
` (326 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Tejun Heo, Hui Su,
Peter Zijlstra (Intel), John Stultz, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit c23810313bdf6b02f39a1f2a1464c4b18bd39e31 ]
Proxy execution separates the scheduling context from the execution
context. Commit aa4f74dfd42b ("sched: Fix runtime accounting w/ split
exec & sched contexts") made per-task and thread-group runtime
accounting follow the task that actually executes, while cgroup CPU
usage is charged to the donor.
When the donor and execution task belong to different cgroups, this
makes a task's execution time count against a different cgroup from the
one the task belongs to.
Cgroup CPU usage should follow the execution context, matching the
per-task, thread-group, and cgroup user/system accounting. Keep
scheduling state associated with the donor, but charge cgroup CPU
usage to rq->curr.
A reproducer with the donor and execution task in separate cgroups
showed the execution task accumulating runtime while cgroup CPU usage
was charged to the donor's cgroup. With this change, the execution
task's cgroup accumulates the CPU usage instead. The same behavior was
verified with an RT donor and with legacy cpuacct accounting.
Fixes: aa4f74dfd42b ("sched: Fix runtime accounting w/ split exec & sched contexts")
Suggested-by: Tejun Heo <tj@kernel.org>
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Tejun Heo <tj@kernel.org>
Acked-by: John Stultz <jstultz@google.com>
Link: https://patch.msgid.link/20260904034707.268416-1-sh_def@163.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/fair.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index a30d539a3f054..bb8a5f358ee19 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1373,7 +1373,6 @@ static s64 update_se(struct rq *rq, struct sched_entity *se)
se->exec_start = now;
if (entity_is_task(se)) {
- struct task_struct *donor = task_of(se);
struct task_struct *running = rq->curr;
/*
* If se is a task, we account the time against the running
@@ -1386,8 +1385,7 @@ static s64 update_se(struct rq *rq, struct sched_entity *se)
account_group_exec_runtime(running, delta_exec);
account_mm_sched(rq, running, delta_exec);
- /* cgroup time is always accounted against the donor */
- cgroup_account_cputime(donor, delta_exec);
+ cgroup_account_cputime(running, delta_exec);
} else {
/* If not task, account the time against donor se */
se->sum_exec_runtime += delta_exec;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 419/733] sched/core: Call wq_worker_tick() for the execution context
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (417 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 418/733] sched: Account cgroup CPU time to the execution context Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 420/733] net/sched: cls_route: free emptied bucket on filter move Greg Kroah-Hartman
` (325 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hui Su, Peter Zijlstra (Intel),
Tejun Heo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hui Su <sh_def@163.com>
[ Upstream commit f5741d2b34519d387edf6e9798fc7030c20a35f3 ]
wq_worker_tick() accounts CPU time and detects CPU-intensive work for
the kworker that is actually running. With proxy execution, rq->donor
is the scheduling context while rq->curr is the execution context.
Calling the hook with rq->donor can skip workqueue accounting when a
kworker is executing on behalf of a donor task. It can also account a
blocked kworker when the donor is a worker but rq->curr is the task
actually executing. The former can delay WORKER_CPU_INTENSIVE handling
and pool concurrency management, which can delay pending kernel work
and userspace operations depending on it.
Use rq->curr for the workqueue tick hook while retaining rq->donor for
scheduler accounting.
Fixes: af0c8b2bf67b ("sched: Split scheduler and execution contexts")
Signed-off-by: Hui Su <sh_def@163.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Acked-by: Tejun Heo <tj@kernel.org>
Link: https://patch.msgid.link/20260902150208.1209922-2-sh_def@163.com
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/sched/core.c | 9 +++++----
1 file changed, 5 insertions(+), 4 deletions(-)
diff --git a/kernel/sched/core.c b/kernel/sched/core.c
index d0992ecda4c72..35d647c8c3683 100644
--- a/kernel/sched/core.c
+++ b/kernel/sched/core.c
@@ -5780,8 +5780,8 @@ void sched_tick(void)
{
int cpu = smp_processor_id();
struct rq *rq = cpu_rq(cpu);
- /* accounting goes to the donor task */
- struct task_struct *donor;
+ /* scheduler accounting goes to the donor task */
+ struct task_struct *curr, *donor;
struct rq_flags rf;
unsigned long hw_pressure;
u64 resched_latency;
@@ -5792,6 +5792,7 @@ void sched_tick(void)
sched_clock_tick();
rq_lock(rq, &rf);
+ curr = rq->curr;
donor = rq->donor;
psi_account_irqtime(rq, donor, NULL);
@@ -5817,8 +5818,8 @@ void sched_tick(void)
perf_event_task_tick();
- if (donor->flags & PF_WQ_WORKER)
- wq_worker_tick(donor);
+ if (curr->flags & PF_WQ_WORKER)
+ wq_worker_tick(curr);
if (!scx_switched_all()) {
rq->idle_balance = idle_cpu(cpu);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 420/733] net/sched: cls_route: free emptied bucket on filter move
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (418 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 419/733] sched/core: Call wq_worker_tick() for " Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 421/733] net/sched: cls_route: Reject handle aliasing Greg Kroah-Hartman
` (324 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Jamal Hadi Salim,
Victor Nogueira, Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit 1853f30cf5c84971f99788a76207c6f745380896 ]
route4_change can move an existing filter to a different top-level
bucket: route4_set_parms recomputes the handle from TCA_ROUTE4_TO/
FROM/IIF, and the handle-mismatch check is gated on the 'new' flag, so
for an existing filter the new handle may differ from the old one and
land in a different bucket. When this happens, the filter is unlinked
from the old bucket, but the bucket itself is never freed once it goes
empty. The stale empty bucket remains in head->table[], causing
route4_delete to report *last=false even after the last live filter is
gone. That pins the empty tcf_proto and causes a leak.
Fix this by refcounting the filters linked to a bucket and freeing the
bucket when the count drops to zero. The existing scan in route4_delete
goes away with it.
The count is updated at all sites that link or unlink a filter during add,
change and delete, and the bucket is dropped from head->table[] as soon as
it reaches zero.
Conditions to recreate the bug:
CONFIG_NET_CLS_ROUTE4=y, CONFIG_NET_SCH_INGRESS=y, CONFIG_NET_CLS_ACT=y.
tc qdisc replace dev lo clsact
tc filter add dev lo ingress protocol ip pref 100 route from 1 to 1
tc filter change dev lo ingress protocol ip pref 100 handle 0x10001 \
route from 1 to 2
tc filter del dev lo ingress protocol ip pref 100 handle 0x10002 \
route from 1 to 2
tc filter show dev lo ingress | grep -c 'pref 100 route chain 0 '
Fixes: 1e052be69d04 ("net_sched: destroy proto tp when all filters are gone")
Reported-by: Vega <vega@nebusec.ai>
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/20260907192133.2639067-2-victor@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_route.c | 45 +++++++++++++++++++++----------------------
1 file changed, 22 insertions(+), 23 deletions(-)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 0d1324c905837..17b0ebb766626 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -11,6 +11,7 @@
#include <linux/kernel.h>
#include <linux/string.h>
#include <linux/errno.h>
+#include <linux/refcount.h>
#include <linux/skbuff.h>
#include <net/dst.h>
#include <net/route.h>
@@ -41,6 +42,7 @@ struct route4_head {
struct route4_bucket {
/* 16 FROM buckets + 16 IIF buckets + 1 wildcard bucket */
struct route4_filter __rcu *ht[16 + 16 + 1];
+ refcount_t filters_ref;
struct rcu_head rcu;
};
@@ -336,7 +338,7 @@ static int route4_delete(struct tcf_proto *tp, void *arg, bool *last,
struct route4_filter *nf;
struct route4_bucket *b;
unsigned int h = 0;
- int i, h1;
+ int h1;
if (!head || !f)
return -EINVAL;
@@ -362,23 +364,14 @@ static int route4_delete(struct tcf_proto *tp, void *arg, bool *last,
tcf_exts_get_net(&f->exts);
tcf_queue_work(&f->rwork, route4_delete_filter_work);
- /* Strip RTNL protected tree */
- for (i = 0; i <= 32; i++) {
- struct route4_filter *rt;
-
- rt = rtnl_dereference(b->ht[i]);
- if (rt)
- goto out;
+ if (refcount_dec_and_test(&b->filters_ref)) {
+ RCU_INIT_POINTER(head->table[to_hash(h)], NULL);
+ kfree_rcu(b, rcu);
}
-
- /* OK, session has no flows */
- RCU_INIT_POINTER(head->table[to_hash(h)], NULL);
- kfree_rcu(b, rcu);
break;
}
}
-out:
*last = true;
for (h1 = 0; h1 <= 256; h1++) {
if (rcu_access_pointer(head->table[h1])) {
@@ -459,6 +452,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
if (b == NULL)
return -ENOBUFS;
+ refcount_set(&b->filters_ref, 1);
rcu_assign_pointer(head->table[h1], b);
} else {
unsigned int h2 = from_hash(nhandle >> 16);
@@ -468,6 +462,8 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
fp = rtnl_dereference(fp->next))
if (fp->handle == f->handle)
return -EEXIST;
+
+ refcount_inc(&b->filters_ref);
}
if (tb[TCA_ROUTE4_TO])
@@ -500,7 +496,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
struct route4_filter *fold, *f1, *pfp, *f = NULL;
struct route4_bucket *b;
struct nlattr *tb[TCA_ROUTE4_MAX + 1];
- unsigned int h, th;
+ unsigned int h;
int err;
bool new = true;
@@ -560,17 +556,20 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
rcu_assign_pointer(*fp, f);
if (fold) {
- th = to_hash(fold->handle);
+ b = fold->bkt;
h = from_hash(fold->handle >> 16);
- b = rtnl_dereference(head->table[th]);
- if (b) {
- fp = &b->ht[h];
- for (pfp = rtnl_dereference(*fp); pfp;
- fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
- if (pfp == fold) {
- rcu_assign_pointer(*fp, fold->next);
- break;
+ fp = &b->ht[h];
+ for (pfp = rtnl_dereference(*fp); pfp;
+ fp = &pfp->next, pfp = rtnl_dereference(*fp)) {
+ if (pfp == fold) {
+ rcu_assign_pointer(*fp, fold->next);
+ if (refcount_dec_and_test(&b->filters_ref)) {
+ unsigned int th = to_hash(fold->handle);
+
+ RCU_INIT_POINTER(head->table[th], NULL);
+ kfree_rcu(b, rcu);
}
+ break;
}
}
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 421/733] net/sched: cls_route: Reject handle aliasing
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (419 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 420/733] net/sched: cls_route: free emptied bucket on filter move Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 422/733] net/sched: cls_route: Fix in-place replace Greg Kroah-Hartman
` (323 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jamal Hadi Salim,
Victor Nogueira, Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit b74a8455a2f271f54695b6a8ec1f113824a46c0e ]
route4_set_parms() rejects a duplicate by scanning the destination chain
for f->handle, but f->handle is the handle the filter has before the
update, not the one it is about to be linked under. The comparison and
the insertion therefore use different handles, which causes breakage.
When a change moves the filter to a chain that already holds nhandle,
the scan looks for the old handle instead, misses the collision and
links a second filter with the same handle:
tc filter add dev lo ingress protocol ip pref 100 \
route from 1 to 1 classid 1:1 action ok
tc filter add dev lo ingress protocol ip pref 100 \
route from 2 to 2 classid 1:2 action drop
tc filter change dev lo ingress protocol ip pref 100 handle 0x10001 \
route from 2 to 2 classid 1:1 action ok
tc filter show dev lo ingress
... fh 0x00020002 flowid 1:2 to 2 from 2
... fh 0x00020002 flowid 1:1 to 2 from 2
The newcomer is appended after the incumbent, and both end up with the
same f->id. route4_get() returns the first match, so the second filter
can no longer be addressed by handle, and route4_classify() stops at the
first filter whose f->id matches. The second filter is dumped but is
effectively dead.
Fix this by comparing against nhandle.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260829205422.854785-1-victor%40mojatatu.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/20260907192133.2639067-3-victor@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_route.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 17b0ebb766626..9710b77d379c4 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -460,8 +460,12 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
for (fp = rtnl_dereference(b->ht[h2]);
fp;
fp = rtnl_dereference(fp->next))
- if (fp->handle == f->handle)
+ if (fp->handle == nhandle) {
+ NL_SET_ERR_MSG_FMT(extack,
+ "Handle %x is already in use",
+ nhandle);
return -EEXIST;
+ }
refcount_inc(&b->filters_ref);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 422/733] net/sched: cls_route: Fix in-place replace
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (420 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 421/733] net/sched: cls_route: Reject handle aliasing Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 423/733] net/sched: cls_api: Dont replay RTM_GETCHAIN in tc_ctl_chain() Greg Kroah-Hartman
` (322 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Jamal Hadi Salim,
Victor Nogueira, Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Victor Nogueira <victor@mojatatu.com>
[ Upstream commit 41e85e54e5649a1617698438b0ce64c6f9d83d69 ]
Building on the previous patch, route4_set_parms rejects a duplicate by
scanning the destination chain for nhandle, but the scan doesn't exclude
the older version it is replacing, so an in-place replace will match
the older version's handle and fail.
Fix this by passing the older filter as a parameter to route4_set_parms
(replacing "new") and skipping it in the scan.
Excluding the older version is not enough on its own. nhandle is built
out of TCA_ROUTE4_TO, TCA_ROUTE4_FROM and TCA_ROUTE4_IIF alone, while the
0x7F00 bits, which only tell apart filters sharing one key, are folded in
on the create path. Letting the replace through would therefore rename
the filter it replaces: replacing handle 0x10101 stored it back as
0x10001, and a sibling at 0x10201 could then no longer be replaced at
all, since its own nhandle collided with the renamed filter.
tc filter add ... handle 0x10101 route from 1 to 1 classid 1:1
tc filter add ... handle 0x10201 route from 1 to 1 classid 1:2
tc filter replace ... handle 0x10101 route from 1 to 1 classid 1:9
... fh 0x00010001 flowid 1:9 to 1 from 1
... fh 0x00010201 flowid 1:2 to 1 from 1
tc filter replace ... handle 0x10201 route from 1 to 1 classid 1:8
Error: Handle 10001 is already in use.
So carry those bits over when the key the request builds is the key the
older filter already has. An in-place replace then keeps the handle
userspace named the filter by, while a request that does change the key
still renames it, as it did before.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260829205422.854785-1-victor%40mojatatu.com
Acked-by: Jamal Hadi Salim <jhs@mojatatu.com>
Signed-off-by: Victor Nogueira <victor@mojatatu.com>
Link: https://patch.msgid.link/20260907192133.2639067-4-victor@mojatatu.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_route.c | 27 +++++++++++++--------------
1 file changed, 13 insertions(+), 14 deletions(-)
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 9710b77d379c4..0f211f030fd9a 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -393,8 +393,9 @@ static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
static int route4_set_parms(struct net *net, struct tcf_proto *tp,
unsigned long base, struct route4_filter *f,
u32 handle, struct route4_head *head,
- struct nlattr **tb, struct nlattr *est, int new,
- u32 flags, struct netlink_ext_ack *extack)
+ struct nlattr **tb, struct nlattr *est,
+ struct route4_filter *fold, u32 flags,
+ struct netlink_ext_ack *extack)
{
u32 id = 0, to = 0, nhandle = 0x8000;
struct route4_filter *fp;
@@ -407,7 +408,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
return err;
if (tb[TCA_ROUTE4_TO]) {
- if (new && handle & 0x8000) {
+ if (!fold && handle & 0x8000) {
NL_SET_ERR_MSG(extack, "Invalid handle");
return -EINVAL;
}
@@ -430,14 +431,14 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
} else
nhandle |= 0xFFFF << 16;
- if (handle && new) {
+ if (handle && (!fold || nhandle == (handle & ~0x7F00)))
nhandle |= handle & 0x7F00;
- if (nhandle != handle) {
- NL_SET_ERR_MSG_FMT(extack,
- "Handle mismatch constructed: %x (expected: %x)",
- handle, nhandle);
- return -EINVAL;
- }
+
+ if (handle && !fold && nhandle != handle) {
+ NL_SET_ERR_MSG_FMT(extack,
+ "Handle mismatch constructed: %x (expected: %x)",
+ handle, nhandle);
+ return -EINVAL;
}
if (!nhandle) {
@@ -460,7 +461,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
for (fp = rtnl_dereference(b->ht[h2]);
fp;
fp = rtnl_dereference(fp->next))
- if (fp->handle == nhandle) {
+ if (fp != fold && fp->handle == nhandle) {
NL_SET_ERR_MSG_FMT(extack,
"Handle %x is already in use",
nhandle);
@@ -502,7 +503,6 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
struct nlattr *tb[TCA_ROUTE4_MAX + 1];
unsigned int h;
int err;
- bool new = true;
if (!handle) {
NL_SET_ERR_MSG(extack, "Creating with handle of 0 is invalid");
@@ -539,11 +539,10 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
f->tp = fold->tp;
f->bkt = fold->bkt;
- new = false;
}
err = route4_set_parms(net, tp, base, f, handle, head, tb,
- tca[TCA_RATE], new, flags, extack);
+ tca[TCA_RATE], fold, flags, extack);
if (err < 0)
goto errout;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 423/733] net/sched: cls_api: Dont replay RTM_GETCHAIN in tc_ctl_chain().
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (421 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 422/733] net/sched: cls_route: Fix in-place replace Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 424/733] net: sun4i-emac: fix missing of_node_put() for phy_node Greg Kroah-Hartman
` (321 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Taras Madan, Kuniyuki Iwashima,
Jamal Hadi Salim, hybris, Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuniyuki Iwashima <kuniyu@google.com>
[ Upstream commit dff39930ad5e53d202bfdfb14687d1d2fd753b4d ]
If a netlink socket sends RTM_GETCHAIN requests repeatedly
without recv()ing the responses, tc_ctl_chain() hogs CPU and
triggers Hung Task splat. [0]
As caught in the stack trace, netlink_attachskb() could confuse
tc_ctl_chain() by returning -EAGAIN when the userspace netlink
socket's receive buffer is full.
The replay: label exists since commit 32a4f5ecd738 ("net: sched:
introduce chain object to uapi") but was not used initially.
Since commit 9f407f1768d3 ("net: sched: introduce chain templates"),
the label is needed for RTM_NEWCHAIN because tcf_proto_lookup_ops()
may release RTNL to call request_module().
However, the replay logic is unnecessary for RTM_GETCHAIN.
Let's apply the replay logic only for RTM_NEWCHAIN.
[0]:
INFO: task repro:1018 is blocked on a mutex likely owned by task repro:1022.
task:repro state:R running task stack:14096 pid:1022 tgid:1014 ppid:961 task_flags:0x400040 flags:0x00080000
Call Trace:
<TASK>
? clockevents_program_event (kernel/time/clockevents.c:372)
? pskb_expand_head (net/core/skbuff.c:615)
? skb_release_data (net/core/skbuff.c:1122)
? netlink_attachskb (./include/linux/skbuff.h:1323 ./include/linux/skbuff.h:1332 net/netlink/af_netlink.c:1232)
? __netlink_lookup (./include/linux/rcupdate.h:882 ./include/linux/rhashtable.h:711 net/netlink/af_netlink.c:499)
? tc_chain_notify (net/sched/cls_api.c:3045)
? tc_chain_notify (./include/linux/skbuff.h:1384 net/sched/cls_api.c:3041)
? netlink_unicast (net/netlink/af_netlink.c:1335)
? rtnl_unicast (./include/net/netlink.h:1198 net/core/rtnetlink.c:985)
? tc_ctl_chain (net/sched/cls_api.c:3242)
? rtnetlink_rcv_msg (net/core/rtnetlink.c:7146)
? netlink_unicast (net/netlink/af_netlink.c:1354)
? __pfx_rtnetlink_rcv_msg (net/core/rtnetlink.c:7177)
? netlink_rcv_skb (net/netlink/af_netlink.c:2556)
? netlink_unicast (net/netlink/af_netlink.c:1319)
? netlink_sendmsg (net/netlink/af_netlink.c:1900)
? __sock_sendmsg (net/socket.c:800)
? __sys_sendto (net/socket.c:2281)
? __x64_sys_sendto (net/socket.c:2288 net/socket.c:2284 net/socket.c:2284)
? do_syscall_64 (arch/x86/entry/syscall_64.c:61 arch/x86/entry/syscall_64.c:84)
? entry_SYSCALL_64_after_hwframe (arch/x86/entry/entry_64.S:121)
</TASK>
Fixes: 2ed9db3074fc ("net: sched: cls_api: fix dead code in switch")
Reported-by: Taras Madan <tarasmadan@google.com>
Signed-off-by: Kuniyuki Iwashima <kuniyu@google.com>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Tested-by: hybris@mojatatu.ai
Link: https://patch.msgid.link/20260908205537.863484-1-kuniyu@google.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/sched/cls_api.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 9966766661d50..c47d2ee13641d 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -3254,7 +3254,7 @@ static int tc_ctl_chain(struct sk_buff *skb, struct nlmsghdr *n,
tcf_chain_put(chain);
errout_block:
tcf_block_release(q, block, true);
- if (err == -EAGAIN)
+ if (err == -EAGAIN && n->nlmsg_type == RTM_NEWCHAIN)
/* Replay the request. */
goto replay;
return err;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 424/733] net: sun4i-emac: fix missing of_node_put() for phy_node
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (422 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 423/733] net/sched: cls_api: Dont replay RTM_GETCHAIN in tc_ctl_chain() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 425/733] net: hinic: fix mailbox segment buffer overflow Greg Kroah-Hartman
` (320 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Li Youhong, Simon Horman,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Youhong <liyouhong@kylinos.cn>
[ Upstream commit af406abfecad2f48d8f1fc646d3994f0982bac62 ]
of_parse_phandle() returns a node pointer with an elevated refcount.
Add the missing of_node_put() on the probe error path after
register_netdev() fails and in emac_remove().
Fixes: 492205050d77 ("net: Add EMAC ethernet driver found on Allwinner A10 SoC's")
Signed-off-by: Li Youhong <liyouhong@kylinos.cn>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904080758.2432748-1-dayou5941@163.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/allwinner/sun4i-emac.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/drivers/net/ethernet/allwinner/sun4i-emac.c b/drivers/net/ethernet/allwinner/sun4i-emac.c
index a297874f4a819..9382b4b329bdf 100644
--- a/drivers/net/ethernet/allwinner/sun4i-emac.c
+++ b/drivers/net/ethernet/allwinner/sun4i-emac.c
@@ -1067,6 +1067,7 @@ static int emac_probe(struct platform_device *pdev)
return 0;
out_release_sram:
+ of_node_put(db->phy_node);
sunxi_sram_release(&pdev->dev);
out_clk_disable_unprepare:
clk_disable_unprepare(db->clk);
@@ -1094,6 +1095,7 @@ static void emac_remove(struct platform_device *pdev)
}
unregister_netdev(ndev);
+ of_node_put(db->phy_node);
sunxi_sram_release(&pdev->dev);
clk_disable_unprepare(db->clk);
irq_dispose_mapping(ndev->irq);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 425/733] net: hinic: fix mailbox segment buffer overflow
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (423 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 424/733] net: sun4i-emac: fix missing of_node_put() for phy_node Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 426/733] net: dsa: mt7530: add EN7528 support Greg Kroah-Hartman
` (319 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Aamir Ahmed, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aamir Ahmed <elb12345@hotmail.co.uk>
[ Upstream commit 5d4d985957434867bbe85e4fa5e638f3e48ad522 ]
check_mbox_seq_id_and_seg_len() validates that seq_id does not
exceed SEQ_ID_MAX_VAL (42) and seg_len does not exceed
MBOX_SEG_LEN (48). However, this allows the last segment
(seq_id=42) to carry a full 48-byte payload, writing to offset
42*48=2016 for 48 bytes (ending at byte 2064). The receive
buffer is only MBOX_MAX_BUF_SZ (2048) bytes, resulting in a
16-byte heap buffer overflow.
The hinic3 driver already handles this correctly by defining
MBOX_LAST_SEG_MAX_LEN and rejecting the last segment when it
exceeds the remaining buffer space. Apply the same fix to the
hinic driver.
Fixes: a425b6e1c69b ("hinic: add mailbox function support")
Signed-off-by: Aamir Ahmed <elb12345@hotmail.co.uk>
Link: https://patch.msgid.link/AS8P251MB0001AE870B09020B46B5D7DBC8B22@AS8P251MB0001.EURP251.PROD.OUTLOOK.COM
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
index 2784127327e64..6e67a6c9578e1 100644
--- a/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
+++ b/drivers/net/ethernet/huawei/hinic/hinic_hw_mbox.c
@@ -128,6 +128,7 @@ enum hinic_mbox_tx_status {
#define SEQ_ID_START_VAL 0
#define SEQ_ID_MAX_VAL 42
+#define MBOX_LAST_SEG_MAX_LEN (MBOX_MAX_BUF_SZ - SEQ_ID_MAX_VAL * MBOX_SEG_LEN)
#define NO_DMA_ATTRIBUTE_VAL 0
@@ -372,7 +373,8 @@ recv_pf_from_vf_mbox_handler(struct hinic_mbox_func_to_func *func_to_func,
static bool check_mbox_seq_id_and_seg_len(struct hinic_recv_mbox *recv_mbox,
u8 seq_id, u8 seg_len)
{
- if (seq_id > SEQ_ID_MAX_VAL || seg_len > MBOX_SEG_LEN)
+ if (seq_id > SEQ_ID_MAX_VAL || seg_len > MBOX_SEG_LEN ||
+ (seq_id == SEQ_ID_MAX_VAL && seg_len > MBOX_LAST_SEG_MAX_LEN))
return false;
if (seq_id == 0) {
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 426/733] net: dsa: mt7530: add EN7528 support
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (424 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 425/733] net: hinic: fix mailbox segment buffer overflow Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 427/733] net: dsa: mt7530: populate lpi_interfaces to fix EEE support Greg Kroah-Hartman
` (318 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ahmed Naseef, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ahmed Naseef <naseefkm@gmail.com>
[ Upstream commit cf23fcc9437e5c383d9f282197d580a5a3fd6e6e ]
The EcoNet EN7528 SoC integrates an MT7530 switch (the chip revision
register reads 0x7530), memory-mapped in the SoC register space and
reached through the same MMIO glue used for the built-in switches of the
MediaTek MT7988 and Airoha EN7581/AN7583 SoCs. Its reset sequence and its
PHY indirect access registers are the same as on those switches, so add
an ID_EN7528 variant bound with the "econet,en7528-switch" compatible,
reusing mt7988_setup() and the indirect PHY accessors.
The switch core, however, is an MT7530 and not an MT7531 derivative: the
CPU port to trap frames to is set through the MT7530-style CPU_EN /
CPU_PORT fields of the MFC register rather than the MT7531 CFC register,
so add it to the MT7530 handling in mt753x_conduit_state_change(). For the
same reason the MT7530 mirror and force-mode register layouts already
apply to it as the default of the MT753X_*() macros.
The four user ports (1-4) are connected to integrated Gigabit PHYs at
MDIO addresses 9-12 of the switch internal MDIO bus. The CPU port (port
6) is connected to the SoC Ethernet MAC at a fixed 1000 Mbps full duplex
link, so the port capabilities cannot be shared with the MT7988 and
EN7581 switches, whose CPU ports run at 10 Gbps.
The LAN GPHYs advertise EEE by default, but negotiating EEE with some
link partners results in an unstable link with dropped frames. Leave the
LPI capabilities empty for the EN7528 so that phylink disables EEE on
these PHYs and refuses to enable it from userspace.
Signed-off-by: Ahmed Naseef <naseefkm@gmail.com>
Link: https://patch.msgid.link/8c7dfabd860ab0a6dd771c2bac7b7599eb369a4f.1783770059.git.naseefkm@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Stable-dep-of: 3c18e3c9a54e ("net: dsa: mt7530: populate lpi_interfaces to fix EEE support")
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/mt7530-mmio.c | 1 +
drivers/net/dsa/mt7530.c | 58 ++++++++++++++++++++++++++++++-----
drivers/net/dsa/mt7530.h | 1 +
3 files changed, 52 insertions(+), 8 deletions(-)
diff --git a/drivers/net/dsa/mt7530-mmio.c b/drivers/net/dsa/mt7530-mmio.c
index 119fdd863d917..fd68b1cd06306 100644
--- a/drivers/net/dsa/mt7530-mmio.c
+++ b/drivers/net/dsa/mt7530-mmio.c
@@ -12,6 +12,7 @@
static const struct of_device_id mt7988_of_match[] = {
{ .compatible = "airoha,an7583-switch", .data = &mt753x_table[ID_AN7583], },
{ .compatible = "airoha,en7581-switch", .data = &mt753x_table[ID_EN7581], },
+ { .compatible = "econet,en7528-switch", .data = &mt753x_table[ID_EN7528], },
{ .compatible = "mediatek,mt7988-switch", .data = &mt753x_table[ID_MT7988], },
{ /* sentinel */ },
};
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index aa33d94e11b5f..55131bfd11f6d 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -2902,6 +2902,30 @@ static void en7581_mac_port_get_caps(struct dsa_switch *ds, int port,
}
}
+static void en7528_mac_port_get_caps(struct dsa_switch *ds, int port,
+ struct phylink_config *config)
+{
+ switch (port) {
+ /* Ports which are connected to switch PHYs. There is no MII pinout. */
+ case 1 ... 4:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+
+ config->mac_capabilities |= MAC_10 | MAC_100 | MAC_1000FD;
+ break;
+
+ /* Port 6 is connected to SoC's GMAC at 1000 Mbps full duplex. There
+ * is no MII pinout.
+ */
+ case 6:
+ __set_bit(PHY_INTERFACE_MODE_INTERNAL,
+ config->supported_interfaces);
+
+ config->mac_capabilities |= MAC_1000FD;
+ break;
+ }
+}
+
static void
mt7530_mac_config(struct dsa_switch *ds, int port, unsigned int mode,
phy_interface_t interface)
@@ -3091,17 +3115,24 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
struct phylink_config *config)
{
struct mt7530_priv *priv = ds->priv;
- u32 eeecr;
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
- config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
-
- eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
- /* tx_lpi_timer should be in microseconds. The time units for
- * LPI threshold are unspecified.
+ /* The EN7528 GPHYs report EEE capability, but negotiating EEE with
+ * common link partners (e.g. Realtek GbE NICs) results in an unstable
+ * link with dropped frames. Leave the LPI capabilities empty so that
+ * phylink disables EEE on these PHYs and refuses to enable it from
+ * userspace.
*/
- config->lpi_timer_default = FIELD_GET(LPI_THRESH_MASK, eeecr);
+ if (priv->id != ID_EN7528) {
+ u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
+
+ config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
+ /* tx_lpi_timer should be in microseconds. The time units for
+ * LPI threshold are unspecified.
+ */
+ config->lpi_timer_default = FIELD_GET(LPI_THRESH_MASK, eeecr);
+ }
priv->info->mac_port_get_caps(ds, port, config);
}
@@ -3244,7 +3275,8 @@ mt753x_conduit_state_change(struct dsa_switch *ds,
* forwarded to the numerically smallest CPU port whose conduit
* interface is up.
*/
- if (priv->id != ID_MT7530 && priv->id != ID_MT7621)
+ if (priv->id != ID_MT7530 && priv->id != ID_MT7621 &&
+ priv->id != ID_EN7528)
return;
mask = BIT(cpu_dp->index);
@@ -3449,6 +3481,16 @@ const struct mt753x_info mt753x_table[] = {
.phy_write_c45 = mt7531_ind_c45_phy_write,
.mac_port_get_caps = en7581_mac_port_get_caps,
},
+ [ID_EN7528] = {
+ .id = ID_EN7528,
+ .pcs_ops = &mt7530_pcs_ops,
+ .sw_setup = mt7988_setup,
+ .phy_read_c22 = mt7531_ind_c22_phy_read,
+ .phy_write_c22 = mt7531_ind_c22_phy_write,
+ .phy_read_c45 = mt7531_ind_c45_phy_read,
+ .phy_write_c45 = mt7531_ind_c45_phy_write,
+ .mac_port_get_caps = en7528_mac_port_get_caps,
+ },
};
EXPORT_SYMBOL_GPL(mt753x_table);
diff --git a/drivers/net/dsa/mt7530.h b/drivers/net/dsa/mt7530.h
index dd33b0df3419e..5f1e841f42c0e 100644
--- a/drivers/net/dsa/mt7530.h
+++ b/drivers/net/dsa/mt7530.h
@@ -21,6 +21,7 @@ enum mt753x_id {
ID_MT7988 = 3,
ID_EN7581 = 4,
ID_AN7583 = 5,
+ ID_EN7528 = 6,
};
#define NUM_TRGMII_CTRL 5
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 427/733] net: dsa: mt7530: populate lpi_interfaces to fix EEE support
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (425 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 426/733] net: dsa: mt7530: add EN7528 support Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 428/733] net: ethernet: mtk_eth_soc: " Greg Kroah-Hartman
` (317 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Sviridkin <f@lex.la>
[ Upstream commit 3c18e3c9a54e1239b72849502ca4737604bfbb46 ]
phylink_create() decides once and for all that a MAC supports managed
EEE, and it requires the tx_lpi ops plus non-empty lpi_capabilities and
lpi_interfaces. mt753x_phylink_get_caps() leaves lpi_interfaces empty.
So ever since the conversion to phylink managed EEE, ethtool has
answered "Not supported" on every mt753x port, and phy_disable_eee()
has locked userspace out of turning EEE on. That undoes what
commit 06dfcd4098cf ("net: dsa: mt7530: fix enabling EEE on MT7531
switch on all boards") arranged: EEE off by default, but reachable
with ethtool.
Leave the speeds above 1 Gbps out of both bitmaps. PMCR folds
SPEED_2500 and SPEED_10000 onto PMCR_FORCE_SPEED_1000, so
PMCR_FORCE_EEE1G would govern LPI on such a link, and that is
unvalidated rather than known unsupported: MediaTek's SDK driver sets
the EEE force bits for 100 Mbps and 1 Gbps only, and the unit of the
wakeup timers is undocumented with the port clock at 2.5 times the
rate.
LPI stays off until userspace enables it, but the EEE advertisement of
a PHY that advertises it out of reset comes back, since phylink stops
force-clearing it.
Fixes: 9cf21773f535 ("net: dsa: mt7530: convert to phylink managed EEE")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260903123644.23800-2-f@lex.la
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/dsa/mt7530.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
diff --git a/drivers/net/dsa/mt7530.c b/drivers/net/dsa/mt7530.c
index 55131bfd11f6d..56ee8dc34f518 100644
--- a/drivers/net/dsa/mt7530.c
+++ b/drivers/net/dsa/mt7530.c
@@ -3118,23 +3118,31 @@ static void mt753x_phylink_get_caps(struct dsa_switch *ds, int port,
config->mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE;
+ priv->info->mac_port_get_caps(ds, port, config);
+
/* The EN7528 GPHYs report EEE capability, but negotiating EEE with
* common link partners (e.g. Realtek GbE NICs) results in an unstable
* link with dropped frames. Leave the LPI capabilities empty so that
* phylink disables EEE on these PHYs and refuses to enable it from
* userspace.
*/
- if (priv->id != ID_EN7528) {
+ if (priv->id != ID_EN7528 &&
+ config->mac_capabilities & (MAC_100FD | MAC_1000FD)) {
u32 eeecr = mt7530_read(priv, MT753X_PMEEECR_P(port));
- config->lpi_capabilities = MAC_100FD | MAC_1000FD | MAC_2500FD;
+ /* LPI above 1 Gbps is not supported */
+ config->lpi_capabilities = config->mac_capabilities &
+ (MAC_100FD | MAC_1000FD);
+ phy_interface_copy(config->lpi_interfaces,
+ config->supported_interfaces);
+ __clear_bit(PHY_INTERFACE_MODE_2500BASEX,
+ config->lpi_interfaces);
+
/* tx_lpi_timer should be in microseconds. The time units for
* LPI threshold are unspecified.
*/
config->lpi_timer_default = FIELD_GET(LPI_THRESH_MASK, eeecr);
}
-
- priv->info->mac_port_get_caps(ds, port, config);
}
static int mt753x_pcs_validate(struct phylink_pcs *pcs,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 428/733] net: ethernet: mtk_eth_soc: populate lpi_interfaces to fix EEE support
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (426 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 427/733] net: dsa: mt7530: populate lpi_interfaces to fix EEE support Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 429/733] net: phy: mediatek-ge: disable EEE on the MT7530 PHY Greg Kroah-Hartman
` (316 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Aleksei Sviridkin, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksei Sviridkin <f@lex.la>
[ Upstream commit d876c9cb2d16ed259449fe9da08c37a5cb81d724 ]
phylink_create() decides once and for all that a MAC supports managed
EEE, and it requires the tx_lpi ops plus non-empty lpi_capabilities and
lpi_interfaces. mtk_add_mac() leaves lpi_interfaces empty.
So ever since EEE support was added, ethtool has answered "Not
supported" on every MAC that uses mtk_phylink_ops, and
phy_disable_eee() has locked userspace out of turning EEE on. MT7628
is unaffected, as rt5350_phylink_ops has no tx_lpi methods.
Leave 2.5 Gbps out of both bitmaps, and the xGMII modes that
mtk_mac_enable_tx_lpi() already refuses. MAC_MCR folds SPEED_2500 onto
MAC_MCR_SPEED_1000, so MAC_MCR_EEE1G would govern LPI on such a link,
and that is unvalidated rather than known unsupported: MediaTek's SDK
driver sets the EEE force bits for 100 Mbps and 1 Gbps only, and the
unit of the wakeup timers is undocumented with the port clock at
2.5 times the rate.
mtk_mac_enable_tx_lpi() programs wake-up times taken from MT7531's
reset values, and the SoC's own field has no reset value to fall
back on. Only MT7981 has been seen to exit LPI cleanly with them, so
the LPI interfaces sit behind a new MTK_GMAC_EEE capability that only
MT7981 sets; every other SoC keeps the current behaviour until it has
been confirmed.
LPI stays off until userspace enables it, but the EEE advertisement of
a PHY that advertises it out of reset comes back, since phylink stops
force-clearing it.
Fixes: 952d7325362f ("net: ethernet: mediatek: add EEE support")
Signed-off-by: Aleksei Sviridkin <f@lex.la>
Link: https://patch.msgid.link/20260903123644.23800-3-f@lex.la
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/mediatek/mtk_eth_soc.c | 18 +++++++++++++++---
drivers/net/ethernet/mediatek/mtk_eth_soc.h | 4 +++-
2 files changed, 18 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.c b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
index 351444fb48716..b2473df74dff0 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.c
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.c
@@ -4827,7 +4827,7 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
phy_interface_t phy_mode;
struct phylink *phylink;
struct mtk_mac *mac;
- int id, err;
+ int id, err, i;
int txqs = 1;
u32 val;
@@ -4906,8 +4906,8 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
mac->phylink_config.type = PHYLINK_NETDEV;
mac->phylink_config.mac_capabilities = MAC_ASYM_PAUSE | MAC_SYM_PAUSE |
MAC_10 | MAC_100 | MAC_1000 | MAC_2500FD;
- mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD |
- MAC_2500FD;
+ /* LPI above 1 Gbps is not supported */
+ mac->phylink_config.lpi_capabilities = MAC_100FD | MAC_1000FD;
mac->phylink_config.lpi_timer_default = 1000;
/* MT7623 gmac0 is now missing its speed-specific PLL configuration
@@ -4965,6 +4965,18 @@ static int mtk_add_mac(struct mtk_eth *eth, struct device_node *np)
__set_bit(PHY_INTERFACE_MODE_INTERNAL,
mac->phylink_config.supported_interfaces);
+ /* LPI wake-up timing is only verified on MTK_GMAC_EEE SoCs */
+ if (MTK_HAS_CAPS(eth->soc->caps, MTK_GMAC_EEE)) {
+ phy_interface_copy(mac->phylink_config.lpi_interfaces,
+ mac->phylink_config.supported_interfaces);
+ __clear_bit(PHY_INTERFACE_MODE_2500BASEX,
+ mac->phylink_config.lpi_interfaces);
+ for (i = 0; i < PHY_INTERFACE_MODE_MAX; i++)
+ if (mtk_interface_mode_is_xgmii(eth, i))
+ __clear_bit(i,
+ mac->phylink_config.lpi_interfaces);
+ }
+
phylink = phylink_create(&mac->phylink_config,
of_fwnode_handle(mac->of_node),
phy_mode, mac_ops);
diff --git a/drivers/net/ethernet/mediatek/mtk_eth_soc.h b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
index 0168e2fbc6197..88a9b3b23bea5 100644
--- a/drivers/net/ethernet/mediatek/mtk_eth_soc.h
+++ b/drivers/net/ethernet/mediatek/mtk_eth_soc.h
@@ -994,6 +994,7 @@ enum mkt_eth_capabilities {
MTK_U3_COPHY_V2_BIT,
MTK_SRAM_BIT,
MTK_36BIT_DMA_BIT,
+ MTK_GMAC_EEE_BIT,
/* MUX BITS*/
MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT,
@@ -1034,6 +1035,7 @@ enum mkt_eth_capabilities {
#define MTK_U3_COPHY_V2 BIT_ULL(MTK_U3_COPHY_V2_BIT)
#define MTK_SRAM BIT_ULL(MTK_SRAM_BIT)
#define MTK_36BIT_DMA BIT_ULL(MTK_36BIT_DMA_BIT)
+#define MTK_GMAC_EEE BIT_ULL(MTK_GMAC_EEE_BIT)
#define MTK_ETH_MUX_GDM1_TO_GMAC1_ESW \
BIT_ULL(MTK_ETH_MUX_GDM1_TO_GMAC1_ESW_BIT)
@@ -1117,7 +1119,7 @@ enum mkt_eth_capabilities {
#define MT7981_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | MTK_GMAC2_GEPHY | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
MTK_MUX_U3_GMAC2_TO_QPHY | MTK_U3_COPHY_V2 | \
- MTK_RSTCTRL_PPE1 | MTK_SRAM)
+ MTK_RSTCTRL_PPE1 | MTK_SRAM | MTK_GMAC_EEE)
#define MT7986_CAPS (MTK_GMAC1_SGMII | MTK_GMAC2_SGMII | \
MTK_MUX_GMAC12_TO_GEPHY_SGMII | MTK_QDMA | \
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 429/733] net: phy: mediatek-ge: disable EEE on the MT7530 PHY
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (427 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 428/733] net: ethernet: mtk_eth_soc: " Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 430/733] net: net_failover: Fix the deadlock in net_failover_slave_name_change() Greg Kroah-Hartman
` (315 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andrew Lunn, Vladislav Karmanov,
Paolo Abeni, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladislav Karmanov <vladislav.karmanov.dev@gmail.com>
[ Upstream commit ccbe7540e4aad0d1c3acc249697350b93ccb8025 ]
The MT7530 internal GE PHY advertises EEE by hardware default, but its
EEE support is defective: with EEE advertised, some link partners fail
to establish a stable link. On a 2-pair (4-wire) cable where both ends
advertise gigabit, 1000BASE-T training cannot succeed, and instead of
falling back to 100 Mbps the port loops, so no link or DHCP lease is
ever obtained. MediaTek confirms the hardware is the root cause (Landen
Chao, 2021): "EEE of the 10-year-old MT7530 internal gephy has many IOT
problems, so it is recommended to disable its EEE."
mtk_gephy_config_init() used to clear the EEE advertisement early, but
commit af3b4b0e59de ("net: phy: mediatek-ge: do not disable EEE
advertisement") removed that on the rationale that the DSA subdriver
already performs an early disable. That holds for MT7531, whose
mt7531_setup() clears MDIO_AN_EEE_ADV on each switch PHY, but not for
the MT7530 PHY: neither the MT7621 integrated switch nor the dedicated
MT7530 IC ever had such a loop, so removing it left those boards
without any working early EEE disable and the link flapping came back.
Since the broken hardware is the PHY, fix it in the PHY driver so it
covers all users of this PHY, integrated in a switch or standalone:
- clear MDIO_AN_EEE_ADV in probe(), as early as possible, before
anything can negotiate EEE with the link partner;
- clear it again in config_init() and call phy_disable_eee() there.
config_init() is what phy_init_hw() replays after a PHY reset, when
the register is back at its EEE-advertising hardware default, and
it runs after of_set_phy_eee_broken() in phy_probe(), so the
eee_disabled_modes mask survives and neither phylib nor userspace
can re-enable EEE. dp83867 disables broken EEE from config_init()
the same way.
Auto-negotiation then falls back to a stable 100 Mbps link instead of
looping at gigabit. Tested on ASUS RT-AX53U (MT7621): with a 2-pair
cable on the WAN port, a single clean 100 Mbps link comes up and a
DHCP lease is obtained, where the unpatched driver loops.
Fixes: af3b4b0e59de ("net: phy: mediatek-ge: do not disable EEE advertisement")
Suggested-by: Andrew Lunn <andrew@lunn.ch>
Signed-off-by: Vladislav Karmanov <vladislav.karmanov.dev@gmail.com>
Link: https://patch.msgid.link/20260908145213.3976508-1-vladislav.karmanov.dev@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/phy/mediatek/mtk-ge.c | 29 +++++++++++++++++++++++++++++
1 file changed, 29 insertions(+)
diff --git a/drivers/net/phy/mediatek/mtk-ge.c b/drivers/net/phy/mediatek/mtk-ge.c
index 73d9b72f9d9e2..96d8ac5154e5e 100644
--- a/drivers/net/phy/mediatek/mtk-ge.c
+++ b/drivers/net/phy/mediatek/mtk-ge.c
@@ -62,10 +62,38 @@ static void mtk_gephy_config_init(struct phy_device *phydev)
FIELD_PREP(MTK_MCC_NEARECHO_OFFSET_MASK, 0x3));
}
+static int mt7530_phy_probe(struct phy_device *phydev)
+{
+ /* The MT7530 internal GE PHY has broken EEE: with EEE advertised,
+ * some link partners fail to establish a stable link (on a 2-pair
+ * cable, 1000BASE-T training fails and the port loops instead of
+ * falling back). MediaTek recommends disabling EEE on this PHY.
+ * Clear the advertisement as early as possible, before anything
+ * can negotiate EEE with the link partner.
+ */
+ return phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+}
+
static int mt7530_phy_config_init(struct phy_device *phydev)
{
+ int ret;
+
mtk_gephy_config_init(phydev);
+ /* The probe() clear alone is not durable: phy_init_hw() replays only
+ * ->config_init after a PHY reset, with the register back at its
+ * EEE-advertising hardware default, and phy_probe() zeroes
+ * eee_disabled_modes (of_set_phy_eee_broken()) after ->probe already
+ * ran. Clear the advertisement again and mark EEE disabled, so that
+ * neither phylib nor userspace can re-enable it; dp83867 disables
+ * broken EEE from config_init() the same way.
+ */
+ ret = phy_write_mmd(phydev, MDIO_MMD_AN, MDIO_AN_EEE_ADV, 0);
+ if (ret)
+ return ret;
+
+ phy_disable_eee(phydev);
+
/* Increase post_update_timer */
phy_write_paged(phydev, MTK_PHY_PAGE_EXTENDED_3,
MTK_PHY_RG_LPI_PCS_DSP_CTRL_REG11, 0x4b);
@@ -100,6 +128,7 @@ static struct phy_driver mtk_gephy_driver[] = {
{
PHY_ID_MATCH_EXACT(MTK_GPHY_ID_MT7530),
.name = "MediaTek MT7530 PHY",
+ .probe = mt7530_phy_probe,
.config_init = mt7530_phy_config_init,
/* Interrupts are handled by the switch, not the PHY
* itself.
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 430/733] net: net_failover: Fix the deadlock in net_failover_slave_name_change()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (428 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 429/733] net: phy: mediatek-ge: disable EEE on the MT7530 PHY Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 431/733] octeontx2-af: fix PF/CGX debugfs PCI bus lookup Greg Kroah-Hartman
` (314 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Faicker Mo, Hangbin Liu, Paolo Abeni,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Faicker Mo <faicker.mo@gmail.com>
[ Upstream commit 985a663bf00799c1daf1c5789efa6406958780c8 ]
This is a sibling fix of commit
b84c5632c7b3 ("net: net_failover: Fix the deadlock in slave register").
There is netdev_lock_ops() in the upper callers, so using netif_open()
instead of dev_open().
Call Trace:
__schedule+0x2bb/0x650
schedule+0x27/0xb0
schedule_preempt_disabled+0x15/0x30
__mutex_lock.constprop.0+0x550/0xaf0
__mutex_lock_slowpath+0x13/0x20
mutex_lock+0x3b/0x50
dev_open+0x3b/0xe0
net_failover_slave_name_change+0x22/0x40
failover_event+0xd4/0x1e0
notifier_call_chain+0x62/0xf0
raw_notifier_call_chain+0x16/0x30
call_netdevice_notifiers_info+0x50/0x80
netif_change_name+0x200/0x330
do_setlink.isra.0+0xb12/0xdf0
? security_capable+0x9a/0x1e0
? ns_capable+0x31/0x60
rtnl_setlink+0x302/0x670
? netlink_recvmsg+0x296/0x340
? security_capable+0x9a/0x1e0
? __pfx_rtnl_setlink+0x10/0x10
rtnetlink_rcv_msg+0x384/0x460
? __pfx_rtnetlink_rcv_msg+0x10/0x10
netlink_rcv_skb+0x61/0x120
rtnetlink_rcv+0x15/0x30
netlink_unicast+0x28f/0x3c0
netlink_sendmsg+0x216/0x450
__sys_sendto+0x222/0x230
__x64_sys_sendto+0x24/0x40
x64_sys_call+0x1d5d/0x2390
do_syscall_64+0x105/0x5a0
? do_syscall_64+0x140/0x5a0
? exc_page_fault+0x94/0x1e0
entry_SYSCALL_64_after_hwframe+0x76/0x7e
Fixes: 7e4d784f5810 ("net: hold netdev instance lock during rtnetlink operations")
Signed-off-by: Faicker Mo <faicker.mo@gmail.com>
Reviewed-by: Hangbin Liu <liuhangbin@kylinos.cn>
Link: https://patch.msgid.link/20260908040708.3972058-1-faicker.mo@gmail.com
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/net_failover.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/net_failover.c b/drivers/net/net_failover.c
index 3f7d31033bae8..1b5213e870703 100644
--- a/drivers/net/net_failover.c
+++ b/drivers/net/net_failover.c
@@ -675,7 +675,7 @@ static int net_failover_slave_name_change(struct net_device *slave_dev,
/* We need to bring up the slave after the rename by udev in case
* open failed with EBUSY when it was registered.
*/
- dev_open(slave_dev, NULL);
+ netif_open(slave_dev, NULL);
return 0;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 431/733] octeontx2-af: fix PF/CGX debugfs PCI bus lookup
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (429 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 430/733] net: net_failover: Fix the deadlock in net_failover_slave_name_change() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 432/733] net: phy: dp83867: handle the active-high LED polarity mode Greg Kroah-Hartman
` (313 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Subbaraya Sundeep, Ratheesh Kannoth,
Simon Horman, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ratheesh Kannoth <rkannoth@marvell.com>
[ Upstream commit 4f4b743c2d2bbc336cb164d9d3d2ed6956ad8437 ]
rvu_dbg_rvu_pf_cgx_map_display() locates each RVU PF PCI device via
pci_get_domain_bus_and_slot() when printing the PF-to-CGX map. It
assumed PF0 always sits on PCI bus 1 and derived other PF bus numbers
as pf + 1, but the AF device can be enumerated on a different bus.
Use rvu->pdev->bus->number as the base bus instead, so each PF lookup
uses pf + start on systems where RVU functions are on contiguous buses
but do not start at bus 1.
Fixes: e2fb373038654 ("octeontx2-af: Display CGX, NIX and PF map in debugfs.")
Signed-off-by: Subbaraya Sundeep <sbhatta@marvell.com>
Signed-off-by: Ratheesh Kannoth <rkannoth@marvell.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904085114.3385530-1-rkannoth@marvell.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/marvell/octeontx2/af/rvu_debugfs.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
diff --git a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
index 22ee996768796..904374baae6f3 100644
--- a/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
+++ b/drivers/net/ethernet/marvell/octeontx2/af/rvu_debugfs.c
@@ -829,19 +829,25 @@ static int rvu_dbg_rvu_pf_cgx_map_display(struct seq_file *filp, void *unused)
int pf, domain, blkid;
u8 cgx_id, lmac_id;
u16 pcifunc;
+ u8 start;
- domain = 2;
+ domain = pci_domain_nr(rvu->pdev->bus);
mac_ops = get_mac_ops(rvu_first_cgx_pdata(rvu));
/* There can be no CGX devices at all */
if (!mac_ops)
return 0;
seq_printf(filp, "PCI dev\t\tRVU PF Func\tNIX block\t%s\tLMAC\tCHAN\n",
mac_ops->name);
+
+ /* All the PF devices are on contiguous PCI bus numbers, but the PF0(AF)
+ * may not start from 1 always. Hence get domain and bus from PCI device.
+ */
+ start = rvu->pdev->bus->number;
for (pf = 0; pf < rvu->hw->total_pfs; pf++) {
if (!is_pf_cgxmapped(rvu, pf))
continue;
- pdev = pci_get_domain_bus_and_slot(domain, pf + 1, 0);
+ pdev = pci_get_domain_bus_and_slot(domain, pf + start, 0);
if (!pdev)
continue;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 432/733] net: phy: dp83867: handle the active-high LED polarity mode
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (430 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 431/733] octeontx2-af: fix PF/CGX debugfs PCI bus lookup Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 433/733] net: mana: restore the XDP program pointer when pre-allocation fails Greg Kroah-Hartman
` (312 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
[ Upstream commit 36a45facedd5c8e73bfb2403f8b0dbff05124c9c ]
Commit a274465cc3be ("net: phy: support 'active-high' property for PHY
LEDs") added PHY_LED_ACTIVE_HIGH and made of_phy_led() set the matching
bit in the modes mask when a LED node carries the 'active-high'
property. dp83867 was not part of that series.
dp83867_led_polarity_set() only recognizes PHY_LED_ACTIVE_LOW, so
PHY_LED_ACTIVE_HIGH falls through to the default case and returns -EINVAL.
of_phy_led() propagates the error, of_phy_leds() drops the LEDs registered
so far and passes it on, and phy_probe() fails. A device tree marking a
DP83867 LED as 'active-high', which leds/common.yaml allows and
ethernet-phy.yaml references for led@N nodes, thus stops the PHY from
probing.
Active high is what the function programs when no polarity mode is
requested at all, so the initial value of polarity already satisfies the
request and only the case label is missing.
The same series updated mxl-gpy in commit eb89c79c1b8f ("net: phy:
mxl-gpy: correctly describe LED polarity") and aquantia in
commit 9d55e68b19f2 ("net: phy: aquantia: correctly describe LED
polarity override").
Fixes: a274465cc3be ("net: phy: support 'active-high' property for PHY LEDs")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Link: https://patch.msgid.link/20260903022839.4006614-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/phy/dp83867.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/drivers/net/phy/dp83867.c b/drivers/net/phy/dp83867.c
index 88255e92b4cdb..61a941aa02d94 100644
--- a/drivers/net/phy/dp83867.c
+++ b/drivers/net/phy/dp83867.c
@@ -1150,6 +1150,9 @@ static int dp83867_led_polarity_set(struct phy_device *phydev, int index,
case PHY_LED_ACTIVE_LOW:
polarity = 0;
break;
+ case PHY_LED_ACTIVE_HIGH:
+ polarity = DP83867_LED_POLARITY(index);
+ break;
default:
return -EINVAL;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 433/733] net: mana: restore the XDP program pointer when pre-allocation fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (431 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 432/733] net: phy: dp83867: handle the active-high LED polarity mode Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 434/733] net/rds: fix tcp stream corruption with large pages Greg Kroah-Hartman
` (311 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Long Li, Simon Horman,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Long Li <longli@microsoft.com>
[ Upstream commit 4c46beb807efcc93f5899ebe1f5958248eb296c6 ]
mana_xdp_set() publishes the new program into apc->bpf_prog before it
allocates anything, because mana_pre_alloc_rxbufs() sizes the buffers
from it via mana_get_rxbuf_cfg(). When that allocation fails the
function returns the error directly, skipping the err_dealloc_rxbuffs
label which is the only place that restores the previous pointer.
The attach is reported as failed, so the BPF core drops the reference it
held for the caller and the program can be freed, while apc->bpf_prog
still points at it. The next consumer of mana_xdp_get() - typically
mana_chn_setxdp() from mana_alloc_queues() on the following ifup, or
after a TX timeout reset - then calls bpf_prog_add() on freed memory.
This is reachable from an ordinary "ip link set dev ethX xdp obj ..."
whenever the per-queue RX buffer pre-allocation cannot be satisfied.
Restore the previous program on that error path.
Fixes: 730ff06d3f5c ("net: mana: Use page pool fragments for RX buffers instead of full pages to improve memory efficiency.")
Signed-off-by: Long Li <longli@microsoft.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Link: https://patch.msgid.link/20260904202640.3900685-1-longli@microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/ethernet/microsoft/mana/mana_bpf.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/ethernet/microsoft/mana/mana_bpf.c b/drivers/net/ethernet/microsoft/mana/mana_bpf.c
index 53308e139cbe9..5c9961ee9747a 100644
--- a/drivers/net/ethernet/microsoft/mana/mana_bpf.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_bpf.c
@@ -208,6 +208,7 @@ static int mana_xdp_set(struct net_device *ndev, struct bpf_prog *prog,
if (err) {
NL_SET_ERR_MSG_MOD(extack,
"XDP: Insufficient memory for tx/rx re-config");
+ apc->bpf_prog = old_prog;
return err;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 434/733] net/rds: fix tcp stream corruption with large pages
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (432 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 433/733] net: mana: restore the XDP program pointer when pre-allocation fails Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 435/733] net: stmmac: fix TX descriptor availability check for TSO traffic Greg Kroah-Hartman
` (310 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Greg Marsden, Allison Henderson,
Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Marsden <greg.marsden@oracle.com>
[ Upstream commit 2ac09b5353fe6858411fdc8c6efa60d832e20f13 ]
rds_message_map_pages() assigns PAGE_SIZE bytes to every
scatterlist entry, even when total_len ends in a partial page. The RDS
congestion map is defined as 8192 bytes, so on systems with PAGE_SIZE
greater than 8192 the scatterlist maps bytes beyond the end of the
congestion map. RDS-TCP transmits the SG contents according to those
lengths, so the extra bytes become part of the TCP RDS stream and are
interpreted as subsequent RDS message headers, corrupting the stream.
Limit the final scatterlist mapping to the number of bytes remaining.
This has no effect on systems with a 4K page size and allows RDS-TCP to
be used on systems with 16K and larger page sizes.
The RDS selftest, which previously hung on 16K pages, now passes.
Fixes: 7875e18e0996 ("RDS: Message parsing")
Signed-off-by: Greg Marsden <greg.marsden@oracle.com>
Reviewed-by: Allison Henderson <achender@kernel.org>
Link: https://patch.msgid.link/apxJjxvStibPI0AS@oracle.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/rds/message.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/net/rds/message.c b/net/rds/message.c
index 7feb0eb6537db..9cbf045fe0031 100644
--- a/net/rds/message.c
+++ b/net/rds/message.c
@@ -405,7 +405,9 @@ struct rds_message *rds_message_map_pages(unsigned long *page_addrs, unsigned in
for (i = 0; i < rm->data.op_nents; ++i) {
sg_set_page(&rm->data.op_sg[i],
virt_to_page((void *)page_addrs[i]),
- PAGE_SIZE, 0);
+ i == rm->data.op_nents - 1
+ ? total_len - (i * PAGE_SIZE)
+ : PAGE_SIZE, 0);
}
return rm;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 435/733] net: stmmac: fix TX descriptor availability check for TSO traffic
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (433 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 434/733] net/rds: fix tcp stream corruption with large pages Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 436/733] net: hsr: enable promiscuous mode on interlink port with fwd offload Greg Kroah-Hartman
` (309 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Bianconi, Jakub Kicinski,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
[ Upstream commit 5e38d732ec67a5b1f9a56e6c73add480c4b6030a ]
stmmac_tso_xmit() estimates the number of free TX descriptors required by
a TSO skb as:
(skb->len - proto_hdr_len) / TSO_MAX_BUFF_SIZE + 1
which assumes the payload is split into TSO_MAX_BUFF_SIZE chunks. This
underestimates the descriptors actually consumed by stmmac_tso_allocator(),
since each fragment is mapped individually and so it needs at least one
descriptor regardless of its size. Moreover, one descriptor is used for
the L2/L3/L4 headers and, when the MSS changes, one more is consumed for
the MSS context descriptor.
For a highly fragmented TSO skb the check can therefore pass even when the
ring has too few free slots. stmmac_tso_allocator() then writes past the
available descriptors, overwriting descriptors still owned by the DMA
engine, corrupting the TX ring.
Add stmmac_tso_get_num_desc() to compute the exact number of descriptors
needed for the header, the linear payload and each fragment, plus the MSS
context descriptor when required, and use it in the availability check.
Fixes: f748be531d70 ("stmmac: support new GMAC4")
Signed-off-by: Lorenzo Bianconi <lorenzo.bianconi@oss.qualcomm.com>
Link: https://patch.msgid.link/20260907-stmmac-fix-tso-nfrags-check-v1-1-328459906cdb@oss.qualcomm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
.../net/ethernet/stmicro/stmmac/stmmac_main.c | 31 +++++++++++++++----
1 file changed, 25 insertions(+), 6 deletions(-)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index aa05160c22e35..f801caf65fff1 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -4454,6 +4454,26 @@ static bool stmmac_tso_valid_packet(struct sk_buff *skb)
header_len + gso_size < 16383;
}
+static int stmmac_tso_get_num_desc(struct stmmac_tx_queue *tx_q,
+ struct sk_buff *skb, u32 pay_len)
+{
+ int i, ndesc = 1;
+
+ /* head payload */
+ ndesc += DIV_ROUND_UP(pay_len, TSO_MAX_BUFF_SIZE);
+ /* frag payload */
+ for (i = 0; i < skb_shinfo(skb)->nr_frags; i++) {
+ const skb_frag_t *frag = &skb_shinfo(skb)->frags[i];
+
+ ndesc += DIV_ROUND_UP(skb_frag_size(frag),
+ TSO_MAX_BUFF_SIZE);
+ }
+ /* MSS update requires a new descriptor */
+ ndesc += !!(skb_shinfo(skb)->gso_size != tx_q->mss);
+
+ return ndesc;
+}
+
/**
* stmmac_tso_xmit - Tx entry point of the driver for oversized frames (TSO)
* @skb : the socket buffer
@@ -4497,10 +4517,10 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
struct stmmac_priv *priv = netdev_priv(dev);
unsigned int first_entry, entry, tx_packets;
struct stmmac_txq_stats *txq_stats;
+ int i, first_tx, nfrags, ndesc;
struct stmmac_tx_queue *tx_q;
bool set_ic, is_last_segment;
u32 pay_len, mss, queue;
- int i, first_tx, nfrags;
u8 proto_hdr_len, hdr;
dma_addr_t des;
@@ -4513,14 +4533,15 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
/* Compute header lengths */
proto_hdr_len = stmmac_tso_header_size(skb);
+ pay_len = skb_headlen(skb) - proto_hdr_len; /* no frags */
+
if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4)
hdr = sizeof(struct udphdr);
else
hdr = tcp_hdrlen(skb);
- /* Desc availability based on threshold should be enough safe */
- if (unlikely(stmmac_tx_avail(priv, queue) <
- (((skb->len - proto_hdr_len) / TSO_MAX_BUFF_SIZE + 1)))) {
+ ndesc = stmmac_tso_get_num_desc(tx_q, skb, pay_len);
+ if (unlikely(stmmac_tx_avail(priv, queue) < ndesc)) {
if (!netif_tx_queue_stopped(netdev_get_tx_queue(dev, queue))) {
netif_tx_stop_queue(netdev_get_tx_queue(priv->dev,
queue));
@@ -4532,8 +4553,6 @@ static netdev_tx_t stmmac_tso_xmit(struct sk_buff *skb, struct net_device *dev)
return NETDEV_TX_BUSY;
}
- pay_len = skb_headlen(skb) - proto_hdr_len; /* no frags */
-
mss = skb_shinfo(skb)->gso_size;
/* set new MSS value if needed */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 436/733] net: hsr: enable promiscuous mode on interlink port with fwd offload
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (434 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 435/733] net: stmmac: fix TX descriptor availability check for TSO traffic Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 437/733] openvswitch: fix wrong flag value in get_ipv6_ext_hdrs() Greg Kroah-Hartman
` (308 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, MD Danish Anwar, Simon Horman,
Fernando Fernandez Mancera, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: MD Danish Anwar <danishanwar@ti.com>
[ Upstream commit a2dc179481d18f6df7274522571b64dd50f31e81 ]
hsr_portdev_setup() skips promiscuous mode on non-master ports when
hsr->fwd_offloaded is set. fwd_offloaded is derived only from the ring
slaves' NETIF_F_HW_HSR_FWD bit, so this also skips it for the interlink
port, which never gets forwarding offload. Without promiscuous mode,
the interlink NIC drops unicast frames addressed to hsr_dev's MAC
(e.g. SAN traffic to the RedBox), breaking RedBox whenever the ring is
HW-offloaded.
Fixes: 5055cccfc2d1 ("net: hsr: Provide RedBox support (HSR-SAN)")
Signed-off-by: MD Danish Anwar <danishanwar@ti.com>
Reviewed-by: Simon Horman <horms@kernel.org>
Reviewed-by: Fernando Fernandez Mancera <fmancera@suse.de>
Link: https://patch.msgid.link/20260908090856.2876114-1-danishanwar@ti.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/hsr/hsr_slave.c | 11 +++++++----
1 file changed, 7 insertions(+), 4 deletions(-)
diff --git a/net/hsr/hsr_slave.c b/net/hsr/hsr_slave.c
index 01c73b4b50ddd..a546f70f9cc8b 100644
--- a/net/hsr/hsr_slave.c
+++ b/net/hsr/hsr_slave.c
@@ -149,9 +149,12 @@ static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
int res;
/* Don't use promiscuous mode for offload since L2 frame forward
- * happens at the offloaded hardware.
+ * happens at the offloaded hardware. The interlink port never
+ * gets forwarding offload (RedBox forwarding to/from it is done
+ * by this driver), so it still needs promiscuous mode to receive
+ * frames addressed to hsr_dev's MAC rather than its own.
*/
- if (!port->hsr->fwd_offloaded) {
+ if (!port->hsr->fwd_offloaded || port->type == HSR_PT_INTERLINK) {
res = dev_set_promiscuity(dev, 1);
if (res)
return res;
@@ -176,7 +179,7 @@ static int hsr_portdev_setup(struct hsr_priv *hsr, struct net_device *dev,
fail_rx_handler:
netdev_upper_dev_unlink(dev, hsr_dev);
fail_upper_dev_link:
- if (!port->hsr->fwd_offloaded)
+ if (!port->hsr->fwd_offloaded || port->type == HSR_PT_INTERLINK)
dev_set_promiscuity(dev, -1);
return res;
@@ -240,7 +243,7 @@ void hsr_del_port(struct hsr_port *port)
netdev_update_features(master->dev);
dev_set_mtu(master->dev, hsr_get_max_mtu(hsr));
netdev_rx_handler_unregister(port->dev);
- if (!port->hsr->fwd_offloaded)
+ if (!port->hsr->fwd_offloaded || port->type == HSR_PT_INTERLINK)
dev_set_promiscuity(port->dev, -1);
if (port->type == HSR_PT_SLAVE_A || port->type == HSR_PT_SLAVE_B)
vlan_vids_del_by_dev(port->dev, master->dev);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 437/733] openvswitch: fix wrong flag value in get_ipv6_ext_hdrs()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (435 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 436/733] net: hsr: enable promiscuous mode on interlink port with fwd offload Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 438/733] block: Fix start and length check added to iov_iter_extract_bvecs() Greg Kroah-Hartman
` (307 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Aaron Conole,
Ilya Maximets, Eelco Chaudron, Jakub Kicinski, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eelco Chaudron <echaudro@redhat.com>
[ Upstream commit e184a4a6f423550a25adce867036cdb1ff471745 ]
The ESP and AH cases in get_ipv6_ext_hdrs() used IPPROTO_FRAGMENT instead
of OFPIEH12_FRAG when checking for out-of-order extension headers, causing
the fragment header to not be recognised as a valid predecessor.
The original code used IPPROTO_FRAGMENT (44) as a bitmask constant where
OFPIEH12_FRAG (1 << 4 = 16) was intended. IPPROTO_FRAGMENT encodes bits
2, 3 and 5 (OFPIEH12_AUTH | OFPIEH12_DEST | OFPIEH12_ROUTER), but not
bit 4 (OFPIEH12_FRAG). This caused incorrect OFPIEH12_UNSEQ verdicts in
both the ESP and AH arms: the ESP arm failed to whitelist OFPIEH12_FRAG,
while the AH arm accidentally whitelisted OFPIEH12_AUTH.
With the fix, a packet with two AH headers now also gets OFPIEH12_UNSEQ
in addition to OFPIEH12_UNREP, matching the ESP arm which already sets
UNSEQ on a repeat, which is the intended behavior.
Fixes: 28a3f0601727 ("net: openvswitch: IPv6: Add IPv6 extension header support")
Reported-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Aaron Conole <aconole@redhat.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Signed-off-by: Eelco Chaudron <echaudro@redhat.com>
Link: https://patch.msgid.link/1b1582eb07550d71f3cbe210e5cb31eeb8d0ad86.1788876917.git.echaudro@redhat.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
net/openvswitch/flow.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 46c1d66aad8c3..868d9fdf3afdf 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -288,7 +288,7 @@ static void get_ipv6_ext_hdrs(struct sk_buff *skb, struct ipv6hdr *nh,
if (*ext_hdrs & OFPIEH12_ESP)
*ext_hdrs |= OFPIEH12_UNREP;
if ((*ext_hdrs & ~(OFPIEH12_HOP | OFPIEH12_DEST |
- OFPIEH12_ROUTER | IPPROTO_FRAGMENT |
+ OFPIEH12_ROUTER | OFPIEH12_FRAG |
OFPIEH12_AUTH | OFPIEH12_UNREP)) ||
dest_options_header_count >= 2) {
*ext_hdrs |= OFPIEH12_UNSEQ;
@@ -301,7 +301,7 @@ static void get_ipv6_ext_hdrs(struct sk_buff *skb, struct ipv6hdr *nh,
*ext_hdrs |= OFPIEH12_UNREP;
if ((*ext_hdrs &
~(OFPIEH12_HOP | OFPIEH12_DEST | OFPIEH12_ROUTER |
- IPPROTO_FRAGMENT | OFPIEH12_UNREP)) ||
+ OFPIEH12_FRAG | OFPIEH12_UNREP)) ||
dest_options_header_count >= 2) {
*ext_hdrs |= OFPIEH12_UNSEQ;
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 438/733] block: Fix start and length check added to iov_iter_extract_bvecs()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (436 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 437/733] openvswitch: fix wrong flag value in get_ipv6_ext_hdrs() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 439/733] sunvdc: unmap LDC cookies when the descriptor send fails Greg Kroah-Hartman
` (306 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Keith Busch,
Hannes Reinecke, Christoph Hellwig, Jens Axboe, Alexander Viro,
Paulo Alcantara, netfs, linux-block, linux-fsdevel,
Christoph Hellwig, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
[ Upstream commit b0d8d56b7c93ed767eb4f2be9988e7b9dc023566 ]
Commit 14b007e17881 added an address check using iter_iov_addr() and a
length check using iter_iov_len() to iov_iter_extract_bvecs(), but these
cannot be used so and are unsafe in this circumstance as the functions have
hardwired assumptions about the iterator type. They should only be used
with ITER_UBUF or ITER_IOVEC-type iterators; they shouldn't be used with
ITER_BVEC, ITER_KVEC, ITER_FOLIOQ, ITER_XARRAY or ITER_DISCARD iterators.
This proves to be a problem for cachefiles as an iterator of type
ITER_FOLIOQ is passed and iter_iov_addr() and iter_iov_len() both
malfunction because iter->__iov in iter_iov() is not pointing to an iovec
array.
Fix this by using iov_iter_alignment() instead.
Fixes: 14b007e17881 ("block: validate user space vectors during extraction")
Signed-off-by: David Howells <dhowells@redhat.com>
Reviewed-by: Keith Busch <kbusch@kernel.org>
cc: Hannes Reinecke <hare@kernel.org>
cc: Christoph Hellwig <hch@infradead.org>
cc: Jens Axboe <axboe@kernel.dk>
cc: Alexander Viro <viro@zeniv.linux.org.uk>
cc: Paulo Alcantara <pc@manguebit.org>
cc: netfs@lists.linux.dev
cc: linux-block@vger.kernel.org
cc: linux-fsdevel@vger.kernel.org
Reviewed-by: Christoph Hellwig <hch@lst.de>
Link: https://patch.msgid.link/1667275.1788941191@warthog.procyon.org.uk
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
lib/iov_iter.c | 18 ++++++++++++++++--
1 file changed, 16 insertions(+), 2 deletions(-)
diff --git a/lib/iov_iter.c b/lib/iov_iter.c
index 34a52e9ba9e1b..5238731910917 100644
--- a/lib/iov_iter.c
+++ b/lib/iov_iter.c
@@ -1920,15 +1920,29 @@ ssize_t iov_iter_extract_bvecs(struct iov_iter *iter, struct bio_vec *bv,
unsigned short max_vecs, unsigned mem_align_mask,
iov_iter_extraction_t extraction_flags)
{
- unsigned long start = (unsigned long)iter_iov_addr(iter);
unsigned short entries_left = max_vecs - *nr_vecs;
unsigned short nr_pages, i = 0;
size_t left, offset, len;
struct page **pages;
ssize_t size;
- if ((start | iter_iov_len(iter)) & mem_align_mask)
+ /*
+ * DMA engines typically have both memory address and length alignment
+ * requirements, so check these against the alignment mask. For UBUF,
+ * IOVEC and KVEC, only the current segment will be extracted from; for
+ * everything else we might extract from multiple segments, so we need
+ * to check those too.
+ */
+ if (likely(iter_is_ubuf(iter) ||
+ iter_is_iovec(iter) ||
+ iov_iter_is_kvec(iter))) {
+ unsigned long start = (unsigned long)iter_iov_addr(iter);
+
+ if ((start | iter_iov_len(iter)) & mem_align_mask)
+ return -EINVAL;
+ } else if (iov_iter_alignment(iter) & mem_align_mask) {
return -EINVAL;
+ }
/*
* Move page array up in the allocated memory for the bio vecs as far as
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 439/733] sunvdc: unmap LDC cookies when the descriptor send fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (437 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 438/733] block: Fix start and length check added to iov_iter_extract_bvecs() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 19:03 ` Stian Halseth
2026-09-17 15:12 ` [PATCH 7.2 440/733] ublk: clear force_abort in ublk_queue_reset_io_flags() Greg Kroah-Hartman
` (305 subsequent siblings)
744 siblings, 1 reply; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, John Paul Adrian Glaubitz,
Stian Halseth, Jens Axboe, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stian Halseth <stian@itx.no>
[ Upstream commit 0c6da21fa35e03fc74f09895433ccd6d4a9c3530 ]
__send_request() maps the request's pages into the LDC channel's map
table (ldc_map_sg()), fills in the descriptor and marks it
VIO_DESC_READY before ringing the doorbell via __vdc_tx_trigger().
When the trigger fails, the error path only prints a message: the
descriptor stays READY and the cookies are never unmapped. The
mapping is normally released in vdc_end_one() when the peer completes
the descriptor - but a descriptor whose doorbell was never sent will
never complete, and since dr->prod is not advanced on failure, the
reset path (vdc_requeue_inflight(), which walks [cons, prod)) never
visits it either. The map table entries are leaked permanently.
Since commit a11f6ca9aef9 ("sunvdc: Do not spin in an infinite loop
when vio_ldc_send() returns EAGAIN") trigger failures occur in
practice under load, so every resulting I/O error also leaks one
request's worth of entries from the fixed-size (8192 entries per
channel) map table. Because the allocator hands out contiguous
ranges, fragmentation makes large multi-segment requests fail first
as the table drains, until ldc_map_sg() fails permanently and the
disk is dead until reboot.
It also makes any retry-based recovery unusable: requeuing the
request on -EAGAIN remaps the pages on every attempt, overwriting
desc->cookies and orphaning the previous mapping, so the table
drains at the retry rate. This is the memory exhaustion observed
when the requeue approach was first tested in October 2025.
Roll back on failure: unmap the cookies, mark the descriptor FREE
again and clear the request entry. If the trigger failed with
-ENOTCONN, __vdc_tx_trigger() has already reset the port, which
tears down and reallocates both the dring and the LDC channel
including its map table - nothing to roll back, and the stale
descriptor must not be touched.
Fixes: a11f6ca9aef9 ("sunvdc: Do not spin in an infinite loop when vio_ldc_send() returns EAGAIN")
Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
Link: https://github.com/sparclinux/issues/issues/2
Signed-off-by: Stian Halseth <stian@itx.no>
Link: https://patch.msgid.link/20260901173947.3292110-2-stian@itx.no
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/sunvdc.c | 17 +++++++++++++++++
1 file changed, 17 insertions(+)
diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
index 020bd9f1a7b6a..24ad56536ed60 100644
--- a/drivers/block/sunvdc.c
+++ b/drivers/block/sunvdc.c
@@ -525,6 +525,23 @@ static int __send_request(struct request *req)
err = __vdc_tx_trigger(port);
if (err < 0) {
printk(KERN_ERR PFX "vdc_tx_trigger() failure, err=%d\n", err);
+ /*
+ * If the port was reset (-ENOTCONN), the dring and the
+ * LDC channel including all of its mappings are already
+ * torn down and reallocated - there is nothing to undo
+ * and @desc must not be touched.
+ *
+ * For any other failure the descriptor was never handed
+ * to the peer: unmap the cookies and free the descriptor
+ * again, so that a later retry of the request does not
+ * leak LDC map table entries.
+ */
+ if (err != -ENOTCONN) {
+ ldc_unmap(port->vio.lp, desc->cookies,
+ desc->ncookies);
+ desc->hdr.state = VIO_DESC_FREE;
+ rqe->req = NULL;
+ }
} else {
port->req_id++;
dr->prod = vio_dring_next(dr, dr->prod);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 439/733] sunvdc: unmap LDC cookies when the descriptor send fails
2026-09-17 15:12 ` [PATCH 7.2 439/733] sunvdc: unmap LDC cookies when the descriptor send fails Greg Kroah-Hartman
@ 2026-09-17 19:03 ` Stian Halseth
2026-09-18 19:45 ` Sasha Levin
0 siblings, 1 reply; 748+ messages in thread
From: Stian Halseth @ 2026-09-17 19:03 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, John Paul Adrian Glaubitz, Jens Axboe, Sasha Levin
[-- Attachment #1: Type: text/plain, Size: 4272 bytes --]
Hi,
No objection to this patch, but please also queue its companion
5067d4ba7139 ("sunvdc: fix -EIO issue due to lack of retries")
which was applied to mainline together with this one. The same
applies to the 6.18 and 6.12 queues, which carry this patch as well.
With both applied, the stable trees match mainline behavior.
Order matters: 0c6da21fa35e must go first (it already is, in the
queues).
Best regards
Stian Halseth
On Thu, 2026-09-17 at 16:12 +0100, Greg Kroah-Hartman wrote:
> 7.2-stable review patch. If anyone has any objections, please let me
> know.
>
> ------------------
>
> From: Stian Halseth <stian@itx.no>
>
> [ Upstream commit 0c6da21fa35e03fc74f09895433ccd6d4a9c3530 ]
>
> __send_request() maps the request's pages into the LDC channel's map
> table (ldc_map_sg()), fills in the descriptor and marks it
> VIO_DESC_READY before ringing the doorbell via __vdc_tx_trigger().
> When the trigger fails, the error path only prints a message: the
> descriptor stays READY and the cookies are never unmapped. The
> mapping is normally released in vdc_end_one() when the peer completes
> the descriptor - but a descriptor whose doorbell was never sent will
> never complete, and since dr->prod is not advanced on failure, the
> reset path (vdc_requeue_inflight(), which walks [cons, prod)) never
> visits it either. The map table entries are leaked permanently.
>
> Since commit a11f6ca9aef9 ("sunvdc: Do not spin in an infinite loop
> when vio_ldc_send() returns EAGAIN") trigger failures occur in
> practice under load, so every resulting I/O error also leaks one
> request's worth of entries from the fixed-size (8192 entries per
> channel) map table. Because the allocator hands out contiguous
> ranges, fragmentation makes large multi-segment requests fail first
> as the table drains, until ldc_map_sg() fails permanently and the
> disk is dead until reboot.
>
> It also makes any retry-based recovery unusable: requeuing the
> request on -EAGAIN remaps the pages on every attempt, overwriting
> desc->cookies and orphaning the previous mapping, so the table
> drains at the retry rate. This is the memory exhaustion observed
> when the requeue approach was first tested in October 2025.
>
> Roll back on failure: unmap the cookies, mark the descriptor FREE
> again and clear the request entry. If the trigger failed with
> -ENOTCONN, __vdc_tx_trigger() has already reset the port, which
> tears down and reallocates both the dring and the LDC channel
> including its map table - nothing to roll back, and the stale
> descriptor must not be touched.
>
> Fixes: a11f6ca9aef9 ("sunvdc: Do not spin in an infinite loop when
> vio_ldc_send() returns EAGAIN")
> Reported-by: John Paul Adrian Glaubitz <glaubitz@physik.fu-berlin.de>
> Link: https://github.com/sparclinux/issues/issues/2
> Signed-off-by: Stian Halseth <stian@itx.no>
> Link: https://patch.msgid.link/20260901173947.3292110-2-stian@itx.no
> Signed-off-by: Jens Axboe <axboe@kernel.dk>
> Signed-off-by: Sasha Levin <sashal@kernel.org>
> ---
> drivers/block/sunvdc.c | 17 +++++++++++++++++
> 1 file changed, 17 insertions(+)
>
> diff --git a/drivers/block/sunvdc.c b/drivers/block/sunvdc.c
> index 020bd9f1a7b6a..24ad56536ed60 100644
> --- a/drivers/block/sunvdc.c
> +++ b/drivers/block/sunvdc.c
> @@ -525,6 +525,23 @@ static int __send_request(struct request *req)
> err = __vdc_tx_trigger(port);
> if (err < 0) {
> printk(KERN_ERR PFX "vdc_tx_trigger() failure, err=%d\n", err);
> + /*
> + * If the port was reset (-ENOTCONN), the dring and the
> + * LDC channel including all of its mappings are already
> + * torn down and reallocated - there is nothing to undo
> + * and @desc must not be touched.
> + *
> + * For any other failure the descriptor was never handed
> + * to the peer: unmap the cookies and free the descriptor
> + * again, so that a later retry of the request does not
> + * leak LDC map table entries.
> + */
> + if (err != -ENOTCONN) {
> + ldc_unmap(port->vio.lp, desc->cookies,
> + desc->ncookies);
> + desc->hdr.state = VIO_DESC_FREE;
> + rqe->req = NULL;
> + }
> } else {
> port->req_id++;
> dr->prod = vio_dring_next(dr, dr->prod);
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 228 bytes --]
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 439/733] sunvdc: unmap LDC cookies when the descriptor send fails
2026-09-17 19:03 ` Stian Halseth
@ 2026-09-18 19:45 ` Sasha Levin
0 siblings, 0 replies; 748+ messages in thread
From: Sasha Levin @ 2026-09-18 19:45 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: Sasha Levin, patches, John Paul Adrian Glaubitz, Jens Axboe,
Stian Halseth
> No objection to this patch, but please also queue its companion
>
> 5067d4ba7139 ("sunvdc: fix -EIO issue due to lack of retries")
>
> which was applied to mainline together with this one. The same
> applies to the 6.18 and 6.12 queues, which carry this patch as well.
Queued for 7.2, 6.18, 6.12, 6.6, 6.1, 5.15 and 5.10, thanks.
--
Thanks,
Sasha
^ permalink raw reply [flat|nested] 748+ messages in thread
* [PATCH 7.2 440/733] ublk: clear force_abort in ublk_queue_reset_io_flags()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (438 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 439/733] sunvdc: unmap LDC cookies when the descriptor send fails Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 441/733] erofs: add missing buf->off in erofs_bread() Greg Kroah-Hartman
` (304 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yang Xiuwei, Ming Lei, Jens Axboe,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Xiuwei <yangxiuwei@kylinos.cn>
[ Upstream commit 8a14be55bdc6d5a25cd7b0ac5d4d884fcc727b49 ]
Quiesce sets ubq->force_abort for batch I/O. Recovery never clears
it, so batch fetch keeps failing with -ENODEV and the device stays
QUIESCED.
Fixes: a4d883755399 ("ublk: add UBLK_U_IO_FETCH_IO_CMDS for batch I/O processing")
Signed-off-by: Yang Xiuwei <yangxiuwei@kylinos.cn>
Reviewed-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20260821103047.369522-2-yangxiuwei@kylinos.cn
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/block/ublk_drv.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/block/ublk_drv.c b/drivers/block/ublk_drv.c
index b71283588ea77..d879e8492d59c 100644
--- a/drivers/block/ublk_drv.c
+++ b/drivers/block/ublk_drv.c
@@ -3040,6 +3040,7 @@ static void ublk_queue_reset_io_flags(struct ublk_queue *ubq)
ubq->canceling = false;
spin_unlock(&ubq->cancel_lock);
ubq->fail_io = false;
+ ubq->force_abort = false;
}
/* device can only be started after all IOs are ready */
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 441/733] erofs: add missing buf->off in erofs_bread()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (439 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 440/733] ublk: clear force_abort in ublk_queue_reset_io_flags() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 442/733] tracing: Fix ring_buffer_read_page_size() kernel-doc Greg Kroah-Hartman
` (303 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Binglei Wang, Gao Xiang, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Binglei Wang <l3b2w1@gmail.com>
[ Upstream commit 135d84c66f85426299db01a09d93a79a87af18ba ]
erofs_bread() locates the target folio with
index = (buf->off + offset) >> PAGE_SHIFT;
but computes the in-folio offset without taking buf->off into account:
return buf->base + (offset & ~PAGE_MASK);
If buf->off is not page-aligned, the returned pointer misses the in-page
component of buf->off, so callers end up fetching data from a wrong
offset.
buf->off is set to sbi->dif0.fsoff in erofs_init_metabuf(), and fsoff can
be specified via the "fsoffset=" mount option, which only requires
block-size alignment. Therefore, on an image with a sub-page block size
(e.g. 512 bytes), a non-page-aligned fsoff (e.g. 512) triggers the issue,
since 512 is a multiple of the block size but not of PAGE_SIZE.
It can be reproduced by mounting an image that is placed at a
non-page-aligned offset:
mkfs.erofs -b512 -zlz4hc sub.erofs src/
# prepend 512 bytes of padding to the image
mount -t erofs -o loop,fsoffset=512 padded.erofs /mnt
which fails with
erofs (device loop0): cannot find valid erofs superblock
because the on-disk superblock (at offset 1024 within the image, i.e.
1536 within the padded file) is read from a wrong in-folio offset. With
this fixed, the very same image mounts successfully and its file contents
match those read from the unpadded image.
Fix it by including buf->off in the in-folio offset calculation, so that
it is consistent with the folio index calculation.
Fixes: c36ec00d7f67 ("erofs: add 'fsoffset' mount option to specify filesystem offset")
Signed-off-by: Binglei Wang <l3b2w1@gmail.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
fs/erofs/data.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/fs/erofs/data.c b/fs/erofs/data.c
index 9aa48c8d67d12..b6cdffd0d8936 100644
--- a/fs/erofs/data.c
+++ b/fs/erofs/data.c
@@ -61,7 +61,7 @@ void *erofs_bread(struct erofs_buf *buf, erofs_off_t offset, bool need_kmap)
return NULL;
if (!buf->base)
buf->base = kmap_local_page(buf->page);
- return buf->base + (offset & ~PAGE_MASK);
+ return buf->base + ((buf->off + offset) & ~PAGE_MASK);
}
int erofs_init_metabuf(struct erofs_buf *buf, struct super_block *sb,
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 442/733] tracing: Fix ring_buffer_read_page_size() kernel-doc
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (440 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 441/733] erofs: add missing buf->off in erofs_bread() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 443/733] scripts/mksysmap: drop the MODULE_INFO() symbols from kallsyms Greg Kroah-Hartman
` (302 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Vincent Donnefort,
Steven Rostedt, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
[ Upstream commit 7e645147dfba67edb3ed3090a1ed1d89df77fc27 ]
ring_buffer_read_page_size() takes a parameter named rpage, but its
kernel-doc describes page. As a result, kernel-doc reports rpage as
undescribed and page as an excess parameter description.
Rename the documentation entry to match the function.
Link: https://patch.msgid.link/20260909062917.89482-1-kmehltretter@gmail.com
Fixes: dae8dda341d2 ("tracing: Fix subbuf resize races with trace_pipe_raw readers")
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
kernel/trace/ring_buffer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/ring_buffer.c b/kernel/trace/ring_buffer.c
index 66760542fce10..f958538c649ae 100644
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -7368,7 +7368,7 @@ EXPORT_SYMBOL_GPL(ring_buffer_read_page_data);
/**
* ring_buffer_read_page_size - get size of the read page.
- * @page: the page to get the size from
+ * @rpage: the page to get the size from
*
* Returns size of the page in bytes.
*/
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 443/733] scripts/mksysmap: drop the MODULE_INFO() symbols from kallsyms
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (441 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 442/733] tracing: Fix ring_buffer_read_page_size() kernel-doc Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 444/733] scripts/mksysmap: fix escape of $ in the __pi_ pattern Greg Kroah-Hartman
` (301 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
Nicolas Schier, Nathan Chancellor, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 281b61d408d4c39544583e393c6707af0ef5ee50 ]
Commit 3e86e4d74c04 ("kbuild: keep .modinfo section in vmlinux.unstripped")
keeps .modinfo symbols out of System.map and kallsyms, which assumes unique
IDs have a format like '__UNIQUE_ID_modinfo123'.
However, commit afb026b6d35c ("compiler: Tweak __UNIQUE_ID() naming"), sent
in the same cycle, changes this to '__UNIQUE_ID_modinfo_123'.
As a result this regexp has never matched and every kernel since v6.18 has
carried one kallsyms entries for every MODULE_INFO() declaration in the
kernel whether the modules are compiled or not.
That's 5,810 entries for an x86 defconfig build and 15,200 for arm64.
On x86 defconfig that is 113 KiB of kallsyms tables and 32 KiB of bzImage,
and every lookup walks past them.
Fix the pattern.
Fixes: 3e86e4d74c04 ("kbuild: keep .modinfo section in vmlinux.unstripped")
Assisted-by: LLM
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Link: https://patch.msgid.link/20260908-build-speedup-v1-1-5dc1ac01672d@kernel.org
Signed-off-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
scripts/mksysmap | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mksysmap b/scripts/mksysmap
index c4531eacde202..56a8b8bbdb373 100755
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -83,7 +83,7 @@
/ _SDA2_BASE_$/d
# MODULE_INFO()
-/ __UNIQUE_ID_modinfo[0-9]*$/d
+/ __UNIQUE_ID_modinfo_[0-9]*$/d
# ---------------------------------------------------------------------------
# Ignored patterns
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 444/733] scripts/mksysmap: fix escape of $ in the __pi_ pattern
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (442 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 443/733] scripts/mksysmap: drop the MODULE_INFO() symbols from kallsyms Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 445/733] tracing/remotes: Account for ring buffer page header in size calculation Greg Kroah-Hartman
` (300 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
Nathan Chancellor, Nicolas Schier, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
[ Upstream commit 59351365ac271b5e0eb180f211c531476a36221f ]
Commit b18b047002b7 ("kbuild: change scripts/mksysmap into sed script")
converted scripts/mksysmap from a shell script to a sed script.
However an error was made - escaping of '$' required \\ escaping in shell
but only \ in a sed script.
This was mostly corrected in commit 7a6c355b55c0 ("scripts/mksysmap: Fix
escape chars '$'"), but this fix missed arm64 PIE namespace local symbols
like __pi_$x and __pi_$d which appear in System.map and /proc/kallsyms:
$ grep __pi_\\$ /proc/kallsyms | sort -u
0000000000000000 d __pi_$d
0000000000000000 t __pi_$x
Fix the escaping properly.
Fixes: b18b047002b7 ("kbuild: change scripts/mksysmap into sed script")
Assisted-by: LLM
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Reviewed-by: Nathan Chancellor <nathan@kernel.org>
Reviewed-by: Nicolas Schier <nsc@kernel.org>
Link: https://patch.msgid.link/20260908-build-speedup-v1-2-5dc1ac01672d@kernel.org
Signed-off-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
scripts/mksysmap | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/scripts/mksysmap b/scripts/mksysmap
index 56a8b8bbdb373..856b26ba2ac02 100755
--- a/scripts/mksysmap
+++ b/scripts/mksysmap
@@ -35,7 +35,7 @@
/ __efistub_/d
# arm64 local symbols in PIE namespace
-/ __pi_\\$/d
+/ __pi_\$/d
/ __pi_\.L/d
# arm64 local symbols in non-VHE KVM namespace
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 445/733] tracing/remotes: Account for ring buffer page header in size calculation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (443 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 444/733] scripts/mksysmap: fix escape of $ in the __pi_ pattern Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 446/733] tracing/remotes: Catch nr_page_va overflow in ring_buffer_desc sizing Greg Kroah-Hartman
` (299 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit 442ffa742daa65a0e8fe003abe9fbe472366e4de ]
trace_buffer_desc_size() and trace_remote_alloc_buffer() undercount the
required pages because every ring buffer page contains a header
(BUF_PAGE_HDR_SIZE). Account for that header to ensure allocated remote
ring buffers aren't smaller than requested by the user.
The newly introduced helper __calc_nr_pages_ring_buffer_desc() can
return a value that overflows the descriptor nr_pages field (32 bits).
Link: https://patch.msgid.link/20260911193937.602202-2-vdonnefort@google.com
Fixes: 2e67fabd8b77 ("ring-buffer: Introduce ring-buffer remotes")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/ring_buffer.h | 15 +++++++++++++--
kernel/trace/trace_remote.c | 2 +-
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index afc7daa6ee7dc..11bffb6a142d1 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -3,8 +3,9 @@
#define _LINUX_RING_BUFFER_H
#include <linux/mm.h>
-#include <linux/seq_file.h>
#include <linux/poll.h>
+#include <linux/ring_buffer_types.h>
+#include <linux/seq_file.h>
#include <uapi/linux/trace_mmap.h>
@@ -279,9 +280,19 @@ static inline struct ring_buffer_desc *__first_ring_buffer_desc(struct trace_buf
return (struct ring_buffer_desc *)(&desc->__data[0]);
}
+/*
+ * Returns the number of pages for a ring_buffer_desc. The caller must ensure it
+ * does not overflow ring_buffer_desc::nr_page_va.
+ */
+static inline unsigned long __calc_nr_pages_ring_buffer_desc(size_t size)
+{
+ /* Takes into account the reader page */
+ return max(DIV_ROUND_UP(size, PAGE_SIZE - BUF_PAGE_HDR_SIZE), 2UL) + 1;
+}
+
static inline size_t trace_buffer_desc_size(size_t buffer_size, unsigned int nr_cpus)
{
- unsigned int nr_pages = max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) + 1;
+ unsigned long nr_pages = __calc_nr_pages_ring_buffer_desc(buffer_size);
struct ring_buffer_desc *rbdesc;
return size_add(offsetof(struct trace_buffer_desc, __data),
diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c
index e6724f947170d..0e8ca62301040 100644
--- a/kernel/trace/trace_remote.c
+++ b/kernel/trace/trace_remote.c
@@ -980,7 +980,7 @@ int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_size,
const struct cpumask *cpumask)
{
size_t min_desc_size = trace_buffer_desc_size(buffer_size, cpumask_weight(cpumask));
- unsigned int nr_pages = max(DIV_ROUND_UP(buffer_size, PAGE_SIZE), 2UL) + 1;
+ unsigned int nr_pages = __calc_nr_pages_ring_buffer_desc(buffer_size);
struct ring_buffer_desc *rb_desc;
int cpu, ret = -ENOMEM;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 446/733] tracing/remotes: Catch nr_page_va overflow in ring_buffer_desc sizing
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (444 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 445/733] tracing/remotes: Account for ring buffer page header in size calculation Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 447/733] scsi: target: iscsi: Fix hang for aborted WRITE_PENDING commands Greg Kroah-Hartman
` (298 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort, Steven Rostedt,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vincent Donnefort <vdonnefort@google.com>
[ Upstream commit d059d8bf2c9b5d563d15e7552d73e17d7535013a ]
The number of pages per remote ring buffer is capped by
ring_buffer_desc::nr_page_va (32 bits). A buffer_size large enough to
overflow that field would silently allocate a descriptor smaller than
what was asked for.
Return SIZE_MAX from trace_buffer_desc_size() on nr_page_va overflow.
Link: https://patch.msgid.link/20260911193937.602202-3-vdonnefort@google.com
Fixes: 2e67fabd8b77 ("ring-buffer: Introduce ring-buffer remotes")
Signed-off-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
include/linux/ring_buffer.h | 4 ++++
kernel/trace/trace_remote.c | 6 +++++-
2 files changed, 9 insertions(+), 1 deletion(-)
diff --git a/include/linux/ring_buffer.h b/include/linux/ring_buffer.h
index 11bffb6a142d1..eac3e9080c3c0 100644
--- a/include/linux/ring_buffer.h
+++ b/include/linux/ring_buffer.h
@@ -295,6 +295,10 @@ static inline size_t trace_buffer_desc_size(size_t buffer_size, unsigned int nr_
unsigned long nr_pages = __calc_nr_pages_ring_buffer_desc(buffer_size);
struct ring_buffer_desc *rbdesc;
+ /* Capped by ring_buffer_desc::nr_page_va */
+ if (nr_pages > UINT_MAX)
+ return SIZE_MAX;
+
return size_add(offsetof(struct trace_buffer_desc, __data),
size_mul(nr_cpus, struct_size(rbdesc, page_va, nr_pages)));
}
diff --git a/kernel/trace/trace_remote.c b/kernel/trace/trace_remote.c
index 0e8ca62301040..c79cd21347a03 100644
--- a/kernel/trace/trace_remote.c
+++ b/kernel/trace/trace_remote.c
@@ -980,9 +980,12 @@ int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_size,
const struct cpumask *cpumask)
{
size_t min_desc_size = trace_buffer_desc_size(buffer_size, cpumask_weight(cpumask));
- unsigned int nr_pages = __calc_nr_pages_ring_buffer_desc(buffer_size);
struct ring_buffer_desc *rb_desc;
int cpu, ret = -ENOMEM;
+ unsigned int nr_pages;
+
+ if (min_desc_size == SIZE_MAX)
+ return -E2BIG;
if (desc_size < min_desc_size)
return -EINVAL;
@@ -991,6 +994,7 @@ int trace_remote_alloc_buffer(struct trace_buffer_desc *desc, size_t desc_size,
desc->struct_len = min_desc_size;
rb_desc = __first_ring_buffer_desc(desc);
+ nr_pages = __calc_nr_pages_ring_buffer_desc(buffer_size);
for_each_cpu(cpu, cpumask) {
unsigned int id;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 447/733] scsi: target: iscsi: Fix hang for aborted WRITE_PENDING commands
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (445 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 446/733] tracing/remotes: Catch nr_page_va overflow in ring_buffer_desc sizing Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 448/733] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry Greg Kroah-Hartman
` (297 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Maurizio Lombardi, Laurence Oberman,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maurizio Lombardi <mlombard@redhat.com>
[ Upstream commit d5869dae5080e976d4b03cc33eb7ceb527f242bf ]
When a LUN_RESET aborts a WRITE command that is in the
TRANSPORT_WRITE_PENDING state, the target core sets CMD_T_ABORTED and
waits for the frontend to finish processing.
If the initiator subsequently sends the remaining dataout PDUs,
__iscsit_check_dataout_hdr() catches the payload, stops the dataout
timer if the sequence is final and finally dumps the data. However, the
iSCSI target doesn't trigger the completion process for these aborted
commands. Because of this, the abort path hangs indefinitely in
target_put_cmd_and_wait(), leading to a deadlocked target worker thread.
Fix this by explicitly calling target_complete_cmd() when the final
dataout PDU is received for an aborted WRITE command.
target_complete_cmd() detects the CMD_T_ABORTED flag and cleanly routes
the command into target_abort_work, allowing the abort completion to
successfully unblock.
Signed-off-by: Maurizio Lombardi <mlombard@redhat.com>
Reviewed-by: Laurence Oberman <loberman@redhat.com>
Link: https://patch.msgid.link/20260717143828.76291-2-mlombard@redhat.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/target/iscsi/iscsi_target.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/drivers/target/iscsi/iscsi_target.c b/drivers/target/iscsi/iscsi_target.c
index 62ada3a52210e..124ff269b8e75 100644
--- a/drivers/target/iscsi/iscsi_target.c
+++ b/drivers/target/iscsi/iscsi_target.c
@@ -1533,8 +1533,10 @@ __iscsit_check_dataout_hdr(struct iscsit_conn *conn, void *buf,
*/
if (se_cmd->transport_state & CMD_T_ABORTED) {
if (hdr->flags & ISCSI_FLAG_CMD_FINAL &&
- --cmd->outstanding_r2ts < 1)
+ --cmd->outstanding_r2ts < 1) {
iscsit_stop_dataout_timer(cmd);
+ target_complete_cmd(se_cmd, SAM_STAT_TASK_ABORTED);
+ }
return iscsit_dump_data_payload(conn, payload_length, 1);
}
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 448/733] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (446 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 447/733] scsi: target: iscsi: Fix hang for aborted WRITE_PENDING commands Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 449/733] configfs: unhash the dentry before dropping the item in rmdir Greg Kroah-Hartman
` (296 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vasileios Almpanis, Breno Leitao
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasileios Almpanis <vasilisalmpanis@gmail.com>
commit a7c1290eef60711c10289c056ad32ed1f2b47b12 upstream.
create_link() reads the target's configfs_dirent from
item->ci_dentry->d_fsdata, relying on the item reference taken by
get_target(). That reference pins the item, not its dentry: the dentry is
pinned by DCACHE_PERSISTENT, which configfs_remove_dir() releases via
simple_rmdir() while the item is still alive. A symlink racing with rmdir
of its target can therefore find ->ci_dentry freed and its dirent
released, triggering WARN_ON(!atomic_read(&sd->s_count)) in configfs_get().
Take the dirent in get_target() as well, under ->d_lock and atomically
with the item reference, and pass it down to create_link(). A hashed
dentry has not been killed yet, so its ->d_fsdata reference keeps the
dirent alive there.
Cc: stable@vger.kernel.org
Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com>
Tested-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260730093435.195441-2-vasilisalmpanis@gmail.com
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/configfs/symlink.c | 24 ++++++++++++++++++++----
1 file changed, 20 insertions(+), 4 deletions(-)
--- a/fs/configfs/symlink.c
+++ b/fs/configfs/symlink.c
@@ -76,9 +76,9 @@ static int configfs_get_target_path(stru
static int create_link(struct config_item *parent_item,
struct config_item *item,
+ struct configfs_dirent *target_sd,
struct dentry *dentry)
{
- struct configfs_dirent *target_sd = item->ci_dentry->d_fsdata;
char *body;
int ret;
@@ -115,6 +115,7 @@ static int create_link(struct config_ite
static int get_target(const char *symname, struct config_item **target,
+ struct configfs_dirent **target_sd,
struct super_block *sb)
{
struct path path __free(path_put) = {};
@@ -125,7 +126,20 @@ static int get_target(const char *symnam
return ret;
if (path.dentry->d_sb != sb)
return -EPERM;
- *target = configfs_get_config_item(path.dentry);
+ /*
+ * A hashed dentry guarantees that neither the item nor the dirent
+ * have been released yet, as removals unhash before dropping.
+ * Grab both references here. An item reference alone would not keep
+ * ->ci_dentry alive.
+ */
+ spin_lock(&path.dentry->d_lock);
+ if (!d_unhashed(path.dentry)) {
+ struct configfs_dirent *sd = path.dentry->d_fsdata;
+
+ *target = config_item_get(sd->s_element);
+ *target_sd = configfs_get(sd);
+ }
+ spin_unlock(&path.dentry->d_lock);
if (!*target)
return -ENOENT;
return 0;
@@ -139,6 +153,7 @@ int configfs_symlink(struct mnt_idmap *i
struct configfs_dirent *sd;
struct config_item *parent_item;
struct config_item *target_item = NULL;
+ struct configfs_dirent *target_sd = NULL;
const struct config_item_type *type;
sd = dentry->d_parent->d_fsdata;
@@ -182,7 +197,7 @@ int configfs_symlink(struct mnt_idmap *i
* AV, a thoroughly annoyed bastard.
*/
inode_unlock(dir);
- ret = get_target(symname, &target_item, dentry->d_sb);
+ ret = get_target(symname, &target_item, &target_sd, dentry->d_sb);
inode_lock(dir);
if (ret)
goto out_put;
@@ -196,13 +211,14 @@ int configfs_symlink(struct mnt_idmap *i
ret = type->ct_item_ops->allow_link(parent_item, target_item);
if (!ret) {
mutex_lock(&configfs_symlink_mutex);
- ret = create_link(parent_item, target_item, dentry);
+ ret = create_link(parent_item, target_item, target_sd, dentry);
mutex_unlock(&configfs_symlink_mutex);
if (ret && type->ct_item_ops->drop_link)
type->ct_item_ops->drop_link(parent_item,
target_item);
}
+ configfs_put(target_sd);
config_item_put(target_item);
out_put:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 449/733] configfs: unhash the dentry before dropping the item in rmdir
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (447 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 448/733] configfs: pin the symlink targets dirent instead of chasing ->ci_dentry Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 450/733] powerpc/ps3: Fix repository.c build failure Greg Kroah-Hartman
` (295 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+6b16e3d085833cbf3e25,
Vasileios Almpanis, Breno Leitao
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vasileios Almpanis <vasilisalmpanis@gmail.com>
commit f06c2d26d1999d37e93299db0ecead04ca7d0b9f upstream.
configfs_get_config_item() treats a hashed dentry as proof that
sd->s_element is a live config_item. configfs_rmdir() breaks that:
simple_rmdir() leaves the dentry hashed, the last reference to the item is
dropped right after, and the dentry is only unhashed by d_delete() once
->rmdir() has returned. configfs_symlink() resolves its target holding no
lock on it, so get_target() can land in that window:
BUG: KASAN: slab-use-after-free in config_item_get+0x26/0x90
get_target fs/configfs/symlink.c:128 [inline]
configfs_symlink+0x4ab/0x1030 fs/configfs/symlink.c:185
Unhash in configfs_remove_dir(), while the item is still guaranteed to be
there. A reference obtained just before that stays harmless, as
create_link() rechecks CONFIGFS_USET_DROPPING, already set by
configfs_detach_prep(). Both configfs_unregister_subsystem() paths
d_drop() after detaching, so this only makes rmdir match them.
Reported-by: syzbot+6b16e3d085833cbf3e25@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=6b16e3d085833cbf3e25
Fixes: 7063fbf22611 ("[PATCH] configfs: User-driven configuration filesystem")
Cc: stable@vger.kernel.org
Signed-off-by: Vasileios Almpanis <vasilisalmpanis@gmail.com>
Tested-by: Breno Leitao <leitao@debian.org>
Reviewed-by: Breno Leitao <leitao@debian.org>
Link: https://patch.msgid.link/20260730093435.195441-3-vasilisalmpanis@gmail.com
Signed-off-by: Breno Leitao <leitao@debian.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/configfs/dir.c | 9 +++++++++
1 file changed, 9 insertions(+)
--- a/fs/configfs/dir.c
+++ b/fs/configfs/dir.c
@@ -416,6 +416,15 @@ static void configfs_remove_dir(struct d
if (d_really_is_positive(d)) {
if (unlikely(simple_rmdir(d_inode(parent), d)))
pr_warn("remove_dir (%pd): attributes remain", d);
+ else
+ /*
+ * configfs_get_config_item() takes a hashed dentry as
+ * proof that ->s_element is still alive. Our caller
+ * is about to drop the last reference to the item and
+ * the VFS will not unhash until after we return, so
+ * unhash it here.
+ */
+ d_drop(d);
}
pr_debug(" o %pd removing done (%d)\n", d, d_count(d));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 450/733] powerpc/ps3: Fix repository.c build failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (448 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 449/733] configfs: unhash the dentry before dropping the item in rmdir Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 451/733] powerpc/eeh: Fix recursive locking on devices without EEH sensitive driver Greg Kroah-Hartman
` (294 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Madhavan Srinivasan
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
commit 5ba79d37403d86082ab4083b0f51ec3008a942cb upstream.
GCC fails to build ps3_defconfig with the following errors:
arch/powerpc/platforms/ps3/repository.c: In function ‘make_first_field.constprop’:
arch/powerpc/platforms/ps3/repository.c:78:9: error: ‘strnlen’ specified bound 8 exceeds source size 3 [-Werror=stringop-overread]
78 | memcpy((char *)&n, text, strnlen(text, sizeof(n)));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
arch/powerpc/platforms/ps3/repository.c: In function ‘make_first_field.constprop’:
arch/powerpc/platforms/ps3/repository.c:78:9: error: ‘strnlen’ specified bound 8 exceeds source size 4 [-Werror=stringop-overread]
78 | memcpy((char *)&n, text, strnlen(text, sizeof(n)));
| ^~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The current use of strnlen(text, sizeof(n)) triggers -Wstringop-overread
when text is a short string literal that is smaller than sizeof(n), such
as "bi" or "bus". Use strlen(text) instead and clamp the copy length to
sizeof(n) before memcpy().
Drop the redundant char * cast while at it.
Fixes: f94a84a09148 ("powerpc/ps3: refactor strncpy usage")
Cc: stable@vger.kernel.org
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260703165834.137242-2-thorsten.blum@linux.dev
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/powerpc/platforms/ps3/repository.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/arch/powerpc/platforms/ps3/repository.c
+++ b/arch/powerpc/platforms/ps3/repository.c
@@ -6,6 +6,8 @@
* Copyright 2006 Sony Corp.
*/
+#include <linux/minmax.h>
+
#include <asm/lv1call.h>
#include "platform.h"
@@ -74,8 +76,9 @@ static void _dump_node(unsigned int lpar
static u64 make_first_field(const char *text, u64 index)
{
u64 n = 0;
+ size_t len = min(strlen(text), sizeof(n));
- memcpy((char *)&n, text, strnlen(text, sizeof(n)));
+ memcpy(&n, text, len);
return PS3_VENDOR_ID_NONE + (n >> 32) + index;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 451/733] powerpc/eeh: Fix recursive locking on devices without EEH sensitive driver
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (449 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 450/733] powerpc/ps3: Fix repository.c build failure Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 452/733] powerpc: pci-ioda: Fix the stale irq chip reference Greg Kroah-Hartman
` (293 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Ritesh Harjani (IBM),
Shivaprasad G Bhat, Amit Machhiwal, Madhavan Srinivasan
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivaprasad G Bhat <sbhat@linux.ibm.com>
commit c5e68706527968282e49de205cc2b935823cb88a upstream.
The commit 1010b4c012b0 ("powerpc/eeh: Make EEH driver device hotplug
safe") refactored the EEH code such that the pci_rescan_remove_lock is
held at the beginning of eeh_handle_normal_event() and the
eeh_reset_device() is called with that lock being held. Looks like the
commit missed to remove the existing lock/unlock inside eeh_rmv_device()
which is no longer necessary. This is causing the eehd to hang on the
lock which it actually holds when that code path is taken.
[<0>] 0xc00000011c78f870
[<0>] __switch_to+0xfc/0x1a0
[<0>] pci_lock_rescan_remove+0x30/0x44
[<0>] eeh_rmv_device+0x290/0x2e0
[<0>] eeh_pe_dev_traverse+0x80/0x130
[<0>] eeh_reset_device+0xcc/0x23c
[<0>] eeh_handle_normal_event+0x830/0xa80
[<0>] eeh_event_handler+0xf8/0x190
[<0>] kthread+0x194/0x1b0
[<0>] start_kernel_thread+0x14/0x18
The issue is seen for cases where the errors are detected on the PHB
directly AND|OR for devices where the driver error_detected() returns
PCI_ERS_RESULT_NEED_RESET, and driver being not EEH sensitive(i.e no
error handlers like slot_reset(), resume() etc defined).
Fixes: 1010b4c012b0 ("powerpc/eeh: Make EEH driver device hotplug safe")
Cc: stable <stable@kernel.org>
Reviewed-by: Ritesh Harjani (IBM) <ritesh.list@gmail.com>
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/178404937381.913.2759874335293830160.stgit@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/powerpc/kernel/eeh_driver.c | 2 --
1 file changed, 2 deletions(-)
--- a/arch/powerpc/kernel/eeh_driver.c
+++ b/arch/powerpc/kernel/eeh_driver.c
@@ -533,9 +533,7 @@ static void eeh_rmv_device(struct eeh_de
if (rmv_data)
list_add(&edev->rmv_entry, &rmv_data->removed_vf_list);
} else {
- pci_lock_rescan_remove();
pci_stop_and_remove_bus_device(dev);
- pci_unlock_rescan_remove();
}
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 452/733] powerpc: pci-ioda: Fix the stale irq chip reference
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (450 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 451/733] powerpc/eeh: Fix recursive locking on devices without EEH sensitive driver Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 453/733] x86/amd_node: Avoid divide by zero on virtualized systems Greg Kroah-Hartman
` (292 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Shivaprasad G Bhat,
Gautam Menghani, Madhavan Srinivasan
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shivaprasad G Bhat <sbhat@linux.ibm.com>
commit d96171d911e3b89ca2957c04264019cf2f96287b upstream.
The commit f0ac60e6e311 ("powerpc/powernv/pci: Switch to use
msi_create_parent_irq_domain()") removed the legacy MSI irq chip
pnv_pci_msi_irq_chip but left behind the static definition of it and
its reference in is_pnv_opal_msi().
The KVM IRQ bypass for vfio devices is broken because the
comparision in is_pnv_opal_msi() fails on the comparision with
stale unused variable showing the below errors in dmesg.
kvmppc_set_passthru_irq_hv: Could not assign IRQ map for (X,Y)
kvmppc_set_passthru_irq (irq X, gsi Y) fails: -2
vfio-pci A:B:C.D irq bypass producer (eventfd Z) registration fails: -2
The patch removes the stale variable definition and fixes the
is_pnv_opal_msi() by comparing against the chip name prefix.
Fixes: f0ac60e6e311 ("powerpc/powernv/pci: Switch to use msi_create_parent_irq_domain()")
Cc: stable@kernel.org
Signed-off-by: Shivaprasad G Bhat <sbhat@linux.ibm.com>
Tested-by: Gautam Menghani <gautam@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/178716225364.1437.6201568081502251835.stgit@linux.ibm.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -1623,15 +1623,13 @@ int64_t pnv_opal_pci_msi_eoi(struct irq_
return opal_pci_msi_eoi(phb->opal_id, d->parent_data->hwirq);
}
-static struct irq_chip pnv_pci_msi_irq_chip;
-
/*
* Returns true iff chip is something that we could call
* pnv_opal_pci_msi_eoi for.
*/
bool is_pnv_opal_msi(struct irq_chip *chip)
{
- return chip == &pnv_pci_msi_irq_chip;
+ return chip && chip->name && str_has_prefix(chip->name, "PNV-");
}
EXPORT_SYMBOL_GPL(is_pnv_opal_msi);
@@ -1728,7 +1726,7 @@ static const struct msi_parent_ops pnv_m
.chip_flags = MSI_CHIP_FLAG_SET_EOI,
.bus_select_token = DOMAIN_BUS_NEXUS,
.bus_select_mask = MATCH_PCI_MSI,
- .prefix = "PNV-",
+ .prefix = "PNV-", /* Note: is_pnv_opal_msi() uses this */
.init_dev_msi_info = pnv_init_dev_msi_info,
};
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 453/733] x86/amd_node: Avoid divide by zero on virtualized systems
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (451 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 452/733] powerpc: pci-ioda: Fix the stale irq chip reference Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 454/733] x86/MCE/AMD: Fix inverted interrupt enablement during storm handling Greg Kroah-Hartman
` (291 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Borislav Petkov, Jason Andryuk,
Yazen Ghannam
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <jason.andryuk@amd.com>
commit 72bd92bd8190d7869ecb462649ca40f297822a33 upstream.
On a virtualized system, the number of nodes does not have a relationship to
the number of roots. A Xen PVH dom0 can calculate roots_per_node as 0, which
crashes with a divide by zero in:
if (count++ % roots_per_node)
because the underlying topology code on Xen ends up making num_nodes
2 and num_roots 1 and the integer division result is 0.
The issue is seen with Xen, but it could affect other systems.
Set roots_per_node to 1 in this case. Print a firmware bug when this is
performed for non-virtualized systems.
[ bp: Massage commit message. ]
Fixes: 0a4b61d9c2e4 ("x86/amd_node: Fix AMD root device caching")
Suggested-by: Borislav Petkov <bp@alien8.de>
Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260825214805.39148-2-jason.andryuk@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/amd_node.c | 5 +++++
1 file changed, 5 insertions(+)
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -287,6 +287,11 @@ static int __init amd_smn_init(void)
return -ENOMEM;
roots_per_node = num_roots / num_nodes;
+ if (!roots_per_node) {
+ if (!cpu_feature_enabled(X86_FEATURE_HYPERVISOR))
+ pr_warn(FW_BUG "Error detecting roots per node.\n");
+ roots_per_node = 1;
+ }
count = 0;
node = 0;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 454/733] x86/MCE/AMD: Fix inverted interrupt enablement during storm handling
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (452 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 453/733] x86/amd_node: Avoid divide by zero on virtualized systems Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 455/733] x86/amd_node: Fix potential NULL pointer dereference Greg Kroah-Hartman
` (290 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jasjeet Rangi, Borislav Petkov (AMD),
Ingo Molnar
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jasjeet Rangi <jrangi@purestorage.com>
commit d2929113b15bfc06793b852aeba3d2db6d79fcc9 upstream.
mce_amd_handle_storm() currently does the opposite of what storm
handling needs: it enables thresholding interrupts when a storm is
detected and disables them when the storm subsides.
Flip the "on" function argument before passing it to threshold_restart_bank()
as it should have been done.
To clarify: "on" to mce_handle_storm() means, the storm is on now when
"on" is true, and off when "on" is false.
[ bp: Simplify. ]
Fixes: 5c4663ed1eac ("x86/mce: Handle AMD threshold interrupt storms")
Signed-off-by: Jasjeet Rangi <jrangi@purestorage.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260812221514.598842-2-jrangi@purestorage.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/cpu/mce/amd.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/kernel/cpu/mce/amd.c
+++ b/arch/x86/kernel/cpu/mce/amd.c
@@ -864,7 +864,7 @@ static void amd_deferred_error_interrupt
void mce_amd_handle_storm(unsigned int bank, bool on)
{
- threshold_restart_bank(bank, on);
+ threshold_restart_bank(bank, !on);
}
static void amd_reset_thr_limit(unsigned int bank)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 455/733] x86/amd_node: Fix potential NULL pointer dereference
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (453 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 454/733] x86/MCE/AMD: Fix inverted interrupt enablement during storm handling Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 456/733] crypto: x86/aria - add missing vzeroupper in AVX2 code Greg Kroah-Hartman
` (289 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jason Andryuk, Borislav Petkov (AMD),
Ingo Molnar, Yazen Ghannam, Mario Limonciello (AMD)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Andryuk <jason.andryuk@amd.com>
commit aefdbd574a362dcf7569bada6d72f64a006b9fb9 upstream.
amd_smn_read/write() are exported functions around __amd_smn_rw(), so
they are always available even if amd_smn_init() fails. In that case,
'amd_roots' is NULL and __amd_smn_rw() will access uninitialized memory.
Then, commit:
83518453074d ("x86/amd_node: Add SMN offsets to exclusive region access")
added the 'smn_exclusive' flag, which indicated the calls to
pci_request_config_region_exclusive() succeeded, to prevent
concurrent userspace access.
Commit:
0a4b61d9c2e4 ("x86/amd_node: Fix AMD root device caching")
re-ordered initialization so pci_request_config_region_exclusive() is
called earlier and a failure exits amd_smn_init() before allocating
'amd_roots'. The setting of 'smn_exclusive' moved to the end of
amd_smn_init(), after 'amd_roots' is allocated. It became redundant
and can be removed.
Replace 'smn_exclusive' with directly checking 'amd_roots', to fix a
potential NULL pointer dereference and to simplify the logic.
[ bp: Reorg commit message, touchup comment. ]
[ mingo: Rebase & further touchups. ]
Fixes: 77466b798d59 ("x86/amd_node: Remove dependency on AMD_NB")
Signed-off-by: Jason Andryuk <jason.andryuk@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Yazen Ghannam <yazen.ghannam@amd.com>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260825214805.39148-3-jason.andryuk@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/amd_node.c | 14 ++++++++------
1 file changed, 8 insertions(+), 6 deletions(-)
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -38,7 +38,6 @@ static struct pci_dev **amd_roots;
/* Protect the PCI config register pairs used for SMN. */
static DEFINE_MUTEX(smn_mutex);
-static bool smn_exclusive;
#define SMN_INDEX_OFFSET 0x60
#define SMN_DATA_OFFSET 0x64
@@ -91,11 +90,16 @@ static int __amd_smn_rw(u8 i_off, u8 d_o
if (node >= amd_num_nodes())
return err;
- root = amd_roots[node];
- if (!root)
+ /*
+ * Uninitialized amd_roots indicates pci_request_config_region_exclusive()
+ * didn't run or failed and thus the kernel cannot rely on having
+ * exclusive access to SMN registers so prevent that.
+ */
+ if (!amd_roots)
return err;
- if (!smn_exclusive)
+ root = amd_roots[node];
+ if (!root)
return err;
guard(mutex)(&smn_mutex);
@@ -313,8 +317,6 @@ static int __init amd_smn_init(void)
debugfs_create_file("value", 0600, debugfs_dir, NULL, &smn_value_fops);
}
- smn_exclusive = true;
-
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 456/733] crypto: x86/aria - add missing vzeroupper in AVX2 code
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (454 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 455/733] x86/amd_node: Fix potential NULL pointer dereference Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 457/733] crypto: x86/aria - add missing vzeroupper in AVX-512 code Greg Kroah-Hartman
` (288 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Taehee Yoo, Eric Biggers, Herbert Xu
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit ac53977611428db3bc0b4ac0225e19c3e08ae50b upstream.
Since the AVX2 optimized ARIA code uses YMM registers, execute
vzeroupper before returning from it. This is needed to avoid degrading
the performance of any later SSE code that may happen to be executed.
Fixes: 37d8d3ae7a58 ("crypto: x86/aria - implement aria-avx2")
Cc: stable@vger.kernel.org
Cc: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/crypto/aria-aesni-avx2-asm_64.S | 6 ++++++
1 file changed, 6 insertions(+)
--- a/arch/x86/crypto/aria-aesni-avx2-asm_64.S
+++ b/arch/x86/crypto/aria-aesni-avx2-asm_64.S
@@ -982,6 +982,7 @@ SYM_TYPED_FUNC_START(aria_aesni_avx2_enc
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, %rax);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_aesni_avx2_encrypt_32way)
@@ -1007,6 +1008,7 @@ SYM_TYPED_FUNC_START(aria_aesni_avx2_dec
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, %rax);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_aesni_avx2_decrypt_32way)
@@ -1209,6 +1211,7 @@ SYM_TYPED_FUNC_START(aria_aesni_avx2_ctr
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, %r10);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_aesni_avx2_ctr_crypt_32way)
@@ -1359,6 +1362,7 @@ SYM_TYPED_FUNC_START(aria_aesni_avx2_gfn
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, %rax);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_aesni_avx2_gfni_encrypt_32way)
@@ -1384,6 +1388,7 @@ SYM_TYPED_FUNC_START(aria_aesni_avx2_gfn
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, %rax);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_aesni_avx2_gfni_decrypt_32way)
@@ -1428,6 +1433,7 @@ SYM_TYPED_FUNC_START(aria_aesni_avx2_gfn
%ymm8, %ymm9, %ymm10, %ymm11, %ymm12, %ymm13, %ymm14,
%ymm15, %r10);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_aesni_avx2_gfni_ctr_crypt_32way)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 457/733] crypto: x86/aria - add missing vzeroupper in AVX-512 code
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (455 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 456/733] crypto: x86/aria - add missing vzeroupper in AVX2 code Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 458/733] x86/amd_node: Fix PCI device reference counting in amd_smn_init() Greg Kroah-Hartman
` (287 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Taehee Yoo, Eric Biggers, Herbert Xu
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <ebiggers@kernel.org>
commit 60892a384aa1e65d0e703e1c513417bdf0c80777 upstream.
Since the AVX-512 optimized ARIA code uses ZMM registers, execute
vzeroupper before returning from it. This is needed to avoid degrading
the performance of any later SSE code that may happen to be executed.
Fixes: c970d42001f2 ("crypto: x86/aria - implement aria-avx512")
Cc: stable@vger.kernel.org
Cc: Taehee Yoo <ap420073@gmail.com>
Signed-off-by: Eric Biggers <ebiggers@kernel.org>
Signed-off-by: Herbert Xu <herbert@gondor.apana.org.au>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/crypto/aria-gfni-avx512-asm_64.S | 3 +++
1 file changed, 3 insertions(+)
--- a/arch/x86/crypto/aria-gfni-avx512-asm_64.S
+++ b/arch/x86/crypto/aria-gfni-avx512-asm_64.S
@@ -800,6 +800,7 @@ SYM_TYPED_FUNC_START(aria_gfni_avx512_en
%zmm9, %zmm8, %zmm11, %zmm10, %zmm12, %zmm13, %zmm14,
%zmm15, %rax);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_gfni_avx512_encrypt_64way)
@@ -825,6 +826,7 @@ SYM_TYPED_FUNC_START(aria_gfni_avx512_de
%zmm9, %zmm8, %zmm11, %zmm10, %zmm12, %zmm13, %zmm14,
%zmm15, %rax);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_gfni_avx512_decrypt_64way)
@@ -966,6 +968,7 @@ SYM_TYPED_FUNC_START(aria_gfni_avx512_ct
%zmm9, %zmm8, %zmm11, %zmm10, %zmm12, %zmm13, %zmm14,
%zmm15, %r10);
+ vzeroupper;
FRAME_END
RET;
SYM_FUNC_END(aria_gfni_avx512_ctr_crypt_64way)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 458/733] x86/amd_node: Fix PCI device reference counting in amd_smn_init()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (456 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 457/733] crypto: x86/aria - add missing vzeroupper in AVX-512 code Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 459/733] x86/mm: Fix user-space data loss with MADV_FREE and THP Greg Kroah-Hartman
` (286 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Yazen Ghannam,
Borislav Petkov (AMD), Mario Limonciello (AMD), stable
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <yazen.ghannam@amd.com>
commit 27600805e62f800bacf990354632eae4e487d34c upstream.
The local "root" pointer is a temporary variable used during the device
search. Therefore, refcount related to the search iterators should be cleaned
up after the search is complete.
Use the __free() cleanup macro to ensure the refcount is decremented when the
temporary pointer goes out of scope.
Additionally, increment the refcount when caching a root pointer. This ensures
the in-use refcount is separate from the temporary search refcounting.
Finally, drop the redundant "root = NULL" before the second search loop. The
pci_get_class() iterator always decrements the refcount of its "from"
argument, so the first loop can only fall through with "root" already NULL.
Fixes: 0a4b61d9c2e4 ("x86/amd_node: Fix AMD root device caching")
Closes: https://sashiko.dev/#/patchset/20260806160159.230453-1-jason.andryuk%40amd.com
Reported-by: Sashiko <sashiko-bot@kernel.org>
Assisted-by: LLM
Signed-off-by: Yazen Ghannam <yazen.ghannam@amd.com>
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Cc: <stable@kernel.org>
Link: https://patch.msgid.link/20260903154325.74343-1-yazen.ghannam@amd.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/amd_node.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
--- a/arch/x86/kernel/amd_node.c
+++ b/arch/x86/kernel/amd_node.c
@@ -251,7 +251,7 @@ __setup("amd_smn_debugfs_enable", amd_sm
static int __init amd_smn_init(void)
{
u16 count, num_roots, roots_per_node, node, num_nodes;
- struct pci_dev *root;
+ struct pci_dev *root __free(pci_dev_put) = NULL;
if (!cpu_feature_enabled(X86_FEATURE_ZEN))
return 0;
@@ -262,7 +262,6 @@ static int __init amd_smn_init(void)
return 0;
num_roots = 0;
- root = NULL;
while ((root = get_next_root(root))) {
pci_dbg(root, "Reserving PCI config space\n");
@@ -299,14 +298,13 @@ static int __init amd_smn_init(void)
count = 0;
node = 0;
- root = NULL;
while (node < num_nodes && (root = get_next_root(root))) {
/* Use one root for each node and skip the rest. */
if (count++ % roots_per_node)
continue;
pci_dbg(root, "is root for AMD node %u\n", node);
- amd_roots[node++] = root;
+ amd_roots[node++] = pci_dev_get(root);
}
if (enable_dfs) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 459/733] x86/mm: Fix user-space data loss with MADV_FREE and THP
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (457 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 458/733] x86/amd_node: Fix PCI device reference counting in amd_smn_init() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 460/733] x86/cfi: Fix FineIBT hash offset in cfi_get_func_hash() Greg Kroah-Hartman
` (285 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Orson Peters, Vernon Yang,
Dave Hansen, Ingo Molnar, Rick Edgecombe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vernon Yang <yanglincheng@kylinos.cn>
commit f7491d7c81db0e7c304a7bd757a76d2fbeaff80e upstream.
Some of users of Polars (a data analytics library) have lost production
data from this bug. They seem to have just the right combination of
huge pages, MADV_FREE and heavy reclaim pressure.
pmd_modify() masks the old value with (_HPAGE_CHG_MASK & ~_PAGE_DIRTY),
silently discarding the hardware dirty bit. The subsequent
pmd_mksaveddirty() call is supposed to transfer _PAGE_DIRTY into
_PAGE_SAVED_DIRTY when write-protecting, but the dirty bit was already
stripped from the value, so there is nothing left to transfer.
Contrast with pte_modify(), which keeps _PAGE_DIRTY_BITS in its mask,
and pud_modify(), which keeps _HPAGE_CHG_MASK untouched: pmd_modify()
is the odd one out. Any pmd_modify() on a writable, dirty PMD loses
the dirty state.
One visible consequence is data loss with MADV_FREE on PMD-mapped THP:
memset(buf, 0x5A, size); // PMD-mapped THP, PMD dirty
madvise(buf, size, MADV_FREE); // PMD cleaned but left writable,
// folio marked lazyfree
memset(buf, 0x5A, size); // hardware sets _PAGE_DIRTY again
mprotect(buf, size, PROT_READ); // pmd_modify() drops the dirty bit
mprotect(buf, size, PROT_READ|PROT_WRITE);
// ... memory pressure ...
Reclaim (e.g. under memcg pressure) then finds the lazyfree folio with
no dirty bit set anywhere and frees it in
__discard_anon_folio_pmd_locked(), even though the data was rewritten
after MADV_FREE; subsequent reads fault in fresh zero pages. NUMA
hinting alone can trigger the same loss, as do_huge_pmd_numa_page()
restores the PMD through pmd_modify() as well.
PMD-mapped file THPs are affected too: mprotect()/NUMA hinting dropping
the dirty bit means rewritten data is never written back.
Fix it by keeping _PAGE_DIRTY in the preserved mask, exactly like
pte_modify() and pud_modify() do. The existing
pmd_mksaveddirty()/pmd_clear_saveddirty() pair then performs the
hardware-dirty <-> saved-dirty transition based on the write bit,
preserving the shadow-stack encoding rules.
Fixes: bb3aadf7d446 ("x86/mm: Start actually marking _PAGE_SAVED_DIRTY")
Closes: https://lore.kernel.org/r/CAJxLxMUGu1-L+O_nAONOwOXnS=cNbNApCWqdthRjd76LThtSPg@mail.gmail.com/
Reported-by: Orson Peters <orsonpeters@gmail.com>
Signed-off-by: Vernon Yang <yanglincheng@kylinos.cn>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Rick Edgecombe <rick.p.edgecombe@intel.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260903031608.1194238-1-vernon2gm@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/include/asm/pgtable.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/arch/x86/include/asm/pgtable.h
+++ b/arch/x86/include/asm/pgtable.h
@@ -806,7 +806,7 @@ static inline pmd_t pmd_modify(pmd_t pmd
pmdval_t val = pmd_val(pmd), oldval = val;
pmd_t pmd_result;
- val &= (_HPAGE_CHG_MASK & ~_PAGE_DIRTY);
+ val &= _HPAGE_CHG_MASK;
val |= check_pgprot(newprot) & ~_HPAGE_CHG_MASK;
val = flip_protnone_guard(oldval, val, PHYSICAL_PMD_PAGE_MASK);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 460/733] x86/cfi: Fix FineIBT hash offset in cfi_get_func_hash()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (458 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 459/733] x86/mm: Fix user-space data loss with MADV_FREE and THP Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 461/733] x86/mm/pat: Acquire init_mm write lock on collapse to avoid UAF Greg Kroah-Hartman
` (284 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Soheil Hassas Yeganeh,
Peter Zijlstra (Intel)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Soheil Hassas Yeganeh <soheil.kdev@gmail.com>
commit 5a5d26f2cfe13467166219f6bf58099326912ddb upstream.
The switch of the FineIBT preamble from "subl $hash, %r10d" to the
shorter "subl $hash, %eax" moved the hash immediate from offset 7 to
offset 5 of the preamble. fineibt_preamble_hash was updated to match,
but the open-coded offset in cfi_get_func_hash() was missed and it
still reads the hash at offset 7.
cfi_get_func_hash() is used by the BPF JIT to give a struct_ops
trampoline the CFI hash of the stub function it stands in for. With
FineIBT the trampoline now gets the upper half of the real hash
followed by the first two bytes of the next instruction, so the first
indirect call from the kernel into a struct_ops program,
tcp_init_congestion_control() calling ->init() of a BPF congestion
control for example, fails the FineIBT check and the kernel dies with
a CFI failure.
Move the FineIBT preamble template and its offset defines above
cfi_get_func_hash() and use fineibt_preamble_hash there, so every
reader of the preamble shares one definition of its layout. The
CFI_FINEIBT arm is only built with CONFIG_FINEIBT, the only
configuration in which cfi_mode can take that value.
cfi_get_func_arity() does not need the same treatment: the __bhi_args
call whose displacement it reads still ends at the function address.
Fixes: 85a2d4a890dc ("x86,ibt: Use UDB instead of 0xEA")
Assisted-by: LLM
Signed-off-by: Soheil Hassas Yeganeh <soheil.kdev@gmail.com>
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Cc: stable@vger.kernel.org # 6.18+
Link: https://patch.msgid.link/20260831-b4-x86-cfi-fineibt-func-hash-v1-1-6ffc0af5c4ec@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/alternative.c | 72 ++++++++++++++++++++++--------------------
1 file changed, 38 insertions(+), 34 deletions(-)
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -1207,6 +1207,41 @@ static bool cfi_debug __ro_after_init;
bool cfi_bhi __ro_after_init = false;
#endif
+#ifdef CONFIG_FINEIBT
+/*
+ * <fineibt_preamble_start>:
+ * 0: f3 0f 1e fa endbr64
+ * 4: 2d 78 56 34 12 sub $0x12345678, %eax
+ * 9: 2e 0f 85 03 00 00 00 jne,pn 13 <fineibt_preamble_start+0x13>
+ * 10: 0f 1f 40 d6 nopl -0x2a(%rax)
+ *
+ * Note that the JNE target is the 0xD6 byte inside the NOPL, this decodes as
+ * UDB on x86_64 and raises #UD.
+ */
+asm( ".pushsection .rodata \n"
+ "fineibt_preamble_start: \n"
+ " endbr64 \n"
+ " subl $0x12345678, %eax \n"
+ "fineibt_preamble_bhi: \n"
+ " cs jne.d32 fineibt_preamble_start+0x13 \n"
+ "#fineibt_func: \n"
+ " nopl -42(%rax) \n"
+ "fineibt_preamble_end: \n"
+ ".popsection\n"
+);
+
+extern u8 fineibt_preamble_start[];
+extern u8 fineibt_preamble_bhi[];
+extern u8 fineibt_preamble_end[];
+
+#define fineibt_preamble_size (fineibt_preamble_end - fineibt_preamble_start)
+#define fineibt_preamble_bhi (fineibt_preamble_bhi - fineibt_preamble_start)
+#define fineibt_preamble_ud 0x13
+#define fineibt_preamble_hash 5
+
+#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE)
+#endif /* CONFIG_FINEIBT */
+
#ifdef CONFIG_CFI
u32 cfi_get_func_hash(void *func)
{
@@ -1214,9 +1249,11 @@ u32 cfi_get_func_hash(void *func)
func -= cfi_get_offset();
switch (cfi_mode) {
+#ifdef CONFIG_FINEIBT
case CFI_FINEIBT:
- func += 7;
+ func += fineibt_preamble_hash;
break;
+#endif
case CFI_KCFI:
func += 1;
break;
@@ -1359,39 +1396,6 @@ early_param("cfi", cfi_parse_cmdline);
*/
/*
- * <fineibt_preamble_start>:
- * 0: f3 0f 1e fa endbr64
- * 4: 2d 78 56 34 12 sub $0x12345678, %eax
- * 9: 2e 0f 85 03 00 00 00 jne,pn 13 <fineibt_preamble_start+0x13>
- * 10: 0f 1f 40 d6 nopl -0x2a(%rax)
- *
- * Note that the JNE target is the 0xD6 byte inside the NOPL, this decodes as
- * UDB on x86_64 and raises #UD.
- */
-asm( ".pushsection .rodata \n"
- "fineibt_preamble_start: \n"
- " endbr64 \n"
- " subl $0x12345678, %eax \n"
- "fineibt_preamble_bhi: \n"
- " cs jne.d32 fineibt_preamble_start+0x13 \n"
- "#fineibt_func: \n"
- " nopl -42(%rax) \n"
- "fineibt_preamble_end: \n"
- ".popsection\n"
-);
-
-extern u8 fineibt_preamble_start[];
-extern u8 fineibt_preamble_bhi[];
-extern u8 fineibt_preamble_end[];
-
-#define fineibt_preamble_size (fineibt_preamble_end - fineibt_preamble_start)
-#define fineibt_preamble_bhi (fineibt_preamble_bhi - fineibt_preamble_start)
-#define fineibt_preamble_ud 0x13
-#define fineibt_preamble_hash 5
-
-#define fineibt_prefix_size (fineibt_preamble_size - ENDBR_INSN_SIZE)
-
-/*
* <fineibt_caller_start>:
* 0: b8 78 56 34 12 mov $0x12345678, %eax
* 5: 4d 8d 5b f0 lea -0x10(%r11), %r11
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 461/733] x86/mm/pat: Acquire init_mm write lock on collapse to avoid UAF
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (459 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 460/733] x86/cfi: Fix FineIBT hash offset in cfi_get_func_hash() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 462/733] x86/alternatives: Exclude text poking against change_page_attr() Greg Kroah-Hartman
` (283 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
Mike Rapoport (Microsoft), Dave Hansen, Ingo Molnar,
Kiryl Shutsemau (Meta), David Hildenbrand (Arm), Will Deacon,
David Carlier, Atish Patra, Nikunj A Dadhania
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lorenzo Stoakes (ARM) <ljs@kernel.org>
commit a1c7570cedd03372812a5b693732880867babbca upstream.
x86 implements page attribute modification using its Change Page
Attributes (CPA) mechanism.
This tracks properties of ranges such as cache mode through x86 page
attributes, and as part of that logic manipulates kernel page tables.
Since commit:
41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
ranges of kernel page table entries can be collapsed into
huge page table entries as part of this logic.
As part of this collapse, it frees the page tables which the collapsed
entries previously pointed to, and it does so without any relevant locks
being held to preclude concurrent kernel page table walkers.
The only way this code can be reached is if CPA_COLLAPSE is specified, and
this is only set in set_memory_rox() via:
set_memory_rox()
-> change_page_attr_set_clr()
-> cpa_flush()
-> cpa_collapse_large_pages()
Notable users of this are execmem and BPF when manipulating executable
mappings.
However, this is problematic for ptdump as it walks ranges it does not own
and thus runs the risk of a use-after-free on page tables freed underneath
it.
In addition, concurrent CPA collapse operations are possible which can also
cause races.
Resolve the issue by acquiring the mmap write lock on init_mm across the
whole operation.
It is safe to acquire a sleeping lock as all the callers invoke
set_memory_rox() from process context and in any case,
change_page_attr_set_clr() calls vm_unmap_alias() which ultimately takes a
mutex, disallowing atomic context here.
Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Reviewed-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Reviewed-by: Kiryl Shutsemau (Meta) <kas@kernel.org>
Reviewed-by: David Hildenbrand (Arm) <david@kernel.org>
Reviewed-by: Dave Hansen <dave.hansen@linux.intel.com>
Reviewed-by: Will Deacon <will@kernel.org>
Reviewed-by: David Carlier <devnexen@gmail.com>
Tested-by: Atish Patra <atishp@meta.com>
Tested-by: Nikunj A Dadhania <nikunj@amd.com>
Cc:stable@vger.kernel.org
Link: https://patch.msgid.link/20260813-cpa-fixes-v2-1-39b4ff90f91d@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/mm/pat/set_memory.c | 15 ++++++++++++++-
include/linux/mmap_lock.h | 2 ++
2 files changed, 16 insertions(+), 1 deletion(-)
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -22,6 +22,7 @@
#include <linux/cc_platform.h>
#include <linux/set_memory.h>
#include <linux/memregion.h>
+#include <linux/cleanup.h>
#include <asm/e820/api.h>
#include <asm/processor.h>
@@ -410,7 +411,7 @@ static void __cpa_flush_tlb(void *data)
static int collapse_large_pages(unsigned long addr, struct list_head *pgtables);
-static void cpa_collapse_large_pages(struct cpa_data *cpa)
+static void __cpa_collapse_large_pages(struct cpa_data *cpa)
{
unsigned long start, addr, end;
struct ptdesc *ptdesc, *tmp;
@@ -448,6 +449,18 @@ static void cpa_collapse_large_pages(str
spin_unlock(&cpa_lock);
}
+static void cpa_collapse_large_pages(struct cpa_data *cpa)
+{
+ /*
+ * Take the mmap write lock on init_mm to:
+ * - Avoid a use-after-free if raced by ptdump (which takes its own
+ * write lock on init_mm).
+ * - Serialise concurrent CPA walkers.
+ */
+ scoped_guard(mmap_write_lock, &init_mm)
+ __cpa_collapse_large_pages(cpa);
+}
+
static void cpa_flush(struct cpa_data *cpa, int cache)
{
unsigned int i;
--- a/include/linux/mmap_lock.h
+++ b/include/linux/mmap_lock.h
@@ -622,6 +622,8 @@ static inline void mmap_read_unlock(stru
DEFINE_GUARD(mmap_read_lock, struct mm_struct *,
mmap_read_lock(_T), mmap_read_unlock(_T))
DEFINE_GUARD_COND(mmap_read_lock, _try, mmap_read_trylock(_T))
+DEFINE_GUARD(mmap_write_lock, struct mm_struct *,
+ mmap_write_lock(_T), mmap_write_unlock(_T))
static inline void mmap_read_unlock_non_owner(struct mm_struct *mm)
{
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 462/733] x86/alternatives: Exclude text poking against change_page_attr()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (460 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 461/733] x86/mm/pat: Acquire init_mm write lock on collapse to avoid UAF Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 463/733] mm/slab: take n->list_lock in __slab_try_return_freelist() to avoid race Greg Kroah-Hartman
` (282 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Jiri Slaby, Steffen Dirkwinkel,
Pedro Falcato, Lorenzo Stoakes (ARM), Mike Rapoport (Microsoft),
Dave Hansen, Ingo Molnar, Atish Patra, Nikunj A Dadhania
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pedro Falcato <pfalcato@suse.de>
commit 1587d3394e254639cc36516256031334095e6ef3 upstream.
>From time to time, the following BUG can be observed
in the x86 alternatives patching code [0]:
> kernel BUG at arch/x86/kernel/alternative.c:2576!
> Oops: invalid opcode: 0000 [#1] SMP NOPTI
> CPU: 0 UID: 0 PID: 355 Comm: (udev-worker) Not tainted 7.1.3-1-default #1 PREEMPT(full) openSUSE Tumbleweed 8c1795b03ec64f997e57a8ad38b1161e3b98da64
> Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS unknown 02/02/2022
> RIP: 0010:__text_poke+0x2aa/0x450
> Call Trace:
> <TASK>
> smp_text_poke_batch_finish+0x2a7/0x320
> __static_call_transform+0xb7/0x220
> arch_static_call_transform+0x5b/0xb0
> __static_call_init+0xe9/0x270
> static_call_module_notify+0x11f/0x150
> notifier_call_chain+0x61/0xe0
> blocking_notifier_call_chain_robust+0x63/0xc0
> load_module+0x1c92/0x20c0
> init_module_from_file+0xd8/0x140
> idempotent_init_module+0x100/0x2f0
> __x64_sys_finit_module+0x71/0xe0
> do_syscall_64+0xe1/0x610
> entry_SYSCALL_64_after_hwframe+0x76/0x7e
which matches the following BUG_ON() in alternative.c:
/*
* If something went wrong, crash and burn since recovery paths are not
* implemented.
*/
BUG_ON(!pages[0] || (cross_page_boundary && !pages[1]));
This can happen if vmalloc_to_page() fails, for any reason. Such can happen
if text poking races with CPA, which can possibly result in the collapsing
of page tables (or breaking of PMD hugepages). It is not a problem for most
users of vmalloc_to_page() (they solely own the vmalloc'd range) but, when
CONFIG_ARCH_HAS_EXECMEM_ROX=y, various modules own a single execmem vmalloc
range, and can call set_memory_*() in parallel on it. This can happen to
race against __text_poke and cause havoc in vmalloc_to_page().
Fix it by excluding against CPA using the init_mm mmap read lock.
[ dhansen: Fix up SoB ordering. The actual code flow here was:
Pedro=>Lorenzo=>Mike=>Me which is reflected in the SoB chain
now. I *believe* Mike simply picked up Lorenzo's update to
Pedro's post from the Link ]
Fixes: 64f6a4e10c05 ("x86: re-enable EXECMEM_ROX support")
Reported-by: Jiri Slaby <jirislaby@kernel.org>
Reported-by: Steffen Dirkwinkel <lists@steffen.cc>
Signed-off-by: Pedro Falcato <pfalcato@suse.de>
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Co-developed-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Jiri Slaby <jirislaby@kernel.org>
Tested-by: Atish Patra <atishp@meta.com>
Tested-by: Nikunj A Dadhania <nikunj@amd.com>
Cc: stable@vger.kernel.org
Link: https://bugzilla.opensuse.org/show_bug.cgi?id=1271202 [0]
Link: https://lore.kernel.org/linux-mm/555ea1d43a12c30a8f1eaf10c899b3790d728f33.camel@dirkwinkel.cc/
Link: https://patch.msgid.link/20260813-cpa-fixes-v2-3-39b4ff90f91d@kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/kernel/alternative.c | 39 ++++++++++++++++++++++++++++++++++++---
1 file changed, 36 insertions(+), 3 deletions(-)
--- a/arch/x86/kernel/alternative.c
+++ b/arch/x86/kernel/alternative.c
@@ -6,6 +6,9 @@
#include <linux/vmalloc.h>
#include <linux/memory.h>
#include <linux/execmem.h>
+#include <linux/cleanup.h>
+#include <linux/kgdb.h>
+#include <linux/mmap_lock.h>
#include <asm/text-patching.h>
#include <asm/insn.h>
@@ -2547,6 +2550,38 @@ static void text_poke_memset(void *dst,
typedef void text_poke_f(void *dst, const void *src, size_t len);
+static void __poke_vmalloc_pages(struct page **pages, void *addr,
+ bool cross_page_boundary)
+{
+ pages[0] = vmalloc_to_page(addr);
+ if (cross_page_boundary)
+ pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
+}
+
+static void poke_vmalloc_pages(struct page **pages, void *addr,
+ bool cross_page_boundary)
+{
+ if (in_dbg_master()) {
+ /*
+ * If called from kgdb cannot sleep, but all other CPUs stopped
+ * anyway so safe to proceed without locks
+ */
+ __poke_vmalloc_pages(pages, addr, cross_page_boundary);
+ } else {
+ /*
+ * execmem ROX ranges are shared between modules and can be
+ * collapsed to huge PMD entries, and this collapse can happen
+ * concurrently with a racing set_memory_rox().
+ *
+ * Prevent vmalloc_to_page() from racing by acquiring an
+ * init_mm read lock which pairs with the init_mm write lock in
+ * cpa_collapse_large_pages().
+ */
+ guard(mmap_read_lock)(&init_mm);
+ __poke_vmalloc_pages(pages, addr, cross_page_boundary);
+ }
+}
+
static void *__text_poke(text_poke_f func, void *addr, const void *src, size_t len)
{
bool cross_page_boundary = offset_in_page(addr) + len > PAGE_SIZE;
@@ -2564,9 +2599,7 @@ static void *__text_poke(text_poke_f fun
BUG_ON(!after_bootmem);
if (!core_kernel_text((unsigned long)addr)) {
- pages[0] = vmalloc_to_page(addr);
- if (cross_page_boundary)
- pages[1] = vmalloc_to_page(addr + PAGE_SIZE);
+ poke_vmalloc_pages(pages, addr, cross_page_boundary);
} else {
pages[0] = virt_to_page(addr);
WARN_ON(!PageReserved(pages[0]));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 463/733] mm/slab: take n->list_lock in __slab_try_return_freelist() to avoid race
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (461 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 462/733] x86/alternatives: Exclude text poking against change_page_attr() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 464/733] ipv6: fix fib6 walker UAF on seq stop Greg Kroah-Hartman
` (281 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Hyunwoo Kim, Harry Yoo (Meta),
Hao Li, Vlastimil Babka (SUSE)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harry Yoo (Meta) <harry@kernel.org>
commit 4a724bcf5d703e18957397914d79156fa2cf1174 upstream.
Commit ba7425312607 ("mm, slab: add an optimistic
__slab_try_return_freelist()") incorrectly assumed that nobody has freed
an object to the slab as long as slab->freelist is NULL and cmpxchg
succeeds.
However, as reported by Hyunwoo Kim [1], other CPUs might have freed
an object to the slab, insert the slab to the partial list, then
allocated an object from the slab, and be in the middle of removing
the slab from the list under n->list_lock.
Since __refill_objects_node() puts the slab back on pc.slabs
outside n->list_lock, it might insert the slab into that list while
the slab is concurrently being removed from n->partial.
This led to a list corruption [1]:
list_add corruption. next->prev should be prev
(ffff888100000248), but was dead000000000122.
(next=ffffea000416e410).
kernel BUG at lib/list_debug.c:29!
Oops: invalid opcode: 0000 [#1] SMP NOPTI
CPU: 1 UID: 65534 PID: 144 Comm: poc Not tainted
7.2.0-16172-gcf72cbb39da8-dirty #1 PREEMPT(lazy)
RIP: 0010:__list_add_valid_or_report+0x80/0xd0
...
Call Trace:
alloc_from_new_slab+0x183/0x300
___slab_alloc+0x31c/0x890
__kmalloc_noprof+0x3d4/0x800
lsm_blob_alloc+0x2d/0x50
security_msg_msg_alloc+0x26/0x90
load_msg+0x1aa/0x210
do_msgsnd+0x91/0x800
do_syscall_64+0x109/0x5d0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
...
Kernel panic - not syncing: Fatal exception
This is a classic ABA problem where cmpxchg succeeds but the state has
changed since __refill_objects_node() took the freelist from the slab.
As Vlastimil Babka mentioned [2], it should be rare to return more than
one slab (due to the racy read of slab->counters in
get_partial_node_bulk()). Therefore, instead of introducing additional
complexity, acquire and release n->list_lock twice in the worst case.
Return the slab directly to the partial list and hold n->list_lock
across the cmpxchg and add_partial(). This is similar to the initial
version of commit ba7425312607 [3]. This is enough to avoid the race as
the list manipulation is serialized by n->list_lock. While at it,
bring back unlikely() hint now that the condition is unlikely.
Reported-by: Hyunwoo Kim <imv4bel@gmail.com>
Closes: https://lore.kernel.org/linux-mm/apPa-cGLcyt90l-E@v4bel [1]
Link: https://lore.kernel.org/linux-mm/ae25c193-b95f-40c1-83b6-1c2546467e41@kernel.org [2]
Link: https://lore.kernel.org/all/20260421-b4-refill-optimistic-return-v1-1-24f0bfc1acff@kernel.org [3]
Fixes: ba7425312607 ("mm, slab: add an optimistic __slab_try_return_freelist()")
Cc: stable@vger.kernel.org
Signed-off-by: Harry Yoo (Meta) <harry@kernel.org>
Link: https://patch.msgid.link/20260903-slab-fix-aba-v3-1-b44cb6badd54@kernel.org
Reviewed-by: Hao Li <hao.li@linux.dev>
Signed-off-by: Vlastimil Babka (SUSE) <vbabka@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
mm/slub.c | 20 +++++++++++++-------
1 file changed, 13 insertions(+), 7 deletions(-)
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -5612,10 +5612,12 @@ static noinline void free_to_partial_lis
*
* Fail if the slab isn't full anymore due to a concurrent free.
*/
-static bool __slab_try_return_freelist(struct kmem_cache *s, struct slab *slab,
- void *head, int cnt)
+static bool __slab_try_return_freelist(struct kmem_cache *s,
+ struct kmem_cache_node *n,
+ struct slab *slab, void *head, int cnt)
{
struct freelist_counters old, new;
+ unsigned long flags;
old.freelist = slab->freelist;
old.counters = slab->counters;
@@ -5627,9 +5629,15 @@ static bool __slab_try_return_freelist(s
new.counters = old.counters;
new.inuse -= cnt;
- if (!slab_update_freelist(s, slab, &old, &new, "__slab_try_return_freelist"))
+ spin_lock_irqsave(&n->list_lock, flags);
+
+ if (!slab_update_freelist(s, slab, &old, &new, "__slab_try_return_freelist")) {
+ spin_unlock_irqrestore(&n->list_lock, flags);
return false;
+ }
+ add_partial(n, slab, ADD_TO_TAIL);
+ spin_unlock_irqrestore(&n->list_lock, flags);
return true;
}
@@ -7202,10 +7210,8 @@ __refill_objects_node(struct kmem_cache
void *head = object;
void *tail;
- if (__slab_try_return_freelist(s, slab, head, count)) {
- list_add(&slab->slab_list, &pc.slabs);
+ if (__slab_try_return_freelist(s, n, slab, head, count))
break;
- }
do {
tail = object;
@@ -7218,7 +7224,7 @@ __refill_objects_node(struct kmem_cache
break;
}
- if (!list_empty(&pc.slabs)) {
+ if (unlikely(!list_empty(&pc.slabs))) {
spin_lock_irqsave(&n->list_lock, flags);
list_for_each_entry(slab, &pc.slabs, slab_list)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 464/733] ipv6: fix fib6 walker UAF on seq stop
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (462 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 463/733] mm/slab: take n->list_lock in __slab_try_return_freelist() to avoid race Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 465/733] ipmr: account multicast table and route memory Greg Kroah-Hartman
` (280 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Luxing Yin, Zihan Xi,
Ido Schimmel, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
commit 19b4ed644d68098cc62ab612727f40d30f43476c upstream.
ipv6_route_iter_active() treats a walker in FWS_U at the table root as
already unlinked. fib6_del_route() can move a still-linked walker into
that same state when the current leaf is the last route at the root,
so ipv6_route_native_seq_stop() skips fib6_walker_unlink(). The seq
private object can then be freed while it remains on
net->ipv6.fib6_walkers. A later route deletion walks the dangling list
and uses the freed walker.
Use the list head as membership state and reinitialize it when
unlinking. Keep the existing w->node check so a never-started iterator
with a zeroed private object is not treated as linked.
The same stop helper is used by /proc/net/ipv6_route and by the BPF
ipv6_route iterator. The BPF show path only widens the race.
Fixes: 8d2ca1d7b5c3 ("ipv6: avoid high order memory allocations for /proc/net/ipv6_route")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Co-developed-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Luxing Yin <root@tr0jan.top>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/89699735763f6c297584d7c2ff106239cc1e8ce0.1788837093.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/ip6_fib.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/net/ipv6/ip6_fib.c
+++ b/net/ipv6/ip6_fib.c
@@ -85,7 +85,7 @@ static void fib6_walker_link(struct net
static void fib6_walker_unlink(struct net *net, struct fib6_walker *w)
{
write_lock_bh(&net->ipv6.fib6_walker_lock);
- list_del(&w->lh);
+ list_del_init(&w->lh);
write_unlock_bh(&net->ipv6.fib6_walker_lock);
}
@@ -2758,7 +2758,7 @@ static void *ipv6_route_seq_start(struct
static bool ipv6_route_iter_active(struct ipv6_route_iter *iter)
{
struct fib6_walker *w = &iter->w;
- return w->node && !(w->state == FWS_U && w->node == w->root);
+ return w->node && !list_empty(&w->lh);
}
static void ipv6_route_native_seq_stop(struct seq_file *seq, void *v)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 465/733] ipmr: account multicast table and route memory
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (463 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 464/733] ipv6: fix fib6 walker UAF on seq stop Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 466/733] reboot: fix cad_pid use-after-free race Greg Kroah-Hartman
` (279 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Zihan Xi, Ido Schimmel,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
commit b7ee18725f2292ab554aa96a101ae42d45f008bd upstream.
A netadmin in a user+net namespace can create many IPv4 and IPv6
multicast routing tables with MRT_TABLE and MRT6_TABLE. Each unseen
id allocates an mr_table via the shared mr_table_alloc(), links it
into the per-net list, and leaves it until netns teardown. Those
objects were not charged to memcg, so the host unreclaimable slab
grows with the table count.
Account mr_table allocations with GFP_KERNEL_ACCOUNT and mark the
IPv4/IPv6 MFC caches SLAB_ACCOUNT. This matches the established
handling of IP addresses, routes and alternate interface names.
Unresolved MFC entries are still allocated from softIRQ with
GFP_ATOMIC and are not charged. They expire after 10 seconds and are
bounded by the socket receive queue; see commit 0079ad8e8dc3
("ipmr: remove hard code cache_resolve_queue_len limit").
Fixes: f0ad0860d01e ("ipv4: ipmr: support multiple tables")
Fixes: d1db275dd3f6 ("ipv6: ip6mr: support multiple tables")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/050b58f7fc6b45da0fb12768ebb62d18fa46133d.1788784801.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/ipmr.c | 3 ++-
net/ipv4/ipmr_base.c | 2 +-
net/ipv6/ip6mr.c | 2 +-
3 files changed, 4 insertions(+), 3 deletions(-)
--- a/net/ipv4/ipmr.c
+++ b/net/ipv4/ipmr.c
@@ -3376,7 +3376,8 @@ int __init ip_mr_init(void)
{
int err;
- mrt_cachep = KMEM_CACHE(mfc_cache, SLAB_HWCACHE_ALIGN | SLAB_PANIC);
+ mrt_cachep = KMEM_CACHE(mfc_cache,
+ SLAB_HWCACHE_ALIGN | SLAB_PANIC | SLAB_ACCOUNT);
err = register_pernet_subsys(&ipmr_net_ops);
if (err)
--- a/net/ipv4/ipmr_base.c
+++ b/net/ipv4/ipmr_base.c
@@ -52,7 +52,7 @@ mr_table_alloc(struct net *net, u32 id,
struct mr_table *mrt;
int err;
- mrt = kzalloc_obj(*mrt);
+ mrt = kzalloc_obj(*mrt, GFP_KERNEL_ACCOUNT);
if (!mrt)
return ERR_PTR(-ENOMEM);
mrt->id = id;
--- a/net/ipv6/ip6mr.c
+++ b/net/ipv6/ip6mr.c
@@ -1427,7 +1427,7 @@ int __init ip6_mr_init(void)
{
int err;
- mrt_cachep = KMEM_CACHE(mfc6_cache, SLAB_HWCACHE_ALIGN);
+ mrt_cachep = KMEM_CACHE(mfc6_cache, SLAB_HWCACHE_ALIGN | SLAB_ACCOUNT);
if (!mrt_cachep)
return -ENOMEM;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 466/733] reboot: fix cad_pid use-after-free race
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (464 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 465/733] ipmr: account multicast table and route memory Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 467/733] ftrace: Use rcu_assign_pointer() for tmp_ops filter hash Greg Kroah-Hartman
` (278 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, AutonomousCodeSecurity,
Mateusz Guzik, Bradley Morgan, Oleg Nesterov, Eric W. Biederman,
Pavel Tikhomirov, Cen Zhang (Microsoft),
Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cen Zhang (Microsoft) <blbllhy@gmail.com>
commit 5a88f78df753993469dab4d1831f8fb4256a9468 upstream.
cad_pid is a single kernel-wide struct pid pointer. proc_do_cad_pid()
reads it and passes it to pid_vnr() without protecting the lifetime of
the referenced struct pid. A concurrent writer can replace cad_pid and
drop the final reference to the old struct pid after the reader has
loaded the pointer but before pid_vnr() has finished dereferencing it,
causing a use-after-free.
kill_cad_pid() has the same lifetime race when it passes cad_pid to
kill_pid().
At the time this issue was reported, an unprivileged user could reach the
sysctl through user and PID namespaces because cad_pid was registered in
pid_table[]. Moving cad_pid back to the global reboot sysctl table
corrected that namespace and permission mismatch, but did not fix the
underlying lifetime race.
Fix this by treating cad_pid as an RCU-protected pointer at both read
sites and by waiting for a grace period before dropping the old reference
on the write side.
call_rcu(&old_pid->rcu, ...) cannot be used here because free_pid()
also queues pid->rcu; queueing the same rcu_head twice can corrupt the
RCU callback list.
Original KASAN crash stack:
kernel/pid.c:545 pid_nr_ns() # reads freed pid->level
kernel/pid.c:556 pid_vnr() # calls pid_nr_ns()
kernel/pid.c:775 proc_do_cad_pid() # calls pid_vnr(cad_pid)
Fixes: 9ec52099e4b8 ("[PATCH] replace cad_pid by a struct pid")
Reported-by: AutonomousCodeSecurity@microsoft.com
Closes: https://lore.kernel.org/all/20260717210143.4734-1-blbllhy@gmail.com/
Link: https://lore.kernel.org/all/alz5ZYLE4kaq_v2P@redhat.com/
Link: https://lore.kernel.org/all/al4ICz9biJKtdZc4@redhat.com/
Suggested-by: Mateusz Guzik <mjguzik@gmail.com>
Suggested-by: Bradley Morgan <include@grrlz.net>
Suggested-by: Oleg Nesterov <oleg@redhat.com>
Suggested-by: Eric W. Biederman <ebiederm@xmission.com>
Suggested-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Cc: stable@vger.kernel.org
Signed-off-by: Cen Zhang (Microsoft) <blbllhy@gmail.com>
Link: https://patch.msgid.link/20260814040944.16561-1-blbllhy@gmail.com
Reviewed-by: Bradley Morgan <include@grrlz.net>
Reviewed-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Pavel Tikhomirov <ptikhomirov@virtuozzo.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/linux/sched.h | 2 +-
include/linux/sched/signal.h | 5 +----
init/main.c | 2 +-
kernel/reboot.c | 19 +++++++++++++++----
kernel/signal.c | 12 ++++++++++++
5 files changed, 30 insertions(+), 10 deletions(-)
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1775,7 +1775,7 @@ static inline bool is_lazy_mmu_mode_acti
}
#endif
-extern struct pid *cad_pid;
+extern struct pid __rcu *cad_pid;
/*
* Per process flags
--- a/include/linux/sched/signal.h
+++ b/include/linux/sched/signal.h
@@ -562,10 +562,7 @@ static inline sigset_t *sigmask_to_save(
return res;
}
-static inline int kill_cad_pid(int sig, int priv)
-{
- return kill_pid(cad_pid, sig, priv);
-}
+int kill_cad_pid(int sig, int priv);
/* These can be the second arg to send_sig_info/send_group_sig_info. */
#define SEND_SIG_NOINFO ((struct kernel_siginfo *) 0)
--- a/init/main.c
+++ b/init/main.c
@@ -1636,7 +1636,7 @@ static noinline void __init kernel_init_
*/
set_mems_allowed(node_states[N_MEMORY]);
- cad_pid = get_pid(task_pid(current));
+ rcu_assign_pointer(cad_pid, get_pid(task_pid(current)));
smp_prepare_cpus(setup_max_cpus);
--- a/kernel/reboot.c
+++ b/kernel/reboot.c
@@ -13,7 +13,9 @@
#include <linux/kexec.h>
#include <linux/kmod.h>
#include <linux/kmsg_dump.h>
+#include <linux/rcupdate.h>
#include <linux/reboot.h>
+#include <linux/sched/signal.h>
#include <linux/suspend.h>
#include <linux/syscalls.h>
#include <linux/syscore_ops.h>
@@ -24,8 +26,7 @@
*/
static int C_A_D = 1;
-struct pid *cad_pid;
-EXPORT_SYMBOL(cad_pid);
+struct pid __rcu *cad_pid;
#if defined(CONFIG_ARM)
#define DEFAULT_REBOOT_MODE = REBOOT_HARD
@@ -1371,10 +1372,14 @@ static int proc_do_cad_pid(const struct
{
struct ctl_table tmp_table = *table;
struct pid *new_pid;
+ struct pid *old_pid;
pid_t tmp_pid;
int r;
- tmp_pid = pid_vnr(cad_pid);
+ rcu_read_lock();
+ tmp_pid = pid_vnr(rcu_dereference(cad_pid));
+ rcu_read_unlock();
+
tmp_table.data = &tmp_pid;
r = proc_dointvec(&tmp_table, write, buffer, lenp, ppos);
@@ -1385,7 +1390,13 @@ static int proc_do_cad_pid(const struct
if (!new_pid)
return -ESRCH;
- put_pid(xchg(&cad_pid, new_pid));
+ old_pid = unrcu_pointer(xchg(&cad_pid, RCU_INITIALIZER(new_pid)));
+ /*
+ * Wait for cad_pid readers before put_pid(). We cannot use
+ * call_rcu() here because free_pid() already owns pid->rcu.
+ */
+ synchronize_rcu();
+ put_pid(old_pid);
return 0;
}
--- a/kernel/signal.c
+++ b/kernel/signal.c
@@ -1903,6 +1903,18 @@ int kill_pid(struct pid *pid, int sig, i
}
EXPORT_SYMBOL(kill_pid);
+int kill_cad_pid(int sig, int priv)
+{
+ int ret;
+
+ rcu_read_lock();
+ ret = kill_pid(rcu_dereference(cad_pid), sig, priv);
+ rcu_read_unlock();
+
+ return ret;
+}
+EXPORT_SYMBOL(kill_cad_pid);
+
#ifdef CONFIG_POSIX_TIMERS
/*
* These functions handle POSIX timer signals. POSIX timers use
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 467/733] ftrace: Use rcu_assign_pointer() for tmp_ops filter hash
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (465 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 466/733] reboot: fix cad_pid use-after-free race Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 468/733] ftrace: fork: Initialize function graph state before copy_exec_state() Greg Kroah-Hartman
` (277 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, kernel test robot, Leon Hwang,
Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leon Hwang <leon.hwang@linux.dev>
commit b4dcc18b97913888e8d009624e07c8014ce41b84 upstream.
tmp_ops.func_hash->filter_hash is annotated __rcu, but
update_ftrace_direct_mod() assigns hash to it directly. Sparse reports an
address-space mismatch.
Use rcu_assign_pointer() for the assignment.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260911142512.19344-1-leon.hwang@linux.dev
Fixes: 50b35c9e50a8 ("ftrace: Use hash argument for tmp_ops in update_ftrace_direct_mod")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202609110704.Q3M5vCDV-lkp@intel.com/
Signed-off-by: Leon Hwang <leon.hwang@linux.dev>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ftrace.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/kernel/trace/ftrace.c b/kernel/trace/ftrace.c
index 53d5db60bfa5..673a54fdf392 100644
--- a/kernel/trace/ftrace.c
+++ b/kernel/trace/ftrace.c
@@ -6675,7 +6675,7 @@ int update_ftrace_direct_mod(struct ftrace_ops *ops, struct ftrace_hash *hash, b
/* Enable the tmp_ops to have the same functions as the hash object. */
ftrace_ops_init(&tmp_ops);
- tmp_ops.func_hash->filter_hash = hash;
+ rcu_assign_pointer(tmp_ops.func_hash->filter_hash, hash);
err = register_ftrace_function_nolock(&tmp_ops);
if (err)
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 468/733] ftrace: fork: Initialize function graph state before copy_exec_state()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (466 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 467/733] ftrace: Use rcu_assign_pointer() for tmp_ops filter hash Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 469/733] tracing: Fix memory corruption from the histogram stacktrace modifier Greg Kroah-Hartman
` (276 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bradley Morgan,
Jérémy Jean, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
commit 08cacffeef8f64f1a222c93467ca84f24a46c953 upstream.
dup_task_struct() copies the parent's task_struct, including ret_stack.
ftrace_graph_init_task() clears the copied function graph state, but it
currently runs after copy_exec_state().
For non-CLONE_VM forks, copy_exec_state() allocates a new task_exec_state.
If that allocation fails, copy_process() reaches bad_fork_free and
free_task() calls ftrace_graph_exit_task(). Since the child still carries
the parent's ret_stack pointer, the unwind frees the parent's active
function graph return stack. The parent subsequently accesses freed memory
from function_graph_enter_regs().
KASAN reports:
[ 22.190920] ==================================================================
[ 22.195899] BUG: KASAN: slab-use-after-free in function_graph_enter_regs+0xa76/0xb90
[ 22.200747] Write of size 8 at addr ff110000054dc0a8 by task repro/1
[ 22.205134]
[ 22.210770] CPU: 0 UID: 0 PID: 1 Comm: repro Not tainted 7.2.0-07732-g9328b3b03bdc-dirty #3 PREEMPT(lazy)
[ 22.212576] Hardware name: QEMU Standard PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/2014
[ 22.213750] Call Trace:
[ 22.215271] <TASK>
[ 22.216242] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.217774] dump_stack_lvl+0x4e/0x70
[ 22.220531] print_report+0x157/0x4b4
[ 22.223202] ? fixup_red_left+0x9/0x30
[ 22.224407] ? complete_report_info+0x83/0x110
[ 22.226679] ? function_graph_enter_regs+0xa76/0xb90
[ 22.228084] kasan_report+0xce/0x100
[ 22.230109] ? function_graph_enter_regs+0xa76/0xb90
[ 22.232860] ? stack_trace_save+0x4/0xd0
[ 22.234156] function_graph_enter_regs+0xa76/0xb90
[ 22.236090] ? kasan_save_stack+0x30/0x50
[ 22.237752] ? __pfx_function_graph_enter_regs+0x10/0x10
[ 22.238694] ? ring_buffer_lock_reserve+0x345/0xf80
[ 22.239628] ? stack_trace_save+0x4/0xd0
[ 22.242121] ? stack_trace_save+0x4/0xd0
[ 22.243588] ftrace_graph_func+0xda/0x160
[ 22.245362] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.246520] 0xffffffffa0000095
[ 22.250528] ? stack_trace_save+0x9/0xd0
[ 22.251757] ? ring_buffer_unlock_commit+0x11d/0x5c0
[ 22.253152] stack_trace_save+0x9/0xd0
[ 22.254264] kasan_save_stack+0x30/0x50
[ 22.273631] kasan_save_track+0x14/0x30
[ 22.276763] kasan_save_free_info+0x3b/0x70
[ 22.278296] __kasan_slab_free+0x43/0x70
[ 22.280157] kmem_cache_free+0xbf/0x3b0
[ 22.282963] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.284001] free_task+0xa2/0x160
[ 22.285699] ? ftrace_stub_direct_tramp+0x10/0x10
[ 22.286752] copy_process+0x2aae/0x7bc0
Initialize the child function graph state immediately after
dup_task_struct(), before the first fallible operation.
Cc: stable@vger.kernel.org
Fixes: 6b1c66c9cca9 ("exec_state: relocate dumpable information")
Reviewed-by: Bradley Morgan <include@grrlz.net>
Link: https://patch.msgid.link/20260822195321.962383-2-Jeremy.Jean@oss.cyber.gouv.fr
Assisted-by: Codex:gpt-5
Signed-off-by: Jérémy Jean <Jeremy.Jean@oss.cyber.gouv.fr>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/fork.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/kernel/fork.c
+++ b/kernel/fork.c
@@ -2114,6 +2114,11 @@ __latent_entropy struct task_struct *cop
p = dup_task_struct(current, node);
if (!p)
goto fork_out;
+ /*
+ * Must run before the first fallible op, so error paths never
+ * free the parent's ret_stack.
+ */
+ ftrace_graph_init_task(p);
retval = copy_exec_state(clone_flags, p);
if (retval)
goto bad_fork_free;
@@ -2140,8 +2145,6 @@ __latent_entropy struct task_struct *cop
*/
p->clear_child_tid = (clone_flags & CLONE_CHILD_CLEARTID) ? args->child_tid : NULL;
- ftrace_graph_init_task(p);
-
rt_mutex_init_task(p);
raw_spin_lock_init(&p->blocked_lock);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 469/733] tracing: Fix memory corruption from the histogram stacktrace modifier
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (467 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 468/733] ftrace: fork: Initialize function graph state before copy_exec_state() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 470/733] tracing: Restore :mod: trailer after parsing in ftrace_set_clr_event() Greg Kroah-Hartman
` (275 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit a5e70ba87ca8ebc79b4e63de302d03b0625fe153 upstream.
parse_field() sets HIST_FIELD_FL_STACKTRACE from the ".stacktrace"
modifier before it looks the field name up, and nothing afterwards
checks that the name resolved to a field which holds a stacktrace.
create_hist_field() picks HIST_FIELD_FN_STACK on the strength of the
field pointer alone, which reads a __data_loc word from the record and
follows its low 16 bits as an offset into the same record.
event_hist_trigger() takes the first word there as an entry count and
copies that many longs into a 31 entry array:
n_entries = *stack;
memcpy(entries, ++stack, n_entries * sizeof(unsigned long));
Neither end of that copy is bounded, and the count is whatever the event
holds at the offset, so any field will do:
# cd /sys/kernel/tracing/events/sched/sched_process_fork
# echo 'hist:keys=parent_pid.stacktrace' > trigger
# (true)
BUG: kernel NULL pointer dereference, address: 0000000000000008
RIP: 0010:rb_insert_color+0x18/0x130
timerqueue_linked_add+0x7e/0xd0
enqueue_hrtimer+0x39/0xb0
__hrtimer_run_queues+0x10f/0x1f0
</IRQ>
RIP: 0010:memcpy+0xc/0x30
event_hist_trigger+0x165/0x690
The timer interrupt landed on the rbtree the copy had already run over.
No debug options are needed for this; KASAN reports the same write as an
out-of-bounds read of 13835058055416381440 bytes.
Documentation/trace/histogram.rst already states the rule, "must be a
long[] type", so enforce it once the name has been resolved. Names which
resolve to no field at all, "hitcount.stacktrace" and the common_*
pseudo-fields, are refused for the same reason: they hold no stacktrace
to read.
Cc: stable@vger.kernel.org
Fixes: cc5fc8bfc961 ("tracing/histogram: Add stacktrace type")
Link: https://patch.msgid.link/20260907155045.692664-2-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -2325,6 +2325,7 @@ parse_field(struct hist_trigger_data *hi
struct ftrace_event_field *field = NULL;
char *field_name, *modifier, *str;
struct trace_array *tr = file->tr;
+ bool stack_modifier = false;
modifier = str = kstrdup(field_str, GFP_KERNEL);
if (!modifier)
@@ -2347,9 +2348,10 @@ parse_field(struct hist_trigger_data *hi
*flags |= HIST_FIELD_FL_EXECNAME;
else if (strcmp(modifier, "syscall") == 0)
*flags |= HIST_FIELD_FL_SYSCALL;
- else if (strcmp(modifier, "stacktrace") == 0)
+ else if (strcmp(modifier, "stacktrace") == 0) {
*flags |= HIST_FIELD_FL_STACKTRACE;
- else if (strcmp(modifier, "log2") == 0)
+ stack_modifier = true;
+ } else if (strcmp(modifier, "log2") == 0)
*flags |= HIST_FIELD_FL_LOG2;
else if (strcmp(modifier, "usecs") == 0)
*flags |= HIST_FIELD_FL_TIMESTAMP_USECS;
@@ -2420,6 +2422,12 @@ parse_field(struct hist_trigger_data *hi
}
}
}
+
+ if (stack_modifier &&
+ (!field || field->filter_type != FILTER_STACKTRACE)) {
+ hist_err(tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(field_str));
+ field = ERR_PTR(-EINVAL);
+ }
out:
kfree(str);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 470/733] tracing: Restore :mod: trailer after parsing in ftrace_set_clr_event()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (468 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 469/733] tracing: Fix memory corruption from the histogram stacktrace modifier Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:12 ` [PATCH 7.2 471/733] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
` (274 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Thomas Weißschuh,
Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
commit 911002e99e15f640f1fdc6d276206beaef59e790 upstream.
While ftrace_set_clr_event() modifies its input buffer during parsing,
before returning to the caller the buffer is supposed to be restored
to its original state.
This works correctly for the colon between the subsystem and event
but not the colon at the beginning of :mod:.
Restore the colon, so the :mod: trailer is not stripped after
ftrace_set_clr_event().
Cc: stable@vger.kernel.org
Fixes: 4c86bc531e60 ("tracing: Add :mod: command to enabled module events")
Link: https://patch.msgid.link/20260908-tracing-cli-event-filter-v2-1-05396a3fb663@linutronix.de
Signed-off-by: Thomas Weißschuh <thomas.weissschuh@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events.c | 2 ++
1 file changed, 2 insertions(+)
--- a/kernel/trace/trace_events.c
+++ b/kernel/trace/trace_events.c
@@ -1462,6 +1462,8 @@ int ftrace_set_clr_event(struct trace_ar
/* Put back the colon to allow this to be called again */
if (buf)
*(buf - 1) = ':';
+ if (mod)
+ *(mod - 5) = ':';
return ret;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 471/733] tracing: Set the trace clock before registering the histogram trigger
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (469 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 470/733] tracing: Restore :mod: trailer after parsing in ftrace_set_clr_event() Greg Kroah-Hartman
@ 2026-09-17 15:12 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 472/733] tracing: Fix memory corruption from a "STACKTRACE" histogram key Greg Kroah-Hartman
` (273 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:12 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 6ede78d0563a2a3ae3e46f9c07cedb5d79645429 upstream.
hist_register_trigger() puts the trigger on the global named_triggers
list in cmd_ops->init(), and only then sets the trace clock:
if (data->cmd_ops->init) {
ret = data->cmd_ops->init(data);
if (ret < 0)
goto out;
}
if (hist_data->enable_timestamps) {
ret = tracing_set_clock(file->tr, hist_data->attrs->clock);
if (ret) {
hist_err(tr, HIST_ERR_SET_CLOCK_FAIL, errpos(clock));
goto out;
}
The clock string is not checked anywhere before that call, so a named
trigger using common_timestamp with an unknown clock fails after it has
already become findable. event_hist_trigger_parse() then frees it
without taking it off the list, and the next lookup by name reads the
freed object:
~# cd /sys/kernel/tracing/events/sched/sched_switch
~# echo 'hist:name=foo:keys=common_pid:ts=common_timestamp:clock=bogus' > trigger
bash: echo: write error: Invalid argument
~# echo 'hist:name=foo:keys=common_pid' > trigger
BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
Read of size 8 at addr ffff88800915d760 by task init/1
find_named_trigger+0xac/0xc0
hist_register_trigger+0xc1/0x900
event_hist_trigger_parse+0x3146/0x6af0
event_trigger_write+0xce/0x160
Freed by task 63:
kfree+0x154/0x420
trigger_kthread_fn+0xfd/0x160
Set the clock before the trigger is registered, so that nothing which
can fail runs after it is published, the way commit 6f86bdeab633
("tracing: Fix bad hist from corrupting named_triggers list") moved the
registration below the rest of the setup.
tracing_set_filter_buffering() is reference counted, so the init failure
path has to drop the reference that the clock block now takes first.
Cc: stable@vger.kernel.org
Fixes: a4072fe85ba3 ("tracing: Add a clock attribute for hist triggers")
Link: https://patch.msgid.link/20260907091415.554535-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6631,12 +6631,6 @@ static int hist_register_trigger(char *g
data->cmd_ops = cmd_ops;
}
- if (data->cmd_ops->init) {
- ret = data->cmd_ops->init(data);
- if (ret < 0)
- goto out;
- }
-
if (hist_data->enable_timestamps) {
char *clock = hist_data->attrs->clock;
@@ -6649,6 +6643,15 @@ static int hist_register_trigger(char *g
tracing_set_filter_buffering(file->tr, true);
}
+ if (data->cmd_ops->init) {
+ ret = data->cmd_ops->init(data);
+ if (ret < 0) {
+ if (hist_data->enable_timestamps)
+ tracing_set_filter_buffering(file->tr, false);
+ goto out;
+ }
+ }
+
if (named_data) {
remove_hist_vars(hist_data);
destroy_hist_data(hist_data);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 472/733] tracing: Fix memory corruption from a "STACKTRACE" histogram key
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (470 preceding siblings ...)
2026-09-17 15:12 ` [PATCH 7.2 471/733] tracing: Set the trace clock before registering the histogram trigger Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 473/733] tracing: Take trace_array reference when opening a tracer options file Greg Kroah-Hartman
` (272 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 7f711e62355bb3123a2ca2f97a2facbfebc678c6 upstream.
"cpu", "CPU", "stacktrace" and "STACKTRACE" are generic fields, defined
with an offset and a size of zero so that the filter code can match them
by name. parse_field() maps them onto their common_* equivalents for
backward compatibility, but unlike the common_* names it hands the
placeholder back to the caller instead of NULL.
create_hist_field() takes a non-NULL field as a promise that the record
carries a stacktrace and picks HIST_FIELD_FN_STACK, so the __data_loc
word is read from offset 0, that is from common_type, and its low 16
bits are followed as an offset into the record. What is found there
becomes the length of an unbounded memcpy. Pick an event whose id is
small enough that the offset stays inside its own record and the length
is a kernel text address:
# cd /sys/kernel/tracing
# echo 'hist:keys=STACKTRACE' > events/ftrace/print/trigger
# echo hello > trace_marker
Oops: general protection fault, probably for non-canonical address
RIP: 0010:rb_next+0x23/0x60
</IRQ>
RIP: 0010:memcpy+0xc/0x30
event_hist_trigger+0x2e7/0x12c0
Kernel panic - not syncing: Fatal exception in interrupt
Leave the field NULL, which is what the comment above the branch says
the code does and what common_stacktrace already does. FILTER_CPU and
FILTER_COMM are left alone, their create_hist_field() branches never
look at the field.
Cc: stable@vger.kernel.org
Fixes: 4b512860bdbd ("tracing: Rename stacktrace field to common_stacktrace")
Link: https://patch.msgid.link/20260907155045.692664-3-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 1 +
1 file changed, 1 insertion(+)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -2412,6 +2412,7 @@ parse_field(struct hist_trigger_data *hi
*flags |= HIST_FIELD_FL_CPU;
} else if (field && field->filter_type == FILTER_STACKTRACE) {
*flags |= HIST_FIELD_FL_STACKTRACE;
+ field = NULL;
} else if (field && field->filter_type == FILTER_COMM) {
*flags |= HIST_FIELD_FL_COMM | HIST_FIELD_FL_STRING;
} else {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 473/733] tracing: Take trace_array reference when opening a tracer options file
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (471 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 472/733] tracing: Fix memory corruption from a "STACKTRACE" histogram key Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 474/733] tracing: Dont dereference trace_event_file in deferred trigger free Greg Kroah-Hartman
` (271 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, sashiko-bot, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <rostedt@goodmis.org>
commit ed0aff60f83a9bdc2f6556376ac79c96b3ce7e80 upstream.
When a tracer option file is opened, it is passed a descriptor that points
to an element on the trace_array's topts array. This element has
information to find the trace array and other information. It uses this
element to take a reference of the trace_array so that the trace_array
does not get removed while this file is opened.
Unfortunately, there's a race condition where the element itself could be
freed by the removal of the instance the trace_array represents causing a
use-after-free as this element that is used to find the trace_array to
increment its reference counter is also freed when the instance is
removed.
To solve this, add a trace_array_tracer_options_get() helper function that
will take the address of the element that is passed to the open function
by the inode->i_private pointer and search all the trace_arrays under a
lock to find the one that the element's address is in the range of the
trace_arrays topts array elements. When a match happens, that trace_array's
reference would be increased.
Note, there's a race where if an admin was deleting and creating trace
instances at the same time and the memory of the old trace_array's array
matched the memory of the new trace_array that it could in theory open the
option from the wrong trace array. But we do not care because it would be
stupid to perform that kind of action. As long as the only thing that can
happen is that the option from the wrong trace array is used and doesn't
crash the kernel it will only make the user confused. But if they are
doing something stupid like this, they are already confused, so no harm
done.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260910221209.62dad8d3@robin
Fixes: 7e2cfbd2d3c86 ("tracing: Have option files inc the trace array ref count")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/linux-trace-kernel/20260902121918.5a9e9d1b@gandalf.local.home/
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace.c | 46 +++++++++++++++++++++++++++++++++++++++++++++-
kernel/trace/trace.h | 1 +
2 files changed, 46 insertions(+), 1 deletion(-)
--- a/kernel/trace/trace.c
+++ b/kernel/trace/trace.c
@@ -7715,12 +7715,55 @@ trace_options_write(struct file *filp, c
return cnt;
}
+static bool tr_option_match(struct trace_array *tr, void *topt)
+{
+ for (int i = 0; i < tr->nr_topts; i++) {
+ struct trace_options *tr_topts = &tr->topts[i];
+
+ if (topt >= (void *)&tr_topts->topts[0] &&
+ topt < (void *)&tr_topts->topts[tr_topts->nr_topts])
+ return true;
+ }
+ return false;
+}
+
+/*
+ * The topt is the address of a trace_array->topts[] element that holds the
+ * the tracer options descriptor. But since the trace_array reference has not
+ * been taken yet, it cannot be dereferenced as it could have been freed by
+ * a rmdir of the instance the trace_array represents.
+ *
+ * Search the list of trace_arrays and compare the topt to the address of
+ * the entire trace_array topts array for each trace_array in the list.
+ * If one is matched, then take the reference and return it. If not, the
+ * trace_array no longer exits.
+ */
+static int trace_array_tracer_options_get(void *topt)
+{
+ struct trace_array *tr;
+ int ret;
+
+ ret = security_locked_down(LOCKDOWN_TRACEFS);
+ if (ret)
+ return ret;
+
+ if (tracing_disabled)
+ return -ENODEV;
+
+ guard(mutex)(&trace_types_lock);
+ list_for_each_entry(tr, &ftrace_trace_arrays, list) {
+ if (tr_option_match(tr, topt))
+ return __trace_array_get(tr);
+ }
+ return -ENODEV;
+}
+
static int tracing_open_options(struct inode *inode, struct file *filp)
{
struct trace_option_dentry *topt = inode->i_private;
int ret;
- ret = tracing_check_open_get_tr(topt->tr);
+ ret = trace_array_tracer_options_get(topt);
if (ret)
return ret;
@@ -7982,6 +8025,7 @@ create_trace_option_files(struct trace_a
tr->topts = tr_topts;
tr->topts[tr->nr_topts].tracer = tracer;
tr->topts[tr->nr_topts].topts = topts;
+ tr->topts[tr->nr_topts].nr_topts = cnt;
tr->nr_topts++;
for (cnt = 0; opts[cnt].name; cnt++) {
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -227,6 +227,7 @@ struct array_buffer {
struct trace_options {
struct tracer *tracer;
struct trace_option_dentry *topts;
+ int nr_topts;
};
struct trace_pid_list *trace_pid_list_alloc(void);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 474/733] tracing: Dont dereference trace_event_file in deferred trigger free
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (472 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 473/733] tracing: Take trace_array reference when opening a tracer options file Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 475/733] rust: num: seal Integer Greg Kroah-Hartman
` (270 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexander Gordeev,
Ali Ahmet Memiş, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memiş <aliamemis@disroot.org>
commit bcfe2816e6ec46c3f4c58aa4264476665ddb3f69 upstream.
The enable_event trigger defers trace_event_put_ref() to the
trigger free kthread, but the trace_event_file can already be freed
when the instance is removed.
Keep the trace_event_call directly in enable_trigger_data so the
deferred free does not access the freed trace_event_file.
Cc: stable@vger.kernel.org
Fixes: e091351b3881 ("tracing: Delay module ref count for "enable_event" trigger")
Reported-by: Alexander Gordeev <agordeev@linux.ibm.com>
Closes: https://lore.kernel.org/all/20260828134340.2501683A24-agordeev@linux.ibm.com/
Link: https://patch.msgid.link/20260911155650.354844-1-aliamemis@disroot.org
Signed-off-by: Ali Ahmet Memiş <aliamemis@disroot.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace.h | 1 +
kernel/trace/trace_events_trigger.c | 4 +++-
2 files changed, 4 insertions(+), 1 deletion(-)
--- a/kernel/trace/trace.h
+++ b/kernel/trace/trace.h
@@ -1953,6 +1953,7 @@ struct event_trigger_data {
struct enable_trigger_data {
struct trace_event_file *file;
+ struct trace_event_call *call;
bool enable;
bool hist;
};
--- a/kernel/trace/trace_events_trigger.c
+++ b/kernel/trace/trace_events_trigger.c
@@ -1728,7 +1728,8 @@ static void enable_trigger_private_data_
{
struct enable_trigger_data *enable_data = data->private_data;
- trace_event_put_ref(enable_data->file->event_call);
+ /* The file may already be freed here, only the call is kept alive */
+ trace_event_put_ref(enable_data->call);
kfree(enable_data);
}
@@ -1801,6 +1802,7 @@ int event_enable_trigger_parse(struct ev
enable_data->hist = hist;
enable_data->enable = enable;
enable_data->file = event_enable_file;
+ enable_data->call = event_enable_file->event_call;
trigger_data = trigger_data_alloc(cmd_ops, cmd, param, enable_data);
if (!trigger_data) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 475/733] rust: num: seal Integer
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (473 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 474/733] tracing: Dont dereference trace_event_file in deferred trigger free Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 476/733] rust: pin-init: use irrefutable pattern for `stack_pin_init` Greg Kroah-Hartman
` (269 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Miguel Ojeda, Younes Akhouayri,
Alexandre Courbot
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Younes Akhouayri <git@younes.io>
commit c6709d5e14072d0e3d02f291daee46a199e5dad3 upstream.
Bounded relies on Integer implementations to describe primitive integer
semantics correctly. In particular, it uses Integer::BITS and Signedness
to justify unchecked operations.
Integer is currently safe and externally implementable, so an
implementation can violate those assumptions and make safe Bounded
operations reach undefined behavior.
For example, an Integer implementation for a u8 wrapper can report
BITS = 16. Safe code can then cast a Bounded<u16, 9> containing 256
to that wrapper. Its TryFrom<u16> implementation returns Err, and
Bounded::cast() calls unwrap_unchecked() on it, causing undefined
behavior.
Seal Integer so only the primitive implementations provided by the
kernel crate can satisfy it.
Fixes: 01e345e82ec3 ("rust: num: add Bounded integer wrapping type")
Reported-by: Miguel Ojeda <ojeda@kernel.org>
Closes: https://lore.kernel.org/rust-for-linux/CANiq72mOfR33s4y+Ueivd5NrC5yre+Pcp57ZOBz0msw9A4AP1Q@mail.gmail.com/
Cc: stable@vger.kernel.org
Suggested-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Younes Akhouayri <git@younes.io>
Acked-by: Alexandre Courbot <acourbot@nvidia.com>
Link: https://patch.msgid.link/20260905-feature-rust-num-seal-integer-v2-1-f1311ffbe6e7@younes.io
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
rust/kernel/num.rs | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/rust/kernel/num.rs
+++ b/rust/kernel/num.rs
@@ -13,9 +13,14 @@ pub enum Unsigned {}
/// Designates signed primitive types.
pub enum Signed {}
+mod private {
+ pub trait Sealed {}
+}
+
/// Describes core properties of integer types.
pub trait Integer:
- Sized
+ private::Sealed
+ + Sized
+ Copy
+ Clone
+ PartialEq
@@ -54,6 +59,8 @@ pub trait Integer:
macro_rules! impl_integer {
($($type:ty: $signedness:ty), *) => {
$(
+ impl private::Sealed for $type {}
+
impl Integer for $type {
type Signedness = $signedness;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 476/733] rust: pin-init: use irrefutable pattern for `stack_pin_init`
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (474 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 475/733] rust: num: seal Integer Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 477/733] rust: allow `clippy::as_underscore` in the generated bindings Greg Kroah-Hartman
` (268 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mohamad Alsadhan, Gary Guo,
Miguel Ojeda
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
commit b6b9e6d4abe87b16ab55990b887c6fad8e7a01af upstream.
In Rust 1.100.0, `Infallible` will become an alias of `!`. The let
binding in `stack_pin_init` will thus become unreachable and produce
an "unreachable expression" warning for the subsequent match, and thus
will fail a `-Dwarnings` build. For this macro, all we need to know is
that the error type is uninhabited, so replace this with an irrefutable
pattern instead.
[ The error looks like (dummy reproducer):
error: unreachable expression
--> rust/kernel/sync.rs:177:5
|
177 | pin_init::stack_pin_init!(let num = 42u32);
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
| |
| unreachable expression
| any code following this expression is unreachable
|
= note: `-D unreachable-code` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unreachable_code)]`
= note: this error originates in the macro `pin_init::stack_pin_init` (in Nightly builds, run with -Z macro-backtrace for more info)
- Miguel ]
Reported-by: Mohamad Alsadhan <mo@sdhn.cc>
Closes: https://github.com/Rust-for-Linux/pin-init/pull/171
Signed-off-by: Gary Guo <gary@garyguo.net>
Cc: stable@vger.kernel.org # Needed in 7.1.y and later (for 6.12.y and 6.18.y a custom one is needed).
Link: https://patch.msgid.link/20260828155033.2101924-1-gary@kernel.org
[ Reworded for typos. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
rust/pin-init/src/lib.rs | 8 +-------
1 file changed, 1 insertion(+), 7 deletions(-)
--- a/rust/pin-init/src/lib.rs
+++ b/rust/pin-init/src/lib.rs
@@ -493,13 +493,7 @@ macro_rules! stack_pin_init {
(let $var:ident $(: $t:ty)? = $val:expr) => {
let val = $val;
let mut $var = ::core::pin::pin!($crate::__internal::StackInit$(::<$t>)?::uninit());
- let mut $var = match $crate::__internal::StackInit::init($var, val) {
- Ok(res) => res,
- Err(x) => {
- let x: ::core::convert::Infallible = x;
- match x {}
- }
- };
+ let Ok(mut $var) = $crate::__internal::StackInit::init($var, val);
};
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 477/733] rust: allow `clippy::as_underscore` in the generated bindings
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (475 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 476/733] rust: pin-init: use irrefutable pattern for `stack_pin_init` Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 478/733] rust: allow `unknown_lints` in generated bindings for Rust < 1.88 Greg Kroah-Hartman
` (267 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, John Hubbard, Miguel Ojeda
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: John Hubbard <jhubbard@nvidia.com>
commit 2ac74c6db40adaa29c50cbb281ae9a6f63de18e1 upstream.
A CLIPPY=1 build emitted about 15000 `as _` conversion warnings, all of
them in bindgen's generated output and none in hand-written code.
[ The lint messages look like:
error: using `as _` conversion
--> rust/bindings/bindings_generated.rs:18947:9
|
18947 | self._bitfield_1.get_const::<0usize, 16u8>() as u32 as _
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^-
| |
| help: consider giving the type explicitly: `u32`
|
= help: for further information visit https://rust-lang.github.io/rust-clippy/rust-1.98.0/index.html#as_underscore
= note: `-D clippy::as-underscore` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(clippy::as_underscore)]`
- Miguel ]
bindgen 0.73 returns each bitfield read through a trailing `as _`, and
0.72 returns it through a transmute, which the lint ignores. The
bindings and uapi crates allow `clippy::all` over the generated code.
That group does not cover `clippy::as_underscore`, a restriction lint.
Allow `clippy::as_underscore` by name in the bindings and uapi crates.
Assisted-by: LLM
Signed-off-by: John Hubbard <jhubbard@nvidia.com>
Link: https://patch.msgid.link/20260906215822.1201022-1-jhubbard@nvidia.com
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
[ Removed CI sentence. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
rust/bindings/lib.rs | 1 +
rust/uapi/lib.rs | 1 +
2 files changed, 2 insertions(+)
--- a/rust/bindings/lib.rs
+++ b/rust/bindings/lib.rs
@@ -22,6 +22,7 @@
#![feature(cfi_encoding)]
#[allow(dead_code)]
+#[allow(clippy::as_underscore)]
#[allow(clippy::cast_lossless)]
#[allow(clippy::ptr_as_ptr)]
#[allow(clippy::ref_as_ptr)]
--- a/rust/uapi/lib.rs
+++ b/rust/uapi/lib.rs
@@ -10,6 +10,7 @@
#![no_std]
#![allow(
clippy::all,
+ clippy::as_underscore,
clippy::cast_lossless,
clippy::ptr_as_ptr,
clippy::ref_as_ptr,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 478/733] rust: allow `unknown_lints` in generated bindings for Rust < 1.88
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (476 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 477/733] rust: allow `clippy::as_underscore` in the generated bindings Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 479/733] drm/panic: clean new `clippy::needless_range_loop` lint for Rust 1.100.0 Greg Kroah-Hartman
` (266 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Emilio Cobos Álvarez,
Miguel Ojeda
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <ojeda@kernel.org>
commit f4c3e38111fd84c2c7ae5785755f4a4d476e1cba upstream.
Starting with bindgen 0.73.2 [1], `#[allow(unnecessary_transmutes)]`
are used, even when `--rust-target 1.85` is passed.
However, the lint was introduced in Rust 1.88.0. Thus building with
older Rust versions warns like:
error: unknown lint: `unnecessary_transmutes`
--> rust/uapi/uapi_generated.rs:26294:13
|
26294 | #[allow(unnecessary_transmutes)]
| ^^^^^^^^^^^^^^^^^^^^^^
|
= note: `-D unknown-lints` implied by `-D warnings`
= help: to override `-D warnings` add `#[allow(unknown_lints)]`
Thus allow `unknown_lints` in the generated bindings -- only when building
with older Rust versions.
I have asked upstream if this is intentional [1], i.e. if we are supposed
to always allow unknown lints in case `bindgen` uses such attributes,
or whether it is an oversight.
[ Emilio said it wasn't intentional -- we will work around it for now
on the kernel side. - Miguel ]
Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs).
Cc: Emilio Cobos Álvarez <emilio@crisal.io>
Link: https://github.com/rust-lang/rust-bindgen/pull/3455#issuecomment-5588526559 [1]
Assisted-by: LLM
Link: https://patch.msgid.link/20260908170539.345207-1-ojeda@kernel.org
[ Removed the `cfg` for `allow(unnecessary_transmutes)` as suggested by
Gary. - Miguel ]
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
rust/bindings/lib.rs | 3 ++-
rust/uapi/lib.rs | 3 ++-
2 files changed, 4 insertions(+), 2 deletions(-)
--- a/rust/bindings/lib.rs
+++ b/rust/bindings/lib.rs
@@ -27,7 +27,8 @@
#[allow(clippy::ptr_as_ptr)]
#[allow(clippy::ref_as_ptr)]
#[allow(clippy::undocumented_unsafe_blocks)]
-#[cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))]
+#[cfg_attr(not(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES), allow(unknown_lints))]
+#[allow(unnecessary_transmutes)]
#[cfg_attr(
CONFIG_RUSTC_HAS_SUSPICIOUS_RUNTIME_SYMBOL_DEFINITIONS,
allow(suspicious_runtime_symbol_definitions)
--- a/rust/uapi/lib.rs
+++ b/rust/uapi/lib.rs
@@ -24,7 +24,8 @@
unreachable_pub,
unsafe_op_in_unsafe_fn
)]
-#![cfg_attr(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES, allow(unnecessary_transmutes))]
+#![cfg_attr(not(CONFIG_RUSTC_HAS_UNNECESSARY_TRANSMUTES), allow(unknown_lints))]
+#![allow(unnecessary_transmutes)]
#![cfg_attr(
CONFIG_RUSTC_HAS_SUSPICIOUS_RUNTIME_SYMBOL_DEFINITIONS,
allow(suspicious_runtime_symbol_definitions)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 479/733] drm/panic: clean new `clippy::needless_range_loop` lint for Rust 1.100.0
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (477 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 478/733] rust: allow `unknown_lints` in generated bindings for Rust < 1.88 Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 480/733] ALSA: ctxfi: Fix CA20K2 S/PDIF passthrough Greg Kroah-Hartman
` (265 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Alexandre Courbot, Jocelyn Falempe,
Miguel Ojeda
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <ojeda@kernel.org>
commit 97f8cb91a8c5658fe2ae6f5c2ff6e95474a5eb2f upstream.
Starting with Rust 1.100.0 (expected 2026-11-12), Clippy warns:
warning: the loop variable `i` is only used to index `self.decimals`
--> drivers/gpu/drm/drm_panic_qr.rs:410:18
|
410 | for i in 0..len {
| ^^^^^^
|
note: for this index operation
--> drivers/gpu/drm/drm_panic_qr.rs:411:13
|
411 | self.decimals[i] = (chunk % 10) as u8;
| ^^^^^^^^^^^^^^^^
= help: for further information visit https://rust-lang.github.io/rust-clippy/main/index.html#needless_range_loop
= note: `-W clippy::needless-range-loop` implied by `-W clippy::all`
= help: to override `-W clippy::all` add `#[allow(clippy::needless_range_loop)]`
help: consider using an iterator
|
410 - for i in 0..len {
410 + for <item> in self.decimals.iter_mut().take(len) {
|
The lint did not trigger here before because it could not handle arrays
behind a field access such as `self.decimals` -- Clippy was improved to
catch those cases [1][2].
Thus clean the warning by iterating over a slice rather than using
`take()` so that an out-of-range `len` still triggers the same bounds
check as the indexed loop.
Cc: stable@vger.kernel.org # Needed in 6.18.y and later.
Link: https://github.com/rust-lang/rust-clippy/issues/16631 [1]
Link: https://github.com/rust-lang/rust-clippy/pull/16634 [2]
Assisted-by: LLM
Reviewed-by: Alexandre Courbot <acourbot@nvidia.com>
Reviewed-by: Jocelyn Falempe <jfalempe@redhat.com>
Link: https://patch.msgid.link/20260826145642.43807-1-ojeda@kernel.org
Signed-off-by: Miguel Ojeda <ojeda@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/drm_panic_qr.rs | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/drm_panic_qr.rs
+++ b/drivers/gpu/drm/drm_panic_qr.rs
@@ -407,8 +407,8 @@ impl DecFifo {
for i in (0..self.len).rev() {
self.decimals[i + len] = self.decimals[i];
}
- for i in 0..len {
- self.decimals[i] = (chunk % 10) as u8;
+ for decimal in &mut self.decimals[..len] {
+ *decimal = (chunk % 10) as u8;
chunk = div10(chunk);
}
self.len += len;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 480/733] ALSA: ctxfi: Fix CA20K2 S/PDIF passthrough
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (478 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 479/733] drm/panic: clean new `clippy::needless_range_loop` lint for Rust 1.100.0 Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 481/733] ALSA: us122l: Prevent write upgrades for read mappings Greg Kroah-Hartman
` (264 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Roman Prucha, Takashi Iwai
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Roman Prucha <zorgan.roman@gmail.com>
commit b26a7a80e6bbf8dd17dacb127d12435d79375cf2 upstream.
dao_rsc_init() encodes the DAIO configuration as
conf = (desc->msr & 0x7) | (desc->passthru << 3);
S/PDIF passthrough uses msr=1 and passthru=1, resulting in
conf=9.
daio_mgr_dao_init() masks conf with 0xf, but handles only values
1, 2, 4 and 8 when programming ATXCTL_NUC. As a result, conf=9
falls through to the default case and leaves NUC at its previous
setting.
On a Creative X-Fi Titanium HD SB1270 (CA20K2), this breaks AC3
IEC61937 passthrough when snd_ctxfi runs with
reference_rate=48000,multiple=2. The receiver detects a non-audio
stream but cannot decode the AC3 payload.
With the unmodified driver, multiple=1 makes the same stream work.
Handle conf=9 through the same NUC=0 path as conf=1.
The change was runtime tested on the SB1270 with multiple=2 using
IEC958 stereo PCM, pre-encoded AC3 IEC61937 passthrough and ALSA
A52 live 5.1 encoding.
Fixes: 26a9630c72eb ("ALSA: ctxfi: cthw20k2: fix mask on conf to allow 4 bits")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Roman Prucha <zorgan.roman@gmail.com>
Link: https://patch.msgid.link/20260903-ctxfi-spdif-conf9-fix-v1-1-5e4e3e1f801c@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/pci/ctxfi/cthw20k2.c | 1 +
1 file changed, 1 insertion(+)
--- a/sound/pci/ctxfi/cthw20k2.c
+++ b/sound/pci/ctxfi/cthw20k2.c
@@ -994,6 +994,7 @@ static int daio_mgr_dao_init(struct hw *
/* S/PDIF output */
switch ((conf & 0xf)) {
case 1:
+ case 9:
set_field(&ctl->txctl[idx], ATXCTL_NUC, 0);
break;
case 2:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 481/733] ALSA: us122l: Prevent write upgrades for read mappings
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (479 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 480/733] ALSA: ctxfi: Fix CA20K2 S/PDIF passthrough Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 482/733] ALSA: usbusx2y: fix in04_last array size mismatch with in04_buf Greg Kroah-Hartman
` (263 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kazuki Hanai, Takashi Iwai
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kazuki Hanai <hnkz.64@gmail.com>
commit 71c610aeb1770302ac9c9e0b9a4ecd37f1311928 upstream.
The hwdep mmap callback rejects read-buffer mappings that are initially
writable, but leaves VM_MAYWRITE set on mappings created with PROT_READ.
A process that can open the hwdep node O_RDWR can later use mprotect() to
make the mapping writable.
The read allocation begins with struct usb_stream. Its read_size member is
used by the fault handler to decide which pages belong to the read buffer.
The read VMA intentionally remains expandable because pcm_usb_stream uses
mremap() after reading that size. Changing read_size first can therefore
map and access pages beyond the allocation. The same member is also
consumed by usb_stream_free(), where changing it can make
free_pages_exact() release pages outside the allocation.
Clear VM_MAYWRITE for read-buffer mappings after rejecting an initially
writable VMA. This keeps the separate output-buffer mapping writable while
preventing later permission upgrades.
Fixes: 030a07e44129 ("ALSA: Add USB US122L driver")
Cc: stable@vger.kernel.org
Signed-off-by: Kazuki Hanai <hnkz.64@gmail.com>
Link: https://patch.msgid.link/20260908110053.2950767-1-hnkz.64@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/usx2y/us122l.c | 7 +++++--
1 file changed, 5 insertions(+), 2 deletions(-)
--- a/sound/usb/usx2y/us122l.c
+++ b/sound/usb/usx2y/us122l.c
@@ -180,8 +180,11 @@ static int usb_stream_hwdep_mmap(struct
guard(mutex)(&us122l->mutex);
s = us122l->sk.s;
read = offset < s->read_size;
- if (read && area->vm_flags & VM_WRITE)
- return -EPERM;
+ if (read) {
+ if (area->vm_flags & VM_WRITE)
+ return -EPERM;
+ vm_flags_clear(area, VM_MAYWRITE);
+ }
/* if userspace tries to mmap beyond end of our buffer, fail */
if (size > PAGE_ALIGN(read ? s->read_size : s->write_size)) {
dev_warn(hw->card->dev, "%s: size %lu > %u\n", __func__,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 482/733] ALSA: usbusx2y: fix in04_last array size mismatch with in04_buf
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (480 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 481/733] ALSA: us122l: Prevent write upgrades for read mappings Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 483/733] ALSA: usbusx2y: validate URB actual_length in interrupt callback Greg Kroah-Hartman
` (262 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tristan Madani, Takashi Iwai
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <tristan@talencesecurity.com>
commit 861111a14740e12c36d363e9830f8daa734279c9 upstream.
The in04_last array in struct usx2ydev is declared as char[24], but
in04_buf is allocated as sizeof(struct us428_ctls) which is 21 bytes.
In i_usx2y_in04_int(), when ctl_snapshot_last == -2 (initialization
path):
memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
This copies 24 bytes from a 21-byte slab allocation, reading 3 bytes
past the end of the source object.
Introduce a USX2Y_IN04_SIZE constant defined as sizeof(struct
us428_ctls) and use it consistently for the in04_last array, the
in04_buf allocation, the URB transfer length, and the comparison loop,
replacing the bare 24 and 21 literals throughout.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://patch.msgid.link/20260904205826.4071119-1-tristmd@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/usx2y/usbusx2y.c | 6 +++---
sound/usb/usx2y/usbusx2y.h | 4 +++-
2 files changed, 6 insertions(+), 4 deletions(-)
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -196,7 +196,7 @@ static void i_usx2y_in04_int(struct urb
memcpy(usx2y->in04_last, usx2y->in04_buf, sizeof(usx2y->in04_last));
us428ctls->ctl_snapshot_last = -1;
} else {
- for (i = 0; i < 21; i++) {
+ for (i = 0; i < USX2Y_IN04_SIZE; i++) {
if (usx2y->in04_last[i] != ((char *)usx2y->in04_buf)[i]) {
if (diff < 0)
diff = i;
@@ -305,7 +305,7 @@ int usx2y_in04_init(struct usx2ydev *usx
goto error;
}
- usx2y->in04_buf = kmalloc(21, GFP_KERNEL);
+ usx2y->in04_buf = kmalloc(USX2Y_IN04_SIZE, GFP_KERNEL);
if (!usx2y->in04_buf) {
err = -ENOMEM;
goto error;
@@ -313,7 +313,7 @@ int usx2y_in04_init(struct usx2ydev *usx
init_waitqueue_head(&usx2y->in04_wait_queue);
usb_fill_int_urb(usx2y->in04_urb, usx2y->dev, usb_rcvintpipe(usx2y->dev, 0x4),
- usx2y->in04_buf, 21,
+ usx2y->in04_buf, USX2Y_IN04_SIZE,
i_usx2y_in04_int, usx2y,
10);
if (usb_urb_ep_type_check(usx2y->in04_urb)) {
--- a/sound/usb/usx2y/usbusx2y.h
+++ b/sound/usb/usx2y/usbusx2y.h
@@ -5,6 +5,8 @@
#include "../midi.h"
#include "usbus428ctldefs.h"
+#define USX2Y_IN04_SIZE sizeof(struct us428_ctls)
+
#define NRURBS 2
/* Default value used for nr of packs per urb.
@@ -55,7 +57,7 @@ struct usx2ydev {
int stride;
struct urb *in04_urb;
void *in04_buf;
- char in04_last[24];
+ char in04_last[USX2Y_IN04_SIZE];
unsigned int in04_int_calls;
struct snd_usx2y_urb_seq *us04;
wait_queue_head_t in04_wait_queue;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 483/733] ALSA: usbusx2y: validate URB actual_length in interrupt callback
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (481 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 482/733] ALSA: usbusx2y: fix in04_last array size mismatch with in04_buf Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 484/733] Revert "riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set" Greg Kroah-Hartman
` (261 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tristan Madani, Takashi Iwai
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tristan Madani <tristan@talencesecurity.com>
commit 8f5ef203abda9dd36b2af473c7b737d544f807bd upstream.
i_usx2y_in04_int() processes the interrupt URB data without checking
urb->actual_length. A short transfer from a malfunctioning device
would cause the handler to process uninitialized heap data from the
kmalloc-allocated in04_buf, which is then copied to the mmap-accessible
ctl_snapshot[] array.
Fix by using kzalloc() for in04_buf to zero-initialize the buffer,
and adding an actual_length check to skip processing on short
transfers while still resubmitting the URB.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Tristan Madani <tristan@talencesecurity.com>
Link: https://patch.msgid.link/20260904205826.4071119-2-tristmd@gmail.com
Signed-off-by: Takashi Iwai <tiwai@suse.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/usb/usx2y/usbusx2y.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/sound/usb/usx2y/usbusx2y.c
+++ b/sound/usb/usx2y/usbusx2y.c
@@ -189,6 +189,9 @@ static void i_usx2y_in04_int(struct urb
return;
}
+ if (urb->actual_length < USX2Y_IN04_SIZE)
+ goto resubmit;
+
if (us428ctls) {
diff = -1;
if (us428ctls->ctl_snapshot_last == -2) {
@@ -253,6 +256,7 @@ static void i_usx2y_in04_int(struct urb
if (err)
dev_err(&urb->dev->dev, "in04_int() usb_submit_urb err=%i\n", err);
+resubmit:
urb->dev = usx2y->dev;
usb_submit_urb(urb, GFP_ATOMIC);
}
@@ -305,7 +309,7 @@ int usx2y_in04_init(struct usx2ydev *usx
goto error;
}
- usx2y->in04_buf = kmalloc(USX2Y_IN04_SIZE, GFP_KERNEL);
+ usx2y->in04_buf = kzalloc(USX2Y_IN04_SIZE, GFP_KERNEL);
if (!usx2y->in04_buf) {
err = -ENOMEM;
goto error;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 484/733] Revert "riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set"
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (482 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 483/733] ALSA: usbusx2y: validate URB actual_length in interrupt callback Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 485/733] riscv: hwprobe: initialize pair->value in hwprobe_one_pair() Greg Kroah-Hartman
` (260 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Samuel Holland, Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samuel Holland <samuel.holland@sifive.com>
commit 2d2184ac90365a4af3274e23c98d469f09f91749 upstream.
This reverts commit 3033b2b1e3949274f33a140e2a97571b5a307298.
The reverted patch is userspace-visible behavior change, not a bug fix.
The two variables here (pmm and pmlen) control two independent features:
pmm is the _hardware_ pointer masking mode that applies while executing
in userspace. pmlen is the shift amount that the _kernel_ uses when
untagging addresses; PMLEN_0 means no untagging occurs, so the kernel
does not accept tagged addresses in syscall arguments.
It is valid (as documented and tested by the self test) to enable
pointer masking without enabling the tagged address ABI. This separation
is necessary to allow userspace to create an execution environment
similar to what the kernel supports on arm64 by default, where TBI is
enabled but the tagged address ABI is not. (On arm64, there is no
equivalent to PR_PMLEN_MASK because TBI is always enabled.)
Signed-off-by: Samuel Holland <samuel.holland@sifive.com>
Link: https://patch.msgid.link/20260820014551.1979772-1-samuel.holland@sifive.com
Cc: stable@vger.kernel.org
Fixes: 3033b2b1e394 ("riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set")
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/kernel/process.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/arch/riscv/kernel/process.c
+++ b/arch/riscv/kernel/process.c
@@ -349,10 +349,8 @@ long set_tagged_addr_ctrl(struct task_st
if (arg & PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen))
return -EINVAL;
- if (!(arg & PR_TAGGED_ADDR_ENABLE)) {
+ if (!(arg & PR_TAGGED_ADDR_ENABLE))
pmlen = PMLEN_0;
- pmm = ENVCFG_PMM_PMLEN_0;
- }
if (mmap_write_lock_killable(mm))
return -EINTR;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 485/733] riscv: hwprobe: initialize pair->value in hwprobe_one_pair()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (483 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 484/733] Revert "riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set" Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 486/733] dm/amdgpu: fix malformed link_settings debugfs output Greg Kroah-Hartman
` (259 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Andy Chiu, Jesse Taube,
Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Chiu <tchiu@tenstorrent.com>
commit d0fc6fab20460add1f27402cd8b945d094a56b21 upstream.
The vendor-extension handlers reached from hwprobe_one_pair()
(hwprobe_isa_vendor_ext_thead_0() and friends) only OR the present bits
into pair->value via VENDOR_EXTENSION_SUPPORTED() and clear their own
missing bits; they assume the caller has already zeroed pair->value.
That holds for hwprobe_get_values() (it zeroes each pair) and
hwprobe_get_cpus() (it re-initializes its scratch pair per key), but not
for complete_hwprobe_vdso_data(), which reuses a single pair across all
keys without re-zeroing. A vendor key therefore inherits stale bits from
the previously probed key, and the wrong value is cached in the vDSO
all_cpu_hwprobe_values[] and handed to userspace on the fast patih.
Zero pair->value once at the top of hwprobe_one_pair() so every handler
starts from a clean value regardless of the caller, and drop the now
redundant zeroing in the *_BLOCK_SIZE cases. hwprobe_isa_ext0() keeps its
own zeroing because hwprobe_ext0_has() calls it directly, bypassing
hwprobe_one_pair().
Fixes: a5ea53da65c5 ("riscv: hwprobe: Add thead vendor extension probing")
Signed-off-by: Andy Chiu <tchiu@tenstorrent.com>
Reviewed-by: Jesse Taube <jtaubepe@redhat.com>
Link: https://patch.msgid.link/20260725001614.2578617-2-tchiu@tenstorrent.com
Cc: stable@vger.kernel.org
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/riscv/kernel/sys_hwprobe.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/arch/riscv/kernel/sys_hwprobe.c
+++ b/arch/riscv/kernel/sys_hwprobe.c
@@ -295,6 +295,8 @@ static u64 hwprobe_vec_misaligned(const
static void hwprobe_one_pair(struct riscv_hwprobe *pair,
const struct cpumask *cpus)
{
+ pair->value = 0;
+
switch (pair->key) {
case RISCV_HWPROBE_KEY_MVENDORID:
case RISCV_HWPROBE_KEY_MARCHID:
@@ -329,17 +331,14 @@ static void hwprobe_one_pair(struct risc
break;
case RISCV_HWPROBE_KEY_ZICBOZ_BLOCK_SIZE:
- pair->value = 0;
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOZ))
pair->value = riscv_cboz_block_size;
break;
case RISCV_HWPROBE_KEY_ZICBOM_BLOCK_SIZE:
- pair->value = 0;
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOM))
pair->value = riscv_cbom_block_size;
break;
case RISCV_HWPROBE_KEY_ZICBOP_BLOCK_SIZE:
- pair->value = 0;
if (hwprobe_ext0_has(cpus, RISCV_HWPROBE_EXT_ZICBOP))
pair->value = riscv_cbop_block_size;
break;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 486/733] dm/amdgpu: fix malformed link_settings debugfs output
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (484 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 485/733] riscv: hwprobe: initialize pair->value in hwprobe_one_pair() Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 487/733] drm/amdgpu: skip gfx switch_power_profile during GPU reset Greg Kroah-Hartman
` (258 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Harry Wentland, Alex Hung,
Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harry Wentland <harry.wentland@amd.com>
commit 622b4e8505aa7453a53d17fa3a288871f270fc8b upstream.
[Why]
dp_link_settings_read() passed strlen() of each format string as the size
argument to snprintf() and then advanced rd_buf_ptr by that same fixed amount.
The format-string length has no relation to the formatted output length, so
snprintf() truncated each field at a NUL it wrote inside the buffer while the
pointer was advanced past it. The result is a buffer peppered with embedded NUL
bytes and fields that are silently cut short, so the data read back from the
debugfs node does not reflect the actual link settings.
[How]
Use scnprintf() with the real remaining buffer size
(rd_buf_size - (rd_buf_ptr - rd_buf)) and advance rd_buf_ptr by its return
value, which is the number of characters actually written. This both bounds
each write to the space left in rd_buf and keeps the output a single,
properly terminated string. The now-unused str_len local is removed.
Fixes: 41db5f1931ec ("drm/amd/display: set-read link rate and lane count through debugfs")
Assisted-by: Copilot:claude-opus-4.8
Signed-off-by: Harry Wentland <harry.wentland@amd.com>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 43b9f0f18693c7f7b75613f3aeae25fa2b4e2f76)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c | 20 +++++---------
1 file changed, 8 insertions(+), 12 deletions(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_debugfs.c
@@ -196,7 +196,6 @@ static ssize_t dp_link_settings_read(str
char *rd_buf_ptr = NULL;
const uint32_t rd_buf_size = 100;
uint32_t result = 0;
- uint8_t str_len = 0;
int r;
if (*pos & 3 || size & 3)
@@ -208,29 +207,26 @@ static ssize_t dp_link_settings_read(str
rd_buf_ptr = rd_buf;
- str_len = strlen("Current: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Current: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Current: %d 0x%x %d ",
link->cur_link_settings.lane_count,
link->cur_link_settings.link_rate,
link->cur_link_settings.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Verified: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Verified: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Verified: %d 0x%x %d ",
link->verified_link_cap.lane_count,
link->verified_link_cap.link_rate,
link->verified_link_cap.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Reported: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Reported: %d 0x%x %d ",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Reported: %d 0x%x %d ",
link->reported_link_cap.lane_count,
link->reported_link_cap.link_rate,
link->reported_link_cap.link_spread);
- rd_buf_ptr += str_len;
- str_len = strlen("Preferred: %d 0x%x %d ");
- snprintf(rd_buf_ptr, str_len, "Preferred: %d 0x%x %d\n",
+ rd_buf_ptr += scnprintf(rd_buf_ptr, rd_buf_size - (rd_buf_ptr - rd_buf),
+ "Preferred: %d 0x%x %d\n",
link->preferred_link_setting.lane_count,
link->preferred_link_setting.link_rate,
link->preferred_link_setting.link_spread);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 487/733] drm/amdgpu: skip gfx switch_power_profile during GPU reset
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (485 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 486/733] dm/amdgpu: fix malformed link_settings debugfs output Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 488/733] drm/amdgpu: skip the VMID 0 flush for VRAM Greg Kroah-Hartman
` (257 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Prike Liang, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prike Liang <Prike.Liang@amd.com>
commit 1f1d43418d61c8511779e0f63a954a78b9433b43 upstream.
During resume from GPU reset, the gfx idle work may invoke switch_power_profile
before the reset completes. This causes the following assert error because the
register access occurs without first releasing the GPU reset semaphore:
[ 1576.768935] CR2: 0000559ea133ead0 CR3: 00000002e6c42000 CR4: 0000000000350ef0
[ 1576.768940] Call Trace:
[ 1576.768944] <TASK>
[ 1576.768953] amdgpu_device_rreg+0x21/0x50 [amdgpu]
[ 1576.769158] smu_msg_v1_send_msg+0x1a4/0x6e0 [amdgpu]
[ 1576.769437] smu_cmn_send_smc_msg_with_params_ext+0xba/0x120 [amdgpu]
[ 1576.769721] smu_cmn_send_smc_msg_with_param+0x33/0x40 [amdgpu]
[ 1576.769993] smu_v13_0_0_set_power_profile_mode+0x192/0x2b0 [amdgpu]
[ 1576.770267] smu_bump_power_profile_mode+0x5d/0x80 [amdgpu]
[ 1576.770538] smu_switch_power_profile+0xa4/0xf0 [amdgpu]
[ 1576.770839] amdgpu_dpm_switch_power_profile+0x6f/0x90 [amdgpu]
[ 1576.771210] amdgpu_gfx_profile_idle_work_handler+0xe9/0x130 [amdgpu]
[ 1576.771460] process_one_work+0x23e/0x6f0
[ 1576.771491] worker_thread+0x1c4/0x380
[ 1576.771506] kthread+0x10c/0x150
[ 1576.771512] ? __pfx_worker_thread+0x10/0x10
[ 1576.771518] ? __pfx_kthread+0x10/0x10
[ 1576.771530] ret_from_fork+0x314/0x390
[ 1576.771537] ? __pfx_kthread+0x10/0x10
[ 1576.771546] ret_from_fork_asm+0x1a/0x30
Signed-off-by: Prike Liang <Prike.Liang@amd.com>
Reviewed-by: Alex Deucher <alexander.deucher@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit d93b1ff538ce9750c01e0dd0aa62575579c0fc08)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/pm/amdgpu_dpm.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
+++ b/drivers/gpu/drm/amd/pm/amdgpu_dpm.c
@@ -348,7 +348,8 @@ int amdgpu_dpm_switch_power_profile(stru
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret = 0;
- if (amdgpu_sriov_vf(adev))
+ if (amdgpu_sriov_vf(adev) ||
+ amdgpu_in_reset(adev))
return 0;
if (pp_funcs && pp_funcs->switch_power_profile) {
@@ -367,7 +368,8 @@ int amdgpu_dpm_pause_power_profile(struc
const struct amd_pm_funcs *pp_funcs = adev->powerplay.pp_funcs;
int ret = 0;
- if (amdgpu_sriov_vf(adev))
+ if (amdgpu_sriov_vf(adev) ||
+ amdgpu_in_reset(adev))
return 0;
if (pp_funcs && pp_funcs->pause_power_profile) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 488/733] drm/amdgpu: skip the VMID 0 flush for VRAM
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (486 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 487/733] drm/amdgpu: skip gfx switch_power_profile during GPU reset Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 489/733] watchdog: sunxi_wdt: preserve boot-enabled watchdog Greg Kroah-Hartman
` (256 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Christian König,
Arunpravin Paneer Selvam, Timur Kristóf, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
commit 87ceb8cba73d0b3c4025ff42495bccd8164acaed upstream.
Clear-on-release only runs on VRAM, which amdgpu_ttm_map_buffer() reaches
via its direct MC address without programming a GART window, yet the wipe
still forces a VMID 0 flush. On GFX11 (e.g. Navi33) that spurious SDMA
flush can wedge the engine; only flush when a GART window is actually used.
v2: Let amdgpu_ttm_map_buffer() return whether the VMID 0 flush is needed,
and drive the clear and copy paths from that. (Christian)
v3: Make the vm_needs_flush output parameter mandatory instead of
allowing NULL. (Christian)
Fixes: a68c7eaa7a8f ("drm/amdgpu: Enable clear page functionality")
Closes: https://gitlab.freedesktop.org/drm/amd/-/work_items/5413
Cc: Christian König <christian.koenig@amd.com>
Signed-off-by: Arunpravin Paneer Selvam <Arunpravin.PaneerSelvam@amd.com>
Reviewed-by: Christian König <christian.koenig@amd.com>
Reviewed-by: Timur Kristóf <timur.kristof@gmail.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit a306e406e570b74318ff7d80e5b07b540ca1d3a9)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c | 20 ++++++++++++++------
1 file changed, 14 insertions(+), 6 deletions(-)
--- a/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
+++ b/drivers/gpu/drm/amd/amdgpu/amdgpu_ttm.c
@@ -190,6 +190,8 @@ amdgpu_ttm_job_submit(struct amdgpu_devi
* @tmz: if we should setup a TMZ enabled mapping
* @size: in number of bytes to map, out number of bytes mapped
* @addr: resulting address inside the MC address space
+ * @vm_needs_flush: out, set true if a GART window was programmed (VMID 0 flush
+ * needed) or false for a direct address
*
* Setup one of the GART windows to access a specific piece of memory or return
* the physical address for local memory.
@@ -199,7 +201,8 @@ static int amdgpu_ttm_map_buffer(struct
struct ttm_resource *mem,
struct amdgpu_res_cursor *mm_cur,
unsigned int window,
- bool tmz, uint64_t *size, uint64_t *addr)
+ bool tmz, uint64_t *size, uint64_t *addr,
+ bool *vm_needs_flush)
{
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->bdev);
unsigned int offset, num_pages, num_dw, num_bytes;
@@ -220,9 +223,12 @@ static int amdgpu_ttm_map_buffer(struct
if (!tmz && mem->start != AMDGPU_BO_INVALID_OFFSET) {
*addr = amdgpu_ttm_domain_start(adev, mem->mem_type) +
mm_cur->start;
+ *vm_needs_flush = false;
return 0;
}
+ /* A GART window is programmed below, so its VMID 0 TLB needs a flush */
+ *vm_needs_flush = true;
/*
* If start begins at an offset inside the page, then adjust the size
@@ -322,6 +328,7 @@ static int amdgpu_ttm_copy_mem_to_mem(st
while (src_mm.remaining) {
uint64_t from, to, cur_size, tiling_flags;
uint32_t num_type, data_format, max_com, write_compress_disable;
+ bool src_vm_flush, dst_vm_flush;
struct dma_fence *next;
/* Never copy more than 256MiB at once to avoid a timeout */
@@ -329,12 +336,12 @@ static int amdgpu_ttm_copy_mem_to_mem(st
/* Map src to window 0 and dst to window 1. */
r = amdgpu_ttm_map_buffer(entity, src->bo, src->mem, &src_mm,
- 0, tmz, &cur_size, &from);
+ 0, tmz, &cur_size, &from, &src_vm_flush);
if (r)
goto error;
r = amdgpu_ttm_map_buffer(entity, dst->bo, dst->mem, &dst_mm,
- 1, tmz, &cur_size, &to);
+ 1, tmz, &cur_size, &to, &dst_vm_flush);
if (r)
goto error;
@@ -362,7 +369,7 @@ static int amdgpu_ttm_copy_mem_to_mem(st
}
r = amdgpu_copy_buffer(adev, entity, from, to, cur_size, resv,
- &next, true, copy_flags);
+ &next, src_vm_flush || dst_vm_flush, copy_flags);
if (r)
goto error;
@@ -2580,6 +2587,7 @@ int amdgpu_ttm_clear_buffer(struct amdgp
struct amdgpu_device *adev = amdgpu_ttm_adev(bo->tbo.bdev);
struct dma_fence *fence = NULL;
struct amdgpu_res_cursor dst;
+ bool vm_needs_flush = false;
int r;
if (!entity)
@@ -2601,13 +2609,13 @@ int amdgpu_ttm_clear_buffer(struct amdgp
cur_size = min(dst.size, 256ULL << 20);
r = amdgpu_ttm_map_buffer(entity, &bo->tbo, bo->tbo.resource, &dst,
- 0, false, &cur_size, &to);
+ 0, false, &cur_size, &to, &vm_needs_flush);
if (r)
goto error;
r = amdgpu_ttm_fill_mem(adev, entity,
0, to, cur_size, resv,
- &next, true, k_job_id);
+ &next, vm_needs_flush, k_job_id);
if (r)
goto error;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 489/733] watchdog: sunxi_wdt: preserve boot-enabled watchdog
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (487 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 488/733] drm/amdgpu: skip the VMID 0 flush for VRAM Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 490/733] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
` (255 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, James Hilliard, Guenter Roeck
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: James Hilliard <james.hilliard1@gmail.com>
commit aab55360fa11a2c054798a484ac67ad606f563e4 upstream.
sunxi_wdt_probe() unconditionally stops the watchdog even when firmware
left it running. This opens an unprotected interval during boot and
prevents CONFIG_WATCHDOG_HANDLE_BOOT_ENABLED from taking over the active
watchdog.
Detect an enabled watchdog and decode its programmed interval. Preserve
representable timeouts, and round the 0.5-second interval up to the
minimum representable one-second timeout. Use the configured timeout for
reserved interval encodings. Set the Linux reset mode and ping the
watchdog without clearing its enable bit, then mark it hardware-running
before registration so the watchdog core services it until userspace
takes control. Leave disabled watchdogs untouched.
Fixes: d00680ed0026 ("watchdog: sunxi: New watchdog driver for Allwinner A10/A13")
Cc: stable@vger.kernel.org
Signed-off-by: James Hilliard <james.hilliard1@gmail.com>
Link: https://patch.msgid.link/20260827-submit-sunxi-wdt-boot-enabled-v1-v2-1-610d37dccc97@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/watchdog/sunxi_wdt.c | 45 ++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 44 insertions(+), 1 deletion(-)
--- a/drivers/watchdog/sunxi_wdt.c
+++ b/drivers/watchdog/sunxi_wdt.c
@@ -128,6 +128,38 @@ static int sunxi_wdt_ping(struct watchdo
return 0;
}
+static bool sunxi_wdt_is_running(struct watchdog_device *wdt_dev)
+{
+ struct sunxi_wdt_dev *sunxi_wdt = watchdog_get_drvdata(wdt_dev);
+ const struct sunxi_wdt_reg *regs = sunxi_wdt->wdt_regs;
+
+ return readl(sunxi_wdt->wdt_base + regs->wdt_mode) & WDT_MODE_EN;
+}
+
+static unsigned int sunxi_wdt_get_timeout(struct watchdog_device *wdt_dev)
+{
+ struct sunxi_wdt_dev *sunxi_wdt = watchdog_get_drvdata(wdt_dev);
+ const struct sunxi_wdt_reg *regs = sunxi_wdt->wdt_regs;
+ unsigned int timeout;
+ u32 interval;
+
+ interval = readl(sunxi_wdt->wdt_base + regs->wdt_mode);
+ interval >>= regs->wdt_timeout_shift;
+ interval &= WDT_TIMEOUT_MASK;
+ /* Round the 0.5-second interval up to the minimum representable timeout. */
+ if (!interval)
+ return WDT_MIN_TIMEOUT;
+
+ for (timeout = WDT_MIN_TIMEOUT;
+ timeout < ARRAY_SIZE(wdt_timeout_map); timeout++) {
+ if (wdt_timeout_map[timeout] == interval)
+ return timeout;
+ }
+
+ /* Reserved interval encoding. */
+ return 0;
+}
+
static int sunxi_wdt_set_timeout(struct watchdog_device *wdt_dev,
unsigned int timeout)
{
@@ -259,6 +291,7 @@ static int sunxi_wdt_probe(struct platfo
{
struct device *dev = &pdev->dev;
struct sunxi_wdt_dev *sunxi_wdt;
+ unsigned int running_timeout;
int err;
sunxi_wdt = devm_kzalloc(dev, sizeof(*sunxi_wdt), GFP_KERNEL);
@@ -286,7 +319,17 @@ static int sunxi_wdt_probe(struct platfo
watchdog_set_drvdata(&sunxi_wdt->wdt_dev, sunxi_wdt);
- sunxi_wdt_stop(&sunxi_wdt->wdt_dev);
+ if (sunxi_wdt_is_running(&sunxi_wdt->wdt_dev)) {
+ running_timeout = sunxi_wdt_get_timeout(&sunxi_wdt->wdt_dev);
+ if (running_timeout)
+ sunxi_wdt->wdt_dev.timeout = running_timeout;
+
+ err = sunxi_wdt_start(&sunxi_wdt->wdt_dev);
+ if (err)
+ return err;
+
+ set_bit(WDOG_HW_RUNNING, &sunxi_wdt->wdt_dev.status);
+ }
watchdog_stop_on_reboot(&sunxi_wdt->wdt_dev);
err = devm_watchdog_register_device(dev, &sunxi_wdt->wdt_dev);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 490/733] virtio_mmio: disable IRQ wake before free_irq
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (488 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 489/733] watchdog: sunxi_wdt: preserve boot-enabled watchdog Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 491/733] ufs: create the root dentry after loading cylinder metadata Greg Kroah-Hartman
` (254 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xiong Weimin, Michael S. Tsirkin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiong Weimin <xiongweimin@kylinos.cn>
commit d14d693adb055e98ca705822ba6daebc18602d9a upstream.
When the DT node has "wakeup-source", vm_find_vqs() calls
enable_irq_wake() on the shared IRQ, but vm_del_vqs() freed that IRQ
without a matching disable_irq_wake(). That leaves a wake reference
behind and can warn on later free_irq()/request_irq() cycles.
Record whether enable_irq_wake() succeeded, and disable it in
vm_del_vqs() before free_irq().
Fixes: 02213273f72a ("virtio_mmio: add support to set IRQ of a virtio device as wakeup source")
Cc: stable@vger.kernel.org
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <20260805032937.1606737-1-xiongweimin@kylinos.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/virtio/virtio_mmio.c | 16 +++++++++++++---
1 file changed, 13 insertions(+), 3 deletions(-)
--- a/drivers/virtio/virtio_mmio.c
+++ b/drivers/virtio/virtio_mmio.c
@@ -87,6 +87,9 @@ struct virtio_mmio_device {
void __iomem *base;
unsigned long version;
+
+ /* True if enable_irq_wake() succeeded for the shared IRQ. */
+ bool wake_irq_enabled;
};
/* Configuration interface */
@@ -329,11 +332,17 @@ static void vm_del_vqs(struct virtio_dev
{
struct virtio_mmio_device *vm_dev = to_virtio_mmio_device(vdev);
struct virtqueue *vq, *n;
+ int irq = platform_get_irq(vm_dev->pdev, 0);
list_for_each_entry_safe(vq, n, &vdev->vqs, list)
vm_del_vq(vq);
- free_irq(platform_get_irq(vm_dev->pdev, 0), vm_dev);
+ if (vm_dev->wake_irq_enabled) {
+ disable_irq_wake(irq);
+ vm_dev->wake_irq_enabled = false;
+ }
+
+ free_irq(irq, vm_dev);
}
static void vm_synchronize_cbs(struct virtio_device *vdev)
@@ -460,8 +469,9 @@ static int vm_find_vqs(struct virtio_dev
if (err)
return err;
- if (of_property_read_bool(vm_dev->pdev->dev.of_node, "wakeup-source"))
- enable_irq_wake(irq);
+ if (of_property_read_bool(vm_dev->pdev->dev.of_node, "wakeup-source") &&
+ !enable_irq_wake(irq))
+ vm_dev->wake_irq_enabled = true;
for (i = 0; i < nvqs; ++i) {
struct virtqueue_info *vqi = &vqs_info[i];
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 491/733] ufs: create the root dentry after loading cylinder metadata
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (489 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 490/733] virtio_mmio: disable IRQ wake before free_irq Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 492/733] ufs: validate cylinder group metadata before caching it Greg Kroah-Hartman
` (253 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis, Jan Kara,
Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
commit 55a4c98abb9694b067c6a031d11501f06b6b523c upstream.
ufs_fill_super() installed sb->s_root before it loaded the cylinder
group structures for a writable mount:
sb->s_root = d_make_root(inode);
...
if (!sb_rdonly(sb))
if (!ufs_read_cylinder_structures(sb))
goto failed;
When ufs_read_cylinder_structures() failed, the error path freed the
in-core superblock information and set sb->s_fs_info to NULL while
sb->s_root stayed installed. get_tree_bdev() then reached
deactivate_locked_super(), and because s_root was present,
generic_shutdown_super() called sync_filesystem() and the put_super
operation. Both dereference UFS_SB(sb), which is now NULL, so a mount
that fails only while reading the cylinder groups oopses during
teardown. A crafted image whose first cylinder group cannot be read
reaches this path.
Load the cylinder group metadata first and create the root dentry last,
so the superblock is published to the VFS only once it is fully set up.
ufs_setup_cstotal() and ufs_read_cylinder_structures() take only the
super_block and do not use the root inode, so the reordering is safe.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260801071306.59484-2-ali@iusegentoo.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ufs/super.c | 17 +++++++++--------
1 file changed, 9 insertions(+), 8 deletions(-)
--- a/fs/ufs/super.c
+++ b/fs/ufs/super.c
@@ -1199,6 +1199,15 @@ magic_found:
sb->s_maxbytes = ufs_max_bytes(sb);
sb->s_max_links = UFS_LINK_MAX;
+ ufs_setup_cstotal(sb);
+ /*
+ * Read cylinder group structures
+ */
+ if (!sb_rdonly(sb))
+ if (!ufs_read_cylinder_structures(sb))
+ goto failed;
+
+ /* create the root dentry last, once UFS_SB(sb) is fully set up */
inode = ufs_iget(sb, UFS_ROOTINO);
if (IS_ERR(inode)) {
ret = PTR_ERR(inode);
@@ -1210,14 +1219,6 @@ magic_found:
goto failed;
}
- ufs_setup_cstotal(sb);
- /*
- * Read cylinder group structures
- */
- if (!sb_rdonly(sb))
- if (!ufs_read_cylinder_structures(sb))
- goto failed;
-
UFSD("EXIT\n");
return 0;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 492/733] ufs: validate cylinder group metadata before caching it
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (490 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 491/733] ufs: create the root dentry after loading cylinder metadata Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 493/733] tunnels: Drop stale dst when building an ICMP error for PMTUD Greg Kroah-Hartman
` (252 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ali Ahmet Memis, Jan Kara,
Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ali Ahmet Memis <ali@iusegentoo.com>
commit c9d263be26806d388129fab8c6904bed197fc6af upstream.
ufs_read_cylinder() copies the cylinder group index and the rotor
positions straight from the on-disk group and caches them without any
check:
ucpi->c_cgx = fs32_to_cpu(sb, ucg->cg_cgx);
ucpi->c_rotor = fs32_to_cpu(sb, ucg->cg_rotor);
ucpi->c_frotor = fs32_to_cpu(sb, ucg->cg_frotor);
ucpi->c_irotor = fs32_to_cpu(sb, ucg->cg_irotor);
They are then used as indices during allocation and free:
- c_cgx indexes the cylinder summary array as
UFS_SB(sb)->fs_cs(ucpi->c_cgx), so a value past s_ncg writes a 32
bit count outside the s_csp allocation.
- c_frotor becomes a bitmap scan start, start = c_frotor >> 3, and
then length = ((s_fpg + 7) >> 3) - start. A start beyond the block
bitmap wraps the unsigned length to a huge value, so ubh_scanc()
walks far past the cylinder group buffers. c_irotor drives the
inode bitmap the same way.
A crafted image can set any of these freely, turning an ordinary
allocation into an out of bounds access.
Reject a cylinder group whose recorded index does not match the group
being read, or whose rotors fall outside the group, before the metadata
is cached. Valid filesystems keep cg_cgx equal to the group number and
the rotors within the group, so only malformed images are rejected.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Signed-off-by: Ali Ahmet Memis <ali@iusegentoo.com>
Link: https://patch.msgid.link/20260801071306.59484-3-ali@iusegentoo.com
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/ufs/cylinder.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/fs/ufs/cylinder.c
+++ b/fs/ufs/cylinder.c
@@ -68,6 +68,16 @@ static bool ufs_read_cylinder(struct sup
ucpi->c_clustersumoff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clustersumoff);
ucpi->c_clusteroff = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_clusteroff);
ucpi->c_nclusterblks = fs32_to_cpu(sb, ucg->cg_u.cg_44.cg_nclusterblks);
+
+ /* these on-disk values become array and bitmap indices */
+ if (ucpi->c_cgx != cgno ||
+ ucpi->c_rotor >= uspi->s_fpg ||
+ ucpi->c_frotor >= uspi->s_fpg ||
+ ucpi->c_irotor >= uspi->s_ipg) {
+ ufs_error(sb, __func__,
+ "inconsistent metadata in cylinder group %u\n", cgno);
+ goto failed;
+ }
UFSD("EXIT\n");
return true;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 493/733] tunnels: Drop stale dst when building an ICMP error for PMTUD
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (491 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 492/733] ufs: validate cylinder group metadata before caching it Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 494/733] tick/broadcast: Plug clockevents replacement race Greg Kroah-Hartman
` (251 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Laika Price, Yaroslav Dudkov,
Charles Bordet, Ido Schimmel, David Ahern, Stefano Brivio,
Guillaume Nault, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <idosch@nvidia.com>
commit b58d749633203d92c265317b45fccee555090352 upstream.
Bridged UDP tunnels such as VXLAN and GENEVE build an ICMP error packet
around an overlay packet if the packet is going to exceed the underlay
path MTU. The ICMP error packet is then injected back into the Rx path
with the source and destination addresses swapped, so that it will be
delivered to the overlay source.
If the overlay packet was routed to the UDP tunnel or locally generated,
then it is already carrying a valid dst entry and this entry is not
dropped when transforming the packet to an ICMP error packet. This
causes the IP layer to reuse the dst entry, leading to the ICMP error
packet being dropped or routed out of the UDP tunnel interface in case
of forwarding.
Prior to the blamed commit this could not happen, as
skb_tunnel_check_pmtu() did not build ICMP errors for PACKET_HOST
packets. Such packets were instead encapsulated and, unless the DF bit
was set in the outer header, fragmented by the underlay.
Fix this by making sure that the ICMP error packet does not have a valid
dst entry, thereby forcing the IP layer to perform a route lookup.
Adjust the bridged PMTU exception selftests accordingly. When the
local sender in ns_a pings the overlay destination with a deadline
(-w), ping exits on the first socket error before any reply is
received and returns a non-zero exit code. The test therefore only
passed because the ICMP error was never delivered. Use a packet count
(-c) like the ns_c line above it, so that the ICMP error counts
against the packet budget and the exit code depends on whether echo
replies were received. This passes with and without the fix.
Fixes: 8930424777e4 ("tunnels: Accept PACKET_HOST in skb_tunnel_check_pmtu().")
Cc: stable@vger.kernel.org
Reported-by: Laika Price <laikabcprice@gmail.com>
Closes: https://lore.kernel.org/netdev/20260614-master-v3-1-9f5060ba1ed1@gmail.com/
Reported-by: Yaroslav Dudkov <aroslavdudkov622@gmail.com>
Closes: https://lore.kernel.org/netdev/20260901081825.287173-1-aroslavdudkov622@gmail.com/
Reported-by: Charles Bordet <rough.rock3059@datachamp.fr>
Closes: https://lore.kernel.org/netdev/aHVhQLPJIhq-SYPM@eldamar.lan/
Signed-off-by: Ido Schimmel <idosch@nvidia.com>
Tested-by: Yaroslav Dudkov <aroslavdudkov622@gmail.com>
Reviewed-by: David Ahern <dsahern@kernel.org>
Reviewed-by: Stefano Brivio <sbrivio@redhat.com>
Reviewed-by: Guillaume Nault <gnault@redhat.com>
Link: https://patch.msgid.link/20260902190112.4126199-1-idosch@nvidia.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/ip_tunnel_core.c | 6 ++++++
tools/testing/selftests/net/pmtu.sh | 2 +-
2 files changed, 7 insertions(+), 1 deletion(-)
--- a/net/ipv4/ip_tunnel_core.c
+++ b/net/ipv4/ip_tunnel_core.c
@@ -268,6 +268,9 @@ static int iptunnel_pmtud_build_icmp(str
eth_header(skb, skb->dev, ntohs(eh.h_proto), eh.h_source, eh.h_dest, 0);
skb_reset_mac_header(skb);
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
+
return skb->len;
}
@@ -371,6 +374,9 @@ static int iptunnel_pmtud_build_icmpv6(s
eth_header(skb, skb->dev, ntohs(eh.h_proto), eh.h_source, eh.h_dest, 0);
skb_reset_mac_header(skb);
+ if (skb_valid_dst(skb))
+ skb_dst_drop(skb);
+
return skb->len;
}
--- a/tools/testing/selftests/net/pmtu.sh
+++ b/tools/testing/selftests/net/pmtu.sh
@@ -1457,7 +1457,7 @@ test_pmtu_ipvX_over_bridged_vxlanY_or_ge
mtu "${ns_b}" ${type}_b $((${ll_mtu} + 1000))
run_cmd ${ns_c} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
- run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -w 1 -s $((${ll_mtu} + 500)) ${dst} || return 1
+ run_cmd ${ns_a} ${ping} -q -M want -i 0.1 -c 10 -s $((${ll_mtu} + 500)) ${dst} || return 1
# Check that exceptions were created
pmtu="$(route_get_dst_pmtu_from_exception "${ns_c}" ${dst})"
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 494/733] tick/broadcast: Plug clockevents replacement race
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (492 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 493/733] tunnels: Drop stale dst when building an ICMP error for PMTUD Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 495/733] tools/bootconfig: Fix integer overflow and truncation in size checks Greg Kroah-Hartman
` (250 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, 朱恺乾,
Thomas Gleixner, Thomas Gleixner, Bradley Morgan,
刘术高
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Gleixner <tglx@linutronix.de>
commit 113a9796effe3376d2ec5aabcca1fef4fef4cd62 upstream.
朱恺乾 reported and decoded the following race condition when a broadcast
device is replaced:
CPUA CPUB
__tick_broadcast_oneshot_control()
bc = tick_broadcast_device.evtdev;
tick_install_broadcast_device(dev)
clockevents_exchange_device(cur, dev)
shutdown(cur);
detach(cur);
cur->handler = noop;
tick_broadcast_device.evtdev = dev;
tick_broadcast_set_event(bc, next_event); <- FAIL: arms a detached device.
If the original broadcast device has a restricted interrupt affinity mask
and the last CPU in that mask goes offline then the BUG() in
tick_cleanup_dead_cpu() triggers because the clockevent device is not in
detached state.
The reason for this is that tick_install_broadcast_device() is not
serialized vs. tick broadcast operations.
The obvious cure is to serialize tick_install_broadcast_device() with
tick_broadcast_lock against a concurrent tick broadcast operation.
That requires to split clockevents_exchange_device() into two parts, one
which does the exchange, shutdown and detach operation and the other which
drops the module reference count. This is required because the module
reference cannot be dropped while holding tick_broadcast_lock.
Let clockevents_exchange_device() do both operations as before, but let the
broadcast device code take the two step approach and do the device
exchange under tick_broadcast_lock and drop the module reference count
after releasing it.
Fixes: f8381cba04ba ("[PATCH] tick-management: broadcast functionality")
Reported-by: 朱恺乾 <zhukaiqian@xiaomi.com>
Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Tested-by: 刘术高 <liushugao@xiaomi.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/87cymdsu0r.ffs@tglx
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/time/clockevents.c | 33 ++++++++++++++++++++-------------
kernel/time/tick-broadcast.c | 36 ++++++++++++++++++++++--------------
kernel/time/tick-internal.h | 2 ++
3 files changed, 44 insertions(+), 27 deletions(-)
--- a/kernel/time/clockevents.c
+++ b/kernel/time/clockevents.c
@@ -615,34 +615,41 @@ void clockevents_handle_noop(struct cloc
{
}
-/**
- * clockevents_exchange_device - release and request clock devices
- * @old: device to release (can be NULL)
- * @new: device to request (can be NULL)
- *
- * Called from various tick functions with clockevents_lock held and
- * interrupts disabled.
- */
-void clockevents_exchange_device(struct clock_event_device *old,
- struct clock_event_device *new)
+void __clockevents_exchange_device(struct clock_event_device *old,
+ struct clock_event_device *new)
{
/*
* Caller releases a clock event device. We queue it into the
* released list and do a notify add later.
*/
if (old) {
- module_put(old->owner);
clockevents_switch_state(old, CLOCK_EVT_STATE_DETACHED);
list_move(&old->list, &clockevents_released);
}
if (new) {
- BUG_ON(!clockevent_state_detached(new));
+ WARN_ON(!clockevent_state_detached(new));
clockevents_shutdown(new);
}
}
/**
+ * clockevents_exchange_device - release and request clock devices
+ * @old: device to release (can be NULL)
+ * @new: device to request (can be NULL)
+ *
+ * Called from various tick functions with clockevents_lock held and
+ * interrupts disabled.
+ */
+void clockevents_exchange_device(struct clock_event_device *old,
+ struct clock_event_device *new)
+{
+ __clockevents_exchange_device(old, new);
+ if (old)
+ module_put(old->owner);
+}
+
+/**
* clockevents_suspend - suspend clock devices
*/
void clockevents_suspend(void)
@@ -699,7 +706,7 @@ void tick_offline_cpu(unsigned int cpu)
if (cpumask_test_cpu(cpu, dev->cpumask) &&
cpumask_weight(dev->cpumask) == 1 &&
!tick_is_broadcast_device(dev)) {
- BUG_ON(!clockevent_state_detached(dev));
+ WARN_ON(!clockevent_state_detached(dev));
list_del(&dev->list);
}
}
--- a/kernel/time/tick-broadcast.c
+++ b/kernel/time/tick-broadcast.c
@@ -165,23 +165,31 @@ static bool tick_set_oneshot_wakeup_devi
*/
void tick_install_broadcast_device(struct clock_event_device *dev, int cpu)
{
- struct clock_event_device *cur = tick_broadcast_device.evtdev;
+ struct clock_event_device *cur;
- if (tick_set_oneshot_wakeup_device(dev, cpu))
- return;
+ scoped_guard(raw_spinlock_irqsave, &tick_broadcast_lock) {
- if (!tick_check_broadcast_device(cur, dev))
- return;
+ if (tick_set_oneshot_wakeup_device(dev, cpu))
+ return;
- if (!try_module_get(dev->owner))
- return;
+ cur = tick_broadcast_device.evtdev;
+ if (!tick_check_broadcast_device(cur, dev))
+ return;
- clockevents_exchange_device(cur, dev);
+ if (!try_module_get(dev->owner))
+ return;
+
+ __clockevents_exchange_device(cur, dev);
+ if (cur)
+ cur->event_handler = clockevents_handle_noop;
+ WRITE_ONCE(tick_broadcast_device.evtdev, dev);
+ if (!cpumask_empty(tick_broadcast_mask))
+ tick_broadcast_start_periodic(dev);
+ }
+
+ /* Module release must be outside of the lock */
if (cur)
- cur->event_handler = clockevents_handle_noop;
- tick_broadcast_device.evtdev = dev;
- if (!cpumask_empty(tick_broadcast_mask))
- tick_broadcast_start_periodic(dev);
+ module_put(cur->owner);
if (!(dev->features & CLOCK_EVT_FEAT_ONESHOT))
return;
@@ -1218,7 +1226,7 @@ int tick_broadcast_oneshot_active(void)
*/
bool tick_broadcast_oneshot_available(void)
{
- struct clock_event_device *bc = tick_broadcast_device.evtdev;
+ struct clock_event_device *bc = READ_ONCE(tick_broadcast_device.evtdev);
return bc ? bc->features & CLOCK_EVT_FEAT_ONESHOT : false;
}
@@ -1226,7 +1234,7 @@ bool tick_broadcast_oneshot_available(vo
#else
int __tick_broadcast_oneshot_control(enum tick_broadcast_state state)
{
- struct clock_event_device *bc = tick_broadcast_device.evtdev;
+ struct clock_event_device *bc = READ_ONCE(tick_broadcast_device.evtdev);
if (!bc || (bc->features & CLOCK_EVT_FEAT_HRTIMER))
return -EBUSY;
--- a/kernel/time/tick-internal.h
+++ b/kernel/time/tick-internal.h
@@ -54,6 +54,8 @@ static inline void clockevent_set_state(
}
extern void clockevents_shutdown(struct clock_event_device *dev);
+extern void __clockevents_exchange_device(struct clock_event_device *old,
+ struct clock_event_device *new);
extern void clockevents_exchange_device(struct clock_event_device *old,
struct clock_event_device *new);
extern void clockevents_switch_state(struct clock_event_device *dev,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 495/733] tools/bootconfig: Fix integer overflow and truncation in size checks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (493 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 494/733] tick/broadcast: Plug clockevents replacement race Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 496/733] tracing/user_events: Dont destroy fields when event removal fails Greg Kroah-Hartman
` (249 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Masami Hiramatsu (Google),
Sang-Heon Jeon
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
commit 462d0b066b613103f579793031429db2ca23abc0 upstream.
Sashiko reported that on 32-bit systems, if an attacker crafts size in
the bootconfig footer such that adding BOOTCONFIG_FOOTER_SIZE wraps around
(for instance, if size is 0xFFFFFFFF), the size check in
load_xbc_from_initrd() can be bypassed:
if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
Furthermore, on 64-bit systems with an initrd > 4.29 GB, comparing a
corrupted 32-bit size (e.g. 0xFFFFFFFF) against
stat.st_size - BOOTCONFIG_FOOTER_SIZE can also bypass the check if
size is not bounded. Similarly, load_xbc_file() passes 64-bit stat.st_size
directly into the 32-bit int size parameter of load_xbc_fd(), truncating
large standalone files (>= 2GB).
In both cases, passing 0xFFFFFFFF to load_xbc_fd() truncates to -1,
resulting in malloc(0), an integer overflow in read(), and an
out-of-bounds null-byte write.
Fix this by:
1. Rejecting size > XBC_DATA_MAX or
size > stat.st_size - BOOTCONFIG_FOOTER_SIZE in load_xbc_from_initrd().
2. Rejecting stat.st_size > XBC_DATA_MAX in load_xbc_file() before passing
it to load_xbc_fd().
3. Checking size < 0 || size > XBC_DATA_MAX defensively in load_xbc_fd().
Link: https://lore.kernel.org/all/178905332413.213925.3179977110281463499.stgit@devnote2/
Fixes: 950313ebf79c ("tools: bootconfig: Add bootconfig command")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260909161113.16C691F00A3A@smtp.kernel.org/
Closes: https://lore.kernel.org/all/20260910010137.EE0431F000FF@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/bootconfig/main.c | 13 ++++++++++++-
1 file changed, 12 insertions(+), 1 deletion(-)
--- a/tools/bootconfig/main.c
+++ b/tools/bootconfig/main.c
@@ -140,6 +140,9 @@ static int load_xbc_fd(int fd, char **bu
{
int ret;
+ if (size < 0 || size > XBC_DATA_MAX)
+ return -EINVAL;
+
*buf = malloc(size + 1);
if (!*buf)
return -ENOMEM;
@@ -168,6 +171,13 @@ static int load_xbc_file(const char *pat
return ret;
}
+ if (stat.st_size > XBC_DATA_MAX) {
+ pr_err("%s size is too big\n", path);
+ ret = -E2BIG;
+ close(fd);
+ return ret;
+ }
+
ret = load_xbc_fd(fd, buf, stat.st_size);
close(fd);
@@ -218,7 +228,8 @@ static int load_xbc_from_initrd(int fd,
csum = le32toh(csum);
/* Wrong size error */
- if (stat.st_size < size + BOOTCONFIG_FOOTER_SIZE) {
+ if (size > XBC_DATA_MAX ||
+ size > stat.st_size - BOOTCONFIG_FOOTER_SIZE) {
pr_err("bootconfig size is too big\n");
return -E2BIG;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 496/733] tracing/user_events: Dont destroy fields when event removal fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (494 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 495/733] tools/bootconfig: Fix integer overflow and truncation in size checks Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 497/733] tracing: Free histogram the var ref when its initialization fails Greg Kroah-Hartman
` (248 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Henry Martin, Beau Belgrave,
Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Henry Martin <bsdhenrymartin@gmail.com>
commit 2deb753127d7b7035e893955c5e91875e767d1f8 upstream.
destroy_user_event() destroys the event's fields before attempting to
remove the trace event call. If user_event_set_call_visible() fails,
e.g. because the event is still enabled and trace_remove_event_call()
returns -EBUSY, the event is left registered with an irreversibly
destroyed field list. Any subsequent interaction with the event then
operates on an empty field list while it is still fully visible in
tracefs.
Move the field destruction after the call removal, and splice the
field list back onto the event when the removal fails so the event
remains in a consistent state.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260904115223.2976446-1-bsdhenrymartin@gmail.com
Fixes: 7f5a08c79df35 ("user_events: Add minimal support for trace_event into ftrace")
Signed-off-by: Henry Martin <bsdhenrymartin@gmail.com>
Reviewed-by: Beau Belgrave <beaub@linux.microsoft.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_user.c | 26 ++++++++++++++++++++------
1 file changed, 20 insertions(+), 6 deletions(-)
--- a/kernel/trace/trace_events_user.c
+++ b/kernel/trace/trace_events_user.c
@@ -1122,10 +1122,9 @@ static void user_event_destroy_validator
}
}
-static void user_event_destroy_fields(struct user_event *user)
+static void user_event_destroy_fields(struct list_head *head)
{
struct ftrace_event_field *field, *next;
- struct list_head *head = &user->fields;
list_for_each_entry_safe(field, next, head, link) {
list_del(&field->link);
@@ -1502,17 +1501,32 @@ static int user_event_set_call_visible(s
static int destroy_user_event(struct user_event *user)
{
+ LIST_HEAD(fields);
int ret = 0;
lockdep_assert_held(&event_mutex);
- /* Must destroy fields before call removal */
- user_event_destroy_fields(user);
+ /*
+ * Detach the fields before removing the call. Removing the event
+ * frees the field list memory (trace_destroy_fields() is run on
+ * successful removal and kmem_cache_free()s the fields), but the
+ * fields here are allocated and owned by user_events. Destroy
+ * them separately once removal has succeeded.
+ */
+ list_splice_init(&user->fields, &fields);
ret = user_event_set_call_visible(user, false);
- if (ret)
+ if (ret) {
+ /*
+ * Removal failed and the event stays registered, recover
+ * the fields so it is left in a consistent state.
+ */
+ list_splice(&fields, &user->fields);
return ret;
+ }
+
+ user_event_destroy_fields(&fields);
dyn_event_remove(&user->devent);
hash_del(&user->node);
@@ -2212,7 +2226,7 @@ static int user_event_parse(struct user_
put_user_lock:
mutex_unlock(&event_mutex);
put_user:
- user_event_destroy_fields(user);
+ user_event_destroy_fields(&user->fields);
user_event_destroy_validators(user);
kfree(user->call.print_fmt);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 497/733] tracing: Free histogram the var ref when its initialization fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (495 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 496/733] tracing/user_events: Dont destroy fields when event removal fails Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 498/733] tracing: Free histogram var refs regardless of how often they are referenced Greg Kroah-Hartman
` (247 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 516001d53e6b2ea95a251ee2ef54a1a689a3fd58 upstream.
create_var_ref() allocates a VAR_REF hist_field and then calls
init_var_ref() to fill it in. When that fails the field is leaked.
commit 656fe2ba85e8 ("tracing: Use hist trigger's var_ref array to destroy
var_refs") made destroy_hist_field() return early for
HIST_FIELD_FL_VAR_REF, since var refs are freed by walking the trigger's
var_refs[] array instead. create_var_ref() adds the field to that array
only after init_var_ref() has succeeded, so on this path the field is in
neither place and nothing frees it. The call was correct when it was
written, before var refs were taken out of destroy_hist_field().
init_var_ref() cannot free it either. The caller owns the field, so
init_var_ref() undoes only its own string allocations and leaves the
field alone. Freeing it there would leave create_var_ref() passing freed
memory to destroy_hist_field(), which reads its flags.
Call __destroy_hist_field(), which frees the field without consulting
the flag.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260906133352.3815019-1-donggeunyoo.kernel@gmail.com
Fixes: 656fe2ba85e8 ("tracing: Use hist trigger's var_ref array to destroy var_refs")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -2229,7 +2229,7 @@ static struct hist_field *create_var_ref
ref_field = create_hist_field(var_field->hist_data, NULL, flags, NULL);
if (ref_field) {
if (init_var_ref(ref_field, var_field, system, event_name)) {
- destroy_hist_field(ref_field, 0);
+ __destroy_hist_field(ref_field);
return NULL;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 498/733] tracing: Free histogram var refs regardless of how often they are referenced
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (496 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 497/733] tracing: Free histogram the var ref when its initialization fails Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 499/733] tracing: Free histogram the field rejected for a bad modifier Greg Kroah-Hartman
` (246 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 4bddcb346a6cf4615ca77f69a589623b877ca267 upstream.
Using the same variable three or more times in one hist trigger leaks the
variable reference and its strings when the trigger is removed.
commit 656fe2ba85e8 ("tracing: Use hist trigger's var_ref array to destroy
var_refs") made a trigger's var_refs[] array the only owner of a var ref:
destroy_hist_field() returns early for HIST_FIELD_FL_VAR_REF, so the field
expressions never destroy one. One entry, freed once, no count needed.
commit 8bcebc77e85f ("tracing: Fix histogram code when expression has same
var as value") then made repeated references share one object and added a
count of them. Only the increment side exists, since those expressions
still return early and never drop a reference, so __destroy_hist_field()
sees how many references were created rather than how many are left. It
frees when the decremented count is 0 or 1, so two references work and
three or more leak.
Sharing kept one array entry per object, and create_var_ref() searches and
appends within a single trigger, so nothing outside it holds the object.
Removing a trigger whose variables are still referenced is already refused
by check_var_refs() with -EBUSY. Drop the count and free unconditionally.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260906124025.3550596-1-donggeunyoo.kernel@gmail.com
Fixes: 8bcebc77e85f ("tracing: Fix histogram code when expression has same var as value")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 16 +---------------
1 file changed, 1 insertion(+), 15 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -170,7 +170,6 @@ struct hist_field {
struct hist_field *operands[HIST_FIELD_OPERANDS_MAX];
struct hist_trigger_data *hist_data;
enum hist_field_fn fn_num;
- unsigned int ref;
unsigned int size;
unsigned int offset;
unsigned int is_signed;
@@ -1906,16 +1905,8 @@ out:
return field_op;
}
-static void get_hist_field(struct hist_field *hist_field)
-{
- hist_field->ref++;
-}
-
static void __destroy_hist_field(struct hist_field *hist_field)
{
- if (--hist_field->ref > 1)
- return;
-
kfree(hist_field->var.name);
kfree(hist_field->name);
@@ -1962,8 +1953,6 @@ static struct hist_field *create_hist_fi
if (!hist_field)
return NULL;
- hist_field->ref = 1;
-
hist_field->hist_data = hist_data;
if (flags & HIST_FIELD_FL_EXPR || flags & HIST_FIELD_FL_ALIAS)
@@ -2218,10 +2207,8 @@ static struct hist_field *create_var_ref
for (i = 0; i < hist_data->n_var_refs; i++) {
ref_field = hist_data->var_refs[i];
if (ref_field->var.idx == var_field->var.idx &&
- ref_field->var.hist_data == var_field->hist_data) {
- get_hist_field(ref_field);
+ ref_field->var.hist_data == var_field->hist_data)
return ref_field;
- }
}
/* Sanity check to avoid out-of-bound write on 'hist_data->var_refs' */
if (hist_data->n_var_refs >= TRACING_MAP_VARS_MAX)
@@ -3265,7 +3252,6 @@ static struct hist_field *create_var(str
goto out;
}
- var->ref = 1;
var->flags = HIST_FIELD_FL_VAR;
var->var.idx = idx;
var->var.hist_data = var->hist_data = hist_data;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 499/733] tracing: Free histogram the field rejected for a bad modifier
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (497 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 498/733] tracing: Free histogram var refs regardless of how often they are referenced Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 500/733] tracing: Let histogram values keep the percent and graph modifiers Greg Kroah-Hartman
` (245 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 230234d12ce42ab04132a32c3a848f07a5d27a71 upstream.
Writing a hist trigger whose value or variable carries a modifier that is
not allowed there leaks the fields that were built for it.
__create_val_field() takes the field from parse_expr() and stores it in
hist_data->fields[] only after the modifier checks have run:
hist_field = parse_expr(hist_data, file, field_str, flags, var_name,
&n_subexprs);
...
if (hist_field->flags & HIST_FIELD_FL_VAR) {
if (hist_field->flags & (...))
goto err;
} else {
if (hist_field->flags & (...))
goto err;
}
hist_data->fields[val_idx] = hist_field;
Both checks jump past that store, and the err label returns without
freeing anything. The error unwinds to create_hist_data(), which calls
destroy_hist_data() -> destroy_hist_fields(), and that reaches a field
only by walking fields[]. A field that never got there is unreachable.
commit e0213434fe3e ("tracing: Do not let histogram values have some
modifiers") set ret to -EINVAL and fell through to the store, which left
the field owned by fields[] and freed along with the rest of hist_data.
Splitting the check into a value case and a variable case replaced that
fall-through with a goto that skips it.
With CONFIG_DEBUG_KMEMLEAK, 200 writes of
# echo 'hist:keys=prev_pid:vals=next_pid.log2' > \
events/sched/sched_switch/trigger
each correctly rejected with -EINVAL, leave 332 unreferenced objects
(63744 bytes) reported at create_hist_field(); 200 install and remove
cycles of a valid trigger leave none. A '.log2' field is two
allocations, since create_hist_field() puts the plain field in
operands[0] of the log2 field, and both are reported.
Use destroy_hist_field() rather than __destroy_hist_field() so that
operands[0] is freed as well. It returns early for HIST_FIELD_FL_VAR_REF,
which is what an operand owned by hist_data->var_refs[] needs; the
rejected field itself is never a var ref, because a var ref never carries
a modifier flag.
Cc: stable@vger.kernel.org
Fixes: e30fbc618e97 ("tracing/histograms: Allow variables to have some modifiers")
Link: https://patch.msgid.link/20260907034948.240387-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 1 +
1 file changed, 1 insertion(+)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -4306,6 +4306,7 @@ static int __create_val_field(struct his
return ret;
err:
hist_err(file->tr, HIST_ERR_BAD_FIELD_MODIFIER, errpos(field_str));
+ destroy_hist_field(hist_field, 0);
return -EINVAL;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 500/733] tracing: Let histogram values keep the percent and graph modifiers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (498 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 499/733] tracing: Free histogram the field rejected for a bad modifier Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 501/733] tracing: Keep the entry count when the histogram stats allocation fails Greg Kroah-Hartman
` (244 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 3d617bfd79330ae3acf94862c18bb3ccf5f5a0f9 upstream.
The .percent and .graph modifiers exist only for histogram values, but a
value carrying either of them has been rejected since v6.3. The example
in Documentation/trace/histogram.rst,
# echo 'hist:keys=prev_comm:vals=hitcount.percent:nohitcount' > \
events/sched/sched_switch/trigger
returns -EINVAL.
parse_field() sets the two flags only when the field is neither a key nor
a variable, that is, only on a value:
} else if (strncmp(modifier, "percent", 7) == 0) {
if (*flags & (HIST_FIELD_FL_VAR | HIST_FIELD_FL_KEY))
goto error;
*flags |= HIST_FIELD_FL_PERCENT;
__create_val_field() then rejects a value for carrying them, so no field
can reach hist_trigger_print_val(), where both are implemented.
commit e0213434fe3e ("tracing: Do not let histogram values have some
modifiers") added the check after a value with .buckets oopsed in
hist_field_name(). That happens because .buckets and .log2 make
create_hist_field() build a nested field in operands[0] which
hist_field_name() then walks into. The percent and graph flags do not
create an operand and are not read by hist_field_name(); they are only
used when printing a value.
Stop rejecting the two flags on a value. The check for variables is left
alone, where they are unreachable anyway because parse_field() rejects a
variable carrying them first.
With the two flags removed, the trigger above installs and prints as
documented:
{ prev_comm: rcu_preempt } hitcount (%): 0.00
{ prev_comm: init } hitcount (%): 99.98
Totals:
Hits: 237896
Cc: stable@vger.kernel.org
Fixes: e0213434fe3e ("tracing: Do not let histogram values have some modifiers")
Link: https://patch.msgid.link/20260907052113.430818-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -4288,8 +4288,7 @@ static int __create_val_field(struct his
goto err;
} else {
/* Value */
- if (hist_field->flags & (HIST_FIELD_FL_GRAPH | HIST_FIELD_FL_PERCENT |
- HIST_FIELD_FL_BUCKET | HIST_FIELD_FL_LOG2 |
+ if (hist_field->flags & (HIST_FIELD_FL_BUCKET | HIST_FIELD_FL_LOG2 |
HIST_FIELD_FL_SYM | HIST_FIELD_FL_SYM_OFFSET |
HIST_FIELD_FL_SYSCALL | HIST_FIELD_FL_STACKTRACE))
goto err;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 501/733] tracing: Keep the entry count when the histogram stats allocation fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (499 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 500/733] tracing: Let histogram values keep the percent and graph modifiers Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 502/733] tracing: Take the reference before publishing the named histogram trigger Greg Kroah-Hartman
` (243 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Donggeun Yoo,
Masami Hiramatsu (Google), Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 06f5634ec5584954177f9a22e36b3bfb398a971b upstream.
print_entries() uses n_entries both as the number of sort entries and as
its own return value, so the -ENOMEM it stores when the stats allocation
fails overwrites the count that the cleanup still needs:
n_entries = tracing_map_sort_entries(map, ...);
if (n_entries < 0)
return n_entries;
...
if (!stats) {
n_entries = -ENOMEM;
goto out;
}
...
out:
tracing_map_destroy_sort_entries(sort_entries, n_entries);
tracing_map_destroy_sort_entries() takes an unsigned int and loops up to
it, so -ENOMEM arrives as 4294967284. It walks an array of at most
map->max_elts pointers and calls destroy_sort_entry(), which dereferences
and frees, on whatever lies past the end.
Reading the hist file of a trigger with a .percent value, with that
allocation forced to fail:
BUG: KASAN: vmalloc-out-of-bounds in tracing_map_destroy_sort_entries+0xa0/0xb0
Read of size 8 at addr ffffc90000045000 by task init/1
tracing_map_destroy_sort_entries+0xa0/0xb0
hist_show+0x6f7/0x1df0
seq_read_iter+0x2b8/0x1190
vfs_read+0x176/0xa40
The buggy address belongs to a 4-page vmalloc region starting at
ffffc90000041000 allocated at tracing_map_sort_entries+0x5c/0xd50
A few pages further the fault is fatal. The registers at the oops confirm
the bound: the loop's end pointer less the array start, over the pointer
size, is 4294967284.
Return the error in a separate variable and leave n_entries holding the
count, the way tracing_map_sort_entries() does on its own error path.
The stats block is only entered for a value carrying .percent or .graph,
which __create_val_field() has rejected since v6.3, so this cannot be
reached in mainline as it stands. It becomes reachable again with
"tracing: hist: let values keep the percent and graph modifiers", so it
should be applied first.
Cc: stable@vger.kernel.org
Fixes: abaa5258ce5e ("tracing: Add .percent suffix option to histogram values")
Link: https://patch.msgid.link/20260907060323.480728-1-donggeunyoo.kernel@gmail.com
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/all/20260907053113.1CED91F00A3A@smtp.kernel.org/
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Acked-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -5665,7 +5665,7 @@ static int print_entries(struct seq_file
{
struct tracing_map_sort_entry **sort_entries = NULL;
struct tracing_map *map = hist_data->map;
- int i, j, n_entries;
+ int i, j, n_entries, ret;
struct hist_val_stat *stats = NULL;
u64 val;
@@ -5675,6 +5675,8 @@ static int print_entries(struct seq_file
if (n_entries < 0)
return n_entries;
+ ret = n_entries;
+
/* Calculate the max and the total for each field if needed. */
for (j = 0; j < hist_data->n_vals; j++) {
if (!(hist_data->fields[j]->flags &
@@ -5683,7 +5685,7 @@ static int print_entries(struct seq_file
if (!stats) {
stats = kzalloc_objs(*stats, hist_data->n_vals);
if (!stats) {
- n_entries = -ENOMEM;
+ ret = -ENOMEM;
goto out;
}
}
@@ -5704,7 +5706,7 @@ static int print_entries(struct seq_file
out:
tracing_map_destroy_sort_entries(sort_entries, n_entries);
- return n_entries;
+ return ret;
}
static void hist_trigger_show(struct seq_file *m,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 502/733] tracing: Take the reference before publishing the named histogram trigger
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (500 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 501/733] tracing: Keep the entry count when the histogram stats allocation fails Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 503/733] tracing: Undo the registration when enabling the histogram trigger fails Greg Kroah-Hartman
` (242 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI, Donggeun Yoo,
Tom Zanussi, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 0fe23b8eaba0d3372c66b7b31204408da0715edc upstream.
event_hist_trigger_named_init() puts the trigger on the global
named_triggers list and only then takes the reference on the trigger it
shares its histogram with:
data->ref++;
save_named_trigger(data->named_data->name, data);
ret = event_hist_trigger_init(data->named_data);
if (ret < 0) {
kfree(data->cmd_ops);
data->cmd_ops = &trigger_hist_cmd;
}
return ret;
event_hist_trigger_init() fails when alloc_hist_pad() cannot allocate, and
nothing takes the trigger back off the list on the way out.
event_hist_trigger_parse() frees it, and the next lookup by name reads the
freed object:
BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
Read of size 8 at addr ffff888009346860 by task init/1
find_named_trigger+0xac/0xc0
hist_register_trigger+0xc1/0xa00
event_hist_trigger_parse+0x3146/0x6af0
event_trigger_write+0xce/0x160
Freed by task 67:
kfree+0x154/0x420
trigger_kthread_fn+0xfd/0x160
Do the reference first and publish once it has succeeded, so that nothing
which can fail runs after the trigger becomes findable.
Cc: stable@vger.kernel.org
Fixes: 7ab0fc61ce73 ("tracing: Move histogram trigger variables from stack to per CPU structure")
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-trace-kernel/20260907092944.3950E1F00A3D@smtp.kernel.org/
Link: https://patch.msgid.link/20260907124420.607097-2-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Acked-by: Tom Zanussi <zanussi@kernel.org>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6360,17 +6360,18 @@ static int event_hist_trigger_named_init
{
int ret;
- data->ref++;
-
- save_named_trigger(data->named_data->name, data);
-
ret = event_hist_trigger_init(data->named_data);
if (ret < 0) {
kfree(data->cmd_ops);
data->cmd_ops = &trigger_hist_cmd;
+ return ret;
}
- return ret;
+ data->ref++;
+
+ save_named_trigger(data->named_data->name, data);
+
+ return 0;
}
static void event_hist_trigger_named_free(struct event_trigger_data *data)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 503/733] tracing: Undo the registration when enabling the histogram trigger fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (501 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 502/733] tracing: Take the reference before publishing the named histogram trigger Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 504/733] accel/ivpu: Validate full buffer range in ivpu_to_cpu_addr Greg Kroah-Hartman
` (241 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko AI, Donggeun Yoo,
Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 92383cef66791a0c63a2f27755cadbdb2fbf270b upstream.
Commit 6f86bdeab633 ("tracing: Fix bad hist from corrupting named_triggers
list") described how a trigger that is registered but not on file->triggers
ends up freed while still on the global named_triggers list, and moved the
registration down so that hist_trigger_enable() follows it immediately. One
path still gets there. hist_trigger_enable() adds the trigger and takes it
straight back out when the event cannot be enabled:
list_add_tail_rcu(&data->list, &file->triggers);
update_cond_flag(file);
if (trace_event_trigger_enable_disable(file, 1) < 0) {
list_del_rcu(&data->list);
update_cond_flag(file);
ret--;
}
so the list walk in hist_unregister_trigger() matches nothing, test stays
NULL, and the ->free() that would call del_named_trigger() is skipped.
out_unreg falls through to out_free, which frees the trigger anyway:
BUG: KASAN: slab-use-after-free in find_named_trigger+0xac/0xc0
Read of size 8 at addr ffff8880091d3160 by task init/1
find_named_trigger+0xac/0xc0
hist_register_trigger+0xc1/0xa00
event_hist_trigger_parse+0x3146/0x6af0
event_trigger_write+0xce/0x160
Freed by task 69:
kfree+0x154/0x420
trigger_kthread_fn+0xfd/0x160
Leave the trigger where hist_unregister_trigger() can find it and let that
undo the registration, which is the only code that knows all of what
cmd_ops->init() took: the named list entry, the hist_pad reference, the
reference on the trigger a named histogram is shared with, and the copied
cmd_ops. It also pairs the failed trace_event_trigger_enable_disable(),
whose sm_ref and buffered event reference are otherwise left behind.
Since ->free() releases trigger_data and, for a trigger that does not share
its histogram, hist_data with it, out_unreg can no longer fall through to
out_free. For a trigger that does share, hist_register_trigger() has
already destroyed the caller's hist_data, so the fall-through was reading
freed memory there as well.
Move the enable_timestamps check in hist_unregister_trigger() above the
->free() call for the same reason: hist_data does not outlive it once the
trigger being removed is the one that owns it.
Cc: stable@vger.kernel.org
Fixes: 067fe038e70f ("tracing: Add variable reference handling to hist triggers")
Reported-by: Sashiko AI <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-trace-kernel/20260907092944.3950E1F00A3D@smtp.kernel.org/
Link: https://patch.msgid.link/20260907124420.607097-3-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_events_hist.c | 17 ++++++++++-------
1 file changed, 10 insertions(+), 7 deletions(-)
--- a/kernel/trace/trace_events_hist.c
+++ b/kernel/trace/trace_events_hist.c
@@ -6659,11 +6659,12 @@ static int hist_trigger_enable(struct ev
update_cond_flag(file);
- if (trace_event_trigger_enable_disable(file, 1) < 0) {
- list_del_rcu(&data->list);
- update_cond_flag(file);
+ /*
+ * On failure the caller undoes the registration, and
+ * hist_unregister_trigger() can only find the trigger here.
+ */
+ if (trace_event_trigger_enable_disable(file, 1) < 0)
ret--;
- }
return ret;
}
@@ -6741,13 +6742,13 @@ static void hist_unregister_trigger(char
}
}
- if (test && test->cmd_ops->free)
- test->cmd_ops->free(test);
-
if (hist_data->enable_timestamps) {
if (!hist_data->remove || test)
tracing_set_filter_buffering(file->tr, false);
}
+
+ if (test && test->cmd_ops->free)
+ test->cmd_ops->free(test);
}
static bool hist_file_check_refs(struct trace_event_file *file)
@@ -6952,6 +6953,8 @@ static int event_hist_trigger_parse(stru
return ret;
out_unreg:
event_trigger_unregister(cmd_ops, file, glob+1, trigger_data);
+ /* The unregister frees trigger_data, skip out_free */
+ goto out;
out_free:
remove_hist_vars(hist_data);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 504/733] accel/ivpu: Validate full buffer range in ivpu_to_cpu_addr
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (502 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 503/733] tracing: Undo the registration when enabling the histogram trigger fails Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 505/733] accel/ivpu: Validate firmware log buffer metadata Greg Kroah-Hartman
` (240 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Magdalena Schulfer, Dawid Osuchowski,
Karol Wachowski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Magdalena Schulfer <magdalena.schulfer@intel.com>
commit 3837c3f29fbc3b8c12bebf5c62741e2befe3482a upstream.
Add a size parameter to ivpu_to_cpu_addr() and validate that the
whole [vpu_addr, vpu_addr + size) range stays within the BO.
Cc: stable@vger.kernel.org
Fixes: 647371a6609d ("accel/ivpu: Add GEM buffer object management")
Signed-off-by: Magdalena Schulfer <magdalena.schulfer@intel.com>
Signed-off-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://patch.msgid.link/20260901125749.404338-2-dawid.osuchowski@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ivpu/ivpu_gem.h | 14 +++++++++++---
drivers/accel/ivpu/ivpu_ipc.c | 7 ++++---
2 files changed, 15 insertions(+), 6 deletions(-)
--- a/drivers/accel/ivpu/ivpu_gem.h
+++ b/drivers/accel/ivpu/ivpu_gem.h
@@ -87,15 +87,23 @@ static inline bool ivpu_bo_is_resident(s
return !!bo->base.pages;
}
-static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u32 vpu_addr)
+static inline void *ivpu_to_cpu_addr(struct ivpu_bo *bo, u64 vpu_addr, u64 size)
{
+ u64 bo_size = ivpu_bo_size(bo);
+ u64 offset;
+
if (vpu_addr < bo->vpu_addr)
return NULL;
- if (vpu_addr >= (bo->vpu_addr + ivpu_bo_size(bo)))
+ if (size > bo_size)
+ return NULL;
+
+ offset = vpu_addr - bo->vpu_addr;
+
+ if (offset > bo_size - size)
return NULL;
- return ivpu_bo_vaddr(bo) + (vpu_addr - bo->vpu_addr);
+ return ivpu_bo_vaddr(bo) + offset;
}
static inline u32 cpu_to_vpu_addr(struct ivpu_bo *bo, void *cpu_addr)
--- a/drivers/accel/ivpu/ivpu_ipc.c
+++ b/drivers/accel/ivpu/ivpu_ipc.c
@@ -79,7 +79,7 @@ ivpu_ipc_tx_prepare(struct ivpu_device *
return -ENOMEM;
}
- tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr);
+ tx_buf = ivpu_to_cpu_addr(ipc->mem_tx, tx_buf_vpu_addr, sizeof(*tx_buf));
if (drm_WARN_ON(&vdev->drm, !tx_buf)) {
gen_pool_free(ipc->mm_tx, tx_buf_vpu_addr, sizeof(*tx_buf));
return -EIO;
@@ -420,7 +420,7 @@ void ivpu_ipc_irq_handler(struct ivpu_de
return;
}
- ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr);
+ ipc_hdr = ivpu_to_cpu_addr(ipc->mem_rx, vpu_addr, sizeof(*ipc_hdr));
if (!ipc_hdr) {
ivpu_warn_ratelimited(vdev, "IPC msg 0x%x out of range\n", vpu_addr);
continue;
@@ -429,7 +429,8 @@ void ivpu_ipc_irq_handler(struct ivpu_de
jsm_msg = NULL;
if (ipc_hdr->channel != IVPU_IPC_CHAN_BOOT_MSG) {
- jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, ipc_hdr->data_addr);
+ jsm_msg = ivpu_to_cpu_addr(ipc->mem_rx, ipc_hdr->data_addr,
+ sizeof(*jsm_msg));
if (!jsm_msg) {
ivpu_warn_ratelimited(vdev, "JSM msg 0x%x out of range\n",
ipc_hdr->data_addr);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 505/733] accel/ivpu: Validate firmware log buffer metadata
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (503 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 504/733] accel/ivpu: Validate full buffer range in ivpu_to_cpu_addr Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 506/733] accel/ivpu: Limit firmware log name prints to field size Greg Kroah-Hartman
` (239 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Magdalena Schulfer, Dawid Osuchowski,
Karol Wachowski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Magdalena Schulfer <magdalena.schulfer@intel.com>
commit 0724afc55c77c36c7feb9a7264b02aa7593c5c2d upstream.
The tracing log headers parsed by fw_log_print_buffer() reside in
DMA-shared BOs that the NPU firmware can write to.
fw_log_from_bo() validated log->header_size and log->size, but
fw_log_print_buffer() re-read those same fields from shared memory
afterwards, allowing a TOCTOU where firmware changes them between the
check and the use, and making the host dereference out-of-bounds
addresses while printing logs.
Snapshot the validated values once with READ_ONCE() and pass them down
explicitly in a new struct ivpu_fw_log_desc instead of re-reading them
from the shared struct.
Cc: stable@vger.kernel.org
Fixes: d4e4257afa6e ("accel/ivpu: Add firmware tracing support")
Signed-off-by: Magdalena Schulfer <magdalena.schulfer@intel.com>
Signed-off-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://patch.msgid.link/20260901125749.404338-3-dawid.osuchowski@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ivpu/ivpu_fw_log.c | 76 +++++++++++++++++++++++----------------
1 file changed, 45 insertions(+), 31 deletions(-)
--- a/drivers/accel/ivpu/ivpu_fw_log.c
+++ b/drivers/accel/ivpu/ivpu_fw_log.c
@@ -26,10 +26,17 @@ MODULE_PARM_DESC(fw_log_level,
" error=" __stringify(IVPU_FW_LOG_ERROR)
" fatal=" __stringify(IVPU_FW_LOG_FATAL));
+struct ivpu_fw_log_desc {
+ struct vpu_tracing_buffer_header *log;
+ u32 header_size;
+ u32 size;
+};
+
static int fw_log_from_bo(struct ivpu_device *vdev, struct ivpu_bo *bo, u32 *offset,
- struct vpu_tracing_buffer_header **out_log)
+ struct ivpu_fw_log_desc *desc)
{
struct vpu_tracing_buffer_header *log;
+ u32 header_size, size;
if ((*offset + sizeof(*log)) > ivpu_bo_size(bo))
return -EINVAL;
@@ -39,26 +46,32 @@ static int fw_log_from_bo(struct ivpu_de
if (log->vpu_canary_start != VPU_TRACING_BUFFER_CANARY)
return -EINVAL;
- if (log->header_size < sizeof(*log) || log->header_size > 1024) {
- ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", log->header_size);
+ header_size = READ_ONCE(log->header_size);
+ size = READ_ONCE(log->size);
+
+ if (header_size < sizeof(*log) || header_size > 1024) {
+ ivpu_dbg(vdev, FW_BOOT, "Invalid header size 0x%x\n", header_size);
return -EINVAL;
}
- if (log->size < log->header_size) {
- ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size);
+ if ((char *)log + size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) {
+ ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", size);
return -EINVAL;
}
- if ((char *)log + log->size > (char *)ivpu_bo_vaddr(bo) + ivpu_bo_size(bo)) {
- ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x\n", log->size);
+ if (size < header_size) {
+ ivpu_dbg(vdev, FW_BOOT, "Invalid log size 0x%x < header size 0x%x\n",
+ size, header_size);
return -EINVAL;
}
- *out_log = log;
- *offset += log->size;
+ desc->log = log;
+ desc->header_size = header_size;
+ desc->size = size;
+ *offset += size;
ivpu_dbg(vdev, FW_BOOT,
"FW log name \"%s\", write offset 0x%x size 0x%x, wrap count %d, hdr version %d size %d format %d, alignment %d",
- log->name, log->write_index, log->size, log->wrap_count, log->header_version,
- log->header_size, log->format, log->alignment);
+ log->name, log->write_index, size, log->wrap_count, log->header_version,
+ header_size, log->format, log->alignment);
return 0;
}
@@ -94,11 +107,12 @@ static void fw_log_print_lines(char *buf
drm_printf(p, "%s", line);
}
-static void fw_log_print_buffer(struct vpu_tracing_buffer_header *log, const char *prefix,
+static void fw_log_print_buffer(struct ivpu_fw_log_desc *desc, const char *prefix,
bool only_new_msgs, struct drm_printer *p)
{
- char *log_data = (void *)log + log->header_size;
- u32 data_size = log->size - log->header_size;
+ struct vpu_tracing_buffer_header *log = desc->log;
+ char *log_data = (void *)log + desc->header_size;
+ u32 data_size = desc->size - desc->header_size;
u32 log_start = only_new_msgs ? READ_ONCE(log->read_index) : 0;
u32 log_end = READ_ONCE(log->write_index);
@@ -134,11 +148,11 @@ static void
fw_log_print_all_in_bo(struct ivpu_device *vdev, const char *name,
struct ivpu_bo *bo, bool only_new_msgs, struct drm_printer *p)
{
- struct vpu_tracing_buffer_header *log;
+ struct ivpu_fw_log_desc desc;
u32 next = 0;
- while (fw_log_from_bo(vdev, bo, &next, &log) == 0)
- fw_log_print_buffer(log, name, only_new_msgs, p);
+ while (fw_log_from_bo(vdev, bo, &next, &desc) == 0)
+ fw_log_print_buffer(&desc, name, only_new_msgs, p);
}
void ivpu_fw_log_print(struct ivpu_device *vdev, bool only_new_msgs, struct drm_printer *p)
@@ -149,36 +163,36 @@ void ivpu_fw_log_print(struct ivpu_devic
void ivpu_fw_log_mark_read(struct ivpu_device *vdev)
{
- struct vpu_tracing_buffer_header *log;
+ struct ivpu_fw_log_desc desc;
u32 next;
next = 0;
- while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) {
- log->read_index = READ_ONCE(log->write_index);
- log->read_wrap_count = READ_ONCE(log->wrap_count);
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &desc) == 0) {
+ desc.log->read_index = READ_ONCE(desc.log->write_index);
+ desc.log->read_wrap_count = READ_ONCE(desc.log->wrap_count);
}
next = 0;
- while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) {
- log->read_index = READ_ONCE(log->write_index);
- log->read_wrap_count = READ_ONCE(log->wrap_count);
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &desc) == 0) {
+ desc.log->read_index = READ_ONCE(desc.log->write_index);
+ desc.log->read_wrap_count = READ_ONCE(desc.log->wrap_count);
}
}
void ivpu_fw_log_reset(struct ivpu_device *vdev)
{
- struct vpu_tracing_buffer_header *log;
+ struct ivpu_fw_log_desc desc;
u32 next;
next = 0;
- while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &log) == 0) {
- log->read_index = 0;
- log->read_wrap_count = 0;
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_crit, &next, &desc) == 0) {
+ desc.log->read_index = 0;
+ desc.log->read_wrap_count = 0;
}
next = 0;
- while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &log) == 0) {
- log->read_index = 0;
- log->read_wrap_count = 0;
+ while (fw_log_from_bo(vdev, vdev->fw->mem_log_verb, &next, &desc) == 0) {
+ desc.log->read_index = 0;
+ desc.log->read_wrap_count = 0;
}
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 506/733] accel/ivpu: Limit firmware log name prints to field size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (504 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 505/733] accel/ivpu: Validate firmware log buffer metadata Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 507/733] accel: ethosu: Fix ethosu_job_open() return value Greg Kroah-Hartman
` (238 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, sashiko-bot, Dawid Osuchowski,
Karol Wachowski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
commit 95bf070f3225dc7175725438c916ad321d42fe45 upstream.
The name in struct vpu_tracing_buffer_header is a fixed-size array
populated by the NPU firmware. It is expected to be NUL-terminated,
but nothing on the host side enforces this, so printing it with an
unbounded string conversion would read past the field if the
terminator is ever missing and expose adjacent bytes of the shared
tracing BO through dmesg and the debugfs FW log output.
Print at most as many characters as the name field holds, so the output
never runs past it even if the string is not NUL-terminated.
Cc: stable@vger.kernel.org
Reported-by: sashiko-bot <sashiko-bot@kernel.org>
Closes: https://sashiko.dev/#/patchset/20260827102339.281799-1-dawid.osuchowski@linux.intel.com?part=2
Fixes: d4e4257afa6e ("accel/ivpu: Add firmware tracing support")
Signed-off-by: Dawid Osuchowski <dawid.osuchowski@linux.intel.com>
Reviewed-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Signed-off-by: Karol Wachowski <karol.wachowski@linux.intel.com>
Link: https://patch.msgid.link/20260901125749.404338-4-dawid.osuchowski@linux.intel.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ivpu/ivpu_fw_log.c | 15 +++++++++------
1 file changed, 9 insertions(+), 6 deletions(-)
--- a/drivers/accel/ivpu/ivpu_fw_log.c
+++ b/drivers/accel/ivpu/ivpu_fw_log.c
@@ -69,9 +69,9 @@ static int fw_log_from_bo(struct ivpu_de
*offset += size;
ivpu_dbg(vdev, FW_BOOT,
- "FW log name \"%s\", write offset 0x%x size 0x%x, wrap count %d, hdr version %d size %d format %d, alignment %d",
- log->name, log->write_index, size, log->wrap_count, log->header_version,
- header_size, log->format, log->alignment);
+ "FW log name \"%.*s\", write offset 0x%x size 0x%x, wrap count %d, hdr version %d size %d format %d, alignment %d",
+ (int)ARRAY_SIZE(log->name), log->name, log->write_index, size, log->wrap_count,
+ log->header_version, header_size, log->format, log->alignment);
return 0;
}
@@ -123,7 +123,8 @@ static void fw_log_print_buffer(struct i
if (log->wrap_count == log->read_wrap_count) {
if (log_end <= log_start) {
- drm_printf(p, "==== %s \"%s\" log empty ====\n", prefix, log->name);
+ drm_printf(p, "==== %s \"%.*s\" log empty ====\n", prefix,
+ (int)ARRAY_SIZE(log->name), log->name);
return;
}
} else if (log->wrap_count == log->read_wrap_count + 1) {
@@ -133,7 +134,8 @@ static void fw_log_print_buffer(struct i
log_start = log_end;
}
- drm_printf(p, "==== %s \"%s\" log start ====\n", prefix, log->name);
+ drm_printf(p, "==== %s \"%.*s\" log start ====\n", prefix, (int)ARRAY_SIZE(log->name),
+ log->name);
if (log_end > log_start) {
fw_log_print_lines(log_data + log_start, log_end - log_start, p);
} else {
@@ -141,7 +143,8 @@ static void fw_log_print_buffer(struct i
fw_log_print_lines(log_data, log_end, p);
}
drm_printf(p, "\n\x1b[0m"); /* add new line and clear formatting */
- drm_printf(p, "==== %s \"%s\" log end ====\n", prefix, log->name);
+ drm_printf(p, "==== %s \"%.*s\" log end ====\n", prefix, (int)ARRAY_SIZE(log->name),
+ log->name);
}
static void
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 507/733] accel: ethosu: Fix ethosu_job_open() return value
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (505 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 506/733] accel/ivpu: Limit firmware log name prints to field size Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 508/733] accel: ethosu: Drop IRQF_SHARED flag Greg Kroah-Hartman
` (237 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Frank Li, Rob Herring (Arm)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) <robh@kernel.org>
commit b3c8d4672f7a8735e2884cefcd89286268e88b2e upstream.
A WARN_ON() returns a 0 or 1, not the original negative errno. Just drop
the WARN_ON() as the FD open will pass the return code to userspace and
there's only one possible source of the error (drm_sched_entity_init()).
Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-1-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ethosu/ethosu_job.c | 8 +++-----
1 file changed, 3 insertions(+), 5 deletions(-)
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -356,12 +356,10 @@ int ethosu_job_open(struct ethosu_file_p
{
struct ethosu_device *dev = ethosu_priv->edev;
struct drm_gpu_scheduler *sched = &dev->sched;
- int ret;
- ret = drm_sched_entity_init(ðosu_priv->sched_entity,
- DRM_SCHED_PRIORITY_NORMAL,
- &sched, 1, NULL);
- return WARN_ON(ret);
+ return drm_sched_entity_init(ðosu_priv->sched_entity,
+ DRM_SCHED_PRIORITY_NORMAL,
+ &sched, 1, NULL);
}
void ethosu_job_close(struct ethosu_file_priv *ethosu_priv)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 508/733] accel: ethosu: Drop IRQF_SHARED flag
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (506 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 507/733] accel: ethosu: Fix ethosu_job_open() return value Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 509/733] accel: ethosu: Ensure cmd stream ends with a stop op Greg Kroah-Hartman
` (236 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Frank Li, Rob Herring (Arm)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) <robh@kernel.org>
commit 2cbd3691565f7c86c0eaca305f5beb3435b4ba70 upstream.
The IRQF_SHARED flag doesn't work with runtime-pm as the IRQ handler
could run without resuming the device. This could also be fixed with
runtime-pm calls in the IRQ handler, but there is no known need for a
shared IRQ.
Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-2-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ethosu/ethosu_job.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -325,7 +325,7 @@ int ethosu_job_init(struct ethosu_device
ret = devm_request_threaded_irq(dev, edev->irq,
ethosu_job_irq_handler,
ethosu_job_irq_handler_thread,
- IRQF_SHARED, KBUILD_MODNAME,
+ 0, KBUILD_MODNAME,
edev);
if (ret) {
dev_err(dev, "failed to request irq\n");
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 509/733] accel: ethosu: Ensure cmd stream ends with a stop op
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (507 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 508/733] accel: ethosu: Drop IRQF_SHARED flag Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 510/733] accel: ethosu: Ensure SRAM size is 0 on mapping failure Greg Kroah-Hartman
` (235 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Frank Li, Rob Herring (Arm)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) <robh@kernel.org>
commit eb3a41fd35e352fba387c4320a1fa0352f3e551c upstream.
While the QSIZE register setting should prevent an out of bounds access
of the command stream, it is not clear whether the h/w generates an
interrupt in this case as is required (to prevent a timeout). As a stop op
is expected end of the command stream, let's just ensure it is present. A
stop op in the middle of the command stream also makes no sense.
Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-3-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ethosu/ethosu_device.h | 1 +
drivers/accel/ethosu/ethosu_gem.c | 9 +++++++++
2 files changed, 10 insertions(+)
--- a/drivers/accel/ethosu/ethosu_device.h
+++ b/drivers/accel/ethosu/ethosu_device.h
@@ -68,6 +68,7 @@ struct gen_pool;
#define PROT_ACTIVE_CSL BIT(1)
enum ethosu_cmds {
+ NPU_OP_STOP = 0x0,
NPU_OP_CONV = 0x2,
NPU_OP_DEPTHWISE = 0x3,
NPU_OP_POOL = 0x5,
--- a/drivers/accel/ethosu/ethosu_gem.c
+++ b/drivers/accel/ethosu/ethosu_gem.c
@@ -390,6 +390,7 @@ static int ethosu_gem_cmdstream_copy_and
struct ethosu_validated_cmdstream_info __free(kfree) *info = kzalloc_obj(*info);
struct ethosu_device *edev = to_ethosu_device(ddev);
u32 *bocmds = bo->base.vaddr;
+ bool ends_with_stop = false;
struct cmd_state st;
int i, ret;
@@ -426,6 +427,11 @@ static int ethosu_gem_cmdstream_copy_and
}
switch (cmd) {
+ case NPU_OP_STOP:
+ if (i != size / 4 - 1)
+ return -EINVAL;
+ ends_with_stop = true;
+ break;
case NPU_OP_DMA_START:
srclen = dma_length(info, &st.dma, &st.dma.src);
dstlen = dma_length(info, &st.dma, &st.dma.dst);
@@ -688,6 +694,9 @@ static int ethosu_gem_cmdstream_copy_and
}
}
+ if (!ends_with_stop)
+ return -EINVAL;
+
for (i = 0; i < NPU_BASEP_REGION_MAX; i++) {
if (!info->region_size[i])
continue;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 510/733] accel: ethosu: Ensure SRAM size is 0 on mapping failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (508 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 509/733] accel: ethosu: Ensure cmd stream ends with a stop op Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 511/733] accel: ethosu: Ensure SRAM region size matches job Greg Kroah-Hartman
` (234 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Frank Li, Rob Herring (Arm)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) <robh@kernel.org>
commit f5376d7e0fb703876199d3b6f9f97e128fa2f8a4 upstream.
On a mapping failure of the SRAM, the SRAM size is left as non-zero. The
probe will succeed as the error return is not checked since having SRAM is
not a hard requirement. The non-zero size allows jobs to access SRAM which
is left pointing to physical base address 0x0.
Fixes: 5a5e9c0228e6 ("accel: Add Arm Ethos-U NPU driver")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-4-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ethosu/ethosu_drv.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/drivers/accel/ethosu/ethosu_drv.c
+++ b/drivers/accel/ethosu/ethosu_drv.c
@@ -274,8 +274,6 @@ static int ethosu_device_suspend(struct
static int ethosu_sram_init(struct ethosu_device *ethosudev)
{
- ethosudev->npu_info.sram_size = 0;
-
ethosudev->srampool = of_gen_pool_get(ethosudev->base.dev->of_node, "sram", 0);
if (!ethosudev->srampool)
return 0;
@@ -286,6 +284,7 @@ static int ethosu_sram_init(struct ethos
ethosudev->npu_info.sram_size,
ðosudev->sramphys);
if (!ethosudev->sram) {
+ ethosudev->npu_info.sram_size = 0;
dev_err(ethosudev->base.dev, "failed to allocate from SRAM pool\n");
return -ENOMEM;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 511/733] accel: ethosu: Ensure SRAM region size matches job
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (509 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 510/733] accel: ethosu: Ensure SRAM size is 0 on mapping failure Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 512/733] ata: pata_legacy: remove documentation for removed module parameters Greg Kroah-Hartman
` (233 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Frank Li, Rob Herring (Arm)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) <robh@kernel.org>
commit 2b39d680c9e0fb4d625f2916980977622e84248c upstream.
It is possible for userspace to set the job SRAM size to 0, but then still
have SRAM accesses in the command stream. When the job SRAM size is 0,
setting the region base register is skipped and a stale base address from
a prior job is used.
Check the region size against the job's SRAM size instead of just the size
of the SRAM. The job's SRAM size was already checked against the total SRAM
size.
Fixes: 9cff90774872 ("accel: ethosu: Validate SRAM size on submit")
Cc: stable@vger.kernel.org
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260827-ethosu-fixes-v1-5-346f9ea8791c@kernel.org
Signed-off-by: Rob Herring (Arm) <robh@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/ethosu/ethosu_job.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/accel/ethosu/ethosu_job.c
+++ b/drivers/accel/ethosu/ethosu_job.c
@@ -425,13 +425,13 @@ static int ethosu_ioctl_submit_job(struc
if (!cmd_info->region_size[i])
continue;
if (i == ETHOSU_SRAM_REGION) {
- if (cmd_info->region_size[i] <= edev->npu_info.sram_size)
+ if (cmd_info->region_size[i] <= ejob->sram_size)
continue;
dev_err(dev->dev,
- "cmd stream region %d size greater than SRAM size (%llu > %u)\n",
+ "cmd stream region %d size greater than job SRAM size (%llu > %u)\n",
i, cmd_info->region_size[i],
- edev->npu_info.sram_size);
+ ejob->sram_size);
ret = -EINVAL;
goto out_cleanup_job;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 512/733] ata: pata_legacy: remove documentation for removed module parameters
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (510 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 511/733] accel: ethosu: Ensure SRAM region size matches job Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 513/733] ASoC: amd: acp-da7219-max98357a: dont bind on Raven/Picasso boards Greg Kroah-Hartman
` (232 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ethan Nelson-Moore, Karl Mehltretter,
Damien Le Moal, Randy Dunlap, Niklas Cassel
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Nelson-Moore <enelsonmoore@gmail.com>
commit a19d4f9b8befdcfcd5a87bab91312fe64af3bbb8 upstream.
Commit 3c4d783f6922 ("ata: pata_legacy: remove VLB support") removed
several module parameters from the pata_legacy driver, but neglected to
remove their documentation. Remove it.
Fixes: 3c4d783f6922 ("ata: pata_legacy: remove VLB support")
Cc: stable@vger.kernel.org # 7.0+
Signed-off-by: Ethan Nelson-Moore <enelsonmoore@gmail.com>
Reviewed-by: Karl Mehltretter <kmehltretter@gmail.com>
Reviewed-by: Damien Le Moal <dlemoal@kernel.org>
Reviewed-by: Randy Dunlap <rdunlap@infradead.org>
Link: https://lore.kernel.org/r/20260607064053.195166-1-enelsonmoore@gmail.com
Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/admin-guide/kernel-parameters.txt | 37 ------------------------
1 file changed, 37 deletions(-)
--- a/Documentation/admin-guide/kernel-parameters.txt
+++ b/Documentation/admin-guide/kernel-parameters.txt
@@ -4922,18 +4922,6 @@ Kernel parameters
Set to non-zero if a chip is present that snoops speed
changes. Disabled by default.
- pata_legacy.ht6560a= [HW,LIBATA]
- Format: <int>
- Set to 1, 2, or 3 for HT 6560A on the primary channel,
- the secondary channel, or both channels respectively.
- Disabled by default.
-
- pata_legacy.ht6560b= [HW,LIBATA]
- Format: <int>
- Set to 1, 2, or 3 for HT 6560B on the primary channel,
- the secondary channel, or both channels respectively.
- Disabled by default.
-
pata_legacy.iordy_mask= [HW,LIBATA]
Format: <int>
IORDY enable mask. Set individual bits to allow IORDY
@@ -4946,18 +4934,6 @@ Kernel parameters
with the sequence. By default IORDY is allowed across
all channels.
- pata_legacy.opti82c46x= [HW,LIBATA]
- Format: <int>
- Set to 1, 2, or 3 for Opti 82c611A on the primary
- channel, the secondary channel, or both channels
- respectively. Disabled by default.
-
- pata_legacy.opti82c611a= [HW,LIBATA]
- Format: <int>
- Set to 1, 2, or 3 for Opti 82c465MV on the primary
- channel, the secondary channel, or both channels
- respectively. Disabled by default.
-
pata_legacy.pio_mask= [HW,LIBATA]
Format: <int>
PIO mode mask for autospeed devices. Set individual
@@ -4981,19 +4957,6 @@ Kernel parameters
the first port in the list above (0x1f0), and so on.
By default all supported ports are probed.
- pata_legacy.qdi= [HW,LIBATA]
- Format: <int>
- Set to non-zero to probe QDI controllers. By default
- set to 1 if CONFIG_PATA_QDI_MODULE, 0 otherwise.
-
- pata_legacy.winbond= [HW,LIBATA]
- Format: <int>
- Set to non-zero to probe Winbond controllers. Use
- the standard I/O port (0x130) if 1, otherwise the
- value given is the I/O port to use (typically 0x1b0).
- By default set to 1 if CONFIG_PATA_WINBOND_VLB_MODULE,
- 0 otherwise.
-
pata_platform.pio_mask= [HW,LIBATA]
Format: <int>
Supported PIO mode mask. Set individual bits to allow
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 513/733] ASoC: amd: acp-da7219-max98357a: dont bind on Raven/Picasso boards
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (511 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 512/733] ata: pata_legacy: remove documentation for removed module parameters Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 514/733] ASoC: sprd: validate compress buffer sizes against fixed allocations Greg Kroah-Hartman
` (231 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yorick Rommers, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yorick Rommers <yorick-rommers@hotmail.com>
commit 7e125889f1705fc6326679a3db3b4159f7a8c87e upstream.
The "AMDI5682" ACPI HID is matched by two AMD ASoC machine drivers:
cz-da7219-max98357a (this driver, Carrizo/Stoney) and
acp3x-alc5682-max98357 (Raven/Picasso). cz-da7219-max98357a is linked
first and probes the platform device first; its DAI links reference the
Stoney ACP, which is absent on Raven/Picasso, so its card can never be
instantiated there.
This was harmless until commit 42d99857d6f0 ("ASoC: core: Move all users
to deferrable card binding"): devm_snd_soc_register_card() now returns 0
for a card left pending instead of propagating -EPROBE_DEFER, so
cz_probe() succeeds and permanently binds AMDI5682. acp3x-alc5682-max98357
never binds and the internal speakers and headphone jack get no card.
Detect Raven/Picasso (and later) by the ACP3.x audio coprocessor's
dedicated PCI function (1022:15e2); Carrizo/Stoney reach the ACP through
the GPU driver and have no such device. Return -ENODEV so the driver core
continues probing AMDI5682 with acp3x-alc5682-max98357.
Fixes: 42d99857d6f0 ("ASoC: core: Move all users to deferrable card binding")
Cc: stable@vger.kernel.org
Signed-off-by: Yorick Rommers <yorick-rommers@hotmail.com>
Tested-by: Yorick Rommers <yorick-rommers@hotmail.com>
Link: https://patch.msgid.link/20260907121228.13754-1-yorick-rommers@hotmail.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/amd/acp-da7219-max98357a.c | 23 +++++++++++++++++++++++
1 file changed, 23 insertions(+)
diff --git a/sound/soc/amd/acp-da7219-max98357a.c b/sound/soc/amd/acp-da7219-max98357a.c
index af559653e625..1ac729a58bb4 100644
--- a/sound/soc/amd/acp-da7219-max98357a.c
+++ b/sound/soc/amd/acp-da7219-max98357a.c
@@ -17,6 +17,7 @@
#include <linux/i2c.h>
#include <linux/input.h>
#include <linux/acpi.h>
+#include <linux/pci.h>
#include "acp.h"
#include "../codecs/da7219.h"
@@ -742,6 +743,18 @@ static const struct regulator_desc acp_da7219_desc = {
.n_voltages = 1,
};
+/*
+ * The ACP3.x+ (Raven/Picasso and later) audio coprocessor is a dedicated PCI
+ * function. Carrizo/Stoney - the only platforms handled by this driver - reach
+ * the ACP through the GPU driver and have no such device.
+ */
+#define ACP3X_PCI_DEV_ID 0x15e2
+
+static const struct pci_device_id acp3x_pci_ids[] = {
+ { PCI_DEVICE(PCI_VENDOR_ID_AMD, ACP3X_PCI_DEV_ID) },
+ { 0, },
+};
+
static int cz_probe(struct platform_device *pdev)
{
int ret;
@@ -750,6 +763,16 @@ static int cz_probe(struct platform_device *pdev)
struct regulator_dev *rdev;
struct device *dev = &pdev->dev;
+ /*
+ * AMDI5682 is also matched by acp3x-alc5682-max98357 (Raven/Picasso).
+ * If the ACP3.x PCI function is present this is such a board; return
+ * -ENODEV so that driver binds instead.
+ */
+ if (pci_dev_present(acp3x_pci_ids)) {
+ dev_info(dev, "ACP3.x PCI device present, deferring to acp3x-alc5682-max98357\n");
+ return -ENODEV;
+ }
+
card = (struct snd_soc_card *)acp_soc_is_rltk_max(dev);
if (!card)
return -ENODEV;
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 514/733] ASoC: sprd: validate compress buffer sizes against fixed allocations
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (512 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 513/733] ASoC: amd: acp-da7219-max98357a: dont bind on Raven/Picasso boards Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 515/733] ASoC: sti: initialize IRQ lock before requesting IRQ Greg Kroah-Hartman
` (230 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Tianchu Chen, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianchu Chen <flynnnchen@tencent.com>
commit 7a4ce92d150b9e7ecf1a710a34d8cdeb590d3751 upstream.
sprd_platform_compr_open() allocates the stage 0 IRAM buffer (32K data
area) and the stage 1 DDR buffer (2M data area) with fixed sizes, but
sprd_platform_compr_copy() derives all copy lengths from the user
controlled runtime->fragment_size and the write() count, never
comparing them against the physical buffer sizes. The compress core
only checks fragment_size * fragments for an u32 overflow in
snd_compress_check_input(), so a local user can configure a logical
buffer of up to ~4GB via SNDRV_COMPRESS_SET_PARAMS, far exceeding the
fixed allocations.
A fragment_size larger than the 32K IRAM data area makes the stage 0
copy_from_user() overflow past the IRAM allocation, and a buffer_size
larger than the 2M DDR buffer makes the wrapping copy at the end of
sprd_platform_compr_copy() write fully user controlled data past the
buffer. No SNDRV_PCM_TRIGGER_START is needed, a write() in SETUP
state reaches the copy callback directly.
Reject parameters that do not fit into the fixed buffers in
set_params(), and fix the advertised max fragment size: 128K never
fitted into the 32K IRAM buffer. The caps values may have been carried over
from the qdsp6 driver, which allocates its buffers according to the
advertised maxima, unlike this driver. With 32K as max fragment size
the advertised limits are self-consistent: 32K * 64 = 2M equals the
DDR buffer size.
Discovered by Atuin - Automated Vulnerability Discovery Engine.
Fixes: cce1396936ef ("ASoC: sprd: Add Spreadtrum audio compress offload support")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Tianchu Chen <flynnnchen@tencent.com>
Link: https://patch.msgid.link/4386bc53631b052c1866a91061715b009d98b04f@linux.dev
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/sprd/sprd-pcm-compress.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/sound/soc/sprd/sprd-pcm-compress.c
+++ b/sound/soc/sprd/sprd-pcm-compress.c
@@ -17,7 +17,7 @@
/* Default values if userspace does not set */
#define SPRD_COMPR_MIN_FRAGMENT_SIZE SZ_8K
-#define SPRD_COMPR_MAX_FRAGMENT_SIZE SZ_128K
+#define SPRD_COMPR_MAX_FRAGMENT_SIZE SZ_32K
#define SPRD_COMPR_MIN_NUM_FRAGMENTS 4
#define SPRD_COMPR_MAX_NUM_FRAGMENTS 64
@@ -272,6 +272,19 @@ static int sprd_platform_compr_set_param
int ret;
/*
+ * The stage 0 IRAM buffer and the stage 1 DDR buffer are allocated
+ * with fixed sizes at open time, so the requested fragment size and
+ * fragments must fit into them, otherwise sprd_platform_compr_copy()
+ * would overflow the buffers. Note the compress core only checks the
+ * fragment size and fragments against an u32 overflow, not against
+ * the buffer sizes advertised by get_caps.
+ */
+ if (params->buffer.fragment_size > SPRD_COMPR_IRAM_BUF_SIZE ||
+ (u64)params->buffer.fragment_size * params->buffer.fragments >
+ SPRD_COMPR_AREA_BUF_SIZE)
+ return -EINVAL;
+
+ /*
* Configure the DMA engine 2-stage transfer mode. Channel 1 set as the
* destination channel, and channel 0 set as the source channel, that
* means once the source channel's transaction is done, it will trigger
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 515/733] ASoC: sti: initialize IRQ lock before requesting IRQ
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (513 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 514/733] ASoC: sprd: validate compress buffer sizes against fixed allocations Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 516/733] Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev Greg Kroah-Hartman
` (229 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Runyu Xiao, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 04405aeef4f8d7bcac6dcb1947acafdb4420c2c3 upstream.
uni_reader_init() registers the shared IRQ before initializing
reader->irq_lock. A pending interrupt can invoke the handler while the
lock is still uninitialized.
Initialize the lock before registering the IRQ so the interrupt path
always sees valid lock state.
Fixes: d05d862ead8e ("ASoC: STI: Fix null ptr deference in IRQ handler")
Cc: stable@vger.kernel.org
Assisted-by: Codex:GPT-5
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260830142026.2666914-1-runyu.xiao@seu.edu.cn
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/sti/uniperif_reader.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/sound/soc/sti/uniperif_reader.c
+++ b/sound/soc/sti/uniperif_reader.c
@@ -416,6 +416,8 @@ int uni_reader_init(struct platform_devi
else
reader->hw = &uni_reader_pcm_hw;
+ spin_lock_init(&reader->irq_lock);
+
ret = devm_request_irq(&pdev->dev, reader->irq,
uni_reader_irq_handler, IRQF_SHARED,
dev_name(&pdev->dev), reader);
@@ -424,8 +426,6 @@ int uni_reader_init(struct platform_devi
return -EBUSY;
}
- spin_lock_init(&reader->irq_lock);
-
return 0;
}
EXPORT_SYMBOL_GPL(uni_reader_init);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 516/733] Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (514 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 515/733] ASoC: sti: initialize IRQ lock before requesting IRQ Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 517/733] Bluetooth: btrtl: Dont leak return code when parsing firmware format v2 Greg Kroah-Hartman
` (228 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bartosz Golaszewski,
Dmitry Baryshkov, Xu Rao, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Rao <raoxu@uniontech.com>
commit f5a427b16e45210dee656b0860728f3d496dee85 upstream.
The command and ACL RPMsg endpoints store struct btqcomsmd as their
callback private data. The receive callbacks dereference btq->hdev
without taking an hci_dev reference.
The current teardown order frees the hci_dev before destroying the RPMsg
endpoints in both the hci_register_dev() error path and the driver remove
path. If WCNSS delivers data in that window, the endpoint callback can
run with an already freed hci_dev and pass it to the Bluetooth core.
For qcom_smd endpoints, rpmsg_destroy_ept() closes the channel and clears
the callback under the channel recv_lock. The receive path holds the same
lock while invoking the callback, so destroying the endpoints first both
prevents new callbacks and serializes with any callback already running.
Destroy the command and ACL endpoints before hci_free_dev(). Keep
hci_unregister_dev() first during remove so the HCI core stops issuing
operations before the transport endpoints are shut down. In the full
registration-error cleanup path, return directly after freeing the hci_dev
to avoid falling through to the partial-construction labels and destroying
the endpoints twice.
Fixes: 5052de8deff5 ("soc: qcom: smd: Transition client drivers from smd to rpmsg")
Fixes: 9a39a927be01 ("Bluetooth: btqcomsmd: Fix a resource leak in error handling paths in the probe function")
Cc: stable@vger.kernel.org
Acked-by: Bartosz Golaszewski <bartosz.golaszewski@oss.qualcomm.com>
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Xu Rao <raoxu@uniontech.com>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/bluetooth/btqcomsmd.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/bluetooth/btqcomsmd.c
+++ b/drivers/bluetooth/btqcomsmd.c
@@ -188,7 +188,10 @@ static int btqcomsmd_probe(struct platfo
return 0;
hci_free_dev:
+ rpmsg_destroy_ept(btq->cmd_channel);
+ rpmsg_destroy_ept(btq->acl_channel);
hci_free_dev(hdev);
+ return ret;
destroy_cmd_channel:
rpmsg_destroy_ept(btq->cmd_channel);
destroy_acl_channel:
@@ -202,10 +205,11 @@ static void btqcomsmd_remove(struct plat
struct btqcomsmd *btq = platform_get_drvdata(pdev);
hci_unregister_dev(btq->hdev);
- hci_free_dev(btq->hdev);
rpmsg_destroy_ept(btq->cmd_channel);
rpmsg_destroy_ept(btq->acl_channel);
+
+ hci_free_dev(btq->hdev);
}
static const struct of_device_id btqcomsmd_of_match[] = {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 517/733] Bluetooth: btrtl: Dont leak return code when parsing firmware format v2
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (515 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 516/733] Bluetooth: btqcomsmd: destroy RPMsg endpoints before freeing hci_dev Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 518/733] bootconfig: Fix integer overflow in initrd size check Greg Kroah-Hartman
` (227 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Rong Zhang, Luiz Augusto von Dentz
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rong Zhang <i@rong.moe>
commit 83e3e515fd261600ed8491fb0a8bcdfb115c904e upstream.
When key_id from chip is zero, rtlbt_parse_firmware_v2() intentionally
ignores all security headers. However, the implementation simply breaks
from a switch statement and leaks uninitialized return code `rc' (if the
first section is a security one) or the previous section's `rc'.
Fix it by really skipping a loop with `continue'. For consistency and
readability, also do the same for the default case.
Fixes: 9a24ce5e29b1 ("Bluetooth: btrtl: Firmware format v2 support")
Cc: stable@vger.kernel.org
Signed-off-by: Rong Zhang <i@rong.moe>
Signed-off-by: Luiz Augusto von Dentz <luiz.von.dentz@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/bluetooth/btrtl.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/bluetooth/btrtl.c
+++ b/drivers/bluetooth/btrtl.c
@@ -591,7 +591,7 @@ static int rtlbt_parse_firmware_v2(struc
* headers.
*/
if (!key_id)
- break;
+ continue;
rc = btrtl_parse_section(hdev, btrtl_dev, opcode,
ptr, section_len);
break;
@@ -600,8 +600,7 @@ static int rtlbt_parse_firmware_v2(struc
ptr, section_len);
break;
default:
- rc = 0;
- break;
+ continue;
}
if (rc < 0) {
rtl_dev_err(hdev, "RTL: Parse section (%u) err %d",
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 518/733] bootconfig: Fix integer overflow in initrd size check
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (516 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 517/733] Bluetooth: btrtl: Dont leak return code when parsing firmware format v2 Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 519/733] cpufreq: zero-initialize policy cpumask before sysfs publication Greg Kroah-Hartman
` (226 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Masami Hiramatsu (Google),
Sang-Heon Jeon
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Masami Hiramatsu (Google) <mhiramat@kernel.org>
commit 7812d6dab0698001e50e8c2f901e17da3eb6f429 upstream.
Sashiko reported that in get_boot_config_from_initrd(), a crafted initrd
with a huge bootconfig size (such as 0xFFFFFFFF) can cause the pointer
arithmetic:
data = ((void *)hdr) - size;
to wrap around on 32-bit systems (or when pointer subtraction overflows).
Because data wraps around, the subsequent bounds check:
if ((unsigned long)data < initrd_start)
evaluates to false, bypassing the check. The kernel then calls
xbc_calc_checksum(data, size), which attempts to read 4GB of memory,
hitting unmapped pages and triggering a fatal kernel page fault during
early boot. Furthermore, on 64-bit systems with an initrd > 4.29 GB, an
unbounded 32-bit size can similarly bypass the initrd_start check.
Fix this by:
1. Ensuring the initrd is at least large enough to contain the bootconfig
footer and verifying hdr is within the initrd bounds.
2. Checking that size does not exceed XBC_DATA_MAX and does not exceed
the available space between initrd_start and hdr before performing
pointer subtraction.
Link: https://lore.kernel.org/all/178905333479.213925.1358412668943562406.stgit@devnote2/
Fixes: de462e5f1071 ("bootconfig: Fix to remove bootconfig data from initrd while boot")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/all/20260910010137.EE0431F000FF@smtp.kernel.org/
Assisted-by: Antigravity:gemini-3.8-flash
Signed-off-by: Masami Hiramatsu (Google) <mhiramat@kernel.org>
Reviewed-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
init/main.c | 25 +++++++++++++++----------
1 file changed, 15 insertions(+), 10 deletions(-)
--- a/init/main.c
+++ b/init/main.c
@@ -276,7 +276,8 @@ static void * __init get_boot_config_fro
u8 *hdr;
int i;
- if (!initrd_end)
+ if (!initrd_end || initrd_end < initrd_start ||
+ initrd_end - initrd_start < BOOTCONFIG_MAGIC_LEN + 8)
return NULL;
data = (char *)initrd_end - BOOTCONFIG_MAGIC_LEN;
@@ -293,16 +294,26 @@ static void * __init get_boot_config_fro
found:
hdr = (u8 *)(data - 8);
+ if ((unsigned long)hdr < initrd_start)
+ return NULL;
+
size = get_unaligned_le32(hdr);
csum = get_unaligned_le32(hdr + 4);
- data = ((void *)hdr) - size;
- if ((unsigned long)data < initrd_start) {
- pr_err("bootconfig size %d is greater than initrd size %ld\n",
+ if (size > XBC_DATA_MAX) {
+ pr_err("bootconfig size %u is greater than max size %d\n",
+ size, XBC_DATA_MAX);
+ return NULL;
+ }
+
+ if (size > ((unsigned long)hdr - initrd_start)) {
+ pr_err("bootconfig size %u is greater than initrd size %lu\n",
size, initrd_end - initrd_start);
return NULL;
}
+ data = ((void *)hdr) - size;
+
if (xbc_calc_checksum(data, size) != csum) {
pr_err("bootconfig checksum failed\n");
return NULL;
@@ -405,12 +416,6 @@ static void __init setup_boot_config(voi
return;
}
- if (size >= XBC_DATA_MAX) {
- pr_err("bootconfig size %ld greater than max size %d\n",
- (long)size, XBC_DATA_MAX);
- return;
- }
-
ret = xbc_init(data, size, &msg, &pos);
if (ret < 0) {
if (pos < 0)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 519/733] cpufreq: zero-initialize policy cpumask before sysfs publication
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (517 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 518/733] bootconfig: Fix integer overflow in initrd size check Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 520/733] cpufreq: initialize policy rwsem " Greg Kroah-Hartman
` (225 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhongqiu Han, Viresh Kumar,
Rafael J. Wysocki
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
commit 54d37bcf2f497140b9207968557ddb484058e749 upstream.
cpufreq_policy_alloc() allocates policy->cpus with alloc_cpumask_var(),
i.e. without __GFP_ZERO, unlike the sibling related_cpus and real_cpus
masks. With CONFIG_CPUMASK_OFFSTACK=y the mask is a separate
kmalloc_node() allocation, so its bitmap holds whatever the slab allocator
left behind:
cpufreq_online()
cpufreq_policy_alloc()
alloc_cpumask_var(&policy->cpus) /* bitmap is uninitialized */
kobject_init_and_add() /* policy%u/ appears in sysfs */
cpufreq_policy_online()
cpumask_copy(policy->cpus, cpumask_of(cpu)) /* first valid value */
This leaves a window in which the sysfs attributes are already reachable
while policy->cpus is still garbage. show()/store() gate on
policy_is_inactive(), i.e. cpumask_empty(policy->cpus), so a non-zero
bitmap makes them run the attribute callbacks on a policy that is not
initialized yet.
Fix this by using zalloc_cpumask_var() for policy->cpus.
Fixes: 2fc3384dc75b ("cpufreq: Initialize policy->kobj while allocating policy")
Cc: All applicable <stable@vger.kernel.org>
Signed-off-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://patch.msgid.link/20260901143635.4106960-1-zhongqiu.han@oss.qualcomm.com
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/cpufreq/cpufreq.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1249,7 +1249,7 @@ static struct cpufreq_policy *cpufreq_po
if (!policy)
return NULL;
- if (!alloc_cpumask_var(&policy->cpus, GFP_KERNEL))
+ if (!zalloc_cpumask_var(&policy->cpus, GFP_KERNEL))
goto err_free_policy;
if (!zalloc_cpumask_var(&policy->related_cpus, GFP_KERNEL))
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 520/733] cpufreq: initialize policy rwsem before sysfs publication
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (518 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 519/733] cpufreq: zero-initialize policy cpumask before sysfs publication Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 521/733] exec: do_close_on_exec() before taking exec_update_lock Greg Kroah-Hartman
` (224 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Zhongqiu Han, Runyu Xiao,
Viresh Kumar, Rafael J. Wysocki
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit 3e5d1bf4bd687beb2cb4e32a07af695455925588 upstream.
cpufreq_policy_alloc() initializes policy->rwsem after
kobject_init_and_add() has created the policy sysfs directory and its
default attributes. A sysfs access can therefore reach a policy callback
before the semaphore has been initialized.
Initialize policy->rwsem before publishing the policy kobject so sysfs
callbacks always see an initialized semaphore.
Fixes: 2fc3384dc75b ("cpufreq: Initialize policy->kobj while allocating policy")
Cc: All Applicable <stable@vger.kernel.org>
Link: https://lore.kernel.org/all/20260830155301.2713780-1-runyu.xiao@seu.edu.cn/
Reviewed-by: Zhongqiu Han <zhongqiu.han@oss.qualcomm.com>
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Acked-by: Viresh Kumar <viresh.kumar@linaro.org>
Link: https://patch.msgid.link/20260902041915.3453421-1-runyu.xiao@seu.edu.cn
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/cpufreq/cpufreq.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/drivers/cpufreq/cpufreq.c
+++ b/drivers/cpufreq/cpufreq.c
@@ -1258,6 +1258,8 @@ static struct cpufreq_policy *cpufreq_po
if (!zalloc_cpumask_var(&policy->real_cpus, GFP_KERNEL))
goto err_free_rcpumask;
+ init_rwsem(&policy->rwsem);
+
init_completion(&policy->kobj_unregister);
ret = kobject_init_and_add(&policy->kobj, &ktype_cpufreq,
cpufreq_global_kobject, "policy%u", cpu);
@@ -1272,8 +1274,6 @@ static struct cpufreq_policy *cpufreq_po
goto err_free_real_cpus;
}
- init_rwsem(&policy->rwsem);
-
freq_constraints_init(&policy->constraints);
policy->nb_min.notifier_call = cpufreq_notifier_min;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 521/733] exec: do_close_on_exec() before taking exec_update_lock
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (519 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 520/733] cpufreq: initialize policy rwsem " Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 522/733] exit: hold a reference to thread_pid across proc_flush_pid Greg Kroah-Hartman
` (223 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Benjamin Peterson, Jann Horn,
Jan Kara, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jann Horn <jannh@google.com>
commit e780259b54e618ceb4763fbc21314acf3565e813 upstream.
do_close_on_exec() currently happens while holding the exec_update_lock,
which is used in a lot of places that access process state to
synchronize access checks.
I recently added another such use of exec_update_lock, causing a
regression.
do_close_on_exec() can block waiting for a reply from a filesystem.
That means a hung filesystem can block codepaths that use
exec_update_lock; and it also means that a FUSE filesystem which
attempts to inspect the calling process can deadlock.
To avoid such problems, move do_close_on_exec() before the
exec_update_lock is taken, but after the FD table has been copied if
necessary.
I have looked through all the calls between the old and new position of
the do_close_on_exec() call; there seems to be no file descriptor table
access in between.
Reported-by: Benjamin Peterson <benjamin@locrian.net>
Closes: https://lore.kernel.org/r/f5e8166a-88be-46c5-8939-1e5227ffe4c2@app.fastmail.com
Fixes: 6650527444da ("proc: protect ptrace_may_access() with exec_update_lock (part 1)")
Cc: stable@vger.kernel.org
Signed-off-by: Jann Horn <jannh@google.com>
Link: https://patch.msgid.link/20260907-cloexec-before-exec-update-lock-v1-1-8018c201a7df@google.com
Tested-by: Benjamin Peterson <benjamin@locrian.net>
Reviewed-by: Jan Kara <jack@suse.cz>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/exec.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
--- a/fs/exec.c
+++ b/fs/exec.c
@@ -1150,6 +1150,20 @@ int begin_new_exec(struct linux_binprm *
goto out;
/*
+ * We have to apply CLOEXEC before we change whether the process is
+ * dumpable (in setup_new_exec) to avoid a race with a process in userspace
+ * trying to access the should-be-closed file descriptors of a process
+ * undergoing exec(2).
+ *
+ * This can block on filesystem ->flush() handlers, including waiting
+ * for FUSE daemons, so do it before exec_mmap takes the
+ * exec_update_lock.
+ * This must happen after the point of no return, and after unsharing
+ * the FD table.
+ */
+ do_close_on_exec(me->files);
+
+ /*
* Must be called _before_ exec_mmap() as bprm->mm is
* not visible until then. Doing it here also ensures
* we don't race against replace_mm_exe_file().
@@ -1199,14 +1213,6 @@ int begin_new_exec(struct linux_binprm *
clear_syscall_work_syscall_user_dispatch(me);
- /*
- * We have to apply CLOEXEC before we change whether the process is
- * dumpable (in setup_new_exec) to avoid a race with a process in userspace
- * trying to access the should-be-closed file descriptors of a process
- * undergoing exec(2).
- */
- do_close_on_exec(me->files);
-
if (bprm->secureexec) {
/* Make sure parent cannot signal privileged process. */
me->pdeath_signal = 0;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 522/733] exit: hold a reference to thread_pid across proc_flush_pid
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (520 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 521/733] exec: do_close_on_exec() before taking exec_update_lock Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 523/733] fs: dont return -EINVAL for successful nested thaw Greg Kroah-Hartman
` (222 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+0aee5e8066eddbbe7397,
syzbot+e8b3520b53e78e90034e, Daehyeon Ko, Oleg Nesterov,
Bradley Morgan, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daehyeon Ko <4ncienth@gmail.com>
commit cdd812d0683dee14ead02c9eded568685e61b23f upstream.
Commit 0a36bad01731 ("release_task: kill the no longer needed
get/put_pid(thread_pid)") removed the reference around proc_flush_pid().
It assumed that free_pids(post.pids) at the end of release_task() would
keep thread_pid alive until then.
That assumption is wrong. __change_pid() only records a detached PID in
post.pids when pid_has_task() is false for every PIDTYPE. If another task
still uses the exiting task's PID as its process group or session ID,
__unhash_process() removes the exiting task's PIDTYPE_PID link but leaves
the PID out of post.pids. release_task() therefore holds no reference to
it after dropping tasklist_lock.
The other task can then remove the remaining PIDTYPE links. Its
free_pids() call schedules delayed_put_pid(), and the RCU callback can free
the PID before the first release_task() reaches proc_flush_pid().
An unprivileged reproducer races wait4(-1) against setsid() to trigger this
ordering. Three of three fresh v7.2 KASAN boots reported:
BUG: KASAN: slab-use-after-free in
proc_invalidate_siblings_dcache+0x3e2/0x3f0
Read of size 8 by task h7_pid_reaper/1921
Call Trace:
proc_invalidate_siblings_dcache
release_task
wait_consider_task
__do_wait
do_wait
kernel_wait4
Freed by task 0:
kmem_cache_free
put_pid
delayed_put_pid
rcu_core
Last potentially related work creation:
__call_rcu_common
free_pids
ksys_setsid
KASAN identified a 144-byte object from the pid cache and located the bad
read 80 bytes into the freed object, matching pid->inodes. With an
explicit reference, three of three fresh boots completed without a KASAN
report. The concurrent RCU callback dropped its reference while
proc_flush_pid() was protected, and the balancing put_pid() performed the
final free afterward.
Take a reference before __unhash_process() clears p->thread_pid and release
it after proc_flush_pid() completes.
A tested source reproducer is available privately on request. No
controlled read or write, information leak, or privilege escalation is
claimed. The mainline patch applies directly to v6.19.y and newer;
v6.16.y through v6.18.y need a context-adjusted backport.
Fixes: 0a36bad01731 ("release_task: kill the no longer needed get/put_pid(thread_pid)")
Reported-by: syzbot+0aee5e8066eddbbe7397@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=0aee5e8066eddbbe7397
Reported-by: syzbot+e8b3520b53e78e90034e@syzkaller.appspotmail.com
Link: https://syzkaller.appspot.com/bug?extid=e8b3520b53e78e90034e
Cc: stable@vger.kernel.org # see patch description, needs adjustments for 6.16.y-6.18.y
Signed-off-by: Daehyeon Ko <4ncienth@gmail.com>
Link: https://patch.msgid.link/20260831001221.3755948-1-4ncienth@gmail.com
Acked-by: Oleg Nesterov <oleg@redhat.com>
Reviewed-by: Bradley Morgan <brads@mainlining.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/exit.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/kernel/exit.c
+++ b/kernel/exit.c
@@ -262,8 +262,11 @@ repeat:
pidfs_exit(p);
cgroup_task_release(p);
- /* Retrieve @thread_pid before __unhash_process() may set it to NULL. */
- thread_pid = task_pid(p);
+ /*
+ * Pin @thread_pid before __unhash_process() clears it. The last
+ * PIDTYPE detach can otherwise free it before proc_flush_pid().
+ */
+ thread_pid = get_pid(task_pid(p));
write_lock_irq(&tasklist_lock);
ptrace_release_task(p);
@@ -292,8 +295,8 @@ repeat:
}
write_unlock_irq(&tasklist_lock);
- /* @thread_pid can't go away until free_pids() below */
proc_flush_pid(thread_pid);
+ put_pid(thread_pid);
exit_cred_namespaces(p);
add_device_randomness(&p->se.sum_exec_runtime,
sizeof(p->se.sum_exec_runtime));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 523/733] fs: dont return -EINVAL for successful nested thaw
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (521 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 522/733] exit: hold a reference to thread_pid across proc_flush_pid Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 524/733] function_graph: Use the saved entrys size when reprinting it Greg Kroah-Hartman
` (221 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Moritz Tanner, Lars Ellenberg,
Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Moritz Tanner <moritz.tanner@linbit.com>
commit fe967191e5851ea79818c5fe4e781c3882139218 upstream.
Commit 7366f8b6fc6a ("fs: handle freezing from multiple devices")
replaced the freeze_holders bitmask with per-holder counters to allow
nested freezes. In the bitmask version, a thaw that released a shared
hold while another holder remained returned 0. Since the rework,
thaw_super_locked() drops the freeze reference via freeze_dec() but
then returns -EINVAL when other freezers remain, misinforming the
caller: the thaw did succeed, the superblock just stays frozen for the
remaining holders.
This breaks bdev-initiated freezing. When a filesystem is frozen with
FIFREEZE and additionally frozen via bdev_freeze() -- which nests by
design, see fs_bdev_freeze() -- the subsequent bdev_thaw() receives
-EINVAL from the holder op although its freeze reference was dropped,
and therefore keeps bd_fsfreeze_count elevated. Then device-mapper's
unlock_fs() ignores bdev_thaw()'s return value, so nothing rebalances
the count. After the user's FITHAW and umount, the block device can
never be mounted again:
dm-1: Can't mount, blockdev is frozen
There is no way for userspace to drop the leaked count; only
destroying the block device (or a reboot) recovers the device.
Reproducer (any kernel since v6.8):
dmsetup create dut --table "0 $(blockdev --getsz "$DEV") linear $DEV 0"
mkfs.ext4 /dev/mapper/dut
mount /dev/mapper/dut /mnt
fsfreeze --freeze /mnt # freeze_ucount == 1
dmsetup suspend dut # bd_fsfreeze_count == 1, ucount == 2
dmsetup resume dut # ucount 2 -> 1, but thaw_super()
# returns -EINVAL, so bdev_thaw()
# keeps bd_fsfreeze_count at 1
fsfreeze --unfreeze /mnt # filesystem thaws fine
umount /mnt
mount /dev/mapper/dut /mnt # EBUSY, forever
The same happens with fsfreeze held across an LVM snapshot of the
origin volume.
fs_bdev_thaw()'s documentation already describes the intended
semantics: "If this function returns zero it doesn't mean that the
filesystem is unfrozen as it may have been frozen multiple times".
Restore them by returning 0 when a nested thaw drops its hold while
other freezers remain. Thawing without holding a freeze still fails
with -EINVAL as may_unfreeze() rejects that case before the reference
count is touched.
Fixes: 7366f8b6fc6a ("fs: handle freezing from multiple devices")
Cc: stable@vger.kernel.org # needs adjustments for < 6.17 (no may_unfreeze())
Signed-off-by: Moritz Tanner <moritz.tanner@linbit.com>
Link: https://patch.msgid.link/20260821085451.65206-1-moritz.tanner@linbit.com
Tested-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Reviewed-by: Lars Ellenberg <lars.ellenberg@linbit.com>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/super.c | 9 ++++++---
1 file changed, 6 insertions(+), 3 deletions(-)
--- a/fs/super.c
+++ b/fs/super.c
@@ -2122,11 +2122,14 @@ static int thaw_super_locked(struct supe
goto out_unlock;
/*
- * All freezers share a single active reference.
- * So just unlock in case there are any left.
+ * All freezers share a single active reference. If other freezers
+ * remain, drop our hold and report success; the superblock stays
+ * frozen until the last holder thaws it.
*/
- if (freeze_dec(sb, who))
+ if (freeze_dec(sb, who)) {
+ error = 0;
goto out_unlock;
+ }
if (sb_rdonly(sb)) {
sb->s_writers.frozen = SB_UNFROZEN;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 524/733] function_graph: Use the saved entrys size when reprinting it
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (522 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 523/733] fs: dont return -EINVAL for successful nested thaw Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 525/733] genetlink: pin family module during policy dump Greg Kroah-Hartman
` (220 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 0701995aaf8fc2281154db829ca85e231951e51d upstream.
When a graph entry does not fit in the trace_seq, print_graph_entry()
saves it in the iterator's fgraph_data and reprints it on the next read.
The entry has already been consumed from the ring buffer by then, so the
copy is all that is left of it.
The copy is sized with iter->ent_size, which no longer describes the
saved entry but whatever entry the iterator has moved on to. The
argument count is derived from the same field, so a 72 byte entry saved
and then reprinted ahead of a 48 byte return entry loses its arguments.
Record the size next to the failure flag, so that the two are always set
together, and restore it before reprinting.
Cc: stable@vger.kernel.org
Fixes: ff5c9c576e75 ("ftrace: Add support for function argument to graph tracer")
Link: https://patch.msgid.link/20260906034406.1335316-1-donggeunyoo.kernel@gmail.com
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/trace_functions_graph.c | 3 +++
1 file changed, 3 insertions(+)
--- a/kernel/trace/trace_functions_graph.c
+++ b/kernel/trace/trace_functions_graph.c
@@ -52,6 +52,7 @@ struct fgraph_data {
};
struct ftrace_graph_ret_entry ret;
int failed;
+ int ent_size;
int cpu;
};
@@ -1274,6 +1275,7 @@ print_graph_entry(struct ftrace_graph_en
if (s->full) {
data->failed = 1;
data->cpu = cpu;
+ data->ent_size = iter->ent_size;
} else
data->failed = 0;
}
@@ -1457,6 +1459,7 @@ print_graph_function_flags(struct trace_
if (data && data->failed) {
field = &data->ent.ent;
iter->cpu = data->cpu;
+ iter->ent_size = data->ent_size;
ret = print_graph_entry(field, s, iter, flags);
if (ret == TRACE_TYPE_HANDLED && iter->cpu != cpu) {
per_cpu_ptr(data->cpu_data, iter->cpu)->ignore = 1;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 525/733] genetlink: pin family module during policy dump
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (523 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 524/733] function_graph: Use the saved entrys size when reprinting it Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 526/733] hrtimer: Use hard expiry when updating timers on the same base Greg Kroah-Hartman
` (219 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, XingWang Xiang, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: XingWang Xiang <v3rdant.xiang@gmail.com>
commit 6a1094c34d176827b2b173e163dcc964a13af93f upstream.
The generic netlink controller's policy dump keeps pointers to the target
family's operation and policy tables in its callback state. A dump may be
split across multiple skbs and remain pending after the initial request.
Netlink pins the module which owns the dump callback, but in this case
that is the controller's owner rather than the target family's owner. The
target family can consequently be unregistered and its module unloaded
while a policy dump is pending. Advancing the dump then dereferences
policy memory from the unloaded module.
Take a reference to the target family's module when the dump starts.
Drop it from the error and done paths. This matches the lifetime for which
the dump context retains the family and policy pointers.
Fixes: d07dcf9aadd6 ("netlink: add infrastructure to expose policies to userspace")
Cc: stable@vger.kernel.org
Signed-off-by: XingWang Xiang <v3rdant.xiang@gmail.com>
Link: https://patch.msgid.link/20260902084317.4092542-1-v3rdant.xiang@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netlink/genetlink.c | 21 ++++++++++++++++-----
1 file changed, 16 insertions(+), 5 deletions(-)
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -1513,6 +1513,7 @@ struct ctrl_dump_policy_ctx {
struct netlink_policy_dump_state *state;
const struct genl_family *rt;
struct genl_op_iter *op_iter;
+ struct module *owner;
u32 op;
u16 fam_id;
u8 dump_map:1,
@@ -1555,6 +1556,9 @@ static int ctrl_dumppolicy_start(struct
return -ENOENT;
ctx->rt = rt;
+ ctx->owner = rt->module;
+ if (!try_module_get(ctx->owner))
+ return -ENOENT;
if (tb[CTRL_ATTR_OP]) {
struct genl_split_ops doit, dump;
@@ -1565,7 +1569,7 @@ static int ctrl_dumppolicy_start(struct
err = genl_get_cmd_both(ctx->op, rt, &doit, &dump);
if (err) {
NL_SET_BAD_ATTR(cb->extack, tb[CTRL_ATTR_OP]);
- return err;
+ goto err_put_owner;
}
if (doit.policy) {
@@ -1583,16 +1587,20 @@ static int ctrl_dumppolicy_start(struct
goto err_free_state;
}
- if (!ctx->state)
- return -ENODATA;
+ if (!ctx->state) {
+ err = -ENODATA;
+ goto err_put_owner;
+ }
ctx->dump_map = 1;
return 0;
}
ctx->op_iter = kmalloc_obj(*ctx->op_iter);
- if (!ctx->op_iter)
- return -ENOMEM;
+ if (!ctx->op_iter) {
+ err = -ENOMEM;
+ goto err_put_owner;
+ }
genl_op_iter_init(rt, ctx->op_iter);
ctx->dump_map = genl_op_iter_next(ctx->op_iter);
@@ -1624,6 +1632,8 @@ err_free_state:
netlink_policy_dump_free(ctx->state);
err_free_op_iter:
kfree(ctx->op_iter);
+err_put_owner:
+ module_put(ctx->owner);
return err;
}
@@ -1760,6 +1770,7 @@ static int ctrl_dumppolicy_done(struct n
kfree(ctx->op_iter);
netlink_policy_dump_free(ctx->state);
+ module_put(ctx->owner);
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 526/733] hrtimer: Use hard expiry when updating timers on the same base
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (524 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 525/733] genetlink: pin family module during policy dump Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 527/733] drm/amd/pm: fix gpu metrics energy accumulator for smu 13.0.0/13.0.7 Greg Kroah-Hartman
` (218 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Andrea Parri, Thomas Gleixner
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrea Parri <parri.andrea@gmail.com>
commit c5dcb3aadc18d7b82ba64790721b005d18193d35 upstream.
Rearming a queued timer with nonzero slack can leave the timerqueue out
of order. remove_and_enqueue_same_base() checks the new soft expiry
against its neighbours' hard expiries, then stores the new hard expiry
in the node without requeueing it.
For example, with A at 10 and B at 20, rearming A at 11 with slack 30
passes the neighbour check but leaves A's hard expiry of 41 before B's
20. The same function also caches the soft expiry in base->expires_next
when updating or inserting the first timer, giving next-event selection
an earlier deadline than the queue head's hard expiry.
Set the timer expiry before handling the queue. Use its stored hard
expiry for the in-place ordering check and both updates to
base->expires_next.
The early update is safe because remove_and_enqueue_same_base() runs
with base->cpu_base->lock held. The lock keeps the queue stable while
hrtimer_can_update_in_place() checks the new expiry against both
neighbours. If the check fails, timerqueue_linked_del() removes the node
without comparing expiry values before it is reinserted.
Fixes: eddffab8282e3 ("hrtimer: Keep track of first expiring timer per clock base")
Fixes: 343f2f4dc5425 ("hrtimer: Try to modify timers in place")
Signed-off-by: Andrea Parri <parri.andrea@gmail.com>
Signed-off-by: Thomas Gleixner <tglx@kernel.org>
Assisted-by: LLM
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260910143442.2018-1-parri.andrea@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/time/hrtimer.c | 15 +++++++++++----
1 file changed, 11 insertions(+), 4 deletions(-)
--- a/kernel/time/hrtimer.c
+++ b/kernel/time/hrtimer.c
@@ -1236,13 +1236,23 @@ remove_and_enqueue_same_base(struct hrti
{
bool was_first = false;
+ /*
+ * Updating the sort key while @timer is queued can temporarily
+ * make the tree inconsistent. This is safe under cpu_base->lock:
+ * no other queue operation can observe that state.
+ * hrtimer_can_update_in_place() either confirms that the new expiry
+ * fits between the neighbours or timerqueue_linked_del() removes the
+ * timer without consulting the expiry.
+ */
+ hrtimer_set_expires_range_ns(timer, expires, delta_ns);
+ expires = hrtimer_get_expires(timer);
+
/* Remove it from the timer queue if active */
if (timer->is_queued) {
was_first = !timerqueue_linked_prev(&timer->node);
/* Try to update in place to avoid the de/enqueue dance */
if (hrtimer_can_update_in_place(timer, base, expires)) {
- hrtimer_set_expires_range_ns(timer, expires, delta_ns);
trace_hrtimer_start(timer, mode, true);
if (was_first)
base->expires_next = expires;
@@ -1253,9 +1263,6 @@ remove_and_enqueue_same_base(struct hrti
timerqueue_linked_del(&base->active, &timer->node);
}
- /* Set the new expiry time */
- hrtimer_set_expires_range_ns(timer, expires, delta_ns);
-
debug_activate(timer, mode, timer->is_queued);
base->cpu_base->active_bases |= 1 << base->index;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 527/733] drm/amd/pm: fix gpu metrics energy accumulator for smu 13.0.0/13.0.7
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (525 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 526/733] hrtimer: Use hard expiry when updating timers on the same base Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 528/733] drm/bridge: tc358768: Enforce input bus flags via atomic_check Greg Kroah-Hartman
` (217 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Kevin Wang, Kenneth Feng,
Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kevin Wang <kevin.wang@amd.com>
commit 13ddcc7acb9adbed7627e952a61d1d62cd9546fc upstream.
GPU metrics v1.3 defines energy_accumulator as a 64‑bit field.
The unsupported‑firmware code path assigns UINT_MAX, which is neither the
full‑width invalid value for this field nor its default value.
Fixes: 8de9edb35976 ("drm/amd/pm: remove invalid gpu_metrics.energy_accumulator on smu v13.0.x")
Signed-off-by: Kevin Wang <kevin.wang@amd.com>
Reviewed-by: Kenneth Feng <kenneth.feng@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit c2b948c4fe16eb13d98ff5d1371956cb2f55cdc6)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c | 2 --
drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c | 4 ++--
2 files changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_0_ppt.c
@@ -2094,8 +2094,6 @@ static ssize_t smu_v13_0_0_get_gpu_metri
if ((mp1_ver == IP_VERSION(13, 0, 0) && smu->smc_fw_version <= 0x004e1e00) ||
(mp1_ver == IP_VERSION(13, 0, 10) && smu->smc_fw_version <= 0x00500800))
gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
- else
- gpu_metrics->energy_accumulator = UINT_MAX;
if (metrics->AverageGfxActivity <= SMU_13_0_0_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
--- a/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
+++ b/drivers/gpu/drm/amd/pm/swsmu/smu13/smu_v13_0_7_ppt.c
@@ -2096,8 +2096,8 @@ static ssize_t smu_v13_0_7_get_gpu_metri
metrics->Vcn1ActivityPercentage);
gpu_metrics->average_socket_power = metrics->AverageSocketPower;
- gpu_metrics->energy_accumulator = smu->smc_fw_version <= 0x00521400 ?
- metrics->EnergyAccumulator : UINT_MAX;
+ if (smu->smc_fw_version <= 0x00521400)
+ gpu_metrics->energy_accumulator = metrics->EnergyAccumulator;
if (metrics->AverageGfxActivity <= SMU_13_0_7_BUSY_THRESHOLD)
gpu_metrics->average_gfxclk_frequency = metrics->AverageGfxclkFrequencyPostDs;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 528/733] drm/bridge: tc358768: Enforce input bus flags via atomic_check
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (526 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 527/733] drm/amd/pm: fix gpu metrics energy accumulator for smu 13.0.0/13.0.7 Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 529/733] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Greg Kroah-Hartman
` (216 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Leonardo Costa, Francesco Dolcini,
Swamil Jain, Luca Ceresoli
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Leonardo Costa <leonardo.costa@toradex.com>
commit ed761e0693950fcb4f6b0f60387a3961b972adf3 upstream.
The tc358768 declares static bridge timings requiring pixel data to be
sampled on the positive clock edge.
However, the DRM core default propagation simply copies the output-side
bus flags, coming from the next bridge, connector or panel, to the
input side. If the propagated flags are incompatible with the bridge
ones, the data is wrongly sampled, typically resulting in visual
artifacts on the panel.
Implement the atomic_check hook, replacing the mutually exclusive
mode_fixup, and set the bridge state input bus flags to the ones
required by the tc358768. The sync polarity defaulting previously done
in mode_fixup is carried over into atomic_check unchanged.
Fixes: ff1ca6397b1d ("drm/bridge: Add tc358768 driver")
Cc: stable@vger.kernel.org
Signed-off-by: Leonardo Costa <leonardo.costa@toradex.com>
Reviewed-by: Francesco Dolcini <francesco.dolcini@toradex.com>
Reviewed-by: Swamil Jain <s-jain1@ti.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patch.msgid.link/20260706132440.1594239-1-leoreis.costa@gmail.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/bridge/tc358768.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
--- a/drivers/gpu/drm/bridge/tc358768.c
+++ b/drivers/gpu/drm/bridge/tc358768.c
@@ -1262,10 +1262,13 @@ tc358768_atomic_get_input_bus_fmts(struc
return input_fmts;
}
-static bool tc358768_mode_fixup(struct drm_bridge *bridge,
- const struct drm_display_mode *mode,
- struct drm_display_mode *adjusted_mode)
+static int tc358768_bridge_atomic_check(struct drm_bridge *bridge,
+ struct drm_bridge_state *bridge_state,
+ struct drm_crtc_state *crtc_state,
+ struct drm_connector_state *conn_state)
{
+ struct drm_display_mode *adjusted_mode = &crtc_state->adjusted_mode;
+
/* Default to positive sync */
if (!(adjusted_mode->flags &
@@ -1276,13 +1279,15 @@ static bool tc358768_mode_fixup(struct d
(DRM_MODE_FLAG_PVSYNC | DRM_MODE_FLAG_NVSYNC)))
adjusted_mode->flags |= DRM_MODE_FLAG_PVSYNC;
- return true;
+ bridge_state->input_bus_cfg.flags = bridge->timings->input_bus_flags;
+
+ return 0;
}
static const struct drm_bridge_funcs tc358768_bridge_funcs = {
.attach = tc358768_bridge_attach,
.mode_valid = tc358768_bridge_mode_valid,
- .mode_fixup = tc358768_mode_fixup,
+ .atomic_check = tc358768_bridge_atomic_check,
.atomic_pre_enable = tc358768_bridge_atomic_pre_enable,
.atomic_enable = tc358768_bridge_atomic_enable,
.atomic_disable = tc358768_bridge_atomic_disable,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 529/733] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (527 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 528/733] drm/bridge: tc358768: Enforce input bus flags via atomic_check Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 530/733] drm/drm_exec: fix up contended obj when num_objects is 0 Greg Kroah-Hartman
` (215 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Esben Haabendal, Herve Codina,
Luca Ceresoli
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Esben Haabendal <esben@geanix.com>
commit 4600b4d1a9ee730d03ddac5ce409cd2730ce8c0c upstream.
The error handling of sn65dsi83_reset_pipe() in sn65dsi83_reset_work() has
seen a couple of changes that seems to cause a bit of confusion.
While sn65dsi83_reset_work() has implemented an early exit if
sn65dsi83_reset_pipe() fails since it was added, when a commit from Maxime
Ripard switched to use drm_bridge_helper_reset_crtc() [1] the
sn65dsi83_reset_pipe() function would no longer return an error code, so
the early exit was then a no-op, and even on sn65dsi83_reset_pipe()
failure, enable_irq() has been called.
When drm_bridge_enter()/drm_bridge_exit() resource protection was added,
the drm_bridge_exit() incidentally was always called, which is the correct
approach. But only because the early exit in sn65dsi83_reset_pipe() was
never hit because sn65dsi83_reset_pipe() always returns 0.
In order get back to a situation where enable_irq() is not called on
sn65dsi83_reset_pipe() failure, which should help protect against irq
storms, we need to reintroduce a non-zero return value from
sn65dsi83_reset_pipe() on error, and fix sn65dsi83_reset_work() so that we
always exit the DRM bridge critical section with drm_bridge_exit().
[1] commit e17fadff7ab9 ("drm/bridge: ti-sn65dsi83: Switch to drm_bridge_helper_reset_crtc")
[2] commit d2e8d1bc840b ("drm/bridge: ti-sn65dsi83: protect device resources on unplug")
Fixes: e17fadff7ab9 ("drm/bridge: ti-sn65dsi83: Switch to drm_bridge_helper_reset_crtc")
Cc: stable@vger.kernel.org
Signed-off-by: Esben Haabendal <esben@geanix.com>
Reviewed-by: Herve Codina <herve.codina@bootlin.com>
Reviewed-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Tested-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Link: https://patch.msgid.link/20260831-ti-sn65dsi83-fixes-v5-1-e712765d6c4f@geanix.com
Signed-off-by: Luca Ceresoli <luca.ceresoli@bootlin.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/bridge/ti-sn65dsi83.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/bridge/ti-sn65dsi83.c
+++ b/drivers/gpu/drm/bridge/ti-sn65dsi83.c
@@ -403,7 +403,7 @@ retry:
drm_modeset_drop_locks(&ctx);
drm_modeset_acquire_fini(&ctx);
- return 0;
+ return err;
}
static void sn65dsi83_reset_work(struct work_struct *ws)
@@ -419,11 +419,13 @@ static void sn65dsi83_reset_work(struct
ret = sn65dsi83_reset_pipe(ctx);
if (ret) {
dev_err(ctx->dev, "reset pipe failed %pe\n", ERR_PTR(ret));
- return;
+ goto bridge_exit;
}
+
if (ctx->irq)
enable_irq(ctx->irq);
+bridge_exit:
drm_bridge_exit(idx);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 530/733] drm/drm_exec: fix up contended obj when num_objects is 0
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (528 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 529/733] drm/bridge: ti-sn65dsi83: Fix error handling in sn65dsi83_reset_work() Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:13 ` [PATCH 7.2 531/733] drm/i915: Fix memory leak in query_perf_config_list() Greg Kroah-Hartman
` (214 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sunil Khatri, Christian König
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunil Khatri <sunil.khatri@amd.com>
commit 159720704d9d652b64390c11fb971e15b0a78d23 upstream.
drm_exec_prepare_array() silently returns success without calling
drm_exec_lock_contended() when num_objects is zero. This breaks the
invariant upheld by drm_exec_lock_obj(), where every entry point into
the locking sequence must first attempt to lock any previously
contended object before proceeding.
Drivers that chain multiple drm_exec_prepare_array() calls per
drm_exec_until_all_locked() iteration (e.g. amdgpu's userq signal/wait
ioctls, which prepare separate read and write BO arrays) can pass an
empty array for one of the two calls. If contention is hit while
preparing the non-empty array, exec->contended is set and the loop
retries; on retry, the empty-array call preceding it is a no-op that
never clears exec->contended, so drm_exec_retry_on_contention()
immediately jumps back to the top of the loop without ever reaching
the call that would resolve the contention. This spins forever.
Fix it by having drm_exec_prepare_array() call drm_exec_lock_contended()
directly when num_objects is zero, so a pending contended object dont
loop infinitely.
Fixes: 09593216bff1 ("drm: execution context for GEM buffers v7")
CC: stable@vger.kernel.org # v6.6+
Signed-off-by: Sunil Khatri <sunil.khatri@amd.com>
Link: https://lore.kernel.org/r/20260908091729.2749399-1-sunil.khatri@amd.com
Reviewed-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Christian König <christian.koenig@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/drm_exec.c | 13 +++++++++++++
1 file changed, 13 insertions(+)
--- a/drivers/gpu/drm/drm_exec.c
+++ b/drivers/gpu/drm/drm_exec.c
@@ -322,6 +322,19 @@ int drm_exec_prepare_array(struct drm_ex
{
int ret;
+ /*
+ * Make sure to lock a contended object even when no objects are
+ * given, otherwise drm_exec_retry_on_contention() would loop
+ * forever on patterns like:
+ *
+ * ret = drm_exec_prepare_array(exec, objs, num_objects, ...);
+ * drm_exec_retry_on_contention(exec);
+ *
+ * with num_objects == 0.
+ */
+ if (!num_objects)
+ return drm_exec_lock_contended(exec);
+
for (unsigned int i = 0; i < num_objects; ++i) {
ret = drm_exec_prepare_obj(exec, objects[i], num_fences);
if (unlikely(ret))
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 531/733] drm/i915: Fix memory leak in query_perf_config_list()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (529 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 530/733] drm/drm_exec: fix up contended obj when num_objects is 0 Greg Kroah-Hartman
@ 2026-09-17 15:13 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 532/733] drm/rockchip: analogix_dp: fix unchecked bound endpoint name length Greg Kroah-Hartman
` (213 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:13 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Thorsten Blum, Andi Shyti,
Jani Nikula
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <thorsten.blum@linux.dev>
commit cbd3dafc2003db679ccd2f6c6a2551db79657049 upstream.
When krealloc() fails, free the original oa_config_ids before returning
to avoid a memory leak.
Fixes: 4f6ccc74a85c ("drm/i915: add support for perf configuration queries")
Signed-off-by: Thorsten Blum <thorsten.blum@linux.dev>
Cc: <stable@vger.kernel.org> # v5.5+
Reviewed-by: Andi Shyti <andi.shyti@linux.intel.com>
Signed-off-by: Andi Shyti <andi.shyti@linux.intel.com>
Link: https://patch.msgid.link/20260823205028.178597-2-thorsten.blum@linux.dev
(cherry picked from commit 9977e9d84f46d4f12ad35fbbc0ec4638554bce87)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/i915_query.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/gpu/drm/i915/i915_query.c
+++ b/drivers/gpu/drm/i915/i915_query.c
@@ -403,8 +403,10 @@ static int query_perf_config_list(struct
ids = krealloc(oa_config_ids,
n_configs * sizeof(*oa_config_ids),
GFP_KERNEL);
- if (!ids)
+ if (!ids) {
+ kfree(oa_config_ids);
return -ENOMEM;
+ }
alloc = fetch_and_zero(&n_configs);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 532/733] drm/rockchip: analogix_dp: fix unchecked bound endpoint name length
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (530 preceding siblings ...)
2026-09-17 15:13 ` [PATCH 7.2 531/733] drm/i915: Fix memory leak in query_perf_config_list() Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 533/733] drm/sched: Create a fake device for KUnit tests Greg Kroah-Hartman
` (212 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Yudi Yang, Heiko Stuebner
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yudi Yang <2000jedi@gmail.com>
commit bc69439d983cc491cc86e01fafc1deb94e1bb85e upstream.
rockchip_dp_drm_encoder_enable() uses sprintf() to format a device tree
path into a 32-byte stack buffer. Device tree paths are not limited to
this size, so a sufficiently long path can overflow the buffer.
Use snprintf() with the destination size to truncate the generated name
and keep the writes within bounds.
Fixes: 729f8eefdcad ("drm/rockchip: analogix_dp: Add support for RK3588")
Cc: stable@vger.kernel.org
Signed-off-by: Yudi Yang <2000jedi@gmail.com>
Signed-off-by: Heiko Stuebner <heiko@sntech.de>
Link: https://patch.msgid.link/20260901195511.2761251-1-2000jedi@gmail.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/rockchip/analogix_dp-rockchip.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
+++ b/drivers/gpu/drm/rockchip/analogix_dp-rockchip.c
@@ -241,10 +241,11 @@ static void rockchip_dp_drm_encoder_enab
of_graph_get_remote_port(endpoint.local_node);
of_property_read_u32(remote_port, "reg", &port_id);
- sprintf(name, "%s vp%d", remote_port_parent->full_name, port_id);
+ snprintf(name, sizeof(name), "%s vp%d",
+ remote_port_parent->full_name, port_id);
} else {
- sprintf(name, "%s %s",
- remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
+ snprintf(name, sizeof(name), "%s %s",
+ remote_port_parent->full_name, endpoint.id ? "vopl" : "vopb");
}
DRM_DEV_DEBUG(dp->dev, "vop %s output to dp\n", (ret) ? "LIT" : "BIG");
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 533/733] drm/sched: Create a fake device for KUnit tests
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (531 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 532/733] drm/rockchip: analogix_dp: fix unchecked bound endpoint name length Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 534/733] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches Greg Kroah-Hartman
` (211 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Shixiong Ou, Maxime Ripard,
Philipp Stanner
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shixiong Ou <oushixiong@kylinos.cn>
commit 28cc4d5a75bb07d0eb2fa178db355b04483f5aca upstream.
The DRM scheduler KUnit tests pass NULL for the dev field in
drm_sched_init_args, which NULL-pointer dereferences in the drm_sched_job
trace event via dev_name() on sched->dev.
Give the mock scheduler a device with kunit_device_register(), which is
also cleaned up at test exit. A per-function counter keeps the device
names unique, since some tests create several mock schedulers.
Fixes: 5a99350794fe ("drm/sched: Add scheduler unit testing infrastructure and some basic tests")
Cc: stable@vger.kernel.org
Signed-off-by: Shixiong Ou <oushixiong@kylinos.cn>
Acked-by: Maxime Ripard <mripard@kernel.org>
[phasta: removed static variable init to 0 again]
Signed-off-by: Philipp Stanner <phasta@kernel.org>
Link: https://patch.msgid.link/20260908055941.351486-1-oushixiong1025@163.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/scheduler/tests/mock_scheduler.c | 11 +++++++++++
1 file changed, 11 insertions(+)
--- a/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
+++ b/drivers/gpu/drm/scheduler/tests/mock_scheduler.c
@@ -1,6 +1,8 @@
// SPDX-License-Identifier: GPL-2.0
/* Copyright (c) 2025 Valve Corporation */
+#include <kunit/device.h>
+
#include "sched_tests.h"
/*
@@ -288,6 +290,7 @@ static const struct drm_sched_backend_op
*/
struct drm_mock_scheduler *drm_mock_sched_new(struct kunit *test, long timeout)
{
+ static unsigned int instance;
struct drm_sched_init_args args = {
.ops = &drm_mock_scheduler_ops,
.num_rqs = DRM_SCHED_PRIORITY_COUNT,
@@ -297,11 +300,19 @@ struct drm_mock_scheduler *drm_mock_sche
.name = "drm-mock-scheduler",
};
struct drm_mock_scheduler *sched;
+ struct device *dev;
+ char name[64];
int ret;
sched = kunit_kzalloc(test, sizeof(*sched), GFP_KERNEL);
KUNIT_ASSERT_NOT_NULL(test, sched);
+ snprintf(name, sizeof(name), "%s-%u", args.name, instance++);
+ dev = kunit_device_register(test, name);
+ KUNIT_ASSERT_NOT_ERR_OR_NULL(test, dev);
+
+ args.dev = dev;
+
ret = drm_sched_init(&sched->base, &args);
KUNIT_ASSERT_EQ(test, ret, 0);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 534/733] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (532 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 533/733] drm/sched: Create a fake device for KUnit tests Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 535/733] drm/amd/display: Exit IPS before connector detection on resume Greg Kroah-Hartman
` (210 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lionel Landwerlin,
José Roberto de Souza, intel-xe, Thomas Hellström,
Matthew Auld, Rodrigo Vivi
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Hellström <thomas.hellstrom@linux.intel.com>
commit f5fcf7e638b904397ec0f66d3ea6766ef0cfe25b upstream.
emit_render_cache_flush() sets PIPE_CONTROL0_HDC_PIPELINE_FLUSH to
flush the L2/HDC data cache before fence signalling, but it never
requests a flush of the LSC untyped L1 data cache via the 'Untyped
Data-Port Cache Flush Enable' bit in PIPE_CONTROL DWord0[11].
Per the Bspec, in 3D pipeline mode HDC Pipeline Flush is documented to
also flush/invalidate the untyped L1 cache, but only depending on how
HDC_CHICKEN0[13:11] is programmed. Starting with MTL, this coupling
between HDC Pipeline Flush and the untyped L1 cache flush no longer
holds in practice, regardless of how HDC_CHICKEN0 is programmed, so
relying on it is not safe on newer platforms such as BMG. Mesa's Vulkan
driver (anv) has been assuming the kernel flushes both caches between
submissions, and hit user-visible corruption in apps such as Llama.cpp
because of this gap; it now works around it by flushing both caches
again from userspace at the end of every command buffer.
Correctness between submissions on the same queue is userspace's
responsibility and belongs in Mesa, not the kernel. However, for
security we must ensure stale data can't leak through the untyped L1
dataport cache once memory is reclaimed or evicted, which requires the
KMD to flush it before releasing memory for reuse.
Prior to MTL, HDC_CHICKEN0 could be programmed (as already done for
DG2 via Wa_22010960976/Wa_14013347512) to reliably keep HDC Pipeline
Flush coupled to the untyped L1 cache flush, so those platforms are
unaffected. Mesa's own anv driver found that on MTL the HW
disconnected the two independently of how HDC_CHICKEN0 is programmed,
and could not bring the old behavior back even by writing the register
by hand; see Mesa commit 7c2ff46a4fc3 ("anv: don't prevent L1 untyped
cache flush in 3D mode"). The kernel can't reliably request the flush
from the CS on MTL either, so restrict the new PIPE_CONTROL bit to
GRAPHICS_VERx100 >= 2000 (Xe2 and later), where it can be relied on.
Explicitly set PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH together
with PIPE_CONTROL0_HDC_PIPELINE_FLUSH in emit_render_cache_flush() on
Xe2 and later, so the L1 data cache is known clean before memory is
released for reuse, without depending on undocumented
platform-specific HDC_CHICKEN0 behavior.
Bspec: 56551
Link: https://gitlab.freedesktop.org/mesa/mesa/-/commit/7c2ff46a4fc3e537573ac9503057e0cd29b6fff3
Fixes: 9f8f93bee3ef ("drm/xe: Emit a render cache flush after each rcs/ccs batch")
Reported-by: Lionel Landwerlin <lionel.g.landwerlin@intel.com>
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/issues/8909
Cc: José Roberto de Souza <jose.souza@intel.com>
Cc: intel-xe@lists.freedesktop.org
Cc: <stable@vger.kernel.org> # v6.8+
Assisted-by: GitHub_Copilot:claude-sonnet-5
Signed-off-by: Thomas Hellström <thomas.hellstrom@linux.intel.com>
Reviewed-by: Matthew Auld <matthew.auld@intel.com>
Link: https://patch.msgid.link/20260903114552.48634-1-thomas.hellstrom@linux.intel.com
(cherry picked from commit 434514b6fe731e873808297c268fc52cdf4a1ce6)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/xe/instructions/xe_gpu_commands.h | 1 +
drivers/gpu/drm/xe/xe_ring_ops.c | 11 +++++++++++
2 files changed, 12 insertions(+)
--- a/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
+++ b/drivers/gpu/drm/xe/instructions/xe_gpu_commands.h
@@ -46,6 +46,7 @@
#define GFX_OP_PIPE_CONTROL(len) ((0x3<<29)|(0x3<<27)|(0x2<<24)|((len)-2))
#define PIPE_CONTROL0_QUEUE_DRAIN_MODE BIT(12)
+#define PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH BIT(11) /* gen12 */
#define PIPE_CONTROL0_L3_READ_ONLY_CACHE_INVALIDATE BIT(10) /* gen12 */
#define PIPE_CONTROL0_HDC_PIPELINE_FLUSH BIT(9) /* gen12 */
--- a/drivers/gpu/drm/xe/xe_ring_ops.c
+++ b/drivers/gpu/drm/xe/xe_ring_ops.c
@@ -212,6 +212,7 @@ static int emit_render_cache_flush(struc
{
struct xe_exec_queue *q = job->q;
struct xe_gt *gt = q->gt;
+ struct xe_device *xe = gt_to_xe(gt);
bool lacks_render = !(gt->info.engine_mask & XE_HW_ENGINE_RCS_MASK);
u32 flags0, flags1;
@@ -220,6 +221,16 @@ static int emit_render_cache_flush(struc
LRC_PPHWSP_FLUSH_INVAL_SCRATCH_ADDR, 0);
flags0 = PIPE_CONTROL0_HDC_PIPELINE_FLUSH;
+ /*
+ * Prior to MTL, HDC Pipeline Flush reliably also flushes the LSC
+ * untyped L1 dataport cache, provided HDC_CHICKEN0 is programmed
+ * correctly. Starting with MTL that coupling no longer holds
+ * regardless of how HDC_CHICKEN0 is programmed, but explicitly
+ * requesting the flush via PIPE_CONTROL is itself only reliable
+ * from Xe2 onward, so only gate it in on Xe2+.
+ */
+ if (GRAPHICS_VERx100(xe) >= 2000)
+ flags0 |= PIPE_CONTROL0_UNTYPED_DATAPORT_CACHE_FLUSH;
flags1 = (PIPE_CONTROL_TILE_CACHE_FLUSH |
PIPE_CONTROL_RENDER_TARGET_CACHE_FLUSH |
PIPE_CONTROL_DEPTH_CACHE_FLUSH |
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 535/733] drm/amd/display: Exit IPS before connector detection on resume
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (533 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 534/733] drm/xe: Flush LSC untyped L1 dataport cache after rcs/ccs batches Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 536/733] drm/amd/display: Rebuild InfoFrames on output color space changes Greg Kroah-Hartman
` (209 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Roman Li, Fangzhi Zuo, Ray Wu,
Dan Wheeler, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fangzhi Zuo <jerry.zuo@amd.com>
commit 3001d2073d6542a9e51fa5bca3a39a078094d3c6 upstream.
[Why & How]
On resume, dm_resume() walks the connector list and, for each connector,
calls dc_link_detect_connection_type() at the top of the loop iteration
before the per-connector dc_exit_ips_for_hw_access() that sits in the
detection branch. There is no dc_exit_ips_for_hw_access() before the loop,
so the very first HW access relies on an earlier connector having already
taken the display out of IPS.
Commit d1d51519bc3b ("drm/amd/display: Skip eDP detection when no sink")
skips the eDP connector when no panel is present. On a DCN3.5 APU whose
eDP link has no sink, the eDP iteration - which used to bring the HW out
of IPS first - is now skipped, so a downstream DP connector becomes the
first one processed. Its initial DDC/AUX access then runs while the HW is
still idle, the AUX transfers time out (-ETIMEDOUT), and the EDID read
fails:
[drm:dm_helpers_read_local_edid [amdgpu]] *ERROR* EDID err: 2, on connector: DP-1
amdgpu: [drm] *ERROR* No EDID read.
Take the display out of IPS once before the detection loop so the first
connector processed no longer touches the AUX/DDC engine while the HW is
still in idle power state. This keeps the eDP-skip boot/resume
optimization while fixing the DP EDID read failure.
Fixes: d1d51519bc3b ("drm/amd/display: Skip eDP detection when no sink")
Reviewed-by: Roman Li <roman.li@amd.com>
Signed-off-by: Fangzhi Zuo <jerry.zuo@amd.com>
Signed-off-by: Ray Wu <ray.wu@amd.com>
Tested-by: Dan Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 86420fe3093161971b4064e05be11ffff1df76aa)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -3925,6 +3925,10 @@ static int dm_resume(struct amdgpu_ip_bl
/* On resume we need to rewrite the MSTM control bits to enable MST*/
s3_handle_mst(ddev, false);
+ /* Exit IPS before the detection loop's first AUX/DDC access. */
+ scoped_guard(mutex, &dm->dc_lock)
+ dc_exit_ips_for_hw_access(dm->dc);
+
/* Do detection*/
drm_connector_list_iter_begin(ddev, &iter);
drm_for_each_connector_iter(connector, &iter) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 536/733] drm/amd/display: Rebuild InfoFrames on output color space changes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (534 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 535/733] drm/amd/display: Exit IPS before connector detection on resume Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 537/733] io_uring/rw: end write accounting from ->ki_complete Greg Kroah-Hartman
` (208 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Satyajit Roy, Alex Hung,
Daniel Wheeler, Alex Deucher
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satyajit Roy <sroy14@alum.utk.edu>
commit 8cfd9e22eb5c04b15b82985ff913944f84673d4f upstream.
resource_build_info_frame() derives colorimetry and RGB quantization from
stream->output_color_space. A Broadcast RGB-only atomic commit updates
that field and reprograms the output CSC, but none of the InfoFrame update
predicates include output_color_space. The sink can therefore retain the
previous AVI InfoFrame range while the source starts transmitting a
different pixel range.
Treat an output color space change as an InfoFrame change in update
classification and in both stream programming paths.
Hardware testing on an HDMI 2.1 television confirmed that its automatic
black-level selection follows Full to Limited and Limited to Full
transitions in SDR, HDR, and HDR with VRR active, without a modeset or
visible link blank.
Fixes: 6eb4c13a3845 ("drm/amd/display: Support "Broadcast RGB" drm property")
Signed-off-by: Satyajit Roy <sroy14@alum.utk.edu>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit d6faca79f5720893843e649e70aeb19147ee0578)
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/dc/core/dc.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/gpu/drm/amd/display/dc/core/dc.c
+++ b/drivers/gpu/drm/amd/display/dc/core/dc.c
@@ -3122,6 +3122,7 @@ static struct surface_update_descriptor
}
if ((stream_update->hdr_static_metadata && !stream_update->stream->use_dynamic_meta) ||
+ stream_update->output_color_space ||
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket ||
@@ -4090,6 +4091,7 @@ static void commit_planes_do_stream_upda
hwss_add_setup_periodic_interrupt(&seq_state, dc, pipe_ctx);
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ stream_update->output_color_space ||
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket ||
@@ -4272,6 +4274,7 @@ static void commit_planes_do_stream_upda
dc->hwss.setup_periodic_interrupt(dc, pipe_ctx);
if ((stream_update->hdr_static_metadata && !stream->use_dynamic_meta) ||
+ stream_update->output_color_space ||
stream_update->vrr_infopacket ||
stream_update->vsc_infopacket ||
stream_update->vsp_infopacket ||
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 537/733] io_uring/rw: end write accounting from ->ki_complete
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (535 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 536/733] drm/amd/display: Rebuild InfoFrames on output color space changes Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 538/733] io_uring/net: let io_recv_buf_select return the length of the buffer region Greg Kroah-Hartman
` (207 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, syzbot+2eb3d983669d3e49d4fa,
Jens Axboe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <axboe@kernel.dk>
commit 796aa0547557e63338657ed1c487906f9fac4c73 upstream.
Commit b000145e9907 moved both the fsnotify calls and the write
accounting out of the kiocb completion handler and into the
io_req_rw_complete() task_work. However, only the fsnotify part actually
needed to move as it may sleep. Ending the write accounting is just a
percpu_up_read() on the superblock writers sem.
Deferring it is a problem, because it makes dropping SB_FREEZE_WRITE
protection depend on the ring owner getting to running task_work. But
the task may be blocked in freeze_super(), causing it to never get to
that:
task io-wq worker
--------------------------------------------------------------
io_write()
io_kiocb_start_write() (takes sb_writers, hidden from
lockdep by __sb_writers_release)
write_iter() -> -EIOCBQUEUED
ioctl(FS_IOC_SHUTDOWN)
bdev_freeze()
freeze_super()
percpu_down_write() <- waits for the reader above
io_write()
kiocb_start_write()
percpu_down_read() <- queued
behind the
writer
<bio completes>
io_complete_rw()
queues io_req_rw_complete() <- never runs, task is in D state
End the write from io_complete_rw() instead, and leave only the fsnotify
calls in task_work.
Reported-by: syzbot+2eb3d983669d3e49d4fa@syzkaller.appspotmail.com
Cc: stable@vger.kernel.org
Fixes: b000145e9907 ("io_uring/rw: defer fsnotify calls to task context")
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/rw.c | 29 +++++++++++++++++++----------
1 file changed, 19 insertions(+), 10 deletions(-)
--- a/io_uring/rw.c
+++ b/io_uring/rw.c
@@ -531,20 +531,25 @@ static void io_req_end_write(struct io_k
}
}
-/*
- * Trigger the notifications after having done some IO, and finish the write
- * accounting, if any.
- */
-static void io_req_io_end(struct io_kiocb *req)
+/* Trigger the notifications after having done some IO. */
+static void io_req_io_notify(struct io_kiocb *req)
{
struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
- if (rw->kiocb.ki_flags & IOCB_WRITE) {
- io_req_end_write(req);
+ if (rw->kiocb.ki_flags & IOCB_WRITE)
fsnotify_modify(req->file);
- } else {
+ else
fsnotify_access(req->file);
- }
+}
+
+/* Finish write accounting and notify, for inline completions only. */
+static void io_req_io_end(struct io_kiocb *req)
+{
+ struct io_rw *rw = io_kiocb_to_cmd(req, struct io_rw);
+
+ if (rw->kiocb.ki_flags & IOCB_WRITE)
+ io_req_end_write(req);
+ io_req_io_notify(req);
}
static void __io_complete_rw_common(struct io_kiocb *req, long res)
@@ -577,7 +582,7 @@ void io_req_rw_complete(struct io_tw_req
{
struct io_kiocb *req = tw_req.req;
- io_req_io_end(req);
+ io_req_io_notify(req);
if (req->flags & (REQ_F_BUFFER_SELECTED|REQ_F_BUFFER_RING))
req->cqe.flags |= io_put_kbuf(req, max(req->cqe.res, 0), NULL);
@@ -591,6 +596,10 @@ static void io_complete_rw(struct kiocb
struct io_rw *rw = container_of(kiocb, struct io_rw, kiocb);
struct io_kiocb *req = cmd_to_io_kiocb(rw);
+ /* ring owner may block in freeze_super() before task_work runs */
+ if (kiocb->ki_flags & IOCB_WRITE)
+ io_req_end_write(req);
+
__io_complete_rw_common(req, res);
io_req_set_res(req, io_fixup_rw_res(req, res), 0);
req->io_task_work.func = io_req_rw_complete;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 538/733] io_uring/net: let io_recv_buf_select return the length of the buffer region
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (536 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 537/733] io_uring/rw: end write accounting from ->ki_complete Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 539/733] io_uring/net: dont overconsume buffers when using MSG_TRUNC Greg Kroah-Hartman
` (206 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gabriel Krisman Bertazi, Jens Axboe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Krisman Bertazi <krisman@suse.de>
commit dcbd1c054848848a1937ca0768ce2bdbc31ae621 upstream.
In preparation to using this field as an upper limit to truncation,
return the size of the allocated region.
Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
Cc: stable@vger.kernel.org
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Link: https://patch.msgid.link/20260902230041.1320658-2-krisman@suse.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/net.c | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -1139,6 +1139,7 @@ static int io_recv_buf_select(struct io_
struct io_br_sel *sel, unsigned int issue_flags)
{
struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
+ size_t len;
int ret;
/*
@@ -1184,13 +1185,14 @@ static int io_recv_buf_select(struct io_
/* special case 1 vec, can be a fast path */
if (ret == 1) {
sr->buf = arg.iovs[0].iov_base;
- sr->len = arg.iovs[0].iov_len;
+ len = sr->len = arg.iovs[0].iov_len;
goto map_ubuf;
}
iov_iter_init(&kmsg->msg.msg_iter, ITER_DEST, arg.iovs, ret,
- arg.out_len);
+ arg.out_len);
+ len = arg.out_len;
} else {
- size_t len = sel->val;
+ len = sel->val;
*sel = io_buffer_select(req, &len, sr->buf_group, issue_flags);
if (!sel->addr)
@@ -1204,7 +1206,7 @@ map_ubuf:
return ret;
}
- return 0;
+ return len;
}
int io_recv(struct io_kiocb *req, unsigned int issue_flags)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 539/733] io_uring/net: dont overconsume buffers when using MSG_TRUNC
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (537 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 538/733] io_uring/net: let io_recv_buf_select return the length of the buffer region Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 540/733] ring-buffer: Acquire the lock with irqsave in rb_wake_up_waiters() Greg Kroah-Hartman
` (205 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gabriel Krisman Bertazi, Jens Axboe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabriel Krisman Bertazi <krisman@suse.de>
commit 6028b543884f8735e057ec9eea4908cd61cab230 upstream.
When a recv/recvmsg is issued with MSG_TRUNC and the incoming packet is
larger than the provided buffer, the net layer returns the full length
of the packet rather than the number of bytes actually copied into the
buffer. As a result, io_uring advances more of the provided buffer ring
than was actually filled. Use the actual filled region size to consume
the buffer, but still return the full size to preserve MSG_TRUNC
semantics.
Take care with multishot, because that seems to already truncate the
consumption based on the available payload size.
This was reported in https://github.com/axboe/liburing/issues/1619.
Fixes: ae98dbf43d75 ("io_uring/kbuf: add support for incremental buffer consumption")
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260728191454.1850326-1-krisman@suse.de
Signed-off-by: Gabriel Krisman Bertazi <krisman@suse.de>
Link: https://patch.msgid.link/20260902230041.1320658-3-krisman@suse.de
[axboe: fold in size_t unsigned fix]
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
io_uring/net.c | 41 +++++++++++++++++++++++++++++++++--------
1 file changed, 33 insertions(+), 8 deletions(-)
--- a/io_uring/net.c
+++ b/io_uring/net.c
@@ -884,7 +884,7 @@ int io_recvmsg_prep(struct io_kiocb *req
static inline bool io_recv_finish(struct io_kiocb *req,
struct io_async_msghdr *kmsg,
struct io_br_sel *sel, bool mshot_finished,
- unsigned issue_flags)
+ unsigned issue_flags, int consumed)
{
struct io_sr_msg *sr = io_kiocb_to_cmd(req, struct io_sr_msg);
unsigned int cflags = 0;
@@ -908,7 +908,7 @@ static inline bool io_recv_finish(struct
if (sr->flags & IORING_RECVSEND_BUNDLE) {
size_t this_ret = sel->val - sr->done_io;
- cflags |= io_put_kbufs(req, this_ret, sel->buf_list, io_bundle_nbufs(kmsg, this_ret));
+ cflags |= io_put_kbufs(req, consumed, sel->buf_list, io_bundle_nbufs(kmsg, consumed));
if (sr->flags & IORING_RECV_RETRY)
cflags = req->cqe.flags | (cflags & CQE_F_MASK);
if (sr->mshot_len && sel->val >= sr->mshot_len)
@@ -930,7 +930,7 @@ static inline bool io_recv_finish(struct
return false;
}
} else {
- cflags |= io_put_kbuf(req, sel->val, sel->buf_list);
+ cflags |= io_put_kbuf(req, consumed, sel->buf_list);
}
/*
@@ -1058,6 +1058,8 @@ int io_recvmsg(struct io_kiocb *req, uns
int ret, min_ret = 0;
bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
bool mshot_finished = true;
+ int consumed = 0;
+ size_t len;
sock = sock_from_file(req->file);
if (unlikely(!sock))
@@ -1073,9 +1075,8 @@ int io_recvmsg(struct io_kiocb *req, uns
retry_multishot:
sel.buf_list = NULL;
+ len = sr->len;
if (io_do_buffer_select(req)) {
- size_t len = sr->len;
-
sel = io_buffer_select(req, &len, sr->buf_group, issue_flags);
if (!sel.addr)
return -ENOBUFS;
@@ -1096,6 +1097,7 @@ retry_multishot:
if (req->flags & REQ_F_APOLL_MULTISHOT) {
ret = io_recvmsg_multishot(sock, sr, kmsg, flags,
&mshot_finished);
+ consumed = ret;
} else {
/* disable partial retry for recvmsg with cmsg attached */
if (flags & MSG_WAITALL && !kmsg->msg.msg_controllen)
@@ -1103,6 +1105,15 @@ retry_multishot:
ret = __sys_recvmsg_sock(sock, &kmsg->msg, sr->umsg,
kmsg->uaddr, flags);
+ /*
+ * With MSG_TRUNC, the net layer will return the full size of
+ * the packet, even if we only filled part of it in the buffers.
+ * Adjust the returned size to consume only the real part of the
+ * buffer.
+ */
+ consumed = ret;
+ if (ret > 0)
+ consumed = min_t(size_t, ret, len);
}
if (ret < min_ret) {
@@ -1129,7 +1140,7 @@ retry_multishot:
io_kbuf_recycle(req, sel.buf_list, issue_flags);
sel.val = ret;
- if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags))
+ if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags, consumed))
goto retry_multishot;
return sel.val;
@@ -1216,9 +1227,10 @@ int io_recv(struct io_kiocb *req, unsign
struct io_br_sel sel;
struct socket *sock;
unsigned flags;
- int ret, min_ret = 0;
+ int ret, min_ret = 0, consumed = 0;
bool force_nonblock = issue_flags & IO_URING_F_NONBLOCK;
bool mshot_finished;
+ size_t len = 0;
sock = sock_from_file(req->file);
if (unlikely(!sock))
@@ -1246,6 +1258,7 @@ int io_recv(struct io_kiocb *req, unsign
retry_multishot:
sel.buf_list = NULL;
+ len = sr->len;
if (io_do_buffer_select(req)) {
sel.val = sr->len;
ret = io_recv_buf_select(req, kmsg, &sel, issue_flags);
@@ -1253,6 +1266,7 @@ retry_multishot:
kmsg->msg.msg_inq = -1;
goto out_free;
}
+ len = ret;
sr->buf = NULL;
}
@@ -1283,6 +1297,17 @@ out_free:
}
mshot_finished = ret <= 0;
+
+ /*
+ * With MSG_TRUNC, the net layer will return the full size of
+ * the packet, even if we only filled part of it in the buffers.
+ * Adjust the returned size to consume only the real part of the
+ * buffer.
+ */
+ consumed = ret;
+ if (ret > 0)
+ consumed = min_t(size_t, ret, len);
+
if (ret > 0)
ret += sr->done_io;
else if (sr->done_io)
@@ -1291,7 +1316,7 @@ out_free:
io_kbuf_recycle(req, sel.buf_list, issue_flags);
sel.val = ret;
- if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags))
+ if (!io_recv_finish(req, kmsg, &sel, mshot_finished, issue_flags, consumed))
goto retry_multishot;
return sel.val;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 540/733] ring-buffer: Acquire the lock with irqsave in rb_wake_up_waiters()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (538 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 539/733] io_uring/net: dont overconsume buffers when using MSG_TRUNC Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 541/733] ring-buffer: Check resize_disabled before publishing the new subbuf order Greg Kroah-Hartman
` (204 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vincent Donnefort,
Sebastian Andrzej Siewior, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
commit 815e07c8fe885a87751c2496a30ae0dcd4118210 upstream.
rb_wake_up_waiters() is a irq_work callback which is initialized with
init_irq_work(). As such it will be invoked in thread context on
PREEMPT_RT. Invoking the callback in IRQ context on PREEMPT_RT is not an
option due its usage of wake_up_all(). Since this callback may run in
thread context, it needs to acquire ring_buffer_per_cpu::reader_lock with
disabling interrupts and may not assume that they are disabled.
Use raw_spinlock_irqsave() to acquire ring_buffer_per_cpu::reader_lock.
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260911102152.YEtwkBj9@linutronix.de
Fixes: 68282dd930ea3 ("ring-buffer: Fix resetting of shortest_full")
Reviewed-by: Vincent Donnefort <vdonnefort@google.com>
Signed-off-by: Sebastian Andrzej Siewior <bigeasy@linutronix.de>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ring_buffer.c | 13 ++++++-------
1 file changed, 6 insertions(+), 7 deletions(-)
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -885,14 +885,13 @@ static void rb_wake_up_waiters(struct ir
struct ring_buffer_per_cpu *cpu_buffer =
container_of(rbwork, struct ring_buffer_per_cpu, irq_work);
- /* Called from interrupt context */
- raw_spin_lock(&cpu_buffer->reader_lock);
- rbwork->wakeup_full = false;
- rbwork->full_waiters_pending = false;
+ scoped_guard(raw_spinlock_irqsave, &cpu_buffer->reader_lock) {
+ rbwork->wakeup_full = false;
+ rbwork->full_waiters_pending = false;
- /* Waking up all waiters, they will reset the shortest full */
- cpu_buffer->shortest_full = 0;
- raw_spin_unlock(&cpu_buffer->reader_lock);
+ /* Waking up all waiters, they will reset the shortest full */
+ cpu_buffer->shortest_full = 0;
+ }
wake_up_all(&rbwork->full_waiters);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 541/733] ring-buffer: Check resize_disabled before publishing the new subbuf order
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (539 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 540/733] ring-buffer: Acquire the lock with irqsave in rb_wake_up_waiters() Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 542/733] net/sched: act_api: release all action references on NEWACTION failure Greg Kroah-Hartman
` (203 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, David Carlier, Steven Rostedt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <devnexen@gmail.com>
commit d860c67c051685abb0460b593b193f0f45f4fa92 upstream.
ring_buffer_subbuf_order_set() stores the new order and only then walks
the CPUs, returning -EBUSY if any of them has resizing disabled. A user
mapped buffer has resizing disabled, and __rb_map_vma() reads
buffer->subbuf_order without buffer->mutex, so an mmap of an already
mapped CPU racing the failing order change sizes the mapping with the
new order and inserts pages past the sub-buffer into the VMA.
Check the CPUs before storing the new order.
Cc: stable@vger.kernel.org
Fixes: 117c39200d9d ("ring-buffer: Introducing ring-buffer mapping functions")
Link: https://patch.msgid.link/20260912103938.1127021-1-devnexen@gmail.com
Signed-off-by: David Carlier <devnexen@gmail.com>
Signed-off-by: Steven Rostedt <rostedt@goodmis.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
kernel/trace/ring_buffer.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/kernel/trace/ring_buffer.c
+++ b/kernel/trace/ring_buffer.c
@@ -7457,6 +7457,14 @@ int ring_buffer_subbuf_order_set(struct
old_capacity = rb_subbuf_capacity(buffer);
+ /* The mmap fast path reads subbuf_order without buffer->mutex. */
+ for_each_buffer_cpu(buffer, cpu) {
+ if (!cpumask_test_cpu(cpu, buffer->cpumask))
+ continue;
+ if (atomic_read(&buffer->buffers[cpu]->resize_disabled))
+ return -EBUSY;
+ }
+
atomic_inc(&buffer->record_disabled);
/* Make sure all commits have finished */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 542/733] net/sched: act_api: release all action references on NEWACTION failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (540 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 541/733] ring-buffer: Check resize_disabled before publishing the new subbuf order Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 543/733] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
` (202 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Xuanqiang Luo, Jamal Hadi Salim,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
commit 478eb5abb51931a152abab068f8a717b7ff480fd upstream.
When a batched RTM_NEWACTION request replaces an existing action,
tcf_idr_check_alloc() takes a temporary reference on it. If a later
action fails to initialize, tcf_action_destroy() uses strict release
semantics to clean up the actions initialized so far. For an action
bound to a filter, the strict check returns -EPERM without dropping
the temporary reference.
This error also makes tcf_action_destroy() return before releasing
subsequent entries. Any new action initialized between the bound
action and the failing entry is leaked together with its reserved
IDR slot, preventing reuse of its index.
Use tcf_idr_release() to drop each reference held by the batch without
rejecting bound actions. This allows cleanup to continue through all
initialized entries and preserves the module reference release when
an action is destroyed. Explicit action deletion and flushing retain
their separate bind-count checks.
Fixes: 55334a5db5cd ("net_sched: act: refuse to remove bound action outside")
Cc: stable@vger.kernel.org
Signed-off-by: Xuanqiang Luo <luoxuanqiang@kylinos.cn>
Reviewed-by: Jamal Hadi Salim <jhs@mojatatu.com>
Link: https://patch.msgid.link/20260909070336.32979-2-xuanqiang.luo@linux.dev
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/sched/act_api.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
--- a/net/sched/act_api.c
+++ b/net/sched/act_api.c
@@ -1200,18 +1200,13 @@ EXPORT_SYMBOL(tcf_action_exec);
int tcf_action_destroy(struct tc_action *actions[], int bind)
{
- const struct tc_action_ops *ops;
struct tc_action *a;
int ret = 0, i;
tcf_act_for_each_action(i, a, actions) {
actions[i] = NULL;
- ops = a->ops;
- ret = __tcf_idr_release(a, bind, true);
- if (ret == ACT_P_DELETED)
- module_put(ops->owner);
- else if (ret < 0)
- return ret;
+ /* Drop our reference even if the action is still bound to a filter. */
+ ret = tcf_idr_release(a, bind);
}
return ret;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 543/733] net: bridge: use option bits for CFM/MRP frame handlers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (541 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 542/733] net/sched: act_api: release all action references on NEWACTION failure Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 544/733] net: dsa: tag_brcm: legacy FCS: request needed tailroom Greg Kroah-Hartman
` (201 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Nikolay Aleksandrov, Yilin Zhu,
Zhiling Zou, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
commit 7a49e6b16f36b8e085521699adbca3e321b6dd0c upstream.
CFM and MRP register a global br_frame_type whose hlist_node is linked
into the per-bridge frame_type_list when the first MEP/MRP instance is
created. Enabling the protocol on multiple bridges therefore inserts the
same node into multiple lists. Unregistering it on one bridge then
corrupts list state belonging to another.
These handlers can only be installed once per bridge, and they are
uncommon. Track their per-bridge enable state with net_bridge option
bits, which already live on the Rx hot cache line, and dispatch the
matching handler directly from the receive path. Check both bits
together first as an unlikely case.
Remove the generic frame_type_list and br_frame_type helpers, which
have had no other users since CFM and MRP were added. That shrinks
struct net_bridge by 8 bytes and drops the list walk from the fast
path. When neither protocol is compiled in, BR_CFM_MRP_OPTS is 0 and
the compiler prunes the branch.
Fixes: 90c628dd47ff ("net: bridge: extend the process of special frames")
Fixes: dc32cbb3dbd7 ("bridge: cfm: Kernel space implementation of CFM. CCM frame RX added.")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Nikolay Aleksandrov <razor@blackwall.org>
Co-developed-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Yilin Zhu <zylzyl2333@gmail.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Acked-by: Nikolay Aleksandrov <razor@blackwall.org>
Link: https://patch.msgid.link/0345b9d5aa60ba416f6738ff1b87140f0a749cb8.1788417901.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/bridge/br_cfm.c | 11 +++--------
net/bridge/br_device.c | 1 -
net/bridge/br_input.c | 35 ++++++++++++++---------------------
net/bridge/br_mrp.c | 13 +++----------
net/bridge/br_private.h | 26 +++++++++++++++-----------
5 files changed, 35 insertions(+), 51 deletions(-)
--- a/net/bridge/br_cfm.c
+++ b/net/bridge/br_cfm.c
@@ -367,7 +367,7 @@ static u32 ccm_tlv_extract(struct sk_buf
}
/* note: already called with rcu_read_lock */
-static int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
+int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb)
{
u32 mdlevel, interval, size, index, max;
const struct br_cfm_common_hdr *hdr;
@@ -489,11 +489,6 @@ static int br_cfm_frame_rx(struct net_br
return 1;
}
-static struct br_frame_type cfm_frame_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_CFM),
- .frame_handler = br_cfm_frame_rx,
-};
-
int br_cfm_mep_create(struct net_bridge *br,
const u32 instance,
struct br_cfm_mep_create *const create,
@@ -559,7 +554,7 @@ int br_cfm_mep_create(struct net_bridge
INIT_DELAYED_WORK(&mep->ccm_tx_dwork, ccm_tx_work_expired);
if (hlist_empty(&br->mep_list))
- br_add_frame(br, &cfm_frame_type);
+ br_opt_toggle(br, BROPT_CFM_ENABLED, true);
hlist_add_tail_rcu(&mep->head, &br->mep_list);
@@ -588,7 +583,7 @@ static void mep_delete_implementation(st
kfree_rcu(mep, rcu);
if (hlist_empty(&br->mep_list))
- br_del_frame(br, &cfm_frame_type);
+ br_opt_toggle(br, BROPT_CFM_ENABLED, false);
}
int br_cfm_mep_delete(struct net_bridge *br,
--- a/net/bridge/br_device.c
+++ b/net/bridge/br_device.c
@@ -503,7 +503,6 @@ void br_dev_setup(struct net_device *dev
spin_lock_init(&br->lock);
INIT_LIST_HEAD(&br->port_list);
INIT_HLIST_HEAD(&br->fdb_list);
- INIT_HLIST_HEAD(&br->frame_type_list);
#if IS_ENABLED(CONFIG_BRIDGE_MRP)
INIT_HLIST_HEAD(&br->mrp_list);
#endif
--- a/net/bridge/br_input.c
+++ b/net/bridge/br_input.c
@@ -317,17 +317,25 @@ frame_finish:
return RX_HANDLER_CONSUMED;
}
+#define BR_CFM_MRP_OPTS \
+ ((IS_ENABLED(CONFIG_BRIDGE_CFM) ? BIT(BROPT_CFM_ENABLED) : 0UL) | \
+ (IS_ENABLED(CONFIG_BRIDGE_MRP) ? BIT(BROPT_MRP_ENABLED) : 0UL))
+
/* Return 0 if the frame was not processed otherwise 1
* note: already called with rcu_read_lock
*/
static int br_process_frame_type(struct net_bridge_port *p,
struct sk_buff *skb)
{
- struct br_frame_type *tmp;
+ struct net_bridge *br = p->br;
- hlist_for_each_entry_rcu(tmp, &p->br->frame_type_list, list)
- if (unlikely(tmp->type == skb->protocol))
- return tmp->frame_handler(p, skb);
+ if (skb->protocol == htons(ETH_P_CFM) &&
+ br_opt_get(br, BROPT_CFM_ENABLED))
+ return br_cfm_frame_rx(p, skb);
+
+ if (skb->protocol == htons(ETH_P_MRP) &&
+ br_opt_get(br, BROPT_MRP_ENABLED))
+ return br_mrp_process(p, skb);
return 0;
}
@@ -425,7 +433,8 @@ static rx_handler_result_t br_handle_fra
}
}
- if (unlikely(br_process_frame_type(p, skb)))
+ if (unlikely((READ_ONCE(p->br->options) & BR_CFM_MRP_OPTS) &&
+ br_process_frame_type(p, skb)))
return RX_HANDLER_PASS;
forward:
@@ -467,19 +476,3 @@ rx_handler_func_t *br_get_rx_handler(con
return br_handle_frame;
}
-
-void br_add_frame(struct net_bridge *br, struct br_frame_type *ft)
-{
- hlist_add_head_rcu(&ft->list, &br->frame_type_list);
-}
-
-void br_del_frame(struct net_bridge *br, struct br_frame_type *ft)
-{
- struct br_frame_type *tmp;
-
- hlist_for_each_entry(tmp, &br->frame_type_list, list)
- if (ft == tmp) {
- hlist_del_rcu(&ft->list);
- return;
- }
-}
--- a/net/bridge/br_mrp.c
+++ b/net/bridge/br_mrp.c
@@ -6,13 +6,6 @@
static const u8 mrp_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x1 };
static const u8 mrp_in_test_dmac[ETH_ALEN] = { 0x1, 0x15, 0x4e, 0x0, 0x0, 0x3 };
-static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
-
-static struct br_frame_type mrp_frame_type __read_mostly = {
- .type = cpu_to_be16(ETH_P_MRP),
- .frame_handler = br_mrp_process,
-};
-
static bool br_mrp_is_ring_port(struct net_bridge_port *p_port,
struct net_bridge_port *s_port,
struct net_bridge_port *port)
@@ -486,7 +479,7 @@ static void br_mrp_del_impl(struct net_b
kfree_rcu(mrp, rcu);
if (hlist_empty(&br->mrp_list))
- br_del_frame(br, &mrp_frame_type);
+ br_opt_toggle(br, BROPT_MRP_ENABLED, false);
}
/* Adds a new MRP instance.
@@ -536,7 +529,7 @@ int br_mrp_add(struct net_bridge *br, st
rcu_assign_pointer(mrp->s_port, p);
if (hlist_empty(&br->mrp_list))
- br_add_frame(br, &mrp_frame_type);
+ br_opt_toggle(br, BROPT_MRP_ENABLED, true);
INIT_DELAYED_WORK(&mrp->test_work, br_mrp_test_work_expired);
INIT_DELAYED_WORK(&mrp->in_test_work, br_mrp_in_test_work_expired);
@@ -1241,7 +1234,7 @@ no_forward:
* normal forwarding.
* note: already called with rcu_read_lock
*/
-static int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
{
/* If there is no MRP instance do normal forwarding */
if (likely(!test_bit(BR_MRP_AWARE_BIT, &p->flags)))
--- a/net/bridge/br_private.h
+++ b/net/bridge/br_private.h
@@ -491,12 +491,13 @@ enum net_bridge_opts {
BROPT_MST_ENABLED,
BROPT_MDB_OFFLOAD_FAIL_NOTIFICATION,
BROPT_FDB_LOCAL_VLAN_0,
+ BROPT_CFM_ENABLED,
+ BROPT_MRP_ENABLED,
};
struct net_bridge {
spinlock_t lock;
spinlock_t hash_lock;
- struct hlist_head frame_type_list;
struct net_device *dev;
unsigned long options;
/* These fields are accessed on each packet */
@@ -928,16 +929,6 @@ int nbp_backup_change(struct net_bridge_
int br_handle_frame_finish(struct net *net, struct sock *sk, struct sk_buff *skb);
rx_handler_func_t *br_get_rx_handler(const struct net_device *dev);
-struct br_frame_type {
- __be16 type;
- int (*frame_handler)(struct net_bridge_port *port,
- struct sk_buff *skb);
- struct hlist_node list;
-};
-
-void br_add_frame(struct net_bridge *br, struct br_frame_type *ft);
-void br_del_frame(struct net_bridge *br, struct br_frame_type *ft);
-
static inline bool br_rx_handler_check_rcu(const struct net_device *dev)
{
return rcu_dereference(dev->rx_handler) == br_get_rx_handler(dev);
@@ -2076,6 +2067,7 @@ int br_mrp_parse(struct net_bridge *br,
bool br_mrp_enabled(struct net_bridge *br);
void br_mrp_port_del(struct net_bridge *br, struct net_bridge_port *p);
int br_mrp_fill_info(struct sk_buff *skb, struct net_bridge *br);
+int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb);
#else
static inline int br_mrp_parse(struct net_bridge *br, struct net_bridge_port *p,
struct nlattr *attr, int cmd,
@@ -2099,6 +2091,11 @@ static inline int br_mrp_fill_info(struc
return 0;
}
+static inline int br_mrp_process(struct net_bridge_port *p, struct sk_buff *skb)
+{
+ return 0;
+}
+
#endif
/* br_cfm.c */
@@ -2107,6 +2104,7 @@ int br_cfm_parse(struct net_bridge *br,
struct nlattr *attr, int cmd, struct netlink_ext_ack *extack);
bool br_cfm_created(struct net_bridge *br);
void br_cfm_port_del(struct net_bridge *br, struct net_bridge_port *p);
+int br_cfm_frame_rx(struct net_bridge_port *port, struct sk_buff *skb);
int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br);
int br_cfm_status_fill_info(struct sk_buff *skb,
struct net_bridge *br,
@@ -2131,6 +2129,12 @@ static inline void br_cfm_port_del(struc
{
}
+static inline int br_cfm_frame_rx(struct net_bridge_port *port,
+ struct sk_buff *skb)
+{
+ return 0;
+}
+
static inline int br_cfm_config_fill_info(struct sk_buff *skb, struct net_bridge *br)
{
return -EOPNOTSUPP;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 544/733] net: dsa: tag_brcm: legacy FCS: request needed tailroom
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (542 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 543/733] net: bridge: use option bits for CFM/MRP frame handlers Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 545/733] net: hso: fix TIOCMIWAIT race Greg Kroah-Hartman
` (200 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+28eef7d8af9428e6, Weiming Shi,
Florian Fainelli, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit 5be081b83abd3f17d908953b4bb77279f5a149e3 upstream.
The legacy FCS tagger calculates the CRC over skb->len bytes starting at
skb->data. When a nonlinear skb reaches the tagger, this reads past the
linear head into unrelated slab memory.
The tagger appends an Ethernet FCS but does not declare that tailroom. As a
result, DSA leaves NETIF_F_SG and NETIF_F_FRAGLIST enabled on the user
port, and nonlinear skbs can reach the CRC calculation.
Declare the required tailroom. DSA will then clear those features and the
networking core will linearize skbs before the tagger runs.
A KASAN-enabled dsa_loop test using this tagger reports:
BUG: KASAN: slab-out-of-bounds in crc32_le
Read of size 1 at addr ffff8880397086c0 by task exp/135
Call Trace:
crc32_le (lib/crc/crc32-main.c:38)
brcm_leg_fcs_tag_xmit (net/dsa/tag_brcm.c:343)
dsa_user_xmit (net/dsa/user.c:942)
dev_hard_start_xmit (net/core/dev.c:3937)
__dev_queue_xmit (net/core/dev.c:4926)
packet_sendmsg (net/packet/af_packet.c:3110)
__sys_sendto (net/socket.c:2281)
The buggy address belongs to the object at ffff888039708400
which belongs to the cache skbuff_small_head of size 704
The buggy address is located 0 bytes to the right of
allocated 704-byte region [ffff888039708400, ffff8880397086c0)
Fixes: ef07df397a62 ("net: dsa: tag_brcm: add support for legacy FCS tags")
Cc: stable@vger.kernel.org
Reported-by: co+28eef7d8af9428e6@bugs.sh
Closes: https://lore.kernel.org/all/jH6u350kaBRuqklDjd3k3BW4nWzp0tYRjq3p%40bugs.sh/
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Reviewed-by: Florian Fainelli <florian.fainelli@broadcom.com>
Link: https://patch.msgid.link/20260908165047.2786340-1-bestswngs@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/dsa/tag_brcm.c | 1 +
1 file changed, 1 insertion(+)
--- a/net/dsa/tag_brcm.c
+++ b/net/dsa/tag_brcm.c
@@ -373,6 +373,7 @@ static const struct dsa_device_ops brcm_
.xmit = brcm_leg_fcs_tag_xmit,
.rcv = brcm_leg_tag_rcv,
.needed_headroom = BRCM_LEG_TAG_LEN,
+ .needed_tailroom = ETH_FCS_LEN,
};
DSA_TAG_DRIVER(brcm_legacy_fcs_netdev_ops);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 545/733] net: hso: fix TIOCMIWAIT race
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (543 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 544/733] net: dsa: tag_brcm: legacy FCS: request needed tailroom Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 546/733] net: macb: initialize PTP state before registering clock Greg Kroah-Hartman
` (199 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Johan Hovold, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <johan@kernel.org>
commit 00f9fbc12320253bfc576fb7539d860029c82d0f upstream.
The task state must be updated before checking the wakeup condition to
avoid missing a racing modem status update.
Fixes: 542f54823614 ("tty: Modem functions for the HSO driver")
Cc: stable@vger.kernel.org # 2.6.29
Signed-off-by: Johan Hovold <johan@kernel.org>
Link: https://patch.msgid.link/20260907065235.100848-1-johan@kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/usb/hso.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/net/usb/hso.c
+++ b/drivers/net/usb/hso.c
@@ -1547,10 +1547,10 @@ hso_wait_modem_status(struct hso_serial
spin_unlock_irq(&serial->serial_lock);
add_wait_queue(&tiocmget->waitq, &wait);
for (;;) {
+ set_current_state(TASK_INTERRUPTIBLE);
spin_lock_irq(&serial->serial_lock);
memcpy(&cnow, &tiocmget->icount, sizeof(struct uart_icount));
spin_unlock_irq(&serial->serial_lock);
- set_current_state(TASK_INTERRUPTIBLE);
if (((arg & TIOCM_RNG) && (cnow.rng != cprev.rng)) ||
((arg & TIOCM_DSR) && (cnow.dsr != cprev.dsr)) ||
((arg & TIOCM_CD) && (cnow.dcd != cprev.dcd))) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 546/733] net: macb: initialize PTP state before registering clock
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (544 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 545/733] net: hso: fix TIOCMIWAIT race Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 547/733] net: mana: Reserve extra CQ slot for the fence completion CQE Greg Kroah-Hartman
` (198 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Théo Lebrun, Vadim Fedorenko,
Runyu Xiao, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Runyu Xiao <runyu.xiao@seu.edu.cn>
commit e1406330d70e56dd44fa6fbafc86e77e5c80c122 upstream.
gem_ptp_init() registers the PTP clock before initializing
bp->tsu_clk_lock and the TSU hardware. Since ptp_clock_register()
publishes the PTP character device, userspace may invoke PTP callbacks
before the lock and hardware are ready.
In addition, gem_ptp_init() is called from both the interface open and
resume paths. Reinitializing tsu_clk_lock there can reset the lock while
timestamp processing is using it.
This race is theoretical and has not been observed in practice.
Initialize tsu_clk_lock once during probe and initialize the TSU before
registering the PTP clock.
Fixes: ab91f0a9b5f4 ("net: macb: Add hardware PTP support")
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/netdev/20260904030439.3994047-1-runyu.xiao@seu.edu.cn/
Reviewed-by: Théo Lebrun <theo.lebrun@bootlin.com>
Reviewed-by: Vadim Fedorenko <vadim.fedorenko@linux.dev>
Signed-off-by: Runyu Xiao <runyu.xiao@seu.edu.cn>
Link: https://patch.msgid.link/20260908103924.607033-1-runyu.xiao@seu.edu.cn
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/cadence/macb_main.c | 1 +
drivers/net/ethernet/cadence/macb_ptp.c | 5 +----
2 files changed, 2 insertions(+), 4 deletions(-)
--- a/drivers/net/ethernet/cadence/macb_main.c
+++ b/drivers/net/ethernet/cadence/macb_main.c
@@ -5878,6 +5878,7 @@ static int macb_probe(struct platform_de
}
spin_lock_init(&bp->lock);
spin_lock_init(&bp->stats_lock);
+ spin_lock_init(&bp->tsu_clk_lock);
/* setup capabilities */
macb_configure_caps(bp, macb_config);
--- a/drivers/net/ethernet/cadence/macb_ptp.c
+++ b/drivers/net/ethernet/cadence/macb_ptp.c
@@ -334,6 +334,7 @@ void gem_ptp_init(struct net_device *net
bp->tsu_rate = bp->ptp_info->get_tsu_rate(bp);
bp->ptp_clock_info.max_adj = bp->ptp_info->get_ptp_max_adj();
gem_ptp_init_timer(bp);
+ gem_ptp_init_tsu(bp);
bp->ptp_clock = ptp_clock_register(&bp->ptp_clock_info, &netdev->dev);
if (IS_ERR(bp->ptp_clock)) {
pr_err("ptp clock register failed: %ld\n",
@@ -345,10 +346,6 @@ void gem_ptp_init(struct net_device *net
return;
}
- spin_lock_init(&bp->tsu_clk_lock);
-
- gem_ptp_init_tsu(bp);
-
dev_info(&bp->pdev->dev, "%s ptp clock registered.\n",
GEM_PTP_TIMER_NAME);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 547/733] net: mana: Reserve extra CQ slot for the fence completion CQE
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (545 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 546/733] net: macb: initialize PTP state before registering clock Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 548/733] net: mpls: clear inner_protocol when the last label is popped Greg Kroah-Hartman
` (197 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sahil Chandna, Haiyang Zhang,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sahil Chandna <sahilchandna@linux.microsoft.com>
commit 80dd7e754b3aa9637a0758ad93fa209f9650ec48 upstream.
The RX completion queue is sized to hold exactly one CQE per posted RX WQE.
MANA_FENCE_RQ makes hardware post an additional CQE_RX_OBJECT_FENCE after
the packet CQEs. The current sizing reserves no extra slot for it and in
rare cases, CQ has no guaranteed slot for the fence CQE when it is full of
packet CQEs. This can lead to dropping the fence completion while the
driver waits holding RTNL lock throughout the timeout duration.
Reserve one extra CQE slot for CQE_RX_OBJECT_FENCE. mana_gd_alloc_memory()
requires queue_size to be a power-of-two and at least MANA_PAGE_SIZE;
the reservation pushes cq_size past a power-of-two, so round up the CQ size
in mana_create_rxq().
Cc: stable@vger.kernel.org
Fixes: 6cc74443a773 ("net: mana: Add RX fencing")
Signed-off-by: Sahil Chandna <sahilchandna@linux.microsoft.com>
Reviewed-by: Haiyang Zhang <haiyangz@microsoft.com>
Link: https://patch.msgid.link/20260901121837.3503240-1-sahilchandna@linux.microsoft.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/microsoft/mana/mana_en.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/microsoft/mana/mana_en.c
+++ b/drivers/net/ethernet/microsoft/mana/mana_en.c
@@ -2756,6 +2756,10 @@ static int mana_alloc_rx_wqe(struct mana
*cq_size += COMP_ENTRY_SIZE;
}
+ /* Reserve an extra slot for Fence completion
+ * event (CQE_RX_OBJECT_FENCE) in case RX CQ is full.
+ */
+ *cq_size += COMP_ENTRY_SIZE;
return 0;
}
@@ -2850,7 +2854,7 @@ static struct mana_rxq *mana_create_rxq(
goto out;
rq_size = MANA_PAGE_ALIGN(rq_size);
- cq_size = MANA_PAGE_ALIGN(cq_size);
+ cq_size = MANA_PAGE_ALIGN(roundup_pow_of_two(cq_size));
/* Create RQ */
memset(&spec, 0, sizeof(spec));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 548/733] net: mpls: clear inner_protocol when the last label is popped
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (546 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 547/733] net: mana: Reserve extra CQ slot for the fence completion CQE Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 549/733] net: openvswitch: fix use-after-free of the flow table mask array Greg Kroah-Hartman
` (196 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fourie Zhang, Jiri Benc,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fourie Zhang <littleddfu@gmail.com>
commit 78a86d75a70e1e227711c72865c59b1422d0a5ae upstream.
skb_mpls_push() records the pre-encapsulation network header once, gated
on !skb->inner_protocol. skb_mpls_pop() never clears that record, so it
outlives the encapsulation it describes.
Open vSwitch can then re-push MPLS onto a packet whose
inner_network_header still points at the older, deeper offset: push a
label, pop every label, recirculate (ovs_flow_key_update() re-derives
key->eth.type and resets network_header, but leaves inner_*), then push
again. ovs_fragment() trusts the record:
skb->network_header = skb->inner_network_header;
so skb_network_offset() goes negative. The bound check is signed:
if (skb_network_offset(skb) > MAX_L2_LEN)
a negative offset passes it, and prepare_frag() widens the value:
unsigned int hlen = skb_network_offset(skb);
memcpy(&data->l2_data, skb->data, hlen);
which is a ~4GiB memcpy out of a 30-byte per-CPU buffer.
Reproduced on v7.3-rc1. RDX is the truncated length, (unsigned int)(-8):
BUG: unable to handle page fault for address: ffffe8ffffc16000
#PF: supervisor write access in kernel mode
Oops: 0002 [#1] SMP KASAN NOPTI
RIP: 0010:memcpy+0x8/0x20
RDX: 00000000fffffff8 RSI: ffff888105d732db RDI: ffffe8ffffc16000
prepare_frag+0x3df/0x4e0
ovs_fragment+0x589/0x7e0
do_output+0x4ce/0x5e0
do_execute_actions+0x55d2/0x7b30
ovs_execute_actions+0xea/0x450
Same root-cause shape as commit 975b5b067f52 ("ipv6: sr: restore network
header before routing and forwarding"): a stale network header offset
reaching a consumer that widens it. Here it originates in the MPLS
push/pop path.
Clear inner_protocol once the packet is no longer MPLS, so a later push
re-records the current header. net/sched/act_mpls.c is the only other
skb_mpls_pop() caller and gets the same fix; sch_frag.c saves and
restores inner_protocol around fragmentation in the same way OVS does.
Fixes: 48d2ab609b6b ("net: mpls: Fixups for GSO")
Cc: stable@vger.kernel.org
Signed-off-by: Fourie Zhang <fouriezhang@tencent.com>
Acked-by: Jiri Benc <jbenc@redhat.com>
Link: https://patch.msgid.link/20260902092719.2874481-1-fouriezhang@tencent.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/core/skbuff.c | 7 +++++++
1 file changed, 7 insertions(+)
--- a/net/core/skbuff.c
+++ b/net/core/skbuff.c
@@ -6678,6 +6678,13 @@ int skb_mpls_pop(struct sk_buff *skb, __
}
skb->protocol = next_proto;
+ /* The last label is gone, so the inner header recorded by
+ * skb_mpls_push() no longer describes this packet. Drop it, or a
+ * later push keeps the stale offset.
+ */
+ if (!eth_p_mpls(next_proto))
+ skb->inner_protocol = 0;
+
return 0;
}
EXPORT_SYMBOL_GPL(skb_mpls_pop);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 549/733] net: openvswitch: fix use-after-free of the flow table mask array
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (547 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 548/733] net: mpls: clear inner_protocol when the last label is popped Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 550/733] net: phy: dp83td510: handle the active-high LED polarity mode Greg Kroah-Hartman
` (195 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Ilya Maximets,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
commit ba4ba11ed6eb8972c69070417fc27b48deb002e8 upstream.
tbl_mask_array_realloc() retires the old mask_array before it stops being
reachable:
old = ovsl_dereference(tbl->mask_array);
if (old) {
...
call_rcu(&old->rcu, mask_array_rcu_cb);
}
rcu_assign_pointer(tbl->mask_array, new);
call_rcu() only waits for read-side critical sections already in flight.
tbl->mask_array still points at old between the call_rcu() and the
rcu_assign_pointer(), so a reader entering ovs_flow_tbl_lookup_stats() in
that window picks up old in a fresh critical section that the pending
grace period does not cover.
tbl_mask_array_realloc() runs in process context under ovs_mutex, so the
window is preemptible and can outlast the grace period. Then
mask_array_rcu_cb() frees old before the swap runs:
BUG: KASAN: slab-use-after-free in flow_lookup.constprop.0+0x2bf/0x2f0
Read of size 8 at addr ffff888020b3e018 by task poc/741
flow_lookup.constprop.0+0x2bf/0x2f0
ovs_flow_tbl_lookup_stats+0x4a3/0x5c0
ovs_dp_process_packet+0x19c/0x710
ovs_vport_receive+0x243/0x390
internal_dev_xmit+0x81/0x170
Freed by task 728:
kfree+0x16a/0x4e0
rcu_core+0x853/0x1030
Publish the new array before retiring the old one. The kfree_rcu() that
call_rcu() replaced ran after the swap.
Fixes: eac87c413bf9 ("net: openvswitch: reorder masks array based on usage")
Cc: stable@vger.kernel.org
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Ilya Maximets <i.maximets@ovn.org>
Acked-by: Eelco Chaudron echaudro@redhat.com
Link: https://patch.msgid.link/DE115F9C-2545-423E-A702-986FC952FD62@doyensec.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/openvswitch/flow_table.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/openvswitch/flow_table.c
+++ b/net/openvswitch/flow_table.c
@@ -257,11 +257,13 @@ static int tbl_mask_array_realloc(struct
if (ovsl_dereference(old->masks[i]))
new->masks[new->count++] = old->masks[i];
}
- call_rcu(&old->rcu, mask_array_rcu_cb);
}
rcu_assign_pointer(tbl->mask_array, new);
+ if (old)
+ call_rcu(&old->rcu, mask_array_rcu_cb);
+
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 550/733] net: phy: dp83td510: handle the active-high LED polarity mode
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (548 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 549/733] net: openvswitch: fix use-after-free of the flow table mask array Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 551/733] netfs: Fix uninitialized return value in netfs_unbuffered_write() Greg Kroah-Hartman
` (194 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Donggeun Yoo, Andrew Lunn,
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
commit 6ca81bbc31cdc964e4b74d17b86215d4a810a56f upstream.
dp83td510_led_polarity_set() only recognizes PHY_LED_ACTIVE_LOW, so
PHY_LED_ACTIVE_HIGH falls through to the default case and returns -EINVAL.
of_phy_led() propagates the error, of_phy_leds() drops the LEDs registered
so far and passes it on, and phy_probe() returns it. A device tree marking
a DP83TD510 LED as 'active-high', which leds/common.yaml allows and
ethernet-phy.yaml references for led@N nodes, thus leaves the mdio device
unbound, so phy_attach_direct() falls back to the genphy driver, which
cannot drive this 10BASE-T1L single-mode PHY, so the interface has no
usable link.
The callback initializes polarity to DP83TD510E_LED_POLARITY(index), which
is the active-high setting, so the request is already satisfied and only
the case label is missing.
Cc: stable@vger.kernel.org
Fixes: 5b281fe7e396 ("net: phy: dp83td510: introduce LED framework support")
Signed-off-by: Donggeun Yoo <donggeunyoo.kernel@gmail.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
Link: https://patch.msgid.link/20260908105959.70453-3-donggeunyoo.kernel@gmail.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/phy/dp83td510.c | 3 +++
1 file changed, 3 insertions(+)
--- a/drivers/net/phy/dp83td510.c
+++ b/drivers/net/phy/dp83td510.c
@@ -439,6 +439,9 @@ static int dp83td510_led_polarity_set(st
case PHY_LED_ACTIVE_LOW:
polarity = 0;
break;
+ case PHY_LED_ACTIVE_HIGH:
+ polarity = DP83TD510E_LED_POLARITY(index);
+ break;
default:
return -EINVAL;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 551/733] netfs: Fix uninitialized return value in netfs_unbuffered_write()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (549 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 550/733] net: phy: dp83td510: handle the active-high LED polarity mode Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 552/733] netfilter: cttimeout: prevent UAF during module unload Greg Kroah-Hartman
` (193 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, David Howells,
Paulo Alcantara, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit f18e8774f4d3137fa0a5fb8ffa83d59a719666d8 upstream.
If preparation of the first subrequest fails,
netfs_unbuffered_write() exits its loop before ret is initialized. The
empty-iterator check can do the same.
For synchronous writes, netfs_unbuffered_write_iter_locked() may then
return an unrelated error instead of wreq->error. This is reachable
through CIFS if cifs_prepare_write() fails to reopen the file or obtain
credits.
Initialize ret to 0 so the caller returns wreq->error if no data was
written, or the number of bytes already written otherwise.
Found with Clang's -Wconditional-uninitialized.
Fixes: a0b4c7a49137e ("netfs: Fix unbuffered/DIO writes to dispatch subrequests in strict sequence")
Cc: stable@vger.kernel.org
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260827134304.2075713-2-dhowells@redhat.com
Acked-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/netfs/direct_write.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/netfs/direct_write.c
+++ b/fs/netfs/direct_write.c
@@ -95,7 +95,7 @@ static int netfs_unbuffered_write(struct
{
struct netfs_io_subrequest *subreq = NULL;
struct netfs_io_stream *stream = &wreq->io_streams[0];
- int ret;
+ int ret = 0;
_enter("%llx", wreq->len);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 552/733] netfilter: cttimeout: prevent UAF during module unload
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (550 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 551/733] netfs: Fix uninitialized return value in netfs_unbuffered_write() Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 553/733] netfilter: nf_log: unregister loggers before per-net teardown Greg Kroah-Hartman
` (192 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Pablo Neira Ayuso
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit fec9b1de0d02de8dafa3cc344bcb91cf28660643 upstream.
nf_ct_set_timeout() protects the timeout hook dereference and policy lookup
with rcu_read_lock(). cttimeout_exit(), however, unregisters the per-net
operations before it clears the hook.
This allows the following interleaving:
CPU 0 CPU 1
cttimeout_exit() nf_ct_set_timeout()
unregister_pernet_subsys() rcu_read_lock()
kfree(pernet) h = nf_ct_timeout_hook
h->timeout_find_get()
nfct_timeout_pernet()
The hook still points to ctnl_timeout_find_get() when CPU 1 looks up the
already freed per-net timeout list. KASAN reported:
BUG: KASAN: slab-use-after-free in ctnl_timeout_find_get
Read of size 8 by task poc/90
Call Trace:
ctnl_timeout_find_get+0x271/0x2a0 [nfnetlink_cttimeout]
nf_ct_set_timeout+0x7b/0x3c0
xt_ct_tg_check+0x724/0xb20
xt_check_target+0x234/0xa90
do_ipt_set_ctl+0x570/0x1270
Allocated by task 89:
__kmalloc_noprof+0x16e/0x460
ops_init+0x6d/0x420
register_pernet_operations+0x2f6/0x670
Freed by task 91:
kfree+0x131/0x390
ops_undo_list+0x3d4/0x730
unregister_pernet_operations+0x232/0x490
unregister_pernet_subsys+0x1c/0x30
cttimeout_exit+0x52/0x970 [nfnetlink_cttimeout]
Clear the hook and wait for existing readers before unregistering the
per-net operations. This blocks new policy lookups and ensures readers that
observed the hook finish before the per-net storage is freed.
Fixes: ebfbe67568a7 ("netfilter: cttimeout: use net_generic infra")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netfilter/nfnetlink_cttimeout.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/netfilter/nfnetlink_cttimeout.c
+++ b/net/netfilter/nfnetlink_cttimeout.c
@@ -652,9 +652,9 @@ static void __exit cttimeout_exit(void)
{
nfnetlink_subsys_unregister(&cttimeout_subsys);
- unregister_pernet_subsys(&cttimeout_ops);
RCU_INIT_POINTER(nf_ct_timeout_hook, NULL);
synchronize_net();
+ unregister_pernet_subsys(&cttimeout_ops);
}
module_init(cttimeout_init);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 553/733] netfilter: nf_log: unregister loggers before per-net teardown
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (551 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 552/733] netfilter: cttimeout: prevent UAF during module unload Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 554/733] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out Greg Kroah-Hartman
` (191 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Pablo Neira Ayuso
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit 2c018cc4842c33f0c732962e2ab58635e8ae5823 upstream.
nf_log_syslog and nfnetlink_log unregister their per-network namespace
operations before unregistering their global logger backends. This
leaves a window where a sysctl or netlink writer can rebind the still-
registered logger after the per-net pre-exit callback cleared the old
selection.
The race looks like this:
CPU 0 CPU 1
---- ----
unregister_pernet_subsys()
nf_log_unset(net, logger)
net->nf.nf_loggers[pf] = NULL
lock nf_log_mutex
find logger in loggers[][]
net->nf.nf_loggers[pf] = logger
unlock nf_log_mutex
nf_log_unregister(logger)
lock nf_log_mutex
loggers[pf][type] = NULL
unlock nf_log_mutex
synchronize_rcu()
module exit returns
module core frees backend memory
Later, a sysctl read or packet logging operation can dereference the
stale per-net logger pointer.
Fix this by unregistering the global logger backends before tearing down
per-net state. Once the global registrations are gone, later writers can
no longer rebind the logger. unregister_pernet_subsys() already waits
for an RCU grace period after the pre-exit callback clears the per-net
selection, while nf_log_unregister() continues to cover readers of the
global logger table.
Apply this ordering fix to both nf_log backends that combine per-net
teardown with global logger registration.
Fixes: 5b023fc8d8e0 ("netfilter: enable per netns support for nf_loggers")
Cc: stable@vger.kernel.org
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netfilter/nf_log_syslog.c | 2 +-
net/netfilter/nfnetlink_log.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/net/netfilter/nf_log_syslog.c
+++ b/net/netfilter/nf_log_syslog.c
@@ -1073,12 +1073,12 @@ err1:
static void __exit nf_log_syslog_exit(void)
{
- unregister_pernet_subsys(&nf_log_syslog_net_ops);
nf_log_unregister(&nf_ip_logger);
nf_log_unregister(&nf_arp_logger);
nf_log_unregister(&nf_ip6_logger);
nf_log_unregister(&nf_netdev_logger);
nf_log_unregister(&nf_bridge_logger);
+ unregister_pernet_subsys(&nf_log_syslog_net_ops);
}
module_init(nf_log_syslog_init);
--- a/net/netfilter/nfnetlink_log.c
+++ b/net/netfilter/nfnetlink_log.c
@@ -1238,8 +1238,8 @@ static void __exit nfnetlink_log_fini(vo
{
nfnetlink_subsys_unregister(&nfulnl_subsys);
netlink_unregister_notifier(&nfulnl_rtnl_notifier);
- unregister_pernet_subsys(&nfnl_log_net_ops);
nf_log_unregister(&nfulnl_logger);
+ unregister_pernet_subsys(&nfnl_log_net_ops);
}
MODULE_DESCRIPTION("netfilter userspace logging");
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 554/733] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (552 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 553/733] netfilter: nf_log: unregister loggers before per-net teardown Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 555/733] vdpa: ifcvf: Put device on unsupported feature error Greg Kroah-Hartman
` (190 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ilya Maximets, Florian Westphal,
Pablo Neira Ayuso
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ilya Maximets <i.maximets@ovn.org>
commit 7a099b347fef536a84068076e2d384f044e5cfc5 upstream.
NLM_F_DUMP_FILTERED is only set on data elements in the conntrack dump.
But when everything is filtered out it is confusing for the user space,
since the flag is not reported anymore and it looks like the table was
empty, which may or may not be the case.
'answer_flags' were introduced precisely for this use case, and the
conntrack dump should set the flag in there in case the filtering was
applied.
This is important, for example, to be able to tell if the filters are
supported or not by the kernel without modifying the kernel state.
With the proper reporting of NLM_F_DUMP_FILTERED on NLMSG_DONE, an
application in user space can just try and dump with an arbitrary
filter without worrying that there could be no matching entry. The
reported flag will signal that the filtering was applied and therefore
supported.
Fixes: cb8aa9a3affb ("netfilter: ctnetlink: add kernel side filtering for dump")
Cc: stable@vger.kernel.org
Signed-off-by: Ilya Maximets <i.maximets@ovn.org>
Reviewed-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netfilter/nf_conntrack_netlink.c | 2 ++
1 file changed, 2 insertions(+)
--- a/net/netfilter/nf_conntrack_netlink.c
+++ b/net/netfilter/nf_conntrack_netlink.c
@@ -1077,6 +1077,8 @@ static int ctnetlink_start(struct netlin
}
cb->data = filter;
+ if (filter)
+ cb->answer_flags = NLM_F_DUMP_FILTERED;
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 555/733] vdpa: ifcvf: Put device on unsupported feature error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (553 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 554/733] netfilter: report NLM_F_DUMP_FILTERED when all is filtered out Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 556/733] vdpa: solidrun: Free IRQs after request failure Greg Kroah-Hartman
` (189 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xiong Weimin, Michael S. Tsirkin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiong Weimin <xiongweimin@kylinos.cn>
commit 4d470be71196ca0ce302e6623454533dc31b465b upstream.
Route unsupported provisioned features through the common error path after
vdpa_alloc_device() so the allocated device and adapter pointer are
released consistently.
Fixes: 46fc0917bbab ("vDPA/ifcvf: implement features provisioning")
Cc: stable@vger.kernel.org # v6.3+
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <178589471294.1556376.4816776800128323034@kylinos.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/vdpa/ifcvf/ifcvf_main.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/vdpa/ifcvf/ifcvf_main.c
+++ b/drivers/vdpa/ifcvf/ifcvf_main.c
@@ -724,7 +724,8 @@ static int ifcvf_vdpa_dev_add(struct vdp
if (config->device_features & ~device_features) {
IFCVF_ERR(pdev, "The provisioned features 0x%llx are not supported by this device with features 0x%llx\n",
config->device_features, device_features);
- return -EINVAL;
+ ret = -EINVAL;
+ goto err;
}
device_features &= config->device_features;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 556/733] vdpa: solidrun: Free IRQs after request failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (554 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 555/733] vdpa: ifcvf: Put device on unsupported feature error Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 557/733] scripts/sorttable: Mark long_size as __maybe_unused Greg Kroah-Hartman
` (188 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xiong Weimin, Michael S. Tsirkin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xiong Weimin <xiongweimin@kylinos.cn>
commit e847542ab0545c73354849126150206c29d83929 upstream.
Unwind IRQs already requested by snet_request_irqs() before returning a
VQ IRQ request error so a later DRIVER_OK retry starts from a clean
state. The IRQs are requested and freed while the PCI device remains
bound, so the driver cannot wait for devres cleanup at detach time.
Fixes: 51a8f9d7f587 ("virtio: vdpa: new SolidNET DPU driver.")
Cc: stable@vger.kernel.org # v6.3+
Signed-off-by: Xiong Weimin <xiongweimin@kylinos.cn>
Signed-off-by: Michael S. Tsirkin <mst@redhat.com>
Message-ID: <178589471328.1556376.15570536900532373521@kylinos.cn>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/vdpa/solidrun/snet_main.c | 6 +++++-
1 file changed, 5 insertions(+), 1 deletion(-)
--- a/drivers/vdpa/solidrun/snet_main.c
+++ b/drivers/vdpa/solidrun/snet_main.c
@@ -418,11 +418,15 @@ static int snet_request_irqs(struct pci_
snet->vqs[i]->irq_name, snet->vqs[i]);
if (ret) {
SNET_ERR(pdev, "Failed to request IRQ\n");
- return ret;
+ goto err_free_irqs;
}
snet->vqs[i]->irq = irq;
}
return 0;
+
+err_free_irqs:
+ snet_free_irqs(snet);
+ return ret;
}
static void snet_set_status(struct vdpa_device *vdev, u8 status)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 557/733] scripts/sorttable: Mark long_size as __maybe_unused
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (555 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 556/733] vdpa: solidrun: Free IRQs after request failure Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 558/733] fs: autofs: fix memory leak in autofs_fill_super() Greg Kroah-Hartman
` (187 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nathan Chancellor, Nicolas Schier,
Nicolas Schier
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nathan Chancellor <nathan@kernel.org>
commit 4f73462856576797b8f3c55564a9be99f76dc67b upstream.
When building in a kernel tree prior to commit b055f4c431e3 ("sorttable:
Move ELF parsing into scripts/elf-parse.[ch]") with clang-23 or newer,
which implements a new warning under -Wunused-but-set-variable for
static global variable, there is a warning from sorttable because
long_size is unused when MCOUNT_SORT_ENABLED is not set:
scripts/sorttable.c:452:12: error: variable 'long_size' set but not used [-Werror,-Wunused-but-set-global]
452 | static int long_size;
| ^
Mark long_size as __maybe_unused to avoid inserting more ugly #ifdef
directives while insuring the warning does not reappear, as the
aforementioned change does not alter the uses of long_size, so it
appears to be coincidence that the warning disappears after this
refactoring.
Cc: stable@vger.kernel.org
Signed-off-by: Nathan Chancellor <nathan@kernel.org>
Tested-by: Nicolas Schier <n.schier@fritz.com>
Link: https://patch.msgid.link/20260831-sorttable-long_size-unused-but-set-global-v1-1-8a96b88697e5@kernel.org
Signed-off-by: Nicolas Schier <nsc@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
scripts/sorttable.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/scripts/sorttable.c
+++ b/scripts/sorttable.c
@@ -116,7 +116,7 @@ static inline void *get_index(void *star
}
static int extable_ent_size;
-static int long_size;
+static int long_size __maybe_unused;
#define ERRSTR_MAXSZ 256
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 558/733] fs: autofs: fix memory leak in autofs_fill_super()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (556 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 557/733] scripts/sorttable: Mark long_size as __maybe_unused Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 559/733] erofs: add sysfs feature entry for xattr prefixes Greg Kroah-Hartman
` (186 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+df1db6e034b3953e19f5,
Jeffin Philip, Ian Kent, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeffin Philip <jeffinphilip14@gmail.com>
commit 5ab54837fce04a1c9923d0bfd3d5de51fdc768b3 upstream.
In autofs_fill_super(), we create a new inode using
autofs_new_ino(), however, if we fail to create root_inode,
(that is, root_inode failure path), we return -ENOMEM without
freeing the new inode(ino) that we created causing a memory leak.
Fix this by adding autofs_free_ino() to free the inode we created
in root_inode failure path before returning ENOMEM.
Reported-by: syzbot+df1db6e034b3953e19f5@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=df1db6e034b3953e19f5
Fixes: 66917f85db60 ("autofs: add: new_inode check in autofs_fill_super()")
Cc: stable@vger.kernel.org
Signed-off-by: Jeffin Philip <jeffinphilip14@gmail.com>
Link: https://patch.msgid.link/20260903081048.132524-1-jeffinphilip14@gmail.com
Signed-off-by: Ian Kent <raven@themaw.net>
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/autofs/inode.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/autofs/inode.c
+++ b/fs/autofs/inode.c
@@ -323,8 +323,10 @@ static int autofs_fill_super(struct supe
return -ENOMEM;
root_inode = autofs_get_inode(s, S_IFDIR | 0755);
- if (!root_inode)
+ if (!root_inode) {
+ autofs_free_ino(ino);
return -ENOMEM;
+ }
root_inode->i_uid = ctx->uid;
root_inode->i_gid = ctx->gid;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 559/733] erofs: add sysfs feature entry for xattr prefixes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (557 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 558/733] fs: autofs: fix memory leak in autofs_fill_super() Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 560/733] erofs: preserve LZMA decoders on resize failure Greg Kroah-Hartman
` (185 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gao Xiang, Jingbo Xu
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jingbo Xu <jefflexu@linux.alibaba.com>
commit 839f075aabdf5c21048f9801b87c0b841dd3d064 upstream.
Let /sys/fs/erofs/features/xattr_prefixes advertise that this kernel
supports the EROFS_FEATURE_INCOMPAT_XATTR_PREFIXES on-disk format.
Fixes: 6a318ccd7e08 ("erofs: enable long extended attribute name prefixes")
Cc: stable@vger.kernel.org # 6.4+
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Jingbo Xu <jefflexu@linux.alibaba.com>
Signed-off-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
Documentation/ABI/testing/sysfs-fs-erofs | 2 +-
fs/erofs/sysfs.c | 2 ++
2 files changed, 3 insertions(+), 1 deletion(-)
--- a/Documentation/ABI/testing/sysfs-fs-erofs
+++ b/Documentation/ABI/testing/sysfs-fs-erofs
@@ -5,7 +5,7 @@ Description: Shows all enabled kernel fe
Supported features:
compr_cfgs, big_pcluster, chunked_file, device_table,
compr_head2, sb_chksum, ztailpacking, dedupe, fragments,
- 48bit, metabox.
+ xattr_prefixes, 48bit, metabox.
What: /sys/fs/erofs/<disk>/sync_decompress
Date: November 2021
--- a/fs/erofs/sysfs.c
+++ b/fs/erofs/sysfs.c
@@ -95,6 +95,7 @@ EROFS_ATTR_FEATURE(sb_chksum);
EROFS_ATTR_FEATURE(ztailpacking);
EROFS_ATTR_FEATURE(fragments);
EROFS_ATTR_FEATURE(dedupe);
+EROFS_ATTR_FEATURE(xattr_prefixes);
EROFS_ATTR_FEATURE(48bit);
EROFS_ATTR_FEATURE(metabox);
@@ -108,6 +109,7 @@ static struct attribute *erofs_feat_attr
ATTR_LIST(ztailpacking),
ATTR_LIST(fragments),
ATTR_LIST(dedupe),
+ ATTR_LIST(xattr_prefixes),
ATTR_LIST(48bit),
ATTR_LIST(metabox),
NULL,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 560/733] erofs: preserve LZMA decoders on resize failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (558 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 559/733] erofs: add sysfs feature entry for xattr prefixes Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 561/733] fbdev: vfb: defer cleanup until the last reference Greg Kroah-Hartman
` (184 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nikhil Gurudasani, Gao Xiang
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
commit 617d0d8d199ba1790c94310fd75a22d01c97a8d6 upstream.
The pool-resize path frees each stream's old decoder before allocating
its replacement. If an allocation fails after some streams have already
been replaced, the failed stream is put back on the list with state ==
NULL. z_erofs_lzma_max_dictsize is still advanced as if the whole
pool had been resized.
An existing LZMA mount can select the broken stream and pass
NULL to xz_dec_microlzma_reset(). A retry at the same size also
skip another resize attempt. Since the global maximum was advanced,
thus, the invalid state is left unrepaired.
Allocate each replacement before freeing the old decoder, temporarily
retaining one old decoder during allocation. Stop at the first failure
and advance z_erofs_lzma_max_dictsize only after all streams satisfy
the request.
Record each stream's dictionary capacity so retries can skip streams
already enlarged before a partial failure.
Fixes: 622ceaddb764 ("erofs: lzma compression support")
Cc: stable@vger.kernel.org
Signed-off-by: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
Reviewed-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Gao Xiang <xiang@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/erofs/decompressor_lzma.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
--- a/fs/erofs/decompressor_lzma.c
+++ b/fs/erofs/decompressor_lzma.c
@@ -5,6 +5,7 @@
struct z_erofs_lzma {
struct z_erofs_lzma *next;
struct xz_dec_microlzma *state;
+ unsigned int dict_size;
u8 bounce[PAGE_SIZE];
};
@@ -128,11 +129,19 @@ again:
err = 0;
/* 2. walk each isolated stream and grow max dict_size if needed */
for (strm = head; strm; strm = strm->next) {
+ struct xz_dec_microlzma *state;
+
+ if (strm->dict_size >= dict_size)
+ continue;
+ state = xz_dec_microlzma_alloc(XZ_PREALLOC, dict_size);
+ if (!state) {
+ err = -ENOMEM;
+ break;
+ }
if (strm->state)
xz_dec_microlzma_end(strm->state);
- strm->state = xz_dec_microlzma_alloc(XZ_PREALLOC, dict_size);
- if (!strm->state)
- err = -ENOMEM;
+ strm->state = state;
+ strm->dict_size = dict_size;
}
/* 3. push back all to the global list and update max dict_size */
@@ -142,7 +151,8 @@ again:
spin_unlock(&z_erofs_lzma_lock);
wake_up_all(&z_erofs_lzma_wq);
- z_erofs_lzma_max_dictsize = dict_size;
+ if (!err)
+ z_erofs_lzma_max_dictsize = dict_size;
mutex_unlock(&lzma_resize_mutex);
return err;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 561/733] fbdev: vfb: defer cleanup until the last reference
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (559 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 560/733] erofs: preserve LZMA decoders on resize failure Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 562/733] idpf: disable DIM work before freeing q_vectors Greg Kroah-Hartman
` (183 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, co+c25629c98ba36ebe, stable,
Weiming Shi, Helge Deller
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weiming Shi <bestswngs@gmail.com>
commit a0a34a40ed299c9c7cff6af163a5b883ee9d6d73 upstream.
FBIOGETCMAP takes a shallow snapshot of info->cmap and performs the
usercopy after dropping info->lock. vfb_remove() frees the colormap
immediately after unregistering the framebuffer, even when an open file
still holds a reference to fb_info. A concurrent driver unbind can
therefore free the colormap while the ioctl copies it to userspace.
KASAN reports:
BUG: KASAN: slab-use-after-free in _copy_to_user
Read of size 512 by task poc/125
_copy_to_user (./include/linux/instrumented.h:129 ./include/linux/uaccess.h:201 lib/usercopy.c:24)
fb_cmap_to_user (./include/linux/uaccess.h:230 drivers/video/fbdev/core/fbcmap.c:211)
do_fb_ioctl (drivers/video/fbdev/core/fb_chrdev.c:114)
Allocated by task 1:
fb_alloc_cmap_gfp (./include/linux/slab.h:973 ./include/linux/slab.h:1290 drivers/video/fbdev/core/fbcmap.c:108)
vfb_probe (drivers/video/fbdev/vfb.c:459)
Freed by task 124:
fb_dealloc_cmap (drivers/video/fbdev/core/fbcmap.c:151)
vfb_remove (drivers/video/fbdev/vfb.c:489)
unregister_framebuffer() drops the registration reference, and fbdev calls
fb_destroy after the last put_fb_info(). Move the registered framebuffer's
cleanup into an fb_destroy callback so its colormap and screen buffer stay
alive until all file references have been released.
Fixes: 5e266e2e0e19 ("vfb: fix memory leaks in removal path")
Reported-by: co+c25629c98ba36ebe@bugs.sh
Cc: stable@kernel.org
Closes: https://lore.kernel.org/linux-fbdev/f2Kf9GYn1lKR5S1dbvGVtykMxK1RlgP5z8sW@bugs.sh/
Assisted-by: Codex:gpt-5
Signed-off-by: Weiming Shi <bestswngs@gmail.com>
Link: https://lore.kernel.org/linux-fbdev/f2Kf9GYn1lKR5S1dbvGVtykMxK1RlgP5z8sW@bugs.sh/
Signed-off-by: Helge Deller <deller@gmx.de>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/video/fbdev/vfb.c | 11 ++++++++---
1 file changed, 8 insertions(+), 3 deletions(-)
--- a/drivers/video/fbdev/vfb.c
+++ b/drivers/video/fbdev/vfb.c
@@ -78,6 +78,13 @@ static int vfb_pan_display(struct fb_var
static int vfb_mmap(struct fb_info *info,
struct vm_area_struct *vma);
+static void vfb_destroy(struct fb_info *info)
+{
+ vfree(info->screen_buffer);
+ fb_dealloc_cmap(&info->cmap);
+ framebuffer_release(info);
+}
+
static const struct fb_ops vfb_ops = {
.owner = THIS_MODULE,
__FB_DEFAULT_SYSMEM_OPS_RDWR,
@@ -87,6 +94,7 @@ static const struct fb_ops vfb_ops = {
.fb_pan_display = vfb_pan_display,
__FB_DEFAULT_SYSMEM_OPS_DRAW,
.fb_mmap = vfb_mmap,
+ .fb_destroy = vfb_destroy,
};
/*
@@ -485,9 +493,6 @@ static void vfb_remove(struct platform_d
if (info) {
unregister_framebuffer(info);
- vfree(videomemory);
- fb_dealloc_cmap(&info->cmap);
- framebuffer_release(info);
}
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 562/733] idpf: disable DIM work before freeing q_vectors
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (560 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 561/733] fbdev: vfb: defer cleanup until the last reference Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 563/733] inet: frags: invalidate queues before flushing them Greg Kroah-Hartman
` (182 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ijae Kim, Myeonghun Pak,
Samuel Salin, Tony Nguyen
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Myeonghun Pak <mhun512@gmail.com>
commit 7dd4c829bac2916be98a3e34b41daaba7f42b4c4 upstream.
idpf never drains the Tx/Rx DIM works before freeing the memory they
live in. tx_dim and rx_dim are embedded in struct idpf_q_vector, they
are queued from the NAPI poll via net_dim(), and idpf_vport_intr_rel()
ends with kfree(rsrc->q_vectors). Nothing in the driver cancels them.
idpf_tx_dim_work() and idpf_rx_dim_work() then run on freed memory:
idpf_vport_intr_write_itr() writes the ITR register through
q_vector->intr_reg.tx_itr / rx_itr, void __iomem pointers loaded out of
the freed q_vector. No configuration is needed to get there --
IDPF_ITR_IS_DYNAMIC() is defined as (itr_mode) and idpf_vport_alloc()
initialises both modes to IDPF_ITR_DYNAMIC.
Draining after idpf_vport_intr_napi_dis_all() is not enough on its own.
idpf_net_dim() is called from inside the
"if (napi_complete_done(napi, work_done))" branch of the poll, and
napi_complete_done() has already cleared NAPIF_STATE_SCHED by then.
napi_disable_locked() waits only while (val & (NAPIF_STATE_SCHED |
NAPIF_STATE_NPSVC)), so napi_disable() can return while the poll tail is
still queueing the work, and a plain cancel_work_sync() would be
re-armed behind the drain.
Use disable_work_sync(): schedule_work() on a work with a non-zero
disable count is dropped by clear_pending_if_disabled() before
__queue_work() is reached.
Move idpf_init_dim() to idpf_vport_intr_alloc() so the works are
initialised on every path that can reach the drain -- the three
"goto intr_deinit" sites between idpf_vport_intr_init() and
idpf_vport_intr_ena() get there without the enable side having run.
Nothing re-enables them: rsrc->q_vectors is freed on every exit from
idpf_vport_open() and on every idpf_vport_stop(), so the count dies with
the object.
It is a race, not a deterministic failure -- net_dim() only schedules
once DIM_NEVENTS events have accumulated and the profile index changes.
A KASAN ifup/ifdown loop under load is the way to see it.
Fixes: c2d548cad150 ("idpf: add TX splitq napi poll support")
Fixes: 3a8845af66ed ("idpf: add RX splitq napi poll support")
Cc: <stable@vger.kernel.org> # see patch description, needs adjustments for <= 6.9
Co-developed-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Ijae Kim <ae878000@gmail.com>
Signed-off-by: Myeonghun Pak <mhun512@gmail.com>
Tested-by: Samuel Salin <Samuel.salin@intel.com>
Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/intel/idpf/idpf_txrx.c | 24 +++++++++++++++++++++++-
1 file changed, 23 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/intel/idpf/idpf_txrx.c
+++ b/drivers/net/ethernet/intel/idpf/idpf_txrx.c
@@ -4150,6 +4150,26 @@ static void idpf_vport_intr_ena_irq_all(
}
/**
+ * idpf_vport_intr_dis_dim_all - Disable DIM work for all q_vectors
+ * @rsrc: pointer to queue and vector resources
+ *
+ * The DIM works are embedded in the q_vector array that
+ * idpf_vport_intr_rel() frees, and the poll arms them after
+ * napi_complete_done() has already cleared NAPI_STATE_SCHED. Disable
+ * rather than just cancel, so that a poll tail still running past
+ * napi_disable() cannot queue them again behind the drain.
+ */
+static void idpf_vport_intr_dis_dim_all(struct idpf_q_vec_rsrc *rsrc)
+{
+ for (u16 v_idx = 0; v_idx < rsrc->num_q_vectors; v_idx++) {
+ struct idpf_q_vector *q_vector = &rsrc->q_vectors[v_idx];
+
+ disable_work_sync(&q_vector->tx_dim.work);
+ disable_work_sync(&q_vector->rx_dim.work);
+ }
+}
+
+/**
* idpf_vport_intr_deinit - Release all vector associations for the vport
* @vport: main vport structure
* @rsrc: pointer to queue and vector resources
@@ -4159,6 +4179,7 @@ void idpf_vport_intr_deinit(struct idpf_
{
idpf_vport_intr_dis_irq_all(rsrc);
idpf_vport_intr_napi_dis_all(rsrc);
+ idpf_vport_intr_dis_dim_all(rsrc);
idpf_vport_intr_napi_del_all(rsrc);
idpf_vport_intr_rel_irq(vport, rsrc);
}
@@ -4239,7 +4260,6 @@ static void idpf_vport_intr_napi_ena_all
for (u16 q_idx = 0; q_idx < rsrc->num_q_vectors; q_idx++) {
struct idpf_q_vector *q_vector = &rsrc->q_vectors[q_idx];
- idpf_init_dim(q_vector);
napi_enable(&q_vector->napi);
}
}
@@ -4582,6 +4602,8 @@ int idpf_vport_intr_alloc(struct idpf_vp
q_coal = &user_config->q_coalesce[v_idx];
q_vector->vport = vport;
+ idpf_init_dim(q_vector);
+
q_vector->tx_itr_value = q_coal->tx_coalesce_usecs;
q_vector->tx_intr_mode = q_coal->tx_intr_mode;
q_vector->tx_itr_idx = VIRTCHNL2_ITR_IDX_1;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 563/733] inet: frags: invalidate queues before flushing them
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (561 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 562/733] idpf: disable DIM work before freeing q_vectors Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 564/733] ieee802154: 6lowpan: fix NULL dereference in lowpan_newlink Greg Kroah-Hartman
` (181 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kimi Security Team, Weiming Shi,
Eric Dumazet, Yilin Zhang, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yilin Zhang <yilinzhang@moonshot.ai>
commit b824476c56a153934c67c9e0f873e1fd967743d6 upstream.
fqdir_pre_exit() flushes the skbs from incomplete queues without
changing their completion state. A fragment which found a queue before
high_thresh was cleared can then acquire the queue lock and reuse stale
reassembly metadata. A queue concurrently killed after fqdir->dead is
set can instead become INET_FRAG_COMPLETE|INET_FRAG_HASH_DEAD while
still holding its old skbs; skipping it because it is complete leaves
those references behind until asynchronous fqdir teardown.
For IPv6, stale metadata can make ip6_frag_reasm() use the old
nhoffset with a new skb and access memory out of bounds. The resulting
heap corruption can be leveraged for local privilege escalation when
unprivileged network namespaces are available. Unflushed fragments can
also keep conntrack references alive after the conntrack per-net
cleanup point.
Kill each incomplete queue, then flush every queue still owned by the
dying rhashtable. HASH_DEAD identifies that ownership, while complete
queues without it are already owned by another destroy path and must be
left alone. Releasing a timer reference removed by inet_frag_kill() is
deferred to inet_frag_putn(), after the queue lock is dropped.
KASAN report:
BUG: KASAN: slab-out-of-bounds in ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2))
Write of size 1 at addr ff110001039c6e00 by task poc/771
Call Trace:
? ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2))
ipv6_frag_rcv (net/ipv6/reassembly.c:289 (discriminator 2) net/ipv6/reassembly.c:229 (discriminator 2) net/ipv6/reassembly.c:391 (discriminator 2))
ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:479 (discriminator 5))
ip6_input_finish (net/ipv6/ip6_input.c:534)
ipv6_rcv (include/net/dst.h:480 (discriminator 3) net/ipv6/ip6_input.c:119 (discriminator 3) net/ipv6/ip6_input.c:109 (discriminator 3) include/linux/netfilter.h:325 (discriminator 3) include/linux/netfilter.h:319 (discriminator 3) net/ipv6/ip6_input.c:351 (discriminator 3))
packet_sendmsg (net/packet/af_packet.c:3110 net/packet/af_packet.c:3142)
__x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880)
The buggy address belongs to the object at ff110001039c6b40
which belongs to the cache skbuff_small_head of size 704
The buggy address is located 0 bytes to the right of
allocated 704-byte region [ff110001039c6b40, ff110001039c6e00)
BUG: KASAN: slab-out-of-bounds in ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1))
Read of size 1 at addr ff110001039c6e08 by task poc/771
Call Trace:
? ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1))
ip6_protocol_deliver_rcu (net/ipv6/ip6_input.c:423 (discriminator 1))
ip6_input_finish (net/ipv6/ip6_input.c:534)
ipv6_rcv (include/net/dst.h:480 (discriminator 3) net/ipv6/ip6_input.c:119 (discriminator 3) net/ipv6/ip6_input.c:109 (discriminator 3) include/linux/netfilter.h:325 (discriminator 3) include/linux/netfilter.h:319 (discriminator 3) net/ipv6/ip6_input.c:351 (discriminator 3))
packet_sendmsg (net/packet/af_packet.c:3110 net/packet/af_packet.c:3142)
__x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880)
packet_sendmsg (net/packet/af_packet.c:2959 net/packet/af_packet.c:3053 net/packet/af_packet.c:3142)
__x64_sys_sendmmsg (net/socket.c:2883 net/socket.c:2880 net/socket.c:2880)
The buggy address belongs to the object at ff110001039c6b40
which belongs to the cache skbuff_small_head of size 704
The buggy address is located 8 bytes to the right of
allocated 704-byte region [ff110001039c6b40, ff110001039c6e00)
Fixes: 006a5035b495 ("inet: frags: flush pending skbs in fqdir_pre_exit()")
Cc: stable@vger.kernel.org
Reported-by: Kimi Security Team <bug-report@moonshot.ai>
Tested-by: Weiming Shi <shiweiming@moonshot.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Signed-off-by: Yilin Zhang <yilinzhang@moonshot.ai>
Link: https://patch.msgid.link/20260904162800.1095662-1-yilinzhang@moonshot.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/inet_fragment.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/net/ipv4/inet_fragment.c
+++ b/net/ipv4/inet_fragment.c
@@ -235,6 +235,8 @@ void fqdir_pre_exit(struct fqdir *fqdir)
rhashtable_walk_start(&hti);
while ((fq = rhashtable_walk_next(&hti))) {
+ int refs = 0;
+
if (IS_ERR(fq)) {
if (PTR_ERR(fq) != -EAGAIN)
break;
@@ -242,8 +244,12 @@ void fqdir_pre_exit(struct fqdir *fqdir)
}
spin_lock_bh(&fq->lock);
if (!(fq->flags & INET_FRAG_COMPLETE))
+ inet_frag_kill(fq, &refs);
+
+ if (fq->flags & INET_FRAG_HASH_DEAD)
inet_frag_queue_flush(fq, 0);
spin_unlock_bh(&fq->lock);
+ inet_frag_putn(fq, refs);
}
rhashtable_walk_stop(&hti);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 564/733] ieee802154: 6lowpan: fix NULL dereference in lowpan_newlink
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (562 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 563/733] inet: frags: invalidate queues before flushing them Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 565/733] ieee802154: cc2520: fix FIFOP work use-after-free Greg Kroah-Hartman
` (180 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vega, Zhiling Zou, Stefan Schmidt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
commit bf79662bc85e820ac3b846e2f347da29fbf6ac95 upstream.
TUNSETLINK allows a TUN device to change its link-layer type to
ARPHRD_IEEE802154 without initializing ieee802154_ptr. lowpan_newlink()
checks only the device type before dereferencing the pointer, so an
RTM_NEWLINK request can trigger a NULL pointer dereference.
Reject devices without ieee802154_ptr along with devices of the wrong type.
Fixes: 51e0e5d8124e ("ieee802154: 6lowpan: remove multiple lowpan per wpan support")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Link: https://lore.kernel.org/0b715da69bd15a86ddc47dad5cf12da648211050.1787997209.git.zhilinz@nebusec.ai
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ieee802154/6lowpan/core.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/ieee802154/6lowpan/core.c
+++ b/net/ieee802154/6lowpan/core.c
@@ -150,7 +150,7 @@ static int lowpan_newlink(struct net_dev
wdev = dev_get_by_index(dev_net(ldev), nla_get_u32(tb[IFLA_LINK]));
if (!wdev)
return -ENODEV;
- if (wdev->type != ARPHRD_IEEE802154) {
+ if (wdev->type != ARPHRD_IEEE802154 || !wdev->ieee802154_ptr) {
dev_put(wdev);
return -EINVAL;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 565/733] ieee802154: cc2520: fix FIFOP work use-after-free
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (563 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 564/733] ieee802154: 6lowpan: fix NULL dereference in lowpan_newlink Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 566/733] ieee802154: hwsim: serialize pib updates to fix double-free Greg Kroah-Hartman
` (179 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Miquel Raynal, Fan Wu,
Stefan Schmidt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit ff5891b266a7fc6a062710836be84f1cc19338b5 upstream.
The FIFOP interrupt handler queues cc2520_fifop_irqwork. On removal,
cc2520_remove() only flushes the work. The devm-managed FIFOP IRQ
remains active until after ->remove() returns and can queue the work
again after that flush, allowing it to run after the private data is
released.
Disable the work with disable_work_sync() instead of flushing it, so
the handler can no longer queue it once removal begins. Destroy the
buffer mutex last, since the worker and the stop callback invoked
through ieee802154_unregister_hw() both take it.
Found by an in-house static analysis tool.
Fixes: 0da6bc8cc341 ("ieee802154: cc2520: adds driver for TI CC2520 radio")
Cc: stable@vger.kernel.org # v6.10+
Suggested-by: Miquel Raynal <miquel.raynal@bootlin.com>
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://lore.kernel.org/20260812061714.175966-1-fanwu01@zju.edu.cn
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ieee802154/cc2520.c | 5 ++---
1 file changed, 2 insertions(+), 3 deletions(-)
--- a/drivers/net/ieee802154/cc2520.c
+++ b/drivers/net/ieee802154/cc2520.c
@@ -1156,11 +1156,10 @@ static void cc2520_remove(struct spi_dev
{
struct cc2520_private *priv = spi_get_drvdata(spi);
- mutex_destroy(&priv->buffer_mutex);
- flush_work(&priv->fifop_irqwork);
-
+ disable_work_sync(&priv->fifop_irqwork);
ieee802154_unregister_hw(priv->hw);
ieee802154_free_hw(priv->hw);
+ mutex_destroy(&priv->buffer_mutex);
}
static const struct spi_device_id cc2520_ids[] = {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 566/733] ieee802154: hwsim: serialize pib updates to fix double-free
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (564 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 565/733] ieee802154: cc2520: fix FIFOP work use-after-free Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 567/733] ipv4: fib: bound automatic table ID allocation Greg Kroah-Hartman
` (178 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+60332fd095f8bb2946ad,
David Carlier, Stefan Schmidt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Carlier <devnexen@gmail.com>
commit 979d5b8de8ed4e1f997aef12da5694b99be7b871 upstream.
hwsim_update_pib() does an unserialized read-swap-free of phy->pib:
pib_old = rtnl_dereference(phy->pib);
...
rcu_assign_pointer(phy->pib, pib);
kfree_rcu(pib_old, rcu);
It assumes the RTNL is held, but ->set_channel is not always called
under it: the mac802154 scan worker changes channels via
drv_set_channel() without the RTNL. Such an update can race an
RTNL-held one on the same phy; both read the same pib_old and both
kfree_rcu() it, double-freeing the object. With SLUB percpu sheaves
batching kfree_rcu(), this surfaces as a KASAN invalid-free in
rcu_free_sheaf().
struct hwsim_phy has no lock for pib. Add one and make the swap atomic
with rcu_replace_pointer() under it, dropping the misleading
rtnl_dereference().
Reported-by: syzbot+60332fd095f8bb2946ad@syzkaller.appspotmail.com
Closes: https://syzkaller.appspot.com/bug?extid=60332fd095f8bb2946ad
Fixes: f25da51fdc38 ("ieee802154: hwsim: add replacement for fakelb")
Signed-off-by: David Carlier <devnexen@gmail.com>
Cc: stable@vger.kernel.org
Link: https://lore.kernel.org/20260709221858.158063-1-devnexen@gmail.com
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ieee802154/mac802154_hwsim.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/net/ieee802154/mac802154_hwsim.c
+++ b/drivers/net/ieee802154/mac802154_hwsim.c
@@ -72,6 +72,8 @@ struct hwsim_phy {
struct ieee802154_hw *hw;
u32 idx;
+ /* Serializes phy->pib_updates. */
+ spinlock_t pib_lock;
struct hwsim_pib __rcu *pib;
bool suspended;
@@ -102,8 +104,6 @@ static int hwsim_update_pib(struct ieee8
if (!pib)
return -ENOMEM;
- pib_old = rtnl_dereference(phy->pib);
-
pib->page = page;
pib->channel = channel;
pib->filt.short_addr = filt->short_addr;
@@ -112,7 +112,10 @@ static int hwsim_update_pib(struct ieee8
pib->filt.pan_coord = filt->pan_coord;
pib->filt_level = filt_level;
- rcu_assign_pointer(phy->pib, pib);
+ spin_lock_bh(&phy->pib_lock);
+ pib_old = rcu_replace_pointer(phy->pib, pib,
+ lockdep_is_held(&phy->pib_lock));
+ spin_unlock_bh(&phy->pib_lock);
kfree_rcu(pib_old, rcu);
return 0;
}
@@ -952,6 +955,7 @@ static int hwsim_add_one(struct genl_inf
goto err_pib;
}
+ spin_lock_init(&phy->pib_lock);
pib->channel = 13;
pib->filt.short_addr = cpu_to_le16(IEEE802154_ADDR_BROADCAST);
pib->filt.pan_id = cpu_to_le16(IEEE802154_PANID_BROADCAST);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 567/733] ipv4: fib: bound automatic table ID allocation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (565 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 566/733] ieee802154: hwsim: serialize pib updates to fix double-free Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 568/733] ipv6: flowlabel: cap duplicate leases per socket Greg Kroah-Hartman
` (177 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Ido Schimmel, Zihan Xi,
Petr Vorel, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zihan Xi <zihanx@nebusec.ai>
commit efdfb1e27a3328085b79540dfe781d537b576ea1 upstream.
fib_empty_table() probes every table ID from 1 until it finds a
free one. IPv4 tables are stored in a 256-bucket hash table, so a
dense set of IDs makes each probe walk a growing hash chain while
RTNL is held.
Automatic table assignment ("ip rule ... table 0") is an IPv4-only
legacy path. Bound the automatically allocated ID to 4096 so the
RTNL hold stays bounded, without changing lookups of explicitly
specified table IDs.
This changes user-visible behavior. A table-0 rule previously
received the lowest free ID in 1..RT_TABLE_MAX (0xFFFFFFFF). After
this patch the search stops at 4096 and the rule add fails with
ENOBUFS if that range is fully occupied. Explicit table IDs above
4096 remain usable.
The automatic path is unused in practice: it is IPv4-only, not
documented by ip-rule, uncovered by kernel selftests, and both
NetworkManager and systemd refuse table 0.
Fixes: b801f54917b7 ("[NET]: Increate RT_TABLE_MAX to 2^32")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Zihan Xi <zihanx@nebusec.ai>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Reviewed-by: Petr Vorel <pvorel@suse.cz>
Link: https://patch.msgid.link/6f2f2a7a136aee005512a2e1ac8ede62ac8c7bb6.1788258884.git.zihanx@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv4/fib_rules.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/net/ipv4/fib_rules.c
+++ b/net/ipv4/fib_rules.c
@@ -214,6 +214,8 @@ INDIRECT_CALLABLE_SCOPE int fib4_rule_ma
return 1;
}
+#define FIB_MAX_AUTO_TABLE_ID 4096
+
static struct fib_table *fib_empty_table(struct net *net)
{
u32 id = 1;
@@ -222,7 +224,7 @@ static struct fib_table *fib_empty_table
if (!fib_get_table(net, id))
return fib_new_table(net, id);
- if (id++ == RT_TABLE_MAX)
+ if (id++ == FIB_MAX_AUTO_TABLE_ID)
break;
}
return NULL;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 568/733] ipv6: flowlabel: cap duplicate leases per socket
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (566 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 567/733] ipv4: fib: bound automatic table ID allocation Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 569/733] ipvs: reject invalid states in connection template sync records Greg Kroah-Hartman
` (176 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Vega, Ido Schimmel, Zhiling Zou,
Eric Dumazet, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhiling Zou <zhilinz@nebusec.ai>
commit 8d6cd188508513503805c156165de38e4e4a8615 upstream.
ipv6_flowlabel_get() allocates an ipv6_fl_socklist entry for every
successful GET. The recheck path for a compatible existing flowlabel
links another lease without applying any lease admission check. Repeated
GET requests for one shareable label can therefore grow a socket's lease
list without bound.
Reject a new unprivileged lease once the socket already holds
FL_MAX_PER_SOCK leases. Check this on the shared recheck path so reuse
of a globally interned label, including the fl_intern() collision path,
is covered as well. New-label admission remains under the existing
mem_check() policy.
Use capable(CAP_NET_ADMIN) rather than ns_capable(), matching
mem_check(). An unprivileged user must not bypass the cap by creating a
user namespace and a netns where they have CAP_NET_ADMIN, which would
still consume host memory.
Check the capability only when the socket reaches the limit, so
successful unprivileged GET requests below the cap do not generate a
capability audit. Do the admission check before updating linger and
expires so a rejected GET does not refresh the shared label, matching
the existing socket-list allocation failure path.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org
Reported-by: Vega <vega@nebusec.ai>
Suggested-by: Ido Schimmel <idosch@nvidia.com>
Signed-off-by: Zhiling Zou <zhilinz@nebusec.ai>
Reviewed-by: Eric Dumazet <edumazet@google.com>
Reviewed-by: Ido Schimmel <idosch@nvidia.com>
Link: https://patch.msgid.link/83f8535972ff6e3741548476a1d50dec24c758be.1788415194.git.zhilinz@nebusec.ai
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/ipv6/ip6_flowlabel.c | 19 +++++++++++++++++++
1 file changed, 19 insertions(+)
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -461,6 +461,21 @@ done:
return NULL;
}
+static bool fl_sock_at_lease_limit(const struct sock *sk)
+{
+ const struct ipv6_fl_socklist *sfl;
+ int count = 0;
+
+ rcu_read_lock();
+ for_each_sk_fl_rcu(sk, sfl) {
+ if (++count >= FL_MAX_PER_SOCK)
+ break;
+ }
+ rcu_read_unlock();
+
+ return count >= FL_MAX_PER_SOCK;
+}
+
static int mem_check(struct sock *sk)
{
const int unpriv_total_limit = FL_MAX_SIZE - (FL_MAX_SIZE / 4);
@@ -679,6 +694,10 @@ recheck:
err = -ENOMEM;
if (!sfl1)
goto release;
+ err = -ENOBUFS;
+ if (fl_sock_at_lease_limit(sk) &&
+ !capable(CAP_NET_ADMIN))
+ goto release;
if (fl->linger > fl1->linger)
fl1->linger = fl->linger;
if ((long)(fl->expires - fl1->expires) > 0)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 569/733] ipvs: reject invalid states in connection template sync records
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (567 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 568/733] ipv6: flowlabel: cap duplicate leases per socket Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 570/733] mac802154: fix use-after-free of sdata via queued RX frames Greg Kroah-Hartman
` (175 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Kyle Zeng, Julian Anastasov,
Pablo Neira Ayuso
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kyle Zeng <kylebot@openai.com>
commit 74cb39735b6cd0aff4b5584158f09376fd97aadf upstream.
IPVS sync receivers validate protocol states before creating or updating a
connection. For connection templates, however, they only log states outside
the template state range and still store the value in the connection.
A template can be returned by ordinary connection lookup. TCP and SCTP then
use the invalid state as an index into their transition tables.
Reject invalid template states in both sync protocol versions before
looking up or modifying a connection. The version 1 path handles both
IPv4 and IPv6 records.
Fixes: 275411430f89 ("ipvs: add assured state for conn templates")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Kyle Zeng <kylebot@openai.com>
Acked-by: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Pablo Neira Ayuso <pablo@netfilter.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/netfilter/ipvs/ip_vs_sync.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
--- a/net/netfilter/ipvs/ip_vs_sync.c
+++ b/net/netfilter/ipvs/ip_vs_sync.c
@@ -999,10 +999,10 @@ static void ip_vs_process_message_v0(str
pp->name, state);
continue;
}
- } else {
- if (state >= IP_VS_CTPL_S_LAST)
- IP_VS_DBG(7, "BACKUP v0, Invalid tpl state %u\n",
- state);
+ } else if (state >= IP_VS_CTPL_S_LAST) {
+ IP_VS_DBG(7, "BACKUP v0, Invalid tpl state %u\n",
+ state);
+ continue;
}
ip_vs_conn_fill_param(ipvs, AF_INET, s->protocol,
@@ -1159,10 +1159,10 @@ static inline int ip_vs_proc_sync_conn(s
retc = 40;
goto out;
}
- } else {
- if (state >= IP_VS_CTPL_S_LAST)
- IP_VS_DBG(7, "BACKUP, Invalid tpl state %u\n",
- state);
+ } else if (state >= IP_VS_CTPL_S_LAST) {
+ IP_VS_DBG(7, "BACKUP, Invalid tpl state %u\n", state);
+ retc = 40;
+ goto out;
}
if (ip_vs_conn_fill_param_sync(ipvs, af, s, ¶m, pe_data,
pe_data_len, pe_name, pe_name_len)) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 570/733] mac802154: fix use-after-free of sdata via queued RX frames
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (568 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 569/733] ipvs: reject invalid states in connection template sync records Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 571/733] KVM: PPC: Book3S HV: Set irqfd->producer only on success Greg Kroah-Hartman
` (174 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ibrahim Hashimov, Miquel Raynal,
Stefan Schmidt
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ibrahim Hashimov <security@auditcode.ai>
commit 2f37fba846c9fdff5fc15b6d93656057ccd13031 upstream.
The RX softirq producer ieee802154_subif_frame() queues received beacon
and MAC-command frames onto local->rx_beacon_list / rx_mac_cmd_list and
schedules a process-context worker, storing a raw mac_pkt->sdata (and
skb->dev == sdata->dev) with neither a reference nor any locking:
- the lists have no lock: the softirq producer list_add_tail()s while the
mac_wq worker list_del()s, so sibling interfaces on the same phy corrupt
the list;
- the workers dereference the interface after it may have been freed.
mac802154_rx_mac_cmd_worker() touches mac_pkt->sdata directly, and
mac802154_rx_beacon_worker() -> mac802154_process_beacon() dereferences
skb->dev (== sdata->dev). Removing an interface frees its sdata
(netdev_priv) while a queued frame still points at it, so a later worker
run is a use-after-free.
Reproduced under KASAN by flooding a victim interface with MAC command
frames and removing it (the beacon path is the same class via skb->dev):
BUG: KASAN: slab-use-after-free in mac802154_rx_mac_cmd_worker+0x463/0x630 [mac802154]
Read of size 4 at addr ffff888002f9ea18 by task kworker/u8:1/31
Workqueue: phy0-mac-cmds mac802154_rx_mac_cmd_worker [mac802154]
Call Trace:
mac802154_rx_mac_cmd_worker+0x463/0x630 [mac802154]
process_one_work+0x611/0xe80
worker_thread+0x52e/0xdc0
kthread+0x30c/0x630
ret_from_fork+0x2fd/0x3e0
Fix both lists together:
- add local->rx_lock and take it around every list access: the softirq
producer (plain spin_lock, softirq context) and the workers and flush
(spin_lock_bh, process context);
- pin the interface for the lifetime of a queued frame with
netdev_hold()/netdev_put(), so the worker can safely dereference sdata /
skb->dev even while the interface is being removed;
- dequeue under the lock at the head and loop-drain the whole list in the
workers (they previously processed one frame per run and relied on a
later enqueue to drain the rest);
- drop not-yet-started frames of an interface before it is unregistered,
from ieee802154_if_remove() (after the RCU grace period) and from the
ieee802154_remove_interfaces() loop -- the latter is the whole-phy
teardown path, which does not go through ieee802154_if_remove().
An in-flight worker that already dequeued a frame keeps its own netdev
reference; unregister_netdevice() then waits it out in netdev_run_todo(),
which runs at rtnl_unlock() (rtnl released) and after the interface has
been closed, so it does not pin rtnl. A worker blocked in an association
TX only delays that one interface's unregister (the usual "waiting for %s
to become free"), it does not hold rtnl. netdev_hold() is used for this
reason instead of a cancel_work_sync() under rtnl, which would block on
the worker's unbounded MLME TX wait via ieee802154_sync_queue().
The mac-command worker additionally skips processing for a stopped
interface (ieee802154_sdata_running()), avoiding a needless association
response during teardown.
Fixes: 57588c71177f ("mac802154: Handle passive scanning")
Cc: stable@vger.kernel.org
Signed-off-by: Ibrahim Hashimov <security@auditcode.ai>
Assisted-by: AuditCode-AI:2026.07
Reviewed-by: Miquel Raynal <miquel.raynal@bootlin.com>
Link: https://lore.kernel.org/20260725135154.99876-1-security@auditcode.ai
Signed-off-by: Stefan Schmidt <stefan@datenfreihafen.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/net/cfg802154.h | 1
net/mac802154/ieee802154_i.h | 8 ++
net/mac802154/iface.c | 6 ++
net/mac802154/main.c | 1
net/mac802154/rx.c | 120 +++++++++++++++++++++++++++++++++++--------
net/mac802154/scan.c | 10 +--
6 files changed, 117 insertions(+), 29 deletions(-)
--- a/include/net/cfg802154.h
+++ b/include/net/cfg802154.h
@@ -376,6 +376,7 @@ struct cfg802154_mac_pkt {
struct list_head node;
struct sk_buff *skb;
struct ieee802154_sub_if_data *sdata;
+ netdevice_tracker dev_tracker;
u8 page;
u8 channel;
};
--- a/net/mac802154/ieee802154_i.h
+++ b/net/mac802154/ieee802154_i.h
@@ -74,6 +74,10 @@ struct ieee802154_local {
struct work_struct rx_beacon_work;
struct list_head rx_mac_cmd_list;
struct work_struct rx_mac_cmd_work;
+ /* Serializes rx_beacon_list and rx_mac_cmd_list against the RX
+ * softirq producer, the mac_wq workers and the teardown flush.
+ */
+ spinlock_t rx_lock;
/* Association */
struct ieee802154_pan_device *assoc_dev;
@@ -300,6 +304,10 @@ static inline bool mac802154_is_beaconin
}
void mac802154_rx_mac_cmd_worker(struct work_struct *work);
+void mac802154_flush_list(struct list_head *list,
+ struct ieee802154_sub_if_data *sdata);
+void mac802154_flush_queued_pkts(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata);
int mac802154_perform_association(struct ieee802154_sub_if_data *sdata,
struct ieee802154_pan_device *coord,
--- a/net/mac802154/iface.c
+++ b/net/mac802154/iface.c
@@ -694,6 +694,7 @@ void ieee802154_if_remove(struct ieee802
mutex_unlock(&sdata->local->iflist_mtx);
synchronize_rcu();
+ mac802154_flush_queued_pkts(sdata->local, sdata);
unregister_netdevice(sdata->dev);
}
@@ -705,6 +706,11 @@ void ieee802154_remove_interfaces(struct
list_for_each_entry_safe(sdata, tmp, &local->interfaces, list) {
list_del_rcu(&sdata->list);
+ /* Best-effort: a frame the RX softirq queues for this sdata
+ * after the flush still pins the netdev, so the
+ * unregister_netdevice() below waits it out.
+ */
+ mac802154_flush_queued_pkts(local, sdata);
unregister_netdevice(sdata->dev);
}
mutex_unlock(&local->iflist_mtx);
--- a/net/mac802154/main.c
+++ b/net/mac802154/main.c
@@ -91,6 +91,7 @@ ieee802154_alloc_hw(size_t priv_data_len
INIT_LIST_HEAD(&local->interfaces);
INIT_LIST_HEAD(&local->rx_beacon_list);
INIT_LIST_HEAD(&local->rx_mac_cmd_list);
+ spin_lock_init(&local->rx_lock);
mutex_init(&local->iflist_mtx);
tasklet_setup(&local->tasklet, ieee802154_tasklet_handler);
--- a/net/mac802154/rx.c
+++ b/net/mac802154/rx.c
@@ -35,16 +35,23 @@ void mac802154_rx_beacon_worker(struct w
container_of(work, struct ieee802154_local, rx_beacon_work);
struct cfg802154_mac_pkt *mac_pkt;
- mac_pkt = list_first_entry_or_null(&local->rx_beacon_list,
- struct cfg802154_mac_pkt, node);
- if (!mac_pkt)
- return;
+ for (;;) {
+ spin_lock_bh(&local->rx_lock);
+ mac_pkt = list_first_entry_or_null(&local->rx_beacon_list,
+ struct cfg802154_mac_pkt, node);
+ if (mac_pkt)
+ list_del(&mac_pkt->node);
+ spin_unlock_bh(&local->rx_lock);
+ if (!mac_pkt)
+ break;
- mac802154_process_beacon(local, mac_pkt->skb, mac_pkt->page, mac_pkt->channel);
+ mac802154_process_beacon(local, mac_pkt->skb,
+ mac_pkt->page, mac_pkt->channel);
- list_del(&mac_pkt->node);
- kfree_skb(mac_pkt->skb);
- kfree(mac_pkt);
+ netdev_put(mac_pkt->sdata->dev, &mac_pkt->dev_tracker);
+ kfree_skb(mac_pkt->skb);
+ kfree(mac_pkt);
+ }
}
static bool mac802154_should_answer_beacon_req(struct ieee802154_local *local)
@@ -68,22 +75,15 @@ static bool mac802154_should_answer_beac
return interval == IEEE802154_ACTIVE_SCAN_DURATION;
}
-void mac802154_rx_mac_cmd_worker(struct work_struct *work)
+static void mac802154_rx_mac_cmd(struct ieee802154_local *local,
+ struct cfg802154_mac_pkt *mac_pkt)
{
- struct ieee802154_local *local =
- container_of(work, struct ieee802154_local, rx_mac_cmd_work);
- struct cfg802154_mac_pkt *mac_pkt;
u8 mac_cmd;
int rc;
- mac_pkt = list_first_entry_or_null(&local->rx_mac_cmd_list,
- struct cfg802154_mac_pkt, node);
- if (!mac_pkt)
- return;
-
rc = ieee802154_get_mac_cmd(mac_pkt->skb, &mac_cmd);
if (rc)
- goto out;
+ return;
switch (mac_cmd) {
case IEEE802154_CMD_BEACON_REQ:
@@ -121,11 +121,81 @@ void mac802154_rx_mac_cmd_worker(struct
default:
break;
}
+}
+
+void mac802154_rx_mac_cmd_worker(struct work_struct *work)
+{
+ struct ieee802154_local *local =
+ container_of(work, struct ieee802154_local, rx_mac_cmd_work);
+ struct cfg802154_mac_pkt *mac_pkt;
+
+ for (;;) {
+ spin_lock_bh(&local->rx_lock);
+ mac_pkt = list_first_entry_or_null(&local->rx_mac_cmd_list,
+ struct cfg802154_mac_pkt, node);
+ if (mac_pkt)
+ list_del(&mac_pkt->node);
+ spin_unlock_bh(&local->rx_lock);
+ if (!mac_pkt)
+ break;
+
+ /* A stopped interface cannot transmit; skipping avoids a
+ * needless association response (and the !netif_running()
+ * warning it would trip) during teardown. The beacon worker
+ * needs no such check as it never transmits.
+ */
+ if (ieee802154_sdata_running(mac_pkt->sdata))
+ mac802154_rx_mac_cmd(local, mac_pkt);
+
+ netdev_put(mac_pkt->sdata->dev, &mac_pkt->dev_tracker);
+ kfree_skb(mac_pkt->skb);
+ kfree(mac_pkt);
+ }
+}
+
+/**
+ * mac802154_flush_list - free queued RX frames on @list
+ * @list: rx_beacon_list or rx_mac_cmd_list
+ * @sdata: only free frames received on this interface, or %NULL for all
+ *
+ * Each frame pins the net_device it was received on (via netdev_hold()),
+ * so release that reference as the frame is dropped. Caller must hold
+ * local->rx_lock.
+ */
+void mac802154_flush_list(struct list_head *list,
+ struct ieee802154_sub_if_data *sdata)
+{
+ struct cfg802154_mac_pkt *mac_pkt, *tmp;
-out:
- list_del(&mac_pkt->node);
- kfree_skb(mac_pkt->skb);
- kfree(mac_pkt);
+ list_for_each_entry_safe(mac_pkt, tmp, list, node) {
+ if (sdata && mac_pkt->sdata != sdata)
+ continue;
+ list_del(&mac_pkt->node);
+ netdev_put(mac_pkt->sdata->dev, &mac_pkt->dev_tracker);
+ kfree_skb(mac_pkt->skb);
+ kfree(mac_pkt);
+ }
+}
+
+/**
+ * mac802154_flush_queued_pkts - drop queued RX work referencing @sdata
+ * @local: the mac802154 device
+ * @sdata: interface being removed
+ *
+ * The workers dereference the queued frame's interface directly
+ * (mac_pkt->sdata) or through skb->dev in mac802154_process_beacon(). Drop
+ * the not-yet-started entries belonging to @sdata before it is unregistered
+ * so their netdev reference is released; an entry already dequeued by a
+ * running worker keeps its own reference until the worker completes, which
+ * unregister_netdevice() then waits out.
+ */
+void mac802154_flush_queued_pkts(struct ieee802154_local *local,
+ struct ieee802154_sub_if_data *sdata)
+{
+ spin_lock_bh(&local->rx_lock);
+ mac802154_flush_list(&local->rx_beacon_list, sdata);
+ mac802154_flush_list(&local->rx_mac_cmd_list, sdata);
+ spin_unlock_bh(&local->rx_lock);
}
static int
@@ -221,7 +291,10 @@ ieee802154_subif_frame(struct ieee802154
mac_pkt->sdata = sdata;
mac_pkt->page = sdata->local->scan_page;
mac_pkt->channel = sdata->local->scan_channel;
+ netdev_hold(sdata->dev, &mac_pkt->dev_tracker, GFP_ATOMIC);
+ spin_lock(&sdata->local->rx_lock);
list_add_tail(&mac_pkt->node, &sdata->local->rx_beacon_list);
+ spin_unlock(&sdata->local->rx_lock);
queue_work(sdata->local->mac_wq, &sdata->local->rx_beacon_work);
return NET_RX_SUCCESS;
@@ -233,7 +306,10 @@ ieee802154_subif_frame(struct ieee802154
mac_pkt->skb = skb_get(skb);
mac_pkt->sdata = sdata;
+ netdev_hold(sdata->dev, &mac_pkt->dev_tracker, GFP_ATOMIC);
+ spin_lock(&sdata->local->rx_lock);
list_add_tail(&mac_pkt->node, &sdata->local->rx_mac_cmd_list);
+ spin_unlock(&sdata->local->rx_lock);
queue_work(sdata->local->mac_wq, &sdata->local->rx_mac_cmd_work);
return NET_RX_SUCCESS;
--- a/net/mac802154/scan.c
+++ b/net/mac802154/scan.c
@@ -104,13 +104,9 @@ static unsigned int mac802154_scan_get_c
static void mac802154_flush_queued_beacons(struct ieee802154_local *local)
{
- struct cfg802154_mac_pkt *mac_pkt, *tmp;
-
- list_for_each_entry_safe(mac_pkt, tmp, &local->rx_beacon_list, node) {
- list_del(&mac_pkt->node);
- kfree_skb(mac_pkt->skb);
- kfree(mac_pkt);
- }
+ spin_lock_bh(&local->rx_lock);
+ mac802154_flush_list(&local->rx_beacon_list, NULL);
+ spin_unlock_bh(&local->rx_lock);
}
static void
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 571/733] KVM: PPC: Book3S HV: Set irqfd->producer only on success
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (569 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 570/733] mac802154: fix use-after-free of sdata via queued RX frames Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 572/733] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
` (173 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sean Christopherson, leixiang,
Amit Machhiwal, Vaibhav Jain, Madhavan Srinivasan
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: leixiang <leixiang@kylinos.cn>
commit 1144454ea22290d7c6998a2af6239e5995476afc upstream.
Set irqfd->producer only after kvmppc_set_passthru_irq() succeeds to
avoid leaving a dangling pointer on failure. The bypass manager does
not register a failed producer, so the pointer is never cleared.
Fixes: c57875f5f9be ("KVM: PPC: Book3S HV: Enable IRQ bypass")
Suggested-by: Sean Christopherson <seanjc@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: leixiang <leixiang@kylinos.cn>
Reviewed-by: Amit Machhiwal <amachhiw@linux.ibm.com>
Reviewed-by: Vaibhav Jain <vaibhav@linux.ibm.com>
Signed-off-by: Madhavan Srinivasan <maddy@linux.ibm.com>
Link: https://patch.msgid.link/20260709055755.31297-1-leixiang@kylinos.cn
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/powerpc/kvm/book3s_hv.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/arch/powerpc/kvm/book3s_hv.c
+++ b/arch/powerpc/kvm/book3s_hv.c
@@ -6124,12 +6124,12 @@ static int kvmppc_irq_bypass_add_produce
struct kvm_kernel_irqfd *irqfd =
container_of(cons, struct kvm_kernel_irqfd, consumer);
- irqfd->producer = prod;
-
ret = kvmppc_set_passthru_irq(irqfd->kvm, prod->irq, irqfd->gsi);
if (ret)
pr_info("kvmppc_set_passthru_irq (irq %d, gsi %d) fails: %d\n",
prod->irq, irqfd->gsi, ret);
+ else
+ irqfd->producer = prod;
return ret;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 572/733] landlock: Fix use-after-free of the sources parent directory
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (570 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 571/733] KVM: PPC: Book3S HV: Set irqfd->producer only on success Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 573/733] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Greg Kroah-Hartman
` (172 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Norbert Szetei, Günther Noack,
Mickaël Salaün
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Norbert Szetei <norbert@doyensec.com>
commit 2c6dc792538260a8087ac5b22c31b3b8e47c85d6 upstream.
current_check_refer_path() reads old_dentry->d_parent without holding a
reference nor a lock on it, and then dereferences it in
collect_domain_accesses() and in the audit record.
A reference on a child does not pin its parent: __d_move() reassigns
dentry->d_parent and drops the reference the child held on its former
parent. hook_path_rename() is not affected because the rename path
calls lock_rename() before the hook, so the source cannot be reparented
under it. hook_path_link() has no such protection: filename_linkat()
holds a reference on the source dentry but neither locks nor references
its parent, so a concurrent rename(2) can reparent the source while
security_path_link() runs, and the former parent can then be removed and
freed while the hook walks it.
A process can trigger this after entering a Landlock domain that handles
at least one filesystem access right. The process can then race a
linkat(2) loop against rename(2) and rmdir(2):
BUG: KASAN: slab-use-after-free in collect_domain_accesses+0x278/0x290
Read of size 4 at addr ffff888160bd53f4 by task llrepro2/549
collect_domain_accesses+0x278/0x290
current_check_refer_path+0x952/0x1120
security_path_link+0x1be/0x320
filename_linkat+0x342/0x6d0
__x64_sys_linkat+0xfa/0x150
Freed by task 562:
kmem_cache_free+0x139/0x4c0
i_callback+0x4b/0x80
rcu_core+0x7dc/0x10a0
Take a reference on the dentry selected as the source parent, using
dget() for the common-mount-root case and dget_parent() otherwise.
Release it after the hierarchy walk and synchronous audit logging.
Cc: stable@vger.kernel.org
Fixes: b91c3e4ea756 ("landlock: Add support for file reparenting with LANDLOCK_ACCESS_FS_REFER")
Signed-off-by: Norbert Szetei <norbert@doyensec.com>
Reviewed-by: Günther Noack <gnoack3000@gmail.com>
Tested-by: Günther Noack <gnoack3000@gmail.com>
Link: https://patch.msgid.link/E9CDD9E6-E960-4DE2-B1AC-5667D52ABB3E@doyensec.com
[mic: Clarify the caller, reachability, and reference handling]
Signed-off-by: Mickaël Salaün <mic@digikod.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
security/landlock/fs.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
--- a/security/landlock/fs.c
+++ b/security/landlock/fs.c
@@ -1222,11 +1222,12 @@ static int current_check_refer_path(stru
/*
* old_dentry may be the root of the common mount point and
* !IS_ROOT(old_dentry) at the same time (e.g. with open_tree() and
- * OPEN_TREE_CLONE). We do not need to call dget(old_parent) because
- * we keep a reference to old_dentry.
+ * OPEN_TREE_CLONE). Pin the dentry used as old_parent in either case.
+ * Otherwise, dget_parent() safely fetches and pins the current parent
+ * against a concurrent rename(2).
*/
- old_parent = (old_dentry == mnt_dir.dentry) ? old_dentry :
- old_dentry->d_parent;
+ old_parent = (old_dentry == mnt_dir.dentry) ? dget(old_dentry) :
+ dget_parent(old_dentry);
/* new_dir->dentry is equal to new_dentry->d_parent */
allow_parent1 = collect_domain_accesses(subject->domain, mnt_dir.dentry,
@@ -1235,8 +1236,10 @@ static int current_check_refer_path(stru
allow_parent2 = collect_domain_accesses(subject->domain, mnt_dir.dentry,
new_dir->dentry,
&layer_masks_parent2);
- if (allow_parent1 && allow_parent2)
+ if (allow_parent1 && allow_parent2) {
+ dput(old_parent);
return 0;
+ }
/*
* To be able to compare source and destination domain access rights,
@@ -1248,8 +1251,10 @@ static int current_check_refer_path(stru
subject->domain, &mnt_dir, access_request_parent1,
&layer_masks_parent1, &request1, old_dentry,
access_request_parent2, &layer_masks_parent2, &request2,
- exchange ? new_dentry : NULL))
+ exchange ? new_dentry : NULL)) {
+ dput(old_parent);
return 0;
+ }
if (request1.access) {
request1.audit.u.path.dentry = old_parent;
@@ -1259,6 +1264,7 @@ static int current_check_refer_path(stru
request2.audit.u.path.dentry = new_dir->dentry;
landlock_log_denial(subject, &request2);
}
+ dput(old_parent);
/*
* This prioritizes EACCES over EXDEV for all actions, including
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 573/733] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (571 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 572/733] landlock: Fix use-after-free of the sources parent directory Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 574/733] s390/qeth: allow bridgeport queries despite OS_MISMATCH Greg Kroah-Hartman
` (171 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Niklas Schnelle, Benjamin Block,
Matthew Rosato, Farhan Ali, Joerg Roedel
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Schnelle <schnelle@linux.ibm.com>
commit 20db6573301e66cd65ebf6c130b6563c69374d9d upstream.
When using a 5-level translation table via ZPCI_TABLE_TYPE_RFX
get_rso_from_iova() returns NULL when the region-first entry is invalid.
Yet in get_rto_from_iova() the region-second origin rso is not checked
to be non-NULL before accessing rso[rsx] leading to a NULL pointer
dereference instead of a NULL return when iova_to_phys() is called on
a unmapped IOVA. Fix this by adding the missing NULL check.
Cc: stable@vger.kernel.org
Fixes: 81244074b518 ("iommu/s390: allow larger region tables")
Signed-off-by: Niklas Schnelle <schnelle@linux.ibm.com>
Reviewed-by: Benjamin Block <bblock@linux.ibm.com>
Reviewed-by: Matthew Rosato <mjrosato@linux.ibm.com>
Reviewed-by: Farhan Ali <alifm@linux.ibm.com>
Signed-off-by: Joerg Roedel <joerg.roedel@amd.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/iommu/s390-iommu.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/iommu/s390-iommu.c
+++ b/drivers/iommu/s390-iommu.c
@@ -974,6 +974,8 @@ static unsigned long *get_rto_from_iova(
case ZPCI_TABLE_TYPE_RFX:
case ZPCI_TABLE_TYPE_RSX:
rso = get_rso_from_iova(domain, iova);
+ if (!rso)
+ return NULL;
rsx = calc_rsx(iova);
rse = READ_ONCE(rso[rsx]);
if (!reg_entry_isvalid(rse))
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 574/733] s390/qeth: allow bridgeport queries despite OS_MISMATCH
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (572 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 573/733] iommu/s390: Fix NULL dereference in iova_to_phys() with ZPCI_TABLE_TYPE_RFX Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 575/733] s390/crypto: Fix skcipher_walk return code handling in aes_s390 Greg Kroah-Hartman
` (170 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Halil Pasic, Alexandra Winter,
Nagamani PV, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nagamani PV <nagamani@linux.ibm.com>
commit 74f27fc8642b7e8d139796f8c18ee46df393c2b2 upstream.
When HiperSockets interfaces on the same VCHID span different OS
families, reads of the sysfs attributes bridge_role and bridge_state
fail with -EPERM if bridge port ownership belongs to another OS family.
As a result, userspace tools such as 'lszdev -ii' cannot retrieve
bridge_role and bridge_state, even though firmware returns valid bridge
port data for QUERY_BRIDGE_PORTS requests.
The firmware reports IPA_RC_SBP_IQD_OS_MISMATCH (0x0010) to indicate
that bridge port ownership belongs to a different OS family. For
QUERY_BRIDGE_PORTS operations, firmware still returns valid bridge port
data (role=none, state=inactive) together with a primary return code of
0x0000 (success).
Allow QUERY_BRIDGE_PORTS requests to return the bridge port data
provided by the firmware despite OS_MISMATCH. To make the OS family
mismatch visible to userspace, represent the firmware-reported role
"none" as "none (OS family mismatch)" while preserving the reported
bridge_state.
The behavior for non-QUERY bridge port commands is unchanged; SET
operations continue to return -EPERM when another OS family owns the
bridge port.
This restores readability of bridge_role and bridge_state.
Fixes: 1b05cf6285c1 ("qeth: Include error message for "OS Mismatch"")
Cc: stable@vger.kernel.org
Suggested-by: Halil Pasic <pasic@linux.ibm.com>
Reviewed-by: Alexandra Winter <wintera@linux.ibm.com>
Signed-off-by: Nagamani PV <nagamani@linux.ibm.com>
Link: https://patch.msgid.link/20260901155344.3561483-1-nagamani@linux.ibm.com
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/s390/net/qeth_l2.h | 3 ++-
drivers/s390/net/qeth_l2_main.c | 26 ++++++++++++++++++++++----
drivers/s390/net/qeth_l2_sys.c | 7 ++++++-
3 files changed, 30 insertions(+), 6 deletions(-)
--- a/drivers/s390/net/qeth_l2.h
+++ b/drivers/s390/net/qeth_l2.h
@@ -13,7 +13,8 @@ extern const struct attribute_group *qet
int qeth_bridgeport_query_ports(struct qeth_card *card,
enum qeth_sbp_roles *role,
- enum qeth_sbp_states *state);
+ enum qeth_sbp_states *state,
+ bool *os_mismatch);
int qeth_bridgeport_setrole(struct qeth_card *card, enum qeth_sbp_roles role);
int qeth_bridgeport_an_set(struct qeth_card *card, int enable);
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -1158,7 +1158,7 @@ static void qeth_l2_setup_bridgeport_att
qeth_bridgeport_setrole(card, card->options.sbp.role);
/* Let the callback function refresh the stored role value. */
qeth_bridgeport_query_ports(card, &card->options.sbp.role,
- NULL);
+ NULL, NULL);
}
if (card->options.sbp.hostnotification) {
if (qeth_bridgeport_an_set(card, 1))
@@ -1545,6 +1545,7 @@ struct _qeth_sbp_cbctl {
struct {
enum qeth_sbp_roles *role;
enum qeth_sbp_states *state;
+ bool *os_mismatch;
} qports;
} data;
};
@@ -1721,10 +1722,19 @@ static int qeth_bridgeport_query_ports_c
struct qeth_ipa_cmd *cmd = (struct qeth_ipa_cmd *) data;
struct _qeth_sbp_cbctl *cbctl = (struct _qeth_sbp_cbctl *)reply->param;
struct qeth_sbp_port_data *qports;
+ u16 sbp_rc;
int rc;
QETH_CARD_TEXT(card, 2, "brqprtcb");
- rc = qeth_bridgeport_makerc(card, cmd);
+ sbp_rc = cmd->data.sbp.hdr.return_code;
+
+ /* on OS family mismatch, query still returns valid port data;
+ * treat as success
+ */
+ if (sbp_rc == IPA_RC_SBP_IQD_OS_MISMATCH && !cmd->hdr.return_code)
+ rc = 0;
+ else
+ rc = qeth_bridgeport_makerc(card, cmd);
if (rc)
return rc;
@@ -1740,6 +1750,9 @@ static int qeth_bridgeport_query_ports_c
if (cbctl->data.qports.state)
*cbctl->data.qports.state = qports->entry[0].state;
}
+ if (cbctl->data.qports.os_mismatch)
+ *cbctl->data.qports.os_mismatch =
+ (sbp_rc == IPA_RC_SBP_IQD_OS_MISMATCH);
return 0;
}
@@ -1748,13 +1761,17 @@ static int qeth_bridgeport_query_ports_c
* @card: qeth_card structure pointer.
* @role: Role of the port: 0-none, 1-primary, 2-secondary.
* @state: State of the port: 0-inactive, 1-standby, 2-active.
+ * @os_mismatch: if non-NULL, set to true when firmware reports
+ * OS family mismatch.
*
* Returns negative errno-compatible error indication or 0 on success.
*
- * 'role' and 'state' are not updated in case of hardware operation failure.
+ * 'role', 'state' and 'os_mismatch' are not updated in case of
+ * hardware operation failure.
*/
int qeth_bridgeport_query_ports(struct qeth_card *card,
- enum qeth_sbp_roles *role, enum qeth_sbp_states *state)
+ enum qeth_sbp_roles *role, enum qeth_sbp_states *state,
+ bool *os_mismatch)
{
struct qeth_cmd_buffer *iob;
struct _qeth_sbp_cbctl cbctl = {
@@ -1762,6 +1779,7 @@ int qeth_bridgeport_query_ports(struct q
.qports = {
.role = role,
.state = state,
+ .os_mismatch = os_mismatch,
},
},
};
--- a/drivers/s390/net/qeth_l2_sys.c
+++ b/drivers/s390/net/qeth_l2_sys.c
@@ -15,6 +15,7 @@ static ssize_t qeth_bridge_port_role_sta
{
struct qeth_card *card = dev_get_drvdata(dev);
enum qeth_sbp_states state = QETH_SBP_STATE_INACTIVE;
+ bool os_mismatch = false;
int rc = 0;
char *word;
@@ -25,7 +26,7 @@ static ssize_t qeth_bridge_port_role_sta
if (qeth_card_hw_is_reachable(card) &&
card->options.sbp.supported_funcs)
rc = qeth_bridgeport_query_ports(card,
- &card->options.sbp.role, &state);
+ &card->options.sbp.role, &state, &os_mismatch);
if (!rc) {
if (show_state)
switch (state) {
@@ -52,6 +53,10 @@ static ssize_t qeth_bridge_port_role_sta
if (rc)
QETH_CARD_TEXT_(card, 2, "SBP%02x:%02x",
card->options.sbp.role, state);
+ else if (!show_state &&
+ card->options.sbp.role == QETH_SBP_ROLE_NONE &&
+ os_mismatch)
+ rc = sysfs_emit(buf, "%s (OS family mismatch)\n", word);
else
rc = sysfs_emit(buf, "%s\n", word);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 575/733] s390/crypto: Fix skcipher_walk return code handling in aes_s390
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (573 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 574/733] s390/qeth: allow bridgeport queries despite OS_MISMATCH Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 576/733] s390/crypto: Fix use of mutex in atomic context Greg Kroah-Hartman
` (169 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit 15fa028589c3a2545f0bff355eff06d5844196bf upstream.
The return codes from skcipher_walk_virt() were not properly checked
before entering the processing loops in ecb_aes_crypt() and ctr_aes_crypt().
If skcipher_walk_virt() fails, the walk structure may be in an undefined
state, and attempting to process data could lead to incorrect behavior
or accessing uninitialized memory.
Add proper return code checking to ensure correct handling of the walk
initialization and walk advance and eventually return to the caller
with that return code.
Fixes: 7988fb2c03c8 ("crypto: s390/aes - convert to skcipher API")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 5.5+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/aes_s390.c | 12 ++++++------
1 file changed, 6 insertions(+), 6 deletions(-)
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -129,7 +129,7 @@ static int ecb_aes_crypt(struct skcipher
return fallback_skcipher_crypt(sctx, req, modifier);
ret = skcipher_walk_virt(&walk, req, false);
- while ((nbytes = walk.nbytes) != 0) {
+ while (!ret && ((nbytes = walk.nbytes) != 0)) {
/* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_km(sctx->fc | modifier, sctx->key,
@@ -233,7 +233,7 @@ static int cbc_aes_crypt(struct skcipher
return ret;
memcpy(param.iv, walk.iv, AES_BLOCK_SIZE);
memcpy(param.key, sctx->key, sctx->key_len);
- while ((nbytes = walk.nbytes) != 0) {
+ while (!ret && ((nbytes = walk.nbytes) != 0)) {
/* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_kmc(sctx->fc | modifier, ¶m,
@@ -359,7 +359,7 @@ static int xts_aes_crypt(struct skcipher
memcpy(xts_param.key + offset, xts_ctx->key, xts_ctx->key_len);
memcpy(xts_param.init, pcc_param.xts, 16);
- while ((nbytes = walk.nbytes) != 0) {
+ while (!ret && ((nbytes = walk.nbytes) != 0)) {
/* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_km(xts_ctx->fc | modifier, xts_param.key + offset,
@@ -487,7 +487,7 @@ static int fullxts_aes_crypt(struct skci
memcpy(fxts_param.tweak, req->iv, AES_BLOCK_SIZE);
fxts_param.nap[0] = 0x01; /* initial alpha power (1, little-endian) */
- while ((nbytes = walk.nbytes) != 0) {
+ while (!ret && ((nbytes = walk.nbytes) != 0)) {
/* only use complete blocks */
n = nbytes & ~(AES_BLOCK_SIZE - 1);
cpacf_km(xts_ctx->fc | modifier, fxts_param.key + offset,
@@ -577,7 +577,7 @@ static int ctr_aes_crypt(struct skcipher
locked = mutex_trylock(&ctrblk_lock);
ret = skcipher_walk_virt(&walk, req, false);
- while ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE) {
+ while (!ret && ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE)) {
n = AES_BLOCK_SIZE;
if (nbytes >= 2*AES_BLOCK_SIZE && locked)
@@ -596,7 +596,7 @@ static int ctr_aes_crypt(struct skcipher
/*
* final block may be < AES_BLOCK_SIZE, copy only nbytes
*/
- if (nbytes) {
+ if (!ret && nbytes) {
memset(buf, 0, AES_BLOCK_SIZE);
memcpy(buf, walk.src.virt.addr, nbytes);
cpacf_kmctr(sctx->fc, sctx->key, buf, buf,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 576/733] s390/crypto: Fix use of mutex in atomic context
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (574 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 575/733] s390/crypto: Fix skcipher_walk return code handling in aes_s390 Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 577/733] s390/crypto: Fix missing scrub of temp buffers with AES ctr and gcm algorithm Greg Kroah-Hartman
` (168 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Heiko Carstens, Harald Freudenberger,
Holger Dengler, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit d1c44a7d085473173bb360b7218a43699c3f56c7 upstream.
The AES CTR implementation used a mutex to lock one page of exclusive
memory for fast CTR processing. Unfortunately a mutex is not save to
use in atomic or interrupt context. So use a binary semaphore instead
which is save to use in such environments.
Furthermore rework the code to get rid of conditional locking. So
restructure the AES CRT code by extracting the main loop into a
separate function and just give in information about the (locked) page
can be used or not (is not locked).
Fixes: 7988fb2c03c8 ("crypto: s390/aes - convert to skcipher API")
Suggested-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 5.5+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/aes_s390.c | 63 +++++++++++++++++++++++++++-----------------
1 file changed, 39 insertions(+), 24 deletions(-)
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -26,14 +26,14 @@
#include <linux/module.h>
#include <linux/cpufeature.h>
#include <linux/init.h>
-#include <linux/mutex.h>
#include <linux/fips.h>
+#include <linux/semaphore.h>
#include <linux/string.h>
#include <crypto/xts.h>
#include <asm/cpacf.h>
static u8 *ctrblk;
-static DEFINE_MUTEX(ctrblk_lock);
+static DEFINE_SEMAPHORE(ctrblk_sem, 1);
static cpacf_mask_t km_functions, kmc_functions, kmctr_functions,
kma_functions;
@@ -562,46 +562,61 @@ static unsigned int __ctrblk_init(u8 *ct
return n;
}
+static int __ctr_aes_crypt(struct s390_aes_ctx *sctx,
+ struct skcipher_walk *walk, bool locked)
+{
+ unsigned int n, nbytes;
+ int ret = 0;
+ u8 *ctrptr;
+
+ while (!ret && ((nbytes = walk->nbytes) >= AES_BLOCK_SIZE)) {
+ n = AES_BLOCK_SIZE;
+ if (nbytes >= 2 * AES_BLOCK_SIZE && locked)
+ n = __ctrblk_init(ctrblk, walk->iv, nbytes);
+ ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk->iv;
+ cpacf_kmctr(sctx->fc, sctx->key, walk->dst.virt.addr,
+ walk->src.virt.addr, n, ctrptr);
+ if (ctrptr == ctrblk)
+ memcpy(walk->iv, ctrptr + n - AES_BLOCK_SIZE,
+ AES_BLOCK_SIZE);
+ crypto_inc(walk->iv, AES_BLOCK_SIZE);
+ ret = skcipher_walk_done(walk, nbytes - n);
+ }
+
+ return ret;
+}
+
static int ctr_aes_crypt(struct skcipher_request *req)
{
struct crypto_skcipher *tfm = crypto_skcipher_reqtfm(req);
struct s390_aes_ctx *sctx = crypto_skcipher_ctx(tfm);
- u8 buf[AES_BLOCK_SIZE], *ctrptr;
struct skcipher_walk walk;
- unsigned int n, nbytes;
- int ret, locked;
+ u8 buf[AES_BLOCK_SIZE];
+ int ret;
if (unlikely(!sctx->fc))
return fallback_skcipher_crypt(sctx, req, 0);
- locked = mutex_trylock(&ctrblk_lock);
-
ret = skcipher_walk_virt(&walk, req, false);
- while (!ret && ((nbytes = walk.nbytes) >= AES_BLOCK_SIZE)) {
- n = AES_BLOCK_SIZE;
+ if (ret)
+ return ret;
- if (nbytes >= 2*AES_BLOCK_SIZE && locked)
- n = __ctrblk_init(ctrblk, walk.iv, nbytes);
- ctrptr = (n > AES_BLOCK_SIZE) ? ctrblk : walk.iv;
- cpacf_kmctr(sctx->fc, sctx->key, walk.dst.virt.addr,
- walk.src.virt.addr, n, ctrptr);
- if (ctrptr == ctrblk)
- memcpy(walk.iv, ctrptr + n - AES_BLOCK_SIZE,
- AES_BLOCK_SIZE);
- crypto_inc(walk.iv, AES_BLOCK_SIZE);
- ret = skcipher_walk_done(&walk, nbytes - n);
+ if (down_trylock(&ctrblk_sem) == 0) {
+ ret = __ctr_aes_crypt(sctx, &walk, true);
+ up(&ctrblk_sem);
+ } else {
+ ret = __ctr_aes_crypt(sctx, &walk, false);
}
- if (locked)
- mutex_unlock(&ctrblk_lock);
+
/*
* final block may be < AES_BLOCK_SIZE, copy only nbytes
*/
- if (!ret && nbytes) {
+ if (!ret && walk.nbytes > 0) {
memset(buf, 0, AES_BLOCK_SIZE);
- memcpy(buf, walk.src.virt.addr, nbytes);
+ memcpy(buf, walk.src.virt.addr, walk.nbytes);
cpacf_kmctr(sctx->fc, sctx->key, buf, buf,
AES_BLOCK_SIZE, walk.iv);
- memcpy(walk.dst.virt.addr, buf, nbytes);
+ memcpy(walk.dst.virt.addr, buf, walk.nbytes);
crypto_inc(walk.iv, AES_BLOCK_SIZE);
ret = skcipher_walk_done(&walk, 0);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 577/733] s390/crypto: Fix missing scrub of temp buffers with AES ctr and gcm algorithm
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (575 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 576/733] s390/crypto: Fix use of mutex in atomic context Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 578/733] s390/crypto: Fix missing cra_flags in paes_s390 Greg Kroah-Hartman
` (167 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit 8b7c3b6914f19caf648d05726a86af6326d3c2c6 upstream.
In function ctr_aes_crypt() there is a buffer used to process
remaining bytes < AES_BLOCK_SIZE. This buffer was not scrubbed and
thus could lead to expose of unwanted data. When the buffer is used
explicitly scrub it at the end of the code block to avoid exposure of
maybe sensitive data.
In a similar way the function gcm_aes_crypt() hat an error path where
the CPACF param block was not scrubbed. Instead of return early now
these error paths go to end of function where explicit scrubbing is
done. Similar with the buffers which are part of the gcm_sg_walk
structs from the variables gw_in and gw_out.
Fixes: d07f951903fa ("crypto: s390/aes - Fix buffer overread in CTR mode")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.8+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/aes_s390.c | 16 ++++++++++++----
1 file changed, 12 insertions(+), 4 deletions(-)
--- a/arch/s390/crypto/aes_s390.c
+++ b/arch/s390/crypto/aes_s390.c
@@ -619,6 +619,7 @@ static int ctr_aes_crypt(struct skcipher
memcpy(walk.dst.virt.addr, buf, walk.nbytes);
crypto_inc(walk.iv, AES_BLOCK_SIZE);
ret = skcipher_walk_done(&walk, 0);
+ memzero_explicit(buf, sizeof(buf));
}
return ret;
@@ -910,10 +911,14 @@ static int gcm_aes_crypt(struct aead_req
gw_in.ptr, aad_bytes);
n = aad_bytes + pc_bytes;
- if (gcm_in_walk_done(&gw_in, n) != n)
- return -ENOMEM;
- if (gcm_out_walk_done(&gw_out, n) != n)
- return -ENOMEM;
+ if (gcm_in_walk_done(&gw_in, n) != n) {
+ ret = -ENOMEM;
+ goto out;
+ }
+ if (gcm_out_walk_done(&gw_out, n) != n) {
+ ret = -ENOMEM;
+ goto out;
+ }
aadlen -= aad_bytes;
pclen -= pc_bytes;
} while (aadlen + pclen > 0);
@@ -925,7 +930,10 @@ static int gcm_aes_crypt(struct aead_req
} else
scatterwalk_map_and_copy(param.t, req->dst, len, taglen, 1);
+out:
memzero_explicit(¶m, sizeof(param));
+ memzero_explicit(gw_in.buf, sizeof(gw_in.buf));
+ memzero_explicit(gw_out.buf, sizeof(gw_out.buf));
return ret;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 578/733] s390/crypto: Fix missing cra_flags in paes_s390
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (576 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 577/733] s390/crypto: Fix missing scrub of temp buffers with AES ctr and gcm algorithm Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 579/733] s390/crypto: Fix handling of EBUSY in PHMAC when req is pushed to crypto engine Greg Kroah-Hartman
` (166 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit 5b97b969030c099333d973be420edef0d6452e0f upstream.
The 4 algorithms implemented in paes_s390 never had any cra_flags
set. So add code which sets the cra_flag to CRYPTO_ALG_ASYNC and
CRYPTO_ALG_NO_FALLBACK.
Fixes: 4ccd065a69df ("crypto: ahash - Add support for drivers with no fallback")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.17+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/paes_s390.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -576,6 +576,7 @@ static struct skcipher_engine_alg ecb_pa
.base.cra_name = "ecb(paes)",
.base.cra_driver_name = "ecb-paes-s390",
.base.cra_priority = 401, /* combo: aes + ecb + 1 */
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
.base.cra_module = THIS_MODULE,
@@ -842,6 +843,7 @@ static struct skcipher_engine_alg cbc_pa
.base.cra_name = "cbc(paes)",
.base.cra_driver_name = "cbc-paes-s390",
.base.cra_priority = 402, /* cbc-paes-s390 + 1 */
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
.base.cra_module = THIS_MODULE,
@@ -1150,6 +1152,7 @@ static struct skcipher_engine_alg ctr_pa
.base.cra_name = "ctr(paes)",
.base.cra_driver_name = "ctr-paes-s390",
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = 1,
.base.cra_ctxsize = sizeof(struct s390_paes_ctx),
.base.cra_module = THIS_MODULE,
@@ -1593,6 +1596,7 @@ static struct skcipher_engine_alg xts_pa
.base.cra_name = "xts(paes)",
.base.cra_driver_name = "xts-paes-s390",
.base.cra_priority = 402, /* ecb-paes-s390 + 1 */
+ .base.cra_flags = CRYPTO_ALG_ASYNC | CRYPTO_ALG_NO_FALLBACK,
.base.cra_blocksize = AES_BLOCK_SIZE,
.base.cra_ctxsize = sizeof(struct s390_pxts_ctx),
.base.cra_module = THIS_MODULE,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 579/733] s390/crypto: Fix handling of EBUSY in PHMAC when req is pushed to crypto engine
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (577 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 578/733] s390/crypto: Fix missing cra_flags in paes_s390 Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 580/733] s390/crypto: Fix missing scrub of temp buffers with PAES algorithm Greg Kroah-Hartman
` (165 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit 330148371401de474b656eaf521861f12ec1a1ce upstream.
When a request is transferred to the engine via
crypto_transfer_hash_request_to_engine() there are two return codes
signaling a successful transfer: EINPROGRESS and EBUSY. However the
correct handling of EBUSY was missing and has been added as a return
code indicating a successful transfer to the crypto engine.
Fixes: cbbc675506cc ("crypto: s390 - New s390 specific protected key hash phmac")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.17+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/phmac_s390.c | 30 +++++++++++++++++++++---------
1 file changed, 21 insertions(+), 9 deletions(-)
--- a/arch/s390/crypto/phmac_s390.c
+++ b/arch/s390/crypto/phmac_s390.c
@@ -62,8 +62,10 @@ static inline int hwh_prepare(struct aha
*/
static inline int hwh_advance(struct hash_walk_helper *hwh, int n)
{
- if (n < 0)
+ if (n < 0) {
+ hwh->walkbytes = n;
return crypto_hash_walk_done(&hwh->walk, n);
+ }
hwh->walkbytes -= n;
hwh->walkaddr += n;
@@ -606,6 +608,7 @@ static int phmac_update(struct ahash_req
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
struct hash_walk_helper *hwh = &req_ctx->hwh;
+ bool cleanup = true;
int rc;
/* prep the walk in the request context */
@@ -629,12 +632,15 @@ static int phmac_update(struct ahash_req
req_ctx->async_op = OP_UPDATE;
atomic_inc(&tfm_ctx->via_engine_ctr);
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&tfm_ctx->via_engine_ctr);
}
- if (rc != -EINPROGRESS) {
- hwh_advance(hwh, rc);
+ if (cleanup) {
+ if (hwh->walkbytes > 0)
+ hwh_advance(hwh, rc);
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
}
@@ -649,6 +655,7 @@ static int phmac_final(struct ahash_requ
struct crypto_ahash *tfm = crypto_ahash_reqtfm(req);
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
+ bool cleanup = true;
int rc = 0;
/* Try synchronous operation if no active engine usage */
@@ -667,12 +674,14 @@ static int phmac_final(struct ahash_requ
req_ctx->async_op = OP_FINAL;
atomic_inc(&tfm_ctx->via_engine_ctr);
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&tfm_ctx->via_engine_ctr);
}
out:
- if (rc != -EINPROGRESS)
+ if (cleanup)
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
pr_debug("rc=%d\n", rc);
return rc;
@@ -685,6 +694,7 @@ static int phmac_finup(struct ahash_requ
struct phmac_tfm_ctx *tfm_ctx = crypto_ahash_ctx(tfm);
struct kmac_sha2_ctx *kmac_ctx = &req_ctx->kmac_ctx;
struct hash_walk_helper *hwh = &req_ctx->hwh;
+ bool cleanup = true;
int rc;
/* prep the walk in the request context */
@@ -716,15 +726,17 @@ static int phmac_finup(struct ahash_requ
/* req->async_op has been set to either OP_FINUP or OP_FINAL */
atomic_inc(&tfm_ctx->via_engine_ctr);
rc = crypto_transfer_hash_request_to_engine(phmac_crypto_engine, req);
- if (rc != -EINPROGRESS)
+ if (rc == -EINPROGRESS || rc == -EBUSY)
+ cleanup = false;
+ else
atomic_dec(&tfm_ctx->via_engine_ctr);
}
- if (rc != -EINPROGRESS)
+ if (cleanup && hwh->walkbytes > 0)
hwh_advance(hwh, rc);
out:
- if (rc != -EINPROGRESS)
+ if (cleanup)
memzero_explicit(kmac_ctx, sizeof(*kmac_ctx));
pr_debug("rc=%d\n", rc);
return rc;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 580/733] s390/crypto: Fix missing scrub of temp buffers with PAES algorithm
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (578 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 579/733] s390/crypto: Fix handling of EBUSY in PHMAC when req is pushed to crypto engine Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 581/733] s390/crypto: Fix wrong return code to engine in asynch callbacks Greg Kroah-Hartman
` (164 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit 19a218b46b2471d370c11fb52040f36ac8d05d23 upstream.
In function ctr_paes_do_crypt() there is a buffer used to process
remaining bytes < AES_BLOCK_SIZE. This buffer was not scrubbed and
thus could lead to expose of unwanted data. Rework the code to
explicitly scrub the buffer at the end of the function to avoid
exposure of maybe sensitive data.
In function __xts_2keys_prep_param() change the existing scrub to
clean the whole param block instead of just the key field.
Fixes: 6cd87cb5ef6c ("s390/crypto: Rework protected key AES for true asynch support")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.16+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/paes_s390.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -1036,6 +1036,7 @@ static int ctr_paes_do_crypt(struct s390
}
out:
+ memzero_explicit(buf, sizeof(buf));
pr_debug("rc=%d\n", rc);
return rc;
}
@@ -1367,7 +1368,7 @@ static inline int __xts_2keys_prep_param
memcpy(param->init, pcc_param.xts, 16);
}
- memzero_explicit(pcc_param.key, sizeof(pcc_param.key));
+ memzero_explicit(&pcc_param, sizeof(pcc_param));
return rc;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 581/733] s390/crypto: Fix wrong return code to engine in asynch callbacks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (579 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 580/733] s390/crypto: Fix missing scrub of temp buffers with PAES algorithm Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 582/733] s390/crypto: Map EBUSY to EIO when key conversion fails repeatedly Greg Kroah-Hartman
` (163 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit ac1481320110b803ab9b79ab4d2ca11a74fc05f2 upstream.
When crypto_finalize_hash_request() or
crypto_finalize_skcipher_request() explicitly completes a request, the
do_one_request callback must return 0 to indicate successful
handling. Returning a negative error code causes the crypto engine to
assume the driver failed to take ownership and triggers a second
completion via crypto_request_complete(), resulting in a double
completion. This pattern occurs in paes_s390.c 4 times and once in
phmac_s390.c.
Fixed in phmac_do_one_request() and all four paes do_one_request
callbacks (ecb, cbc, ctr, xts) by returning 0 after explicit
finalization instead of propagating the error code.
Fixes: 6cd87cb5ef6c ("s390/crypto: Rework protected key AES for true asynch support")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.16+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/paes_s390.c | 8 ++++----
arch/s390/crypto/phmac_s390.c | 2 +-
2 files changed, 5 insertions(+), 5 deletions(-)
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -568,7 +568,7 @@ static int ecb_paes_do_one_request(struc
atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable();
- return rc;
+ return 0;
}
static struct skcipher_engine_alg ecb_paes_alg = {
@@ -835,7 +835,7 @@ static int cbc_paes_do_one_request(struc
atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable();
- return rc;
+ return 0;
}
static struct skcipher_engine_alg cbc_paes_alg = {
@@ -1145,7 +1145,7 @@ static int ctr_paes_do_one_request(struc
atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable();
- return rc;
+ return 0;
}
static struct skcipher_engine_alg ctr_paes_alg = {
@@ -1589,7 +1589,7 @@ static int xts_paes_do_one_request(struc
atomic_dec(&ctx->via_engine_ctr);
crypto_finalize_skcipher_request(engine, req, rc);
local_bh_enable();
- return rc;
+ return 0;
}
static struct skcipher_engine_alg xts_paes_alg = {
--- a/arch/s390/crypto/phmac_s390.c
+++ b/arch/s390/crypto/phmac_s390.c
@@ -945,7 +945,7 @@ out:
atomic_dec(&tfm_ctx->via_engine_ctr);
crypto_finalize_hash_request(engine, req, rc);
local_bh_enable();
- return rc;
+ return 0;
}
#define S390_ASYNC_PHMAC_ALG(x) \
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 582/733] s390/crypto: Map EBUSY to EIO when key conversion fails repeatedly
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (580 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 581/733] s390/crypto: Fix wrong return code to engine in asynch callbacks Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 583/733] selftests: ublk: install test_common.sh and trace/ scripts Greg Kroah-Hartman
` (162 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Harald Freudenberger, Holger Dengler,
Heiko Carstens, Vasily Gorbik
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <freude@linux.ibm.com>
commit 7a08507ea5b4d06ad8d269287913573f34467565 upstream.
When hardware persistently returns -EBUSY after exhausting retries,
the error propagates to crypto_finalize_*_request(). The crypto API's
completion wrapper treats -EBUSY as a queueing status and swallows it,
preventing the completion callback from firing. This causes callers
using crypto_wait_req() to block indefinitely.
Translate persistent -EBUSY to -EIO after retry exhaustion to ensure
proper error propagation and callback invocation.
Fixes: 6cd87cb5ef6c ("s390/crypto: Rework protected key AES for true asynch support")
Signed-off-by: Harald Freudenberger <freude@linux.ibm.com>
Reviewed-by: Holger Dengler <dengler@linux.ibm.com>
Cc: stable@vger.kernel.org # 6.16+
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/crypto/paes_s390.c | 4 ++++
arch/s390/crypto/phmac_s390.c | 4 ++++
2 files changed, 8 insertions(+)
--- a/arch/s390/crypto/paes_s390.c
+++ b/arch/s390/crypto/paes_s390.c
@@ -220,6 +220,10 @@ static inline int convert_key(const u8 *
xflags);
}
+ /* But finally map -EBUSY to -EIO to indicate an IO failure */
+ if (rc == -EBUSY)
+ rc = -EIO;
+
out:
pr_debug("rc=%d\n", rc);
return rc;
--- a/arch/s390/crypto/phmac_s390.c
+++ b/arch/s390/crypto/phmac_s390.c
@@ -341,6 +341,10 @@ static inline int convert_key(const u8 *
xflags);
}
+ /* But finally map -EBUSY to -EIO to indicate an IO failure */
+ if (rc == -EBUSY)
+ rc = -EIO;
+
out:
pr_debug("rc=%d\n", rc);
return rc;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 583/733] selftests: ublk: install test_common.sh and trace/ scripts
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (581 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 582/733] s390/crypto: Map EBUSY to EIO when key conversion fails repeatedly Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 584/733] perf: RISC-V: store available counter mask as bitmap Greg Kroah-Hartman
` (161 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Mahmoud Nagy Adam, Ming Lei,
Jens Axboe
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mahmoud Nagy Adam <mngyadam@amazon.de>
commit c4fa55f85c47cd5d54d717fb8170746edb10292e upstream.
Every ublk test script sources test_common.sh from its own directory:
. "$(cd "$(dirname "$0")" && pwd)"/test_common.sh
and test_generic_02/12 additionally run bpftrace against the scripts in
trace/. Neither test_common.sh nor trace/ is listed in TEST_FILES, so
"make install" does not copy them into the install directory and every
ublk test fails when run from there:
./test_generic_02.sh: line 4: .../kselftest_install/ublk/test_common.sh: No such file or directory
./test_generic_02.sh: line 8: _have_program: command not found
The bpftrace tests are affected even when bpftrace is installed: the
missing trace/*.bt makes bpftrace exit immediately, and the tests then
report a skip rather than a failure, which hides the problem.
Add both to TEST_FILES, matching how other selftests ship their sourced
helpers (see kexec/kexec_common_lib.sh and zram/zram_lib.sh).
Fixes: 6aecda00b7d1e1 ("selftests: ublk: add kernel selftests for ublk")
Fixes: 723977cab4c0fd ("selftests: ublk: add generic_01 for verifying sequential IO order")
Cc: stable@vger.kernel.org # v6.15+
Assisted-by: Kiro:claude-opus-5
Signed-off-by: Mahmoud Nagy Adam <mngyadam@amazon.de>
Reviewed-by: Ming Lei <tom.leiming@gmail.com>
Link: https://patch.msgid.link/20260909132602.68852-2-mngyadam@amazon.de
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/testing/selftests/ublk/Makefile | 2 ++
1 file changed, 2 insertions(+)
--- a/tools/testing/selftests/ublk/Makefile
+++ b/tools/testing/selftests/ublk/Makefile
@@ -69,6 +69,8 @@ TEST_PROGS += test_stress_08.sh
TEST_PROGS += test_stress_09.sh
TEST_FILES := settings
+TEST_FILES += test_common.sh
+TEST_FILES += trace
TEST_GEN_PROGS_EXTENDED = kublk metadata_size
STANDALONE_UTILS := metadata_size.c
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 584/733] perf: RISC-V: store available counter mask as bitmap
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (582 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 583/733] selftests: ublk: install test_common.sh and trace/ scripts Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 585/733] perf: RISC-V: use BIT_ULL for u64 overflow masks Greg Kroah-Hartman
` (160 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, stable, Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
commit 6809da6e9c08ccc9a09cb0a48c61471679274aaa upstream.
The available-counter mask was a single unsigned long, but iteration
uses RISCV_MAX_COUNTERS, which is 64. On RV32 that reads past the object.
Filling with an unsigned-long bit at index 32 and above is also wrong.
Use DECLARE_BITMAP and set_bit/bitmap helpers. Walk each bitmap word
into CFG_MATCH when checking events, when allocating an index, and when
stopping all counters. Set the counter base to i times BITS_PER_LONG.
Share the CFG_MATCH ecall through a small helper so the 32-bit argument
split is not duplicated. On qemu-system-riscv32 the probe bitmap has bits
above XLEN set, so the first word alone is not enough.
Fixes: e9991434596f ("RISC-V: Add perf platform driver based on SBI PMU extension")
Assisted-by: DeepSeek:deepseek-v3
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/prpmask02cmap.v2.1786434000.git.liuxixin@kylinos.cn
Cc: stable@kernel.org
[pjw@kernel.org: updated to apply; fixed checkpatch.pl issues]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/perf/riscv_pmu_legacy.c | 5 +-
drivers/perf/riscv_pmu_sbi.c | 88 ++++++++++++++++++++++++++++------------
include/linux/perf/riscv_pmu.h | 2
3 files changed, 66 insertions(+), 29 deletions(-)
--- a/drivers/perf/riscv_pmu_legacy.c
+++ b/drivers/perf/riscv_pmu_legacy.c
@@ -110,8 +110,9 @@ static void pmu_legacy_init(struct riscv
{
pr_info("Legacy PMU implementation is available\n");
- pmu->cmask = BIT(RISCV_PMU_LEGACY_CYCLE) |
- BIT(RISCV_PMU_LEGACY_INSTRET);
+ bitmap_zero(pmu->cmask, RISCV_MAX_COUNTERS);
+ set_bit(RISCV_PMU_LEGACY_CYCLE, pmu->cmask);
+ set_bit(RISCV_PMU_LEGACY_INSTRET, pmu->cmask);
pmu->ctr_start = pmu_legacy_ctr_start;
pmu->ctr_stop = NULL;
pmu->event_map = pmu_legacy_event_map;
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -97,7 +97,7 @@ static unsigned int riscv_pmu_irq_mask;
static unsigned int riscv_pmu_irq;
/* Cache the available counters in a bitmask */
-static unsigned long cmask;
+static DECLARE_BITMAP(cmask, RISCV_MAX_COUNTERS);
static int pmu_event_find_cache(u64 config);
struct sbi_pmu_event_data {
@@ -359,16 +359,38 @@ free_mem:
return result;
}
+static struct sbiret pmu_sbi_ctr_cfg_match(unsigned long cbase,
+ unsigned long ctr_mask,
+ unsigned long cflags,
+ unsigned long event_idx,
+ u64 config)
+{
+#if defined(CONFIG_32BIT)
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
+ ctr_mask, cflags, event_idx, config, config >> 32);
+#else
+ return sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
+ ctr_mask, cflags, event_idx, config, 0);
+#endif
+}
+
static void pmu_sbi_check_event(struct sbi_pmu_event_data *edata)
{
- struct sbiret ret;
+ struct sbiret ret = { .error = SBI_ERR_NOT_SUPPORTED };
+ int i;
- ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH,
- 0, cmask, 0, edata->event_idx, 0, 0);
- if (!ret.error) {
- sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
- ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
- } else if (ret.error == SBI_ERR_NOT_SUPPORTED) {
+ for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
+ if (!cmask[i])
+ continue;
+ ret = pmu_sbi_ctr_cfg_match(i * BITS_PER_LONG, cmask[i], 0,
+ edata->event_idx, 0);
+ if (!ret.error) {
+ sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
+ ret.value, 0x1, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
+ return;
+ }
+ }
+ if (ret.error == SBI_ERR_NOT_SUPPORTED) {
/* This event cannot be monitored by any counter */
edata->event_idx = -ENOENT;
}
@@ -488,10 +510,10 @@ int riscv_pmu_get_hpm_info(u32 *hw_ctr_w
union sbi_pmu_ctr_info *info;
u32 hpm_width = 0, hpm_count = 0;
- if (!cmask)
+ if (bitmap_empty(cmask, RISCV_MAX_COUNTERS))
return -EINVAL;
- for_each_set_bit(i, &cmask, RISCV_MAX_COUNTERS) {
+ for_each_set_bit(i, cmask, RISCV_MAX_COUNTERS) {
info = &pmu_ctr_list[i];
if (!info)
continue;
@@ -540,8 +562,8 @@ static int pmu_sbi_ctr_get_idx(struct pe
struct riscv_pmu *rvpmu = to_riscv_pmu(event->pmu);
struct cpu_hw_events *cpuc = this_cpu_ptr(rvpmu->hw_events);
struct sbiret ret;
- int idx;
- uint64_t cbase = 0, cmask = rvpmu->cmask;
+ int idx, i;
+ u64 cbase = 0, cmask = 0;
unsigned long cflags = 0;
cflags = pmu_sbi_get_filter_flags(event);
@@ -562,14 +584,21 @@ static int pmu_sbi_ctr_get_idx(struct pe
}
/* retrieve the available counter index */
-#if defined(CONFIG_32BIT)
- ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
- cmask, cflags, hwc->event_base, hwc->config,
- hwc->config >> 32);
-#else
- ret = sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_CFG_MATCH, cbase,
- cmask, cflags, hwc->event_base, hwc->config, 0);
-#endif
+ if (cmask) {
+ ret = pmu_sbi_ctr_cfg_match(cbase, cmask, cflags, hwc->event_base,
+ hwc->config);
+ } else {
+ ret.error = SBI_ERR_NOT_SUPPORTED;
+ for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
+ if (!rvpmu->cmask[i])
+ continue;
+ cbase = i * BITS_PER_LONG;
+ ret = pmu_sbi_ctr_cfg_match(cbase, rvpmu->cmask[i], cflags,
+ hwc->event_base, hwc->config);
+ if (!ret.error)
+ break;
+ }
+ }
if (ret.error) {
pr_debug("Not able to find a counter for event %lx config %llx\n",
hwc->event_base, hwc->config);
@@ -577,7 +606,7 @@ static int pmu_sbi_ctr_get_idx(struct pe
}
idx = ret.value;
- if (!test_bit(idx, &rvpmu->cmask) || !pmu_ctr_list[idx].value)
+ if (!test_bit(idx, rvpmu->cmask) || !pmu_ctr_list[idx].value)
return -ENOENT;
/* Additional sanity check for the counter id */
@@ -881,7 +910,7 @@ static int pmu_sbi_get_ctrinfo(int nctr,
/* The logical counter ids are not expected to be contiguous */
continue;
- *mask |= BIT(i);
+ set_bit(i, mask);
cinfo.value = ret.value;
if (cinfo.type == SBI_PMU_CTR_TYPE_FW)
@@ -898,12 +927,19 @@ static int pmu_sbi_get_ctrinfo(int nctr,
static inline void pmu_sbi_stop_all(struct riscv_pmu *pmu)
{
+ int i;
+
/*
* No need to check the error because we are disabling all the counters
* which may include counters that are not enabled yet.
*/
- sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
- 0, pmu->cmask, SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
+ for (i = 0; i < BITS_TO_LONGS(RISCV_MAX_COUNTERS); i++) {
+ if (!pmu->cmask[i])
+ continue;
+ sbi_ecall(SBI_EXT_PMU, SBI_EXT_PMU_COUNTER_STOP,
+ i * BITS_PER_LONG, pmu->cmask[i],
+ SBI_PMU_STOP_FLAG_RESET, 0, 0, 0);
+ }
}
static inline void pmu_sbi_stop_hw_ctrs(struct riscv_pmu *pmu)
@@ -1444,7 +1480,7 @@ static int pmu_sbi_device_probe(struct p
}
/* cache all the information about counters now */
- if (pmu_sbi_get_ctrinfo(num_counters, &cmask))
+ if (pmu_sbi_get_ctrinfo(num_counters, cmask))
goto out_free;
ret = pmu_sbi_setup_irqs(pmu, pdev);
@@ -1456,7 +1492,7 @@ static int pmu_sbi_device_probe(struct p
pmu->pmu.attr_groups = riscv_pmu_attr_groups;
pmu->pmu.parent = &pdev->dev;
- pmu->cmask = cmask;
+ bitmap_copy(pmu->cmask, cmask, RISCV_MAX_COUNTERS);
pmu->ctr_start = pmu_sbi_ctr_start;
pmu->ctr_stop = pmu_sbi_ctr_stop;
pmu->event_map = pmu_sbi_event_map;
--- a/include/linux/perf/riscv_pmu.h
+++ b/include/linux/perf/riscv_pmu.h
@@ -55,7 +55,7 @@ struct riscv_pmu {
irqreturn_t (*handle_irq)(int irq_num, void *dev);
- unsigned long cmask;
+ DECLARE_BITMAP(cmask, RISCV_MAX_COUNTERS);
u64 (*ctr_read)(struct perf_event *event);
int (*ctr_get_idx)(struct perf_event *event);
int (*ctr_get_width)(int idx);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 585/733] perf: RISC-V: use BIT_ULL for u64 overflow masks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (583 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 584/733] perf: RISC-V: store available counter mask as bitmap Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 586/733] afs: Fix missing kunmap in afs_dir_search_bucket() Greg Kroah-Hartman
` (159 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Xixin Liu, Paul Walmsley
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xixin Liu <liuxixin@kylinos.cn>
commit 6693171c8c540b3a54e671992f0561613076fc3b upstream.
Overflow status and restart masks are u64, but bits were built with
BIT(). On RV32 that is an unsigned long shift, so indices >= 32 truncate
or wrap and corrupt the mask.
Use BIT_ULL() for those u64 bitops.
Fixes: a8625217a054 ("drivers/perf: riscv: Implement SBI PMU snapshot function")
Assisted-by: DeepSeek:deepseek-v3
Signed-off-by: Xixin Liu <liuxixin@kylinos.cn>
Link: https://patch.msgid.link/prpmask01bitul.v2.1786434000.git.liuxixin@kylinos.cn
Cc: stable@vger.kernel.org
[pjw@kernel.org: updated to apply]
Signed-off-by: Paul Walmsley <pjw@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/perf/riscv_pmu_sbi.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
--- a/drivers/perf/riscv_pmu_sbi.c
+++ b/drivers/perf/riscv_pmu_sbi.c
@@ -1038,7 +1038,7 @@ static inline void pmu_sbi_start_ovf_ctr
struct riscv_pmu_snapshot_data *sdata = cpu_hw_evt->snapshot_addr;
for_each_set_bit(idx, cpu_hw_evt->used_hw_ctrs, RISCV_MAX_COUNTERS) {
- if (ctr_ovf_mask & BIT(idx)) {
+ if (ctr_ovf_mask & BIT_ULL(idx)) {
event = cpu_hw_evt->events[idx];
hwc = &event->hw;
max_period = riscv_pmu_ctr_get_width_mask(event);
@@ -1147,14 +1147,14 @@ static irqreturn_t pmu_sbi_ovf_handler(i
hidx = info->csr - CSR_CYCLE;
/* check if the corresponding bit is set in scountovf or overflow mask in shmem */
- if (!(overflow & BIT(hidx)))
+ if (!(overflow & BIT_ULL(hidx)))
continue;
/*
* Keep a track of overflowed counters so that they can be started
* with updated initial value.
*/
- overflowed_ctrs |= BIT(lidx);
+ overflowed_ctrs |= BIT_ULL(lidx);
hw_evt = &event->hw;
/* Update the event states here so that we know the state while reading */
hw_evt->state |= PERF_HES_STOPPED;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 586/733] afs: Fix missing kunmap in afs_dir_search_bucket()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (584 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 585/733] perf: RISC-V: use BIT_ULL for u64 overflow masks Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 587/733] afs: Fix double-unmap of directory block Greg Kroah-Hartman
` (158 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Marc Dionne,
linux-afs, linux-fsdevel, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
commit 950ae84b5cc944fbe27d81806d0b76af765f779c upstream.
Fix afs_dir_search_bucket() to kunmap the block it's using in the "bad:"
path.
Fixes: a5b5beebcf96 ("afs: Use the contained hashtable to search a directory")
Closes: https://sashiko.dev/#/patchset/20260716103030.3065561-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260902121024.3328255-2-dhowells@redhat.com
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/afs/dir_search.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/fs/afs/dir_search.c
+++ b/fs/afs/dir_search.c
@@ -173,12 +173,11 @@ int afs_dir_search_bucket(struct afs_dir
ret = -ENOENT;
found:
+bad:
if (iter->block) {
kunmap_local(iter->block);
iter->block = NULL;
}
-
-bad:
if (ret == -ESTALE)
afs_invalidate_dir(iter->dvnode, afs_dir_invalid_iter_stale);
_leave(" = %d", ret);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 587/733] afs: Fix double-unmap of directory block
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (585 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 586/733] afs: Fix missing kunmap in afs_dir_search_bucket() Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 588/733] afs: Fix incorrect free in candidate cleanup in afs_lookup_server() Greg Kroah-Hartman
` (157 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Marc Dionne,
linux-afs, linux-fsdevel, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
commit e3cfd3eb7d5be7787cc69530b423f788f14d084f upstream.
Fix afs_edit_dir_remove() to use a cleanup function to unmap the block
pointed to by afs_dir_iter::block if it's left pointing to something rather
than manually kunmapping the blocks. Manually kunmapping without clearing
iter.blocks can result in a double-kunmap if afs_dir_find_block() is called
twice in a row (which would be the case if the block being modified is not
first in the hash chain).
Fixes: a5b5beebcf96 ("afs: Use the contained hashtable to search a directory")
Closes: https://sashiko.dev/#/patchset/20260716103030.3065561-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260902121024.3328255-3-dhowells@redhat.com
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/afs/dir_edit.c | 9 ++-------
fs/afs/dir_search.c | 10 ++--------
fs/afs/internal.h | 8 ++++++++
3 files changed, 12 insertions(+), 15 deletions(-)
--- a/fs/afs/dir_edit.c
+++ b/fs/afs/dir_edit.c
@@ -442,7 +442,7 @@ void afs_edit_dir_remove(struct afs_vnod
/* Check and clear the entry. */
de = &block->dirents[slot];
if (de->u.valid != 1)
- goto error_unmap;
+ goto error;
trace_afs_edit_dir(vnode, why, afs_edit_dir_delete, b, slot,
ntohl(de->u.vnode), ntohl(de->u.unique),
@@ -458,7 +458,6 @@ void afs_edit_dir_remove(struct afs_vnod
/* Clear the constituent entries. */
next = de->u.hash_next;
memset(de, 0, sizeof(*de) * iter.nr_slots);
- kunmap_local(block);
/* Adjust the hash chain: if iter->prev_entry is 0, the hashtable head
* index is previous; otherwise it's slot number of the previous entry.
@@ -485,7 +484,6 @@ void afs_edit_dir_remove(struct afs_vnod
pde = &pblock->dirents[ps];
prev_next = pde->u.hash_next;
if (prev_next != htons(entry)) {
- kunmap_local(pblock);
pr_warn("%llx:%llx:%x: not prev in chain b=%x p=%x,%x e=%x %*s",
vnode->fid.vid, vnode->fid.vnode, vnode->fid.unique,
iter.bucket, iter.prev_entry, prev_next, entry,
@@ -493,7 +491,6 @@ void afs_edit_dir_remove(struct afs_vnod
goto error;
}
pde->u.hash_next = next;
- kunmap_local(pblock);
}
netfs_single_mark_inode_dirty(&vnode->netfs.inode);
@@ -503,18 +500,16 @@ void afs_edit_dir_remove(struct afs_vnod
_debug("Remove %s from %u[%u]", name->name, b, slot);
out_unmap:
+ afs_dir_end_iter(&iter);
kunmap_local(meta);
_leave("");
return;
already_invalidated:
- kunmap_local(block);
trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_inval,
0, 0, 0, 0, name->name);
goto out_unmap;
-error_unmap:
- kunmap_local(block);
error:
trace_afs_edit_dir(vnode, why, afs_edit_dir_delete_error,
0, 0, 0, 0, name->name);
--- a/fs/afs/dir_search.c
+++ b/fs/afs/dir_search.c
@@ -75,10 +75,7 @@ union afs_xdr_dir_block *afs_dir_find_bl
_enter("%zx,%d", block, slot);
- if (iter->block) {
- kunmap_local(iter->block);
- iter->block = NULL;
- }
+ afs_dir_end_iter(iter);
if (dvnode->directory_size < blend)
goto fail;
@@ -174,10 +171,7 @@ int afs_dir_search_bucket(struct afs_dir
ret = -ENOENT;
found:
bad:
- if (iter->block) {
- kunmap_local(iter->block);
- iter->block = NULL;
- }
+ afs_dir_end_iter(iter);
if (ret == -ESTALE)
afs_invalidate_dir(iter->dvnode, afs_dir_invalid_iter_stale);
_leave(" = %d", ret);
--- a/fs/afs/internal.h
+++ b/fs/afs/internal.h
@@ -1133,6 +1133,14 @@ int afs_dir_search_bucket(struct afs_dir
int afs_dir_search(struct afs_vnode *dvnode, const struct qstr *name,
struct afs_fid *_fid, afs_dataversion_t *_dir_version);
+static inline void afs_dir_end_iter(struct afs_dir_iter *iter)
+{
+ if (iter->block) {
+ kunmap_local(iter->block);
+ iter->block = NULL;
+ }
+}
+
/*
* dir_silly.c
*/
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 588/733] afs: Fix incorrect free in candidate cleanup in afs_lookup_server()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (586 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 587/733] afs: Fix double-unmap of directory block Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 589/733] afs: Clear stale peer app data after address list changes Greg Kroah-Hartman
` (156 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, David Howells, Marc Dionne,
linux-afs, linux-fsdevel, Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <dhowells@redhat.com>
commit 044d596094af4b769fb8e1173dff0d08bd68db6c upstream.
Fix afs_lookup_server() to not free an existing server's endpoint state
when cleaning up a candidate server. The candidate record doesn't have an
endpoint state yet at this point, so the free for that can just be removed.
Fixes: 4882ba78574e ("afs: Fix afs_server ref accounting")
Link: https://sashiko.dev/#/patchset/20260729160108.2031453-1-dhowells%40redhat.com
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260902121024.3328255-4-dhowells@redhat.com
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/afs/server.c | 1 -
1 file changed, 1 deletion(-)
--- a/fs/afs/server.c
+++ b/fs/afs/server.c
@@ -242,7 +242,6 @@ struct afs_server *afs_lookup_server(str
out:
afs_put_addrlist(alist, afs_alist_trace_put_server_create);
if (candidate) {
- kfree(rcu_access_pointer(server->endpoint_state));
kfree(candidate);
afs_dec_servers_outstanding(cell->net);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 589/733] afs: Clear stale peer app data after address list changes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (587 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 588/733] afs: Fix incorrect free in candidate cleanup in afs_lookup_server() Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 590/733] hwmon: (applesmc) fix key backlight workqueue leak on register failure Greg Kroah-Hartman
` (155 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Chengfeng Ye, Qi Zhang,
David Howells, Marc Dionne, linux-afs, linux-fsdevel,
Christian Brauner (Amutable)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chengfeng Ye <nicoyip.dev@gmail.com>
commit ba0623fc19a424f4745394c499f9f28a8d88d397 upstream.
afs_fs_probe_fileserver() fetches the current endpoint state under
server->fs_lock, but leaves old_alist as NULL. Consequently,
afs_set_peer_appdata() treats every address list replacement as initial
setup and only binds the new peers; it never unbinds peers removed from
the old list.
An address refresh can therefore proceed as follows. CPU 0 replaces
server S's list and drops Pold without clearing Pold->app_data. The
server destroyer then clears only S's current peers and lets S reach its
RCU callback. After the callback frees S, CPU 1 handles a callback
through an RxRPC connection that still pins Pold, reads Pold->app_data,
and calls afs_use_server() on the freed object.
KASAN reported:
BUG: KASAN: slab-use-after-free in afs_find_server+0x3c/0xa0
Read of size 4 at addr ffff8881013e1af0 by task krxrpcio/7001/74
Call Trace:
afs_find_server+0x3c/0xa0
afs_rx_new_call+0x15c/0x390
rxrpc_new_incoming_call+0x97c/0x1730
rxrpc_input_packet.constprop.0+0xd03/0xec0
rxrpc_io_thread+0x967/0x1640
Allocated by task 93:
afs_lookup_server+0x1a7/0x14c0
afs_alloc_server_list+0x43f/0xb60
afs_create_volume+0x923/0x1490
afs_get_tree+0x1c6/0x10a0
Freed by task 0:
kfree+0x131/0x3c0
rcu_core+0x50a/0x1850
Last potentially related work creation:
__call_rcu_common.constprop.0+0x71/0xa10
afs_put_server+0x213/0x2b0
Preserve old->addresses for the peer app-data update so that removed
peers are cleared before the endpoint state is replaced. Also advance
both cursors when the old and new lists share a peer; activating the
old/new comparison without this would otherwise loop forever on the
shared entry.
Fixes: 40e8b52fe8c8 ("afs: Use the per-peer app data provided by rxrpc")
Signed-off-by: Chengfeng Ye <nicoyip.dev@gmail.com>
Signed-off-by: Qi Zhang <marsy12010123@gmail.com>
Signed-off-by: David Howells <dhowells@redhat.com>
Link: https://patch.msgid.link/20260902121024.3328255-5-dhowells@redhat.com
cc: Marc Dionne <marc.dionne@auristor.com>
cc: linux-afs@lists.infradead.org
cc: linux-fsdevel@vger.kernel.org
cc: stable@vger.kernel.org
Signed-off-by: Christian Brauner (Amutable) <brauner@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/afs/addr_list.c | 5 ++++-
fs/afs/fs_probe.c | 1 +
2 files changed, 5 insertions(+), 1 deletion(-)
--- a/fs/afs/addr_list.c
+++ b/fs/afs/addr_list.c
@@ -394,8 +394,11 @@ void afs_set_peer_appdata(struct afs_ser
struct rxrpc_peer *pn = new_alist->addrs[n].peer;
struct rxrpc_peer *po = old_alist->addrs[o].peer;
- if (pn == po)
+ if (pn == po) {
+ n++;
+ o++;
continue;
+ }
if (pn < po) {
rxrpc_kernel_set_peer_data(pn, data);
n++;
--- a/fs/afs/fs_probe.c
+++ b/fs/afs/fs_probe.c
@@ -258,6 +258,7 @@ int afs_fs_probe_fileserver(struct afs_n
lockdep_is_held(&server->fs_lock));
if (old) {
estate->responsive_set = old->responsive_set;
+ old_alist = old->addresses;
if (!new_alist)
new_alist = old->addresses;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 590/733] hwmon: (applesmc) fix key backlight workqueue leak on register failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (588 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 589/733] afs: Clear stale peer app data after address list changes Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:14 ` [PATCH 7.2 591/733] hwmon: (chipcap2) fix channels in humidity alarm notifications Greg Kroah-Hartman
` (154 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Cong Nguyen, Guenter Roeck
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cong Nguyen <congnt264@gmail.com>
commit 5a0aacaa2d593d7582ecfe289529b937b6dc5d3c upstream.
applesmc_create_key_backlight() allocates applesmc_led_wq before calling
led_classdev_register(). When register fails, the error is returned to
applesmc_init(), which jumps to out_light_sysfs and skips
applesmc_release_key_backlight(), leaking the workqueue.
Destroy the workqueue on the register failure path. The bug was introduced
when the inline init block was refactored into a helper that returns errors
directly, dropping the old out_light_wq unwind label.
Fixes: 0b0b5dff8967 ("hwmon: (applesmc) Simplify feature sysfs handling")
Cc: stable@vger.kernel.org
Assisted-by: Claude:claude-opus-4
Signed-off-by: Cong Nguyen <congnt264@gmail.com>
Link: https://patch.msgid.link/20260828105413.2401385-1-congnt264@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/applesmc.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -1249,12 +1249,17 @@ static void applesmc_release_light_senso
static int applesmc_create_key_backlight(void)
{
+ int ret;
+
if (!smcreg.has_key_backlight)
return 0;
applesmc_led_wq = create_singlethread_workqueue("applesmc-led");
if (!applesmc_led_wq)
return -ENOMEM;
- return led_classdev_register(&pdev->dev, &applesmc_backlight);
+ ret = led_classdev_register(&pdev->dev, &applesmc_backlight);
+ if (ret)
+ destroy_workqueue(applesmc_led_wq);
+ return ret;
}
static void applesmc_release_key_backlight(void)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 591/733] hwmon: (chipcap2) fix channels in humidity alarm notifications
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (589 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 590/733] hwmon: (applesmc) fix key backlight workqueue leak on register failure Greg Kroah-Hartman
@ 2026-09-17 15:14 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 592/733] hwmon: (gpio-fan) Fix use-after-free in alarm work Greg Kroah-Hartman
` (153 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:14 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Javier Carrasco, Guenter Roeck
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Carrasco <javier.carrasco.cruz@gmail.com>
commit 286b175bb03893949f24621f356abd9d20368b0a upstream.
hwmon_notify_event() expects the channel number as its last argument,
taken into account with the type parameter that it is a humidity sensor
type. Given that this device only provides one humidity channel, 0 must
be passed. The custom construct to enumerate the channels makes wrong
assumptions by listing all types together (temperature and humidity).
Remove the custom channel enumeration and pass the right channel to
hwmon_notify_event() for hwmon_humidity_min_alarm and
hwmon_humidity_max_alarm.
Fixes: 3af350929e75 ("hwmon: Add support for Amphenol ChipCap 2")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Carrasco <javier.carrasco.cruz@gmail.com>
Link: https://patch.msgid.link/20260823-chipcap2_locks-v2-1-6a26c8e9e2fc@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/chipcap2.c | 9 ++-------
1 file changed, 2 insertions(+), 7 deletions(-)
--- a/drivers/hwmon/chipcap2.c
+++ b/drivers/hwmon/chipcap2.c
@@ -89,11 +89,6 @@ struct cc2_data {
bool process_irqs;
};
-enum cc2_chan_addr {
- CC2_CHAN_TEMP = 0,
- CC2_CHAN_HUMIDITY,
-};
-
/* %RH as a per cent mille from a register value */
static long cc2_rh_convert(u16 data)
{
@@ -492,7 +487,7 @@ static irqreturn_t cc2_low_interrupt(int
if (cc2->process_irqs) {
hwmon_notify_event(cc2->hwmon, hwmon_humidity,
- hwmon_humidity_min_alarm, CC2_CHAN_HUMIDITY);
+ hwmon_humidity_min_alarm, 0);
cc2->rh_alarm.low_alarm = true;
}
@@ -505,7 +500,7 @@ static irqreturn_t cc2_high_interrupt(in
if (cc2->process_irqs) {
hwmon_notify_event(cc2->hwmon, hwmon_humidity,
- hwmon_humidity_max_alarm, CC2_CHAN_HUMIDITY);
+ hwmon_humidity_max_alarm, 0);
cc2->rh_alarm.high_alarm = true;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 592/733] hwmon: (gpio-fan) Fix use-after-free in alarm work
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (590 preceding siblings ...)
2026-09-17 15:14 ` [PATCH 7.2 591/733] hwmon: (chipcap2) fix channels in humidity alarm notifications Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 593/733] hwmon: (mcp9982) Propagate one-shot polling errors Greg Kroah-Hartman
` (152 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Fan Wu, Guenter Roeck
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit a2471ed17b0e6ff7bfb6b2ea8e6e5b04c309d293 upstream.
fan_alarm_irq_handler() queues fan_data->alarm_work, but nothing
cancels it. fan_alarm_notify() dereferences fan_data and its hwmon
device. On unbind, devres frees the interrupt, which only waits for
the handler itself, and then releases the hwmon device and fan_data,
so a pending fan_alarm_notify() can run after those frees.
Replace INIT_WORK() with devm_work_autocancel(), registered before
devm_request_irq(). The devres cleanup then frees the interrupt
first, so no new work can be queued, and cancels the work while
fan_data and the hwmon device are still alive.
This issue was found by an in-house static analysis tool.
Fixes: d6fe1360f42e ("hwmon: add generic GPIO fan driver")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Link: https://patch.msgid.link/20260819033317.446191-1-fanwu01@zju.edu.cn
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/gpio-fan.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/gpio-fan.c
+++ b/drivers/hwmon/gpio-fan.c
@@ -12,6 +12,7 @@
#include <linux/slab.h>
#include <linux/interrupt.h>
#include <linux/irq.h>
+#include <linux/devm-helpers.h>
#include <linux/platform_device.h>
#include <linux/err.h>
#include <linux/kstrtox.h>
@@ -84,6 +85,7 @@ static DEVICE_ATTR_RO(fan1_alarm);
static int fan_alarm_init(struct gpio_fan_data *fan_data)
{
int alarm_irq;
+ int err;
struct device *dev = fan_data->dev;
/*
@@ -94,7 +96,11 @@ static int fan_alarm_init(struct gpio_fa
if (alarm_irq <= 0)
return 0;
- INIT_WORK(&fan_data->alarm_work, fan_alarm_notify);
+ err = devm_work_autocancel(dev, &fan_data->alarm_work,
+ fan_alarm_notify);
+ if (err)
+ return err;
+
irq_set_irq_type(alarm_irq, IRQ_TYPE_EDGE_BOTH);
return devm_request_irq(dev, alarm_irq, fan_alarm_irq_handler,
IRQF_SHARED, "GPIO fan alarm", fan_data);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 593/733] hwmon: (mcp9982) Propagate one-shot polling errors
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (591 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 592/733] hwmon: (gpio-fan) Fix use-after-free in alarm work Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 594/733] hwmon: (pmbus) Clear generic status alarms with CLEAR_FAULTS Greg Kroah-Hartman
` (151 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Nikhil Gurudasani, Guenter Roeck
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
commit 9607c245ca6674955e5e43e3606db410ae9e0b90 upstream.
When a device is in standby, the driver starts a one-shot conversion and
polls the BUSY flag before reading temperature, alarm, or fault data.
The poll result is currently ignored. Therefore, a timeout or a
status-register read failure can be hidden by a later successful read,
causing stale data to be returned as valid.
Return the polling error before reading the requested attribute.
Fixes: e2fe950f34e5 ("hwmon: add support for MCP998X")
Cc: stable@vger.kernel.org
Signed-off-by: Nikhil Gurudasani <nikhilgurudasani314@gmail.com>
Link: https://patch.msgid.link/20260819180701.34797-1-nikhilgurudasani314@gmail.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/mcp9982.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/hwmon/mcp9982.c
+++ b/drivers/hwmon/mcp9982.c
@@ -395,6 +395,8 @@ static int mcp9982_read(struct device *d
reg_status, !(reg_status & MCP9982_STATUS_BUSY),
MCP9982_WAKE_UP_TIME_US,
MCP9982_WAKE_UP_TIME_US * 10);
+ if (ret)
+ return ret;
break;
}
break;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 594/733] hwmon: (pmbus) Clear generic status alarms with CLEAR_FAULTS
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (592 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 593/733] hwmon: (mcp9982) Propagate one-shot polling errors Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 595/733] media: hevc: add bounded tile-count helpers Greg Kroah-Hartman
` (150 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Vishnu Razdan, Guenter Roeck
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vishnu Razdan <vrazdan@openai.com>
commit 6d760f8b41aed74de4402440e4db663d261478bd upstream.
Some hwmon alarms fall back to STATUS_WORD summary bits when no
individual limit alarm is available. On PMBus 1.2 and newer devices,
pmbus_get_boolean() acknowledges these alarms with the same byte-data
write used for detailed status registers. For example, PB_STATUS_INPUT
is 0x2000, so it is truncated to zero when passed to
_pmbus_write_byte_data(). The resulting write cannot acknowledge the
input alarm.
PMBus 1.3 Part II, sections 10.2.4 and 10.2.5, excludes ordinary
STATUS_BYTE and STATUS_WORD summary bits from individual clearing.
Their summary bits clear when the underlying status bits clear, so
changing this to a word-data write would not fix the generic input
alarm either.
Use the existing page CLEAR_FAULTS path for generic STATUS_WORD
alarms, including devices whose status accessor uses STATUS_BYTE.
Keep individual byte writes for detailed status registers on PMBus
1.2 and newer devices. As with the existing older-device fallback,
CLEAR_FAULTS can clear other latched status; an active condition can
reassert its status.
Fixes: 35f165f08950 ("hwmon: (pmbus) Clear pmbus fault/warning bits after read")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Vishnu Razdan <vrazdan@openai.com>
Link: https://patch.msgid.link/20260824-vrazdan-pmbus-status-word-b4-v1-1-2606ecd0c029@openai.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/pmbus/pmbus_core.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/pmbus/pmbus_core.c
+++ b/drivers/hwmon/pmbus/pmbus_core.c
@@ -1192,7 +1192,9 @@ static int pmbus_get_boolean(struct i2c_
regval = status & mask;
if (regval) {
- if (data->revision >= PMBUS_REV_12) {
+ /* Generic STATUS_WORD alarms are not individually clearable. */
+ if (data->revision >= PMBUS_REV_12 &&
+ reg != PMBUS_STATUS_WORD) {
ret = _pmbus_write_byte_data(client, page, reg, regval);
if (ret)
return ret;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 595/733] media: hevc: add bounded tile-count helpers
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (593 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 594/733] hwmon: (pmbus) Clear generic status alarms with CLEAR_FAULTS Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 596/733] media: ipu-bridge: do not use the CVS device lookup for IVSC Greg Kroah-Hartman
` (149 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Benjamin Gaignard,
Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 592dd4f8442a13bed6e946d73d3164ba38b33bbd upstream.
The stateless HEVC decoders compute the number of tile columns and rows
from num_tile_columns_minus1 / num_tile_rows_minus1 and clamp it to the
column_width_minus1[] / row_height_minus1[] capacity before using it as a
loop bound. Add shared helpers in a new <media/v4l2-hevc.h> so the rkvdec
and hantro drivers do not each open-code the min_t() clamp.
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Assisted-by: Claude:claude-opus-4-8
Fixes: 256fa3920874 ("media: v4l: Add definitions for HEVC stateless decoding")
Cc: stable@vger.kernel.org
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
include/media/v4l2-hevc.h | 41 +++++++++++++++++++++++++++++++++++++++++
1 file changed, 41 insertions(+)
create mode 100644 include/media/v4l2-hevc.h
--- /dev/null
+++ b/include/media/v4l2-hevc.h
@@ -0,0 +1,41 @@
+/* SPDX-License-Identifier: GPL-2.0-or-later */
+/*
+ * Helper functions for HEVC stateless codecs.
+ */
+
+#ifndef _MEDIA_V4L2_HEVC_H
+#define _MEDIA_V4L2_HEVC_H
+
+#include <linux/minmax.h>
+#include <media/v4l2-ctrls.h>
+
+/**
+ * v4l2_hevc_pps_num_tile_columns - number of HEVC tile columns, bounded
+ * @pps: the V4L2 HEVC PPS control
+ *
+ * Return the number of tile columns (num_tile_columns_minus1 + 1) clamped to
+ * the capacity of column_width_minus1[]. The control validation already
+ * rejects out-of-range counts; this keeps the consuming drivers bounded too.
+ */
+static inline unsigned int
+v4l2_hevc_pps_num_tile_columns(const struct v4l2_ctrl_hevc_pps *pps)
+{
+ return min_t(unsigned int, pps->num_tile_columns_minus1 + 1,
+ ARRAY_SIZE(pps->column_width_minus1));
+}
+
+/**
+ * v4l2_hevc_pps_num_tile_rows - number of HEVC tile rows, bounded
+ * @pps: the V4L2 HEVC PPS control
+ *
+ * Return the number of tile rows (num_tile_rows_minus1 + 1) clamped to the
+ * capacity of row_height_minus1[].
+ */
+static inline unsigned int
+v4l2_hevc_pps_num_tile_rows(const struct v4l2_ctrl_hevc_pps *pps)
+{
+ return min_t(unsigned int, pps->num_tile_rows_minus1 + 1,
+ ARRAY_SIZE(pps->row_height_minus1));
+}
+
+#endif /* _MEDIA_V4L2_HEVC_H */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 596/733] media: ipu-bridge: do not use the CVS device lookup for IVSC
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (594 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 595/733] media: hevc: add bounded tile-count helpers Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 597/733] media: verisilicon: hantro: bound G2 HEVC tile loop to the buffer capacity Greg Kroah-Hartman
` (148 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sergey Zagursky, Linus Torvalds
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Zagursky <gvozdoder@gmail.com>
commit 856c562c94964a74f63c6d5f38a1509a59a2357d upstream.
Since commit c6b1b34b5090 ("media: pci: intel: Add CVS support for IPU
bridge driver") the internal camera no longer works on laptops where the
sensor sits behind an IVSC, for example a Dell XPS 16 9640 (IPU6,
INTC10CF, ov02c10):
intel-ipu6 0000:00:05.0: Found supported sensor OVTI02C1:00
intel-ipu6 0000:00:05.0: Connected 1 cameras
ivsc_csi intel_vsc-92335fcf-3203-4472-af93-7b4453ac29da: mei-csi probed
without device fwnode!
No sensor subdevice is registered, the media graph has no sensor entity
and userspace finds no camera at all.
ipu_bridge_get_ivsc_csi_dev() first looks for the platform device named
"intel_vsc" and returns its mei-csi child. That device is created by
mei_vsc, which on this machine only appears once the LJCA USB bridge and
its SPI controller have probed, about a second after the IPU6 probe that
runs the bridge:
07:59:29.297 platform INTC10CF:00 created (ACPI scan)
07:59:41 intel-ipu6 probe -> ipu_bridge_init()
07:59:42.391 platform intel_vsc created (mei_vsc)
The commit above added two fallbacks for CVS which match on the ACPI
companion alone. They are reached for every entry of ivsc_acpi_ids[],
IVSC IDs included. The IVSC ACPI device has two physical nodes:
INTC10CF:00/physical_node -> platform/INTC10CF:00 (no driver bound)
INTC10CF:00/physical_node1 -> platform/intel_vsc (mei_vsc)
so bus_find_device_by_acpi_dev(&platform_bus_type, adev) returns the bare
platform device. ipu_bridge_instantiate_ivsc() then attaches the IVSC
software node to that device instead of to the mei-csi client, the bridge
reports success, and the probe is never retried. mei_csi later probes
without a fwnode, the CSI-2 link is never described, and the sensor ACPI
device, which has an honoured _DEP on the IVSC device, is never
enumerated.
Before those fallbacks existed the lookup returned NULL here, the bridge
failed with -ENODEV and the probe was retried once the IVSC device had
shown up.
Skip those fallbacks for IVSC devices, keying on the IVSC IDs rather than
the CVS ones: new CVS IDs keep being added, whereas the IVSC list is
complete. CVS binds a driver to the ACPI device itself, so matching on the
companion stays unambiguous there.
Fixes: c6b1b34b5090 ("media: pci: intel: Add CVS support for IPU bridge driver")
Link: https://lore.kernel.org/linux-media/20260901194526.6369-1-gvozdoder@gmail.com/
Cc: stable@vger.kernel.org
Assisted-by: Claude Code:claude-opus-5
Signed-off-by: Sergey Zagursky <gvozdoder@gmail.com>
Signed-off-by: Linus Torvalds <torvalds@linux-foundation.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/pci/intel/ipu-bridge.c | 24 ++++++++++++++++++++++++
1 file changed, 24 insertions(+)
--- a/drivers/media/pci/intel/ipu-bridge.c
+++ b/drivers/media/pci/intel/ipu-bridge.c
@@ -173,6 +173,19 @@ static const struct acpi_device_id ivsc_
{ "INTC10E1" }, /* PTL */
};
+/*
+ * The subset of ivsc_acpi_ids[] which are IVSC, rather than CVS, devices. The
+ * CVS IDs are deliberately not listed here: new ones keep being added, whereas
+ * this list is complete.
+ */
+static const struct acpi_device_id ivsc_only_acpi_ids[] = {
+ { "INTC1059" },
+ { "INTC1095" },
+ { "INTC100A" },
+ { "INTC10CF" },
+ { }
+};
+
static struct acpi_device *ipu_bridge_get_ivsc_acpi_dev(struct acpi_device *adev)
{
unsigned int i;
@@ -224,6 +237,17 @@ static struct device *ipu_bridge_get_ivs
return csi_dev;
}
+ /*
+ * The lookups below match on the ACPI companion alone. That is fine for
+ * CVS, which binds a driver to that very device, but not for IVSC: there
+ * the ACPI device also has a driverless platform device, which would be
+ * returned instead of the mei-csi client. Return NULL for IVSC so that
+ * the caller fails and the probe is retried once the IVSC device shows
+ * up.
+ */
+ if (!acpi_match_device_ids(adev, ivsc_only_acpi_ids))
+ return NULL;
+
/* Try to locate CVS device on the I2C bus */
csi_dev = bus_find_device_by_acpi_dev(&i2c_bus_type, adev);
if (csi_dev)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 597/733] media: verisilicon: hantro: bound G2 HEVC tile loop to the buffer capacity
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (595 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 596/733] media: ipu-bridge: do not use the CVS device lookup for IVSC Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 598/733] media: rkvdec: bound HEVC tile loops and PPS id to the array capacity Greg Kroah-Hartman
` (147 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Benjamin Gaignard,
Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 06236b094c899c22c12ac5097935eb6719293de8 upstream.
prepare_tile_info_buffer() writes one entry per tile into the tile_sizes
DMA buffer, sized for a grid equal to the PPS uAPI array capacity. Use the
bounded v4l2_hevc_pps_num_tile_columns() / v4l2_hevc_pps_num_tile_rows()
helpers so the loops stay inside the buffer.
Fixes: cb5dd5a0fa51 ("media: hantro: Introduce G2/HEVC decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
+++ b/drivers/media/platform/verisilicon/hantro_g2_hevc_dec.c
@@ -5,6 +5,8 @@
* Copyright (C) 2020 Safran Passenger Innovations LLC
*/
+#include <media/v4l2-hevc.h>
+
#include "hantro_hw.h"
#include "hantro_g2_regs.h"
@@ -15,8 +17,8 @@ static void prepare_tile_info_buffer(str
const struct v4l2_ctrl_hevc_pps *pps = ctrls->pps;
const struct v4l2_ctrl_hevc_sps *sps = ctrls->sps;
u16 *p = (u16 *)((u8 *)ctx->hevc_dec.tile_sizes.cpu);
- unsigned int num_tile_rows = pps->num_tile_rows_minus1 + 1;
- unsigned int num_tile_cols = pps->num_tile_columns_minus1 + 1;
+ unsigned int num_tile_rows = v4l2_hevc_pps_num_tile_rows(pps);
+ unsigned int num_tile_cols = v4l2_hevc_pps_num_tile_columns(pps);
unsigned int pic_width_in_ctbs, pic_height_in_ctbs;
unsigned int max_log2_ctb_size, ctb_size;
bool tiles_enabled, uniform_spacing;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 598/733] media: rkvdec: bound HEVC tile loops and PPS id to the array capacity
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (596 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 597/733] media: verisilicon: hantro: bound G2 HEVC tile loop to the buffer capacity Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 599/733] media: mediatek: vcodec: bound AV1 tile-start copy " Greg Kroah-Hartman
` (146 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 81ad46bb33d8fd279aaa33af5296c648814c964b upstream.
compute_tiles_uniform() and compute_tiles_non_uniform() loop over
num_tile_columns_minus1 + 1 / num_tile_rows_minus1 + 1 entries, and
assemble_hw_pps() writes one COLUMN_WIDTH / ROW_HEIGHT register per tile
and indexes priv_tbl->param_set[] by pic_parameter_set_id, all taken from
the untrusted PPS. Use the bounded v4l2_hevc_pps_num_tile_columns() /
v4l2_hevc_pps_num_tile_rows() helpers for the tile loops, and bail out of
assemble_hw_pps() before indexing priv_tbl->param_set[] with an
out-of-range pic_parameter_set_id, so the writes stay within the hardware
tables.
Fixes: 3595375c2301 ("media: rkvdec: Add HEVC backend")
Fixes: c9a59dc2acc7 ("media: rkvdec: Add HEVC support for the VDPU381 variant")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c | 14 +++++++----
drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c | 7 +++--
drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c | 2 +
3 files changed, 17 insertions(+), 6 deletions(-)
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc-common.c
@@ -16,6 +16,7 @@
*/
#include <linux/v4l2-common.h>
+#include <media/v4l2-hevc.h>
#include <media/v4l2-mem2mem.h>
#include "rkvdec.h"
@@ -37,15 +38,17 @@ void compute_tiles_uniform(struct rkvdec
s32 pic_in_cts_height, u16 *column_width, u16 *row_height)
{
const struct v4l2_ctrl_hevc_pps *pps = run->pps;
+ unsigned int num_cols = v4l2_hevc_pps_num_tile_columns(pps);
+ unsigned int num_rows = v4l2_hevc_pps_num_tile_rows(pps);
int i;
- for (i = 0; i < pps->num_tile_columns_minus1 + 1; i++)
+ for (i = 0; i < num_cols; i++)
column_width[i] = ((i + 1) * pic_in_cts_width) /
(pps->num_tile_columns_minus1 + 1) -
(i * pic_in_cts_width) /
(pps->num_tile_columns_minus1 + 1);
- for (i = 0; i < pps->num_tile_rows_minus1 + 1; i++)
+ for (i = 0; i < num_rows; i++)
row_height[i] = ((i + 1) * pic_in_cts_height) /
(pps->num_tile_rows_minus1 + 1) -
(i * pic_in_cts_height) /
@@ -57,17 +60,20 @@ void compute_tiles_non_uniform(struct rk
s32 pic_in_cts_height, u16 *column_width, u16 *row_height)
{
const struct v4l2_ctrl_hevc_pps *pps = run->pps;
+ unsigned int num_cols = v4l2_hevc_pps_num_tile_columns(pps);
+ unsigned int num_rows = v4l2_hevc_pps_num_tile_rows(pps);
s32 sum = 0;
int i;
- for (i = 0; i < pps->num_tile_columns_minus1; i++) {
+ /* The last tile entry is written after the loop, so iterate one less. */
+ for (i = 0; i < num_cols - 1; i++) {
column_width[i] = pps->column_width_minus1[i] + 1;
sum += column_width[i];
}
column_width[i] = pic_in_cts_width - sum;
sum = 0;
- for (i = 0; i < pps->num_tile_rows_minus1; i++) {
+ for (i = 0; i < num_rows - 1; i++) {
row_height[i] = pps->row_height_minus1[i] + 1;
sum += row_height[i];
}
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-hevc.c
@@ -12,6 +12,7 @@
* Jeffy Chen <jeffy.chen@rock-chips.com>
*/
+#include <media/v4l2-hevc.h>
#include <media/v4l2-mem2mem.h>
#include "rkvdec.h"
@@ -135,6 +136,8 @@ static void assemble_hw_pps(struct rkvde
* packet unit). so the driver copy SPS/PPS information to the exact PPS
* packet unit for HW accessing.
*/
+ if (pps->pic_parameter_set_id >= ARRAY_SIZE(priv_tbl->param_set))
+ return;
hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
memset(hw_ps, 0, sizeof(*hw_ps));
@@ -253,9 +256,9 @@ static void assemble_hw_pps(struct rkvde
if (pps->flags & V4L2_HEVC_PPS_FLAG_TILES_ENABLED) {
/* Userspace also provide column width and row height for uniform spacing */
- for (i = 0; i <= pps->num_tile_columns_minus1; i++)
+ for (i = 0; i < v4l2_hevc_pps_num_tile_columns(pps); i++)
WRITE_PPS(pps->column_width_minus1[i], COLUMN_WIDTH(i));
- for (i = 0; i <= pps->num_tile_rows_minus1; i++)
+ for (i = 0; i < v4l2_hevc_pps_num_tile_rows(pps); i++)
WRITE_PPS(pps->row_height_minus1[i], ROW_HEIGHT(i));
} else {
WRITE_PPS(((sps->pic_width_in_luma_samples + ctb_size_y - 1) / ctb_size_y) - 1,
--- a/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
+++ b/drivers/media/platform/rockchip/rkvdec/rkvdec-vdpu381-hevc.c
@@ -145,6 +145,8 @@ static void assemble_hw_pps(struct rkvde
* packet unit). so the driver copy SPS/PPS information to the exact PPS
* packet unit for HW accessing.
*/
+ if (pps->pic_parameter_set_id >= ARRAY_SIZE(priv_tbl->param_set))
+ return;
hw_ps = &priv_tbl->param_set[pps->pic_parameter_set_id];
memset(hw_ps, 0, sizeof(*hw_ps));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 599/733] media: mediatek: vcodec: bound AV1 tile-start copy to the array capacity
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (597 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 598/733] media: rkvdec: bound HEVC tile loops and PPS id to the array capacity Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 600/733] media: v4l2-h264: Fix memcmp() size in B1 reference list comparison Greg Kroah-Hartman
` (145 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 37bef2170d4c88fc3d708eecf3ef0f4032bc1372 upstream.
vdec_av1_slice_setup_tile() copies tile_cols + 1 / tile_rows + 1 entries
into mi_col_starts[] / mi_row_starts[] from the bitstream tile_info. Bound
the copy to the array capacity.
Fixes: 0934d3759615 ("media: mediatek: vcodec: separate decoder and encoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c | 5 +++--
1 file changed, 3 insertions(+), 2 deletions(-)
--- a/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
+++ b/drivers/media/platform/mediatek/vcodec/decoder/vdec/vdec_av1_req_lat_if.c
@@ -1299,11 +1299,12 @@ static void vdec_av1_slice_setup_tile(st
tile->uniform_tile_spacing_flag =
BIT_FLAG(ctrl_tile, V4L2_AV1_TILE_INFO_FLAG_UNIFORM_TILE_SPACING);
- for (i = 0; i < tile->tile_cols + 1; i++)
+ /* Bound the copy to the mi_col_starts[]/mi_row_starts[] capacity. */
+ for (i = 0; i < tile->tile_cols + 1 && i < V4L2_AV1_MAX_TILE_COLS + 1; i++)
tile->mi_col_starts[i] =
ALIGN(ctrl_tile->mi_col_starts[i], BIT(mib_size_log2)) >> mib_size_log2;
- for (i = 0; i < tile->tile_rows + 1; i++)
+ for (i = 0; i < tile->tile_rows + 1 && i < V4L2_AV1_MAX_TILE_ROWS + 1; i++)
tile->mi_row_starts[i] =
ALIGN(ctrl_tile->mi_row_starts[i], BIT(mib_size_log2)) >> mib_size_log2;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 600/733] media: v4l2-h264: Fix memcmp() size in B1 reference list comparison
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (598 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 599/733] media: mediatek: vcodec: bound AV1 tile-start copy " Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 601/733] media: verisilicon: rockchip: guard VPU981 AV1 divisor and tile buffer Greg Kroah-Hartman
` (144 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nicolas Dufresne, Haotian Zhang,
Nicolas Dufresne, Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Haotian Zhang <vulab@iscas.ac.cn>
commit 10e59fbdef13597836bd6459095caa02c80af3d7 upstream.
In v4l2_h264_build_b_ref_lists(), the B0/B1 list equality
check passes the entry count builder->num_valid to memcmp()
instead of a byte size. Since struct v4l2_h264_reference is
two bytes (fields and index), only half of each list is
compared, so distinct lists can be wrongly treated as equal
and trigger an incorrect swap(b1_reflist[0], b1_reflist[1]).
Change the memcmp() size argument to sizeof(b1_reflist[0]) *
builder->num_valid so that the full byte length of both
reference lists is compared.
Fixes: 624922a2739b ("media: v4l2-core: Add helpers to build the H264 P/B0/B1 reflists")
Suggested-by: Nicolas Dufresne <nicolas@ndufresne.ca>
Cc: stable@vger.kernel.org
Signed-off-by: Haotian Zhang <vulab@iscas.ac.cn>
Reviewed-by: Nicolas Dufresne <nicolas.dufresne@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/v4l2-core/v4l2-h264.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/media/v4l2-core/v4l2-h264.c
+++ b/drivers/media/v4l2-core/v4l2-h264.c
@@ -440,7 +440,8 @@ v4l2_h264_build_b_ref_lists(const struct
}
if (builder->num_valid > 1 &&
- !memcmp(b1_reflist, b0_reflist, builder->num_valid))
+ !memcmp(b1_reflist, b0_reflist,
+ sizeof(b1_reflist[0]) * builder->num_valid))
swap(b1_reflist[0], b1_reflist[1]);
print_ref_list_b(builder, b0_reflist, 0);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 601/733] media: verisilicon: rockchip: guard VPU981 AV1 divisor and tile buffer
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (599 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 600/733] media: v4l2-h264: Fix memcmp() size in B1 reference list comparison Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 602/733] media: verisilicon: rockchip: reject AV1 frames exceeding the tile capacity Greg Kroah-Hartman
` (143 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Benjamin Gaignard,
Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit b84f6533a8ed2fd7b282fc7ab4b8efadc745a89c upstream.
rockchip_vpu981_av1_dec_set_tile_info() divides context_update_tile_id by
tile_info->tile_cols and writes one descriptor per tile into the tile_info
DMA buffer, which holds AV1_MAX_TILES entries; tile_cols and tile_rows
come from the bitstream. Guard the division against a zero tile_cols by
initialising the context-update values to zero and computing them only
when tile_cols is non-zero, and stop the descriptor writes once the
tile_info buffer is full. The tile geometry written to the hardware
registers is left unmodified; the per-dimension and total tile bounds are
enforced by the control validation.
Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c | 32 ++++++++--
1 file changed, 26 insertions(+), 6 deletions(-)
--- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
@@ -578,16 +578,30 @@ static void rockchip_vpu981_av1_dec_set_
const struct v4l2_av1_tile_info *tile_info = &ctrls->frame->tile_info;
const struct v4l2_ctrl_av1_tile_group_entry *group_entry =
ctrls->tile_group_entry;
- int context_update_y =
- tile_info->context_update_tile_id / tile_info->tile_cols;
- int context_update_x =
- tile_info->context_update_tile_id % tile_info->tile_cols;
- int context_update_tile_id =
- context_update_x * tile_info->tile_rows + context_update_y;
+ int context_update_y = 0;
+ int context_update_x = 0;
+ int context_update_tile_id = 0;
u8 *dst = av1_dec->tile_info.cpu;
+ u8 *dst_end = dst + av1_dec->tile_info.size;
struct hantro_dev *vpu = ctx->dev;
int tile0, tile1;
+ /*
+ * tile_cols and tile_rows are bounded by the V4L2 control validation
+ * (V4L2_AV1_MAX_TILE_{COLS,ROWS} and V4L2_AV1_MAX_TILE_COUNT). Guard
+ * the divisor here, and keep the descriptor writes within the
+ * AV1_MAX_TILES tile_info buffer below; the register values use the
+ * unmodified tile geometry.
+ */
+ if (tile_info->tile_cols) {
+ context_update_y =
+ tile_info->context_update_tile_id / tile_info->tile_cols;
+ context_update_x =
+ tile_info->context_update_tile_id % tile_info->tile_cols;
+ context_update_tile_id =
+ context_update_x * tile_info->tile_rows + context_update_y;
+ }
+
memset(dst, 0, av1_dec->tile_info.size);
for (tile0 = 0; tile0 < tile_info->tile_cols; tile0++) {
@@ -598,6 +612,10 @@ static void rockchip_vpu981_av1_dec_set_
tile_info->height_in_sbs_minus_1[tile1] + 1;
u32 x0 = tile_info->width_in_sbs_minus_1[tile0] + 1;
+ /* Stop once the tile_info descriptor buffer is full. */
+ if (dst + 16 > dst_end)
+ break;
+
/* tile size in SB units (width,height) */
*dst++ = x0;
*dst++ = 0;
@@ -622,6 +640,8 @@ static void rockchip_vpu981_av1_dec_set_
*dst++ = (end >> 16) & 255;
*dst++ = (end >> 24) & 255;
}
+ if (dst + 16 > dst_end)
+ break;
}
hantro_reg_write(vpu, &av1_multicore_expect_context_update, !!(context_update_x == 0));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 602/733] media: verisilicon: rockchip: reject AV1 frames exceeding the tile capacity
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (600 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 601/733] media: verisilicon: rockchip: guard VPU981 AV1 divisor and tile buffer Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 603/733] media: v4l2-ctrls: validate HEVC tile counts Greg Kroah-Hartman
` (142 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Benjamin Gaignard,
Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 367db8b23c26a913d76ed70457bbcd781c422b49 upstream.
rockchip_vpu981_av1_dec_set_tile_info() indexes the tile group entry
array by tile1 * tile_cols + tile0, reading up to tile_cols * tile_rows
entries, lays out one descriptor per tile in the AV1_MAX_TILES tile_info
buffer, and programs the real tile_cols / tile_rows into the hardware.
The tile group entry control is a dynamic array sized to the number of
entries userspace submitted, independent of tile_cols / tile_rows, so a
frame that claims more tiles than entries reads past the array. A frame
that claims more than AV1_MAX_TILES tiles also leaves the hardware
programmed for more tiles than the descriptor buffer holds.
Reject both in prepare_run(): tile_cols * tile_rows must not exceed the
submitted entry count or AV1_MAX_TILES. The entry count is read via
v4l2_ctrl_find() (ctrl->elems). This mirrors the bound the mediatek AV1
decoder already enforces.
Fixes: 727a400686a2 ("media: verisilicon: Add Rockchip AV1 decoder")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c | 25 ++++++++--
1 file changed, 22 insertions(+), 3 deletions(-)
--- a/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
+++ b/drivers/media/platform/verisilicon/rockchip_vpu981_hw_av1_dec.c
@@ -431,20 +431,39 @@ static int rockchip_vpu981_av1_dec_prepa
{
struct hantro_av1_dec_hw_ctx *av1_dec = &ctx->av1_dec;
struct hantro_av1_dec_ctrls *ctrls = &av1_dec->ctrls;
+ const struct v4l2_av1_tile_info *tile_info;
+ struct v4l2_ctrl *tge;
+ u32 num_tiles;
ctrls->sequence = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_SEQUENCE);
if (WARN_ON(!ctrls->sequence))
return -EINVAL;
- ctrls->tile_group_entry =
- hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY);
- if (WARN_ON(!ctrls->tile_group_entry))
+ tge = v4l2_ctrl_find(&ctx->ctrl_handler,
+ V4L2_CID_STATELESS_AV1_TILE_GROUP_ENTRY);
+ if (WARN_ON(!tge))
return -EINVAL;
+ ctrls->tile_group_entry = tge->p_cur.p;
ctrls->frame = hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FRAME);
if (WARN_ON(!ctrls->frame))
return -EINVAL;
+ /*
+ * rockchip_vpu981_av1_dec_set_tile_info() indexes the tile group
+ * entry array by tile1 * tile_cols + tile0, so it reads up to
+ * tile_cols * tile_rows entries, and lays out one descriptor per tile
+ * in the AV1_MAX_TILES tile_info buffer while programming the real
+ * tile geometry into the hardware. Reject a frame that claims more
+ * tiles than userspace submitted, or more than the hardware tile
+ * buffer holds, so the read stays in bounds and the programmed
+ * geometry matches the descriptors written.
+ */
+ tile_info = &ctrls->frame->tile_info;
+ num_tiles = (u32)tile_info->tile_cols * tile_info->tile_rows;
+ if (num_tiles > tge->elems || num_tiles > AV1_MAX_TILES)
+ return -EINVAL;
+
ctrls->film_grain =
hantro_get_ctrl(ctx, V4L2_CID_STATELESS_AV1_FILM_GRAIN);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 603/733] media: v4l2-ctrls: validate HEVC tile counts
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (601 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 602/733] media: verisilicon: rockchip: reject AV1 frames exceeding the tile capacity Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 604/733] media: v4l2-ctrls: validate AV1 " Greg Kroah-Hartman
` (141 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Benjamin Gaignard,
Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit dc694a9929f7cb9c88ef91e45eb982b7bbe5a477 upstream.
The stateless HEVC decoders read num_tile_columns_minus1 + 1 entries from
column_width_minus1[] and num_tile_rows_minus1 + 1 from row_height_minus1[]
and use them as tile-loop bounds, but std_validate_compound() does not
bound these u8 counts. Reject a V4L2_CTRL_TYPE_HEVC_PPS with tiling
enabled whose tile counts exceed the uAPI array capacity, mirroring the
existing compound-control range checks.
Fixes: 256fa3920874 ("media: v4l: Add definitions for HEVC stateless decoding")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/v4l2-core/v4l2-ctrls-core.c | 12 ++++++++++++
1 file changed, 12 insertions(+)
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -1253,6 +1253,18 @@ static int std_validate_compound(const s
p_hevc_pps->flags &=
~V4L2_HEVC_PPS_FLAG_LOOP_FILTER_ACROSS_TILES_ENABLED;
+ } else {
+ /*
+ * These count the entries the stateless HEVC drivers
+ * read from column_width_minus1[] / row_height_minus1[]
+ * and use as tile-loop bounds.
+ */
+ if (p_hevc_pps->num_tile_columns_minus1 >=
+ ARRAY_SIZE(p_hevc_pps->column_width_minus1))
+ return -EINVAL;
+ if (p_hevc_pps->num_tile_rows_minus1 >=
+ ARRAY_SIZE(p_hevc_pps->row_height_minus1))
+ return -EINVAL;
}
if (p_hevc_pps->flags &
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 604/733] media: v4l2-ctrls: validate AV1 tile counts
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (602 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 603/733] media: v4l2-ctrls: validate HEVC tile counts Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 605/733] bnxt_en: Only restore LRO if the device supports TPA Greg Kroah-Hartman
` (140 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Michael Bommarito, Benjamin Gaignard,
Hans Verkuil
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Bommarito <michael.bommarito@gmail.com>
commit 439058ced617fbb3febc017b9e93bb7387f309e0 upstream.
The stateless AV1 decoders use tile_info.tile_cols and tile_rows as loop
bounds and as indices into the mi_*_starts[] and *_in_sbs_minus_1[]
arrays, as the divisor for context_update_tile_id, and their product
bounds the per-tile descriptor buffers, but std_validate_compound() does
not bound these u8 fields. Reject a V4L2_CTRL_TYPE_AV1_FRAME whose
tile_cols or tile_rows exceeds V4L2_AV1_MAX_TILE_COLS / _ROWS, or whose
product exceeds V4L2_AV1_MAX_TILE_COUNT. A zero tile count is left to the
consuming driver so the zero-initialised control that existing userspace
submits is still accepted.
Fixes: 9de30f579980 ("media: Add AV1 uAPI")
Assisted-by: Claude:claude-opus-4-8
Cc: stable@vger.kernel.org
Signed-off-by: Michael Bommarito <michael.bommarito@gmail.com>
Reviewed-by: Benjamin Gaignard <benjamin.gaignard@collabora.com>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/v4l2-core/v4l2-ctrls-core.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
--- a/drivers/media/v4l2-core/v4l2-ctrls-core.c
+++ b/drivers/media/v4l2-core/v4l2-ctrls-core.c
@@ -793,10 +793,30 @@ static int validate_av1_film_grain(struc
return 0;
}
+static int validate_av1_tile_info(struct v4l2_av1_tile_info *t)
+{
+ /*
+ * tile_cols and tile_rows index the per-tile descriptor arrays and
+ * bound the tile loops in the stateless AV1 drivers; the product
+ * bounds the total tile descriptor count.
+ */
+ if (t->tile_cols > V4L2_AV1_MAX_TILE_COLS ||
+ t->tile_rows > V4L2_AV1_MAX_TILE_ROWS)
+ return -EINVAL;
+
+ if ((u32)t->tile_cols * t->tile_rows > V4L2_AV1_MAX_TILE_COUNT)
+ return -EINVAL;
+
+ return 0;
+}
+
static int validate_av1_frame(struct v4l2_ctrl_av1_frame *f)
{
int ret = 0;
+ ret = validate_av1_tile_info(&f->tile_info);
+ if (ret)
+ return ret;
ret = validate_av1_quantization(&f->quantization);
if (ret)
return ret;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 605/733] bnxt_en: Only restore LRO if the device supports TPA
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (603 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 604/733] media: v4l2-ctrls: validate AV1 " Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 606/733] bnxt_en: Dont free the live rings TPA state on queue restart failure Greg Kroah-Hartman
` (139 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit 4e17b5007b6664559cdad2b2fe270526cf786b5b upstream.
With a P5+ device with firmware that reports max_aggs_supported == 0, it is
possible to make LRO settable by attaching and detaching an XDP program
even though the device does not support TPA.
Fix this by testing BNXT_SUPPORTS_TPA before restoring the feature bit.
Fixes: f0aa6a37a3db ("eth: bnxt: always recalculate features after XDP clearing, fix null-deref")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-2-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -5006,7 +5006,8 @@ void bnxt_set_rx_skb_mode(struct bnxt *b
bnxt_get_max_rings(bp, &rx, &tx, true);
if (rx > 1) {
bp->flags &= ~BNXT_FLAG_NO_AGG_RINGS;
- bp->dev->hw_features |= NETIF_F_LRO;
+ if (BNXT_SUPPORTS_TPA(bp))
+ bp->dev->hw_features |= NETIF_F_LRO;
}
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 606/733] bnxt_en: Dont free the live rings TPA state on queue restart failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (604 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 605/733] bnxt_en: Only restore LRO if the device supports TPA Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 607/733] bnxt_en: Handle buffer allocation failure in bnxt_rx_ring_reset() Greg Kroah-Hartman
` (138 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit 5ce7f36c334d723954855ac769ede2fe0e8f89c8 upstream.
bnxt_queue_mem_alloc() shallow copies the live RX ring into the clone:
memcpy(clone, rxr, sizeof(*rxr));
the code currently clears pointers that the clone owns (such as
rx_agg_bmap), but rx_tpa and rx_tpa_idx_map are left pointing at memory
of the live ring that was cloned.
If an allocation failure happens later and the err_free_tpa_info label
is taken, the live ring's memory can be freed while still in use.
Fix this by initializing the clone's pointers to NULL to prevent live
ring state from being freed inadvertently.
Fixes: bd649c5cc958 ("bnxt_en: handle tpa_info in queue API implementation")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-3-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -16290,6 +16290,8 @@ static int bnxt_queue_mem_alloc(struct n
clone->need_head_pool = false;
clone->rx_page_size = qcfg->rx_page_size;
clone->rx_agg_bmap = NULL;
+ clone->rx_tpa = NULL;
+ clone->rx_tpa_idx_map = NULL;
rc = bnxt_alloc_rx_page_pool(bp, clone, rxr->page_pool->p.nid);
if (rc)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 607/733] bnxt_en: Handle buffer allocation failure in bnxt_rx_ring_reset()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (605 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 606/733] bnxt_en: Dont free the live rings TPA state on queue restart failure Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 608/733] bnxt_en: Propagate RX ring init failures in bnxt_init_nic() Greg Kroah-Hartman
` (137 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit 961e2a17c5e3559b3f8654d2daabdd25a42e770a upstream.
bnxt_rx_ring_reset() frees the ring buffers and then reallocates them,
ignoring the result.
bnxt_alloc_one_rx_ring() can fail in bnxt_alloc_one_tpa_info_data(), which
returns -ENOMEM on the first failed allocation and leaves the remaining
rxr->rx_tpa[] entries zeroed.
The error isn't propagated up, so the loop in bnxt_rx_ring_reset
continues and at the end the code re-enables TPA with partially
unallocated rx_tpa array.
This means that when the agg_id from hardware is mapped to a SW index in
rxr->rx_tpa[], an uninitialized slot can be chosen which would hand a
zero DMA address to the device.
Fix this by falling back to a global reset, which is what the existing
code already does when other functions fail, but unlike the other
failure cases this particular failure has to return because TPA can't
be re-enabled since the allocation failed.
Fixes: 8fbf58e17dce ("bnxt_en: Implement RX ring reset in response to buffer errors.")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-5-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -14564,7 +14564,14 @@ static void bnxt_rx_ring_reset(struct bn
rxr->rx_sw_agg_prod = 0;
rxr->rx_next_cons = 0;
rxr->bnapi->in_reset = false;
- bnxt_alloc_one_rx_ring(bp, i);
+ rc = bnxt_alloc_one_rx_ring(bp, i);
+ if (rc) {
+ netdev_warn(bp->dev, "RX ring reset failed to allocate buffers, rc = %d, falling back to global reset\n",
+ rc);
+ bnxt_reset_task(bp, true);
+ bnxt_rtnl_unlock_sp(bp);
+ return;
+ }
cpr = &rxr->bnapi->cp_ring;
cpr->sw_stats->rx.rx_resets++;
if (bp->flags & BNXT_FLAG_AGG_RINGS)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 608/733] bnxt_en: Propagate RX ring init failures in bnxt_init_nic()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (606 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 607/733] bnxt_en: Handle buffer allocation failure in bnxt_rx_ring_reset() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 609/733] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc() Greg Kroah-Hartman
` (136 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit 8e6a850c0746bb4be167aedf1ee57469fcda09a9 upstream.
bnxt_init_rx_rings() returns an error when bnxt_alloc_one_rx_ring()
fails, but bnxt_init_nic() discards that return value and calls
bnxt_init_chip(), which enables TPA.
If an allocation fails, this could leave rxr->rx_tpa[] partially zeroed
and TPA would be enabled over an array with zeroed entries. This would
lead to a zeroed DMA address being handed out if the agg_idx is
translated to a SW index at a zeroed entry.
Fix this by propagating the error out of bnxt_init_nic(). Both callers
already check its return value and unwind with bnxt_free_skbs() and
bnxt_free_mem(), which tolerate a partially initialized RX ring.
Fixes: c0c050c58d84 ("bnxt_en: New Broadcom ethernet driver.")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-6-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 7 ++++++-
1 file changed, 6 insertions(+), 1 deletion(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -11341,8 +11341,13 @@ static int bnxt_shutdown_nic(struct bnxt
static int bnxt_init_nic(struct bnxt *bp, bool irq_re_init)
{
+ int rc;
+
bnxt_init_cp_rings(bp);
- bnxt_init_rx_rings(bp);
+ rc = bnxt_init_rx_rings(bp);
+ if (rc)
+ return rc;
+
bnxt_init_tx_rings(bp);
bnxt_init_ring_grps(bp, irq_re_init);
bnxt_init_vnics(bp);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 609/733] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (607 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 608/733] bnxt_en: Propagate RX ring init failures in bnxt_init_nic() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 610/733] bnxt_en: Bound SW TPA IDs to prevent crashes Greg Kroah-Hartman
` (135 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Sashiko, Joe Damato, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit b814dfbfeb0a68c9a52073f2caa05a2d5247a329 upstream.
bnxt_alloc_one_tpa_info_data() returns -ENOMEM as soon as one allocation
fails. This leaves the remaining rxr->rx_tpa[] entries zeroed.
bnxt_queue_mem_alloc() discards that return value, so the partially
initialized ring is installed by bnxt_queue_start().
Since the agg_id is picked by the hardware and bnxt_alloc_agg_idx maps
it to a SW index in rxr->rx_tpa[], it is possible that an uninitialized
slot can be chosen which would hand a zero DMA address to the device.
Fix this by checking the return value of bnxt_alloc_one_tpa_info_data
and unwinding, freeing the ring buffers.
Fixes: bd649c5cc958 ("bnxt_en: handle tpa_info in queue API implementation")
Reported-by: Sashiko <sashiko-bot+sashiko@kernel.org>
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260828190900.1767611-1-joe%40dama.to
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-4-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 9 +++++++--
1 file changed, 7 insertions(+), 2 deletions(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -16347,11 +16347,16 @@ static int bnxt_queue_mem_alloc(struct n
bnxt_alloc_one_rx_ring_skb(bp, clone, idx);
if (bp->flags & BNXT_FLAG_AGG_RINGS)
bnxt_alloc_one_rx_ring_netmem(bp, clone, idx);
- if (bp->flags & BNXT_FLAG_TPA)
- bnxt_alloc_one_tpa_info_data(bp, clone);
+ if (bp->flags & BNXT_FLAG_TPA) {
+ rc = bnxt_alloc_one_tpa_info_data(bp, clone);
+ if (rc)
+ goto err_free_rx_ring_skbs;
+ }
return 0;
+err_free_rx_ring_skbs:
+ bnxt_free_one_rx_ring_skbs(bp, clone);
err_free_tpa_info:
bnxt_free_one_tpa_info(bp, clone);
err_free_rx_agg_ring:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 610/733] bnxt_en: Bound SW TPA IDs to prevent crashes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (608 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 609/733] bnxt_en: Propagate TPA buffer allocation failures in bnxt_queue_mem_alloc() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 611/733] bnxt_en: Prevent queue stop with deferred completions Greg Kroah-Hartman
` (134 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Raphael Cardoso Fernandes,
Michael Chan, Joe Damato, Paolo Abeni
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit c0aceaf65b70b3c000e70dd867f3a673015f24ca upstream.
FW supports up to 1024 concurrent TPAs, so the FW TPA ID is in the range
0..1023 (see commit ec4d8e7cf024 ("bnxt_en: Add TPA ID mapping logic for
57500 chips.")). bnxt_alloc_agg_idx is intended to wrap the FW ID down to a
software ID which is used to index rxr->rx_tpa, and to generate a mapping
between FW IDs and the wrapped software ID.
On a 57608 with firmware version 233, the firmware advertises 32
concurrent TPAs. As of the commit under fixes, bp->max_tpa on this NIC
is set to 32.
If the software ID from bnxt_alloc_agg_idx is above 31, this results in
an invalid address being loaded on this line:
tpa_info = &rxr->rx_tpa[agg_id];
because rx_tpa is allocated with only bp->max_tpa (32) entries. Writes
to tpa_info later in the code are out of bounds.
This bug results in a crash at boot:
Oops: general protection fault, kernel NULL pointer dereference 0x8: 0000 [#1] SMP NOPTI
RIP: 0010:bnxt_rx_pkt+0xc0/0x1560
RSP: 0018:ffffc900009b8c78 EFLAGS: 00010246
RAX: 0000000000000000 RBX: 0000000000000048 RCX: 0000000206682516
RDX: ffffc900009b8db4 RSI: 0000000000000000 RDI: 01ffffff038fe1c0
RBP: ffffc9006e687480 R08: ffffc9006e687000 R09: 0000000000003048
R10: 0000000000000480 R11: ffff8881c6083900 R12: 0000000006682516
R13: ffff8881c6095400 R14: 0000000000000016 R15: ffff8881c6b66680
FS: 0000000000000000(0000) GS:ffff88fef3c77000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007fc8bda40584 CR3: 000000807c812001 CR4: 0000000008772ef0
PKRU: 55555554
Call Trace:
<IRQ>
? __netif_receive_skb_list_core+0x1ca/0x250
__bnxt_poll_work+0x152/0x280
bnxt_poll_p5+0x1cd/0x480
__napi_poll+0x30/0x180
net_rx_action+0x20b/0x3b0
? note_gp_changes+0x53/0xe0
? tick_setup_sched_timer+0x180/0x180
? __napi_schedule+0x9a/0xb0
? bnxt_msix+0x24/0x30
handle_softirqs+0xdd/0x2c0
__irq_exit_rcu.llvm.3171231171502365008+0x47/0xf0
common_interrupt+0x85/0x90
</IRQ>
<TASK>
asm_common_interrupt+0x22/0x40
This stack trace is from a crash triggered when an out of bounds rx_tpa
is dereferenced. The invalid write mentioned above is silent in this
particular crash.
Fix this by allocating rx_tpa with bp->max_tpa rounded up to the next
power of 2 (bp->max_tpa_roundup_size) entries and masking the FW TPA ID
with that size, so the wrapped ID can never index past the end of the
array.
Fixes: 54c28fab2fa5 ("bnxt_en: Set bp->max_tpa according to what the FW supports")
Reported-by: Raphael Cardoso Fernandes <raphaelcf@meta.com>
Suggested-by: Michael Chan <michael.chan@broadcom.com>
Cc: stable@vger.kernel.org
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902015652.2421609-7-joe@dama.to
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 27 +++++++++++++++++----------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 2 +-
2 files changed, 18 insertions(+), 11 deletions(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -1514,14 +1514,16 @@ static int bnxt_discard_rx(struct bnxt *
return 0;
}
-static u16 bnxt_alloc_agg_idx(struct bnxt_rx_ring_info *rxr, u16 agg_id)
+static u16 bnxt_alloc_agg_idx(struct bnxt *bp, struct bnxt_rx_ring_info *rxr,
+ u16 agg_id)
{
struct bnxt_tpa_idx_map *map = rxr->rx_tpa_idx_map;
- u16 idx = agg_id & MAX_TPA_P5_MASK;
+ u16 idx = agg_id & (bp->max_tpa_roundup_size - 1);
if (test_bit(idx, map->agg_idx_bmap)) {
- idx = find_first_zero_bit(map->agg_idx_bmap, MAX_TPA_P5);
- if (idx >= MAX_TPA_P5)
+ idx = find_first_zero_bit(map->agg_idx_bmap,
+ bp->max_tpa_roundup_size);
+ if (idx >= bp->max_tpa_roundup_size)
return INVALID_HW_RING_ID;
}
__set_bit(idx, map->agg_idx_bmap);
@@ -1586,7 +1588,7 @@ static void bnxt_tpa_start(struct bnxt *
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
agg_id = TPA_START_AGG_ID_P5(tpa_start);
- agg_id = bnxt_alloc_agg_idx(rxr, agg_id);
+ agg_id = bnxt_alloc_agg_idx(bp, rxr, agg_id);
if (unlikely(agg_id == INVALID_HW_RING_ID)) {
netdev_warn(bp->dev, "Unable to allocate agg ID for ring %d, agg 0x%x\n",
rxr->bnapi->index,
@@ -3584,7 +3586,7 @@ static void bnxt_free_one_tpa_info_data(
{
int i;
- for (i = 0; i < bp->max_tpa; i++) {
+ for (i = 0; i < bp->max_tpa_roundup_size; i++) {
struct bnxt_tpa_info *tpa_info = &rxr->rx_tpa[i];
u8 *data = tpa_info->data;
@@ -3781,7 +3783,7 @@ static void bnxt_free_one_tpa_info(struc
kfree(rxr->rx_tpa_idx_map);
rxr->rx_tpa_idx_map = NULL;
if (rxr->rx_tpa) {
- for (i = 0; i < bp->max_tpa; i++) {
+ for (i = 0; i < bp->max_tpa_roundup_size; i++) {
kfree(rxr->rx_tpa[i].agg_arr);
rxr->rx_tpa[i].agg_arr = NULL;
}
@@ -3807,13 +3809,14 @@ static int bnxt_alloc_one_tpa_info(struc
struct rx_agg_cmp *agg;
int i;
- rxr->rx_tpa = kzalloc_objs(struct bnxt_tpa_info, bp->max_tpa);
+ rxr->rx_tpa = kzalloc_objs(struct bnxt_tpa_info,
+ bp->max_tpa_roundup_size);
if (!rxr->rx_tpa)
return -ENOMEM;
if (!(bp->flags & BNXT_FLAG_CHIP_P5_PLUS))
return 0;
- for (i = 0; i < bp->max_tpa; i++) {
+ for (i = 0; i < bp->max_tpa_roundup_size; i++) {
agg = kzalloc_objs(*agg, MAX_SKB_FRAGS);
if (!agg)
return -ENOMEM;
@@ -3832,6 +3835,9 @@ static int bnxt_alloc_tpa_info(struct bn
bp->max_tpa = MAX_TPA;
if (bp->flags & BNXT_FLAG_CHIP_P5_PLUS) {
+ /* TPA is not supported at all, so there is nothing to
+ * allocate.
+ */
if (!bp->max_tpa_v2)
return 0;
bp->max_tpa = min_t(u16, bp->max_tpa_v2, MAX_TPA_P5);
@@ -3839,6 +3845,7 @@ static int bnxt_alloc_tpa_info(struct bn
if (bp->max_tpa <= 32 && BNXT_CHIP_P5(bp) && !BNXT_NPAR(bp))
bp->max_tpa = MAX_TPA_P5;
}
+ bp->max_tpa_roundup_size = roundup_pow_of_two(bp->max_tpa);
for (i = 0; i < bp->rx_nr_rings; i++) {
struct bnxt_rx_ring_info *rxr = &bp->rx_ring[i];
@@ -4551,7 +4558,7 @@ static int bnxt_alloc_one_tpa_info_data(
u8 *data;
int i;
- for (i = 0; i < bp->max_tpa; i++) {
+ for (i = 0; i < bp->max_tpa_roundup_size; i++) {
data = __bnxt_alloc_rx_frag(bp, &mapping, rxr,
GFP_KERNEL);
if (!data)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -789,7 +789,6 @@ struct nqe_cn {
#define MAX_TPA 64
#define MAX_TPA_P5 256
-#define MAX_TPA_P5_MASK (MAX_TPA_P5 - 1)
#define MAX_TPA_SEGS_P5 0x3f
#if (BNXT_PAGE_SHIFT == 16)
@@ -2382,6 +2381,7 @@ struct bnxt {
u16 max_tpa_v2;
u16 max_tpa;
+ u16 max_tpa_roundup_size;
u32 rx_buf_size;
u32 rx_buf_use_size; /* useable size */
u16 rx_offset;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 611/733] bnxt_en: Prevent queue stop with deferred completions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (609 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 610/733] bnxt_en: Bound SW TPA IDs to prevent crashes Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 612/733] mptcp: do not reschedule the RTX timer for fallback sockets Greg Kroah-Hartman
` (133 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Joe Damato, Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Joe Damato <joe@dama.to>
commit 39b23c1c40e1f73d2b94a09282cc476af647e438 upstream.
When the driver receives a burst of packets, it can mark a BD with the
NO_CMPL bit to defer completions. The expectation is that the last
packet in the ring will have this bit unset and the completion generated
by that packet will cleanup that packet and the ones preceding it. This
helps to reduce the number of completions fired.
The suppressed completions are controlled by the driver and the number
of packets with suppressed completions scales with the size of the ring.
SW USO packets, on the other hand, have an upper bound on the maximum
number of BDs which can be consumed which does not scale with the ring
size.
So, for small rings it is possible that: a burst of packets is handed to
the driver, the driver defers completions for all of the packets because
the number of free descriptors stays above the threshold in the driver.
Then, a USO packet arrives, but the number of BDs available is not
enough and the USO code exits early.
In this case, you end up in a state where the ring is full of packets
with their completions suppressed, which can cause the queue to stop and
never be restarted.
Assuming default CONFIG_MAX_SKB_FRAGS, this is only possible for small
rings (<= 457 descriptors, below the driver default value) when
a burst of packets fills the ring, followed by a large USO packet that
can't fit. For larger rings, the delta between the completion
suppression threshold and the BDs required for SW USO is large enough
that completions will fire and this case is unreachable.
This issue was pointed out by Sashiko and while it seems fairly unlikely
given that the queue size must be small to trigger this, it is indeed
possible.
Fix this by tracking the last BD which deferred completions and
centralizing the logic for deciding when to ring the doorbell. The NO_CMPL
bit is now cleared in bnxt_txr_db_kick(), so every doorbell site is
covered, including the SW USO early exit. This guarantees the ring always
ends in a BD which generates a completion to clean it and wake the queue.
Fixes: cc5d90667db8 ("net: bnxt: Implement software USO")
Cc: <stable@vger.kernel.org> # v7.1+: 4e15e89faac9: net: bnxt: ring the doorbell when SW USO exits early
Signed-off-by: Joe Damato <joe@dama.to>
Link: https://patch.msgid.link/20260902213956.4160615-1-joe@dama.to
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/net/ethernet/broadcom/bnxt/bnxt.c | 42 ++++++++++++++++++++------
drivers/net/ethernet/broadcom/bnxt/bnxt.h | 1
drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c | 21 +++++++------
drivers/net/ethernet/broadcom/bnxt/bnxt_gso.h | 6 +--
4 files changed, 48 insertions(+), 22 deletions(-)
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.c
@@ -462,6 +462,16 @@ u16 bnxt_xmit_get_cfa_action(struct sk_b
static void bnxt_txr_db_kick(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
u16 prod)
{
+ /* If the most recent BD has its completion suppressed, unset the bit
+ * so that a completion is generated, otherwise nothing is left to
+ * clean the ring and wake the queue.
+ */
+ if (txr->kick_txbd0) {
+ txr->kick_txbd0->tx_bd_len_flags_type &=
+ cpu_to_le32(~TX_BD_FLAGS_NO_CMPL);
+ txr->kick_txbd0 = NULL;
+ }
+
/* Sync BD data before updating doorbell */
wmb();
bnxt_db_write(bp, &txr->tx_db, prod);
@@ -485,7 +495,6 @@ static netdev_tx_t bnxt_start_xmit(struc
struct bnxt_sw_tx_bd *tx_buf;
__le32 lflags = 0;
skb_frag_t *frag;
- netdev_tx_t ret;
i = skb_get_queue_mapping(skb);
if (unlikely(i >= bp->tx_nr_rings)) {
@@ -509,11 +518,22 @@ static netdev_tx_t bnxt_start_xmit(struc
if (skb_is_gso(skb) &&
(skb_shinfo(skb)->gso_type & SKB_GSO_UDP_L4) &&
!(bp->flags & BNXT_FLAG_UDP_GSO_CAP)) {
- ret = bnxt_sw_udp_gso_xmit(bp, txr, txq, skb);
- if (txr->kick_pending)
+ int rc = bnxt_sw_udp_gso_xmit(bp, txr, txq, skb);
+
+ /* if SW USO queued a packet, the doorbell will be written
+ * below and there is no reason to track the last BD with
+ * suppressed completions
+ */
+ if (rc > 0)
+ txr->kick_txbd0 = NULL;
+
+ /* if a packet was queued by SW USO or a doorbell was pending
+ * from a previous xmit that was deferred, write the doorbell.
+ */
+ if (rc > 0 || txr->kick_pending)
bnxt_txr_db_kick(bp, txr, txr->tx_prod);
- return ret;
+ return rc < 0 ? NETDEV_TX_BUSY : NETDEV_TX_OK;
}
free_size = bnxt_tx_avail(bp, txr);
@@ -751,23 +771,23 @@ normal_tx:
prod = NEXT_TX(prod);
WRITE_ONCE(txr->tx_prod, prod);
+ txr->kick_txbd0 = NULL;
if (!netdev_xmit_more() || netif_xmit_stopped(txq)) {
bnxt_txr_db_kick(bp, txr, prod);
} else {
- if (free_size >= bp->tx_wake_thresh)
+ if (free_size >= bp->tx_wake_thresh) {
txbd0->tx_bd_len_flags_type |=
cpu_to_le32(TX_BD_FLAGS_NO_CMPL);
+ txr->kick_txbd0 = txbd0;
+ }
txr->kick_pending = 1;
}
tx_done:
if (unlikely(bnxt_tx_avail(bp, txr) <= MAX_SKB_FRAGS + 1)) {
- if (netdev_xmit_more() && !tx_buf->is_push) {
- txbd0->tx_bd_len_flags_type &=
- cpu_to_le32(~TX_BD_FLAGS_NO_CMPL);
+ if (txr->kick_pending)
bnxt_txr_db_kick(bp, txr, prod);
- }
netif_txq_try_stop(txq, bnxt_tx_avail(bp, txr),
bp->tx_wake_thresh);
@@ -5435,6 +5455,8 @@ static void bnxt_clear_ring_indices(stru
txr->tx_prod = 0;
txr->tx_cons = 0;
txr->tx_hw_cons = 0;
+ txr->kick_pending = 0;
+ txr->kick_txbd0 = NULL;
}
rxr = bnapi->rx_ring;
@@ -11785,6 +11807,8 @@ static int bnxt_tx_queue_start(struct bn
txr->tx_prod = 0;
txr->tx_cons = 0;
txr->tx_hw_cons = 0;
+ txr->kick_pending = 0;
+ txr->kick_txbd0 = NULL;
start_tx:
WRITE_ONCE(txr->dev_state, 0);
synchronize_net();
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt.h
@@ -992,6 +992,7 @@ struct bnxt_tx_ring_info {
u16 txq_index;
u8 tx_napi_idx;
u8 kick_pending;
+ struct tx_bd *kick_txbd0;
struct bnxt_db_info tx_db;
struct tx_bd *tx_desc_ring[MAX_TX_PAGES];
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.c
@@ -31,10 +31,14 @@ static u32 bnxt_sw_gso_lhint(unsigned in
return TX_BD_FLAGS_LHINT_2048_AND_LARGER;
}
-netdev_tx_t bnxt_sw_udp_gso_xmit(struct bnxt *bp,
- struct bnxt_tx_ring_info *txr,
- struct netdev_queue *txq,
- struct sk_buff *skb)
+/* Transmit an skb requiring software UDP segmentation.
+ *
+ * Returns 1 if the skb was queued and new BDs were produced, 0 if the skb
+ * was dropped, or -1 if the ring is full and the skb should be retried.
+ * The caller owns the doorbell for all three cases.
+ */
+int bnxt_sw_udp_gso_xmit(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ struct netdev_queue *txq, struct sk_buff *skb)
{
unsigned int last_unmap_len __maybe_unused = 0;
dma_addr_t last_unmap_addr __maybe_unused = 0;
@@ -69,7 +73,7 @@ netdev_tx_t bnxt_sw_udp_gso_xmit(struct
if (unlikely(bnxt_tx_avail(bp, txr) < bds_needed)) {
netif_txq_try_stop(txq, bnxt_tx_avail(bp, txr),
bp->tx_wake_thresh);
- return NETDEV_TX_BUSY;
+ return -1;
}
/* BD backpressure alone cannot prevent overwriting in-flight
@@ -77,7 +81,7 @@ netdev_tx_t bnxt_sw_udp_gso_xmit(struct
*/
if (!netif_txq_maybe_stop(txq, bnxt_inline_avail(txr),
num_segs, num_segs))
- return NETDEV_TX_BUSY;
+ return -1;
if (unlikely(tso_dma_map_init(&map, &pdev->dev, skb, hdr_len)))
goto drop;
@@ -223,16 +227,15 @@ netdev_tx_t bnxt_sw_udp_gso_xmit(struct
netdev_tx_sent_queue(txq, skb->len);
WRITE_ONCE(txr->tx_prod, prod);
- txr->kick_pending = 1;
if (unlikely(bnxt_tx_avail(bp, txr) <= bp->tx_wake_thresh))
netif_txq_try_stop(txq, bnxt_tx_avail(bp, txr),
bp->tx_wake_thresh);
- return NETDEV_TX_OK;
+ return 1;
drop:
dev_kfree_skb_any(skb);
dev_core_stats_tx_dropped_inc(bp->dev);
- return NETDEV_TX_OK;
+ return 0;
}
--- a/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.h
+++ b/drivers/net/ethernet/broadcom/bnxt/bnxt_gso.h
@@ -38,9 +38,7 @@ static inline int bnxt_min_tx_desc_cnt(s
return BNXT_MIN_TX_DESC_CNT;
}
-netdev_tx_t bnxt_sw_udp_gso_xmit(struct bnxt *bp,
- struct bnxt_tx_ring_info *txr,
- struct netdev_queue *txq,
- struct sk_buff *skb);
+int bnxt_sw_udp_gso_xmit(struct bnxt *bp, struct bnxt_tx_ring_info *txr,
+ struct netdev_queue *txq, struct sk_buff *skb);
#endif
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 612/733] mptcp: do not reschedule the RTX timer for fallback sockets
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (610 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 611/733] bnxt_en: Prevent queue stop with deferred completions Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 613/733] mptcp: options: handle MPC data + csum reqd + no csum Greg Kroah-Hartman
` (132 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <pabeni@redhat.com>
commit e2ab913f68c7d11e2561b8a8ad0b87ffefcad667 upstream.
On fallback socket the retrans timer is a quite convoluted no-op, but
currently nothing prevents the MPTCP core to keep rescheduling it.
Additionally gate RTX timer reset to the msk not being fallen back to
TCP yet. To avoid adding multiple tests in fast-path, use a new flags
bit for such condition.
The RTX enable bit is clear at close time and set before the msk could
start retransmitting, with a couple of caveats:
- passive sockets inherit the bit from the listener msk; set the bit on
such socket to avoid flipping it in the fast-path, even if the
listener will obviously never retransmit.
- while fastopening (MPTFO), mptcp_sendmsg_fastopen still ends-up
calling mptcp_connect via tcp_sendmsg_fastopen ->
__inet_stream_connect(ssk->sk_socket), and the first subflow's
sk_socket points to the msk one.
Fixes: b51f9b80c032 ("mptcp: introduce MPTCP retransmission timer")
Cc: stable@vger.kernel.org
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-1-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/protocol.c | 13 ++++++++++---
net/mptcp/protocol.h | 1 +
2 files changed, 11 insertions(+), 3 deletions(-)
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -95,6 +95,7 @@ bool __mptcp_try_fallback(struct mptcp_s
msk->allow_subflows = false;
set_bit(MPTCP_FALLBACK_DONE, &msk->flags);
+ clear_bit(MPTCP_RTX_ENABLED, &msk->flags);
__MPTCP_INC_STATS(net, fb_mib);
spin_unlock_bh(&msk->fallback_lock);
return true;
@@ -1001,13 +1002,14 @@ static bool mptcp_rtx_timer_pending(stru
static void mptcp_reset_rtx_timer(struct sock *sk)
{
+ struct mptcp_sock *msk = mptcp_sk(sk);
unsigned long tout;
- /* prevent rescheduling on close */
- if (unlikely(inet_sk_state_load(sk) == TCP_CLOSE))
+ /* Prevent rescheduling on close and in case of fallback. */
+ if (!test_bit(MPTCP_RTX_ENABLED, &msk->flags))
return;
- tout = mptcp_sk(sk)->timer_ival;
+ tout = msk->timer_ival;
sk_reset_timer(sk, &sk->mptcp_retransmit_timer, jiffies + tout);
}
@@ -3191,6 +3193,9 @@ void mptcp_set_state(struct sock *sk, in
* transition from TCP_SYN_RECV to TCP_CLOSE_WAIT.
*/
break;
+ case TCP_CLOSE:
+ clear_bit(MPTCP_RTX_ENABLED, &mptcp_sk(sk)->flags);
+ fallthrough;
default:
if (oldstate == TCP_ESTABLISHED || oldstate == TCP_CLOSE_WAIT)
MPTCP_DEC_STATS(sock_net(sk), MPTCP_MIB_CURRESTAB);
@@ -4008,6 +4013,7 @@ static int mptcp_connect(struct sock *sk
if (IS_ERR(ssk))
return PTR_ERR(ssk);
+ set_bit(MPTCP_RTX_ENABLED, &msk->flags);
mptcp_set_state(sk, TCP_SYN_SENT);
subflow = mptcp_subflow_ctx(ssk);
#ifdef CONFIG_TCP_MD5SIG
@@ -4155,6 +4161,7 @@ static int mptcp_listen(struct socket *s
goto unlock;
}
+ set_bit(MPTCP_RTX_ENABLED, &msk->flags);
mptcp_set_state(sk, TCP_LISTEN);
sock_set_flag(sk, SOCK_RCU_FREE);
--- a/net/mptcp/protocol.h
+++ b/net/mptcp/protocol.h
@@ -116,6 +116,7 @@
#define MPTCP_WORK_RTX 1
#define MPTCP_FALLBACK_DONE 2
#define MPTCP_WORK_CLOSE_SUBFLOW 3
+#define MPTCP_RTX_ENABLED 4
/* MPTCP socket release cb flags */
#define MPTCP_PUSH_PENDING 1
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 613/733] mptcp: options: handle MPC data + csum reqd + no csum
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (611 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 612/733] mptcp: do not reschedule the RTX timer for fallback sockets Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 614/733] mptcp: subflow: no need to copy thmac during ulp_clone Greg Kroah-Hartman
` (131 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mat Martineau,
Matthieu Baerts (NGI0), Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit ab36b1a80942c78ddb04d006ff38aa7ed3ec0e5e upstream.
Before this modification, a remote peer could send an MP_CAPABLE with
data, with the checksum flag set, but without adding the actual 2 bytes
of checksum. As a result, uninitialised bytes could be used for the
'csum' field.
That was not a critical issue, because this 'csum' field is only used to
compare with the expected one, if previously negotiated in the 3WHS.
Worst case, the checksum is likely wrong, a fallback is done without a
reject if the negotiation was done earlier. That's OK.
Yet, better to take the expected path with this case: only look at the
checksum flag for MP_CAPABLEs not carrying a data-len.
Such packet can be seen as a 3rd or 4th ACK. The RFC8684 mentions [1]
that the 3rd packet should have the checksum flag set. When an MPC + ACK
contains data, the checksum flag is redundant with the checksum field.
It is not clear what should be done for the 4th ACK, nor if the flag has
to be set if the checksum field is set.
Therefore, it seems fine to only look at the presence of the checksum
field, not to break the interaction with stacks that were not setting
both.
Note that linked to this checksum flag on the 3rd ACK, with the current
implementation, we can have a situation where the SYN packets have no
checksum flag, but the 3rd ACK has one, and this is the one that will be
taken into account. First, that's clearly not directly linked to this
patch, but Clashiko forced us to look at that. At the end, that seems
fine to act like that: yes that's not how the negotiation should work,
but being flexible without introducing side effects is also fine: fixing
this would mean increasing the complexity, and that's not worth it.
Fixes: 208e8f66926c ("mptcp: receive checksum for MP_CAPABLE with data")
Cc: stable@vger.kernel.org
Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.1-23 [1]
Closes: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-0-b8f496d71664%40kernel.org?part=1
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-5-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/options.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -93,7 +93,8 @@ static void mptcp_parse_option(const str
* In other words, the only way for checksums not to be used
* is if both hosts in their SYNs set A=0."
*/
- if (flags & MPTCP_CAP_CHECKSUM_REQD)
+ if ((flags & MPTCP_CAP_CHECKSUM_REQD) &&
+ opsize < TCPOLEN_MPTCP_MPC_ACK_DATA)
mp_opt->suboptions |= OPTION_MPTCP_CSUMREQD;
mp_opt->deny_join_id0 = !!(flags & MPTCP_CAP_DENY_JOIN_ID0);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 614/733] mptcp: subflow: no need to copy thmac during ulp_clone
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (612 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 613/733] mptcp: options: handle MPC data + csum reqd + no csum Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 615/733] mptcp: syncookies: remember the request backup flag Greg Kroah-Hartman
` (130 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit 29f641951be0d91036d77edf677807f1447dbe65 upstream.
'thmac' is not used after that point.
Indeed, subflow_ulp_clone() is called when the request on the passive
side is over, so when the truncated HMAC is no longer needed.
Note that in case of SYN cookies, thmac will not be initialised. So
better to remove it to avoid a warning from debug tools like KMSAN for
reading uninitialised data.
Fixes: f296234c98a8 ("mptcp: Add handling of incoming MP_JOIN requests")
Cc: stable@vger.kernel.org
Reviewed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-2-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/subflow.c | 1 -
1 file changed, 1 deletion(-)
--- a/net/mptcp/subflow.c
+++ b/net/mptcp/subflow.c
@@ -2074,7 +2074,6 @@ static void subflow_ulp_clone(const stru
new_ctx->request_bkup = subflow_req->request_bkup;
WRITE_ONCE(new_ctx->remote_id, subflow_req->remote_id);
new_ctx->token = subflow_req->token;
- new_ctx->thmac = subflow_req->thmac;
/* the subflow req id is valid, fetched via subflow_check_req()
* and subflow_token_join_request()
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 615/733] mptcp: syncookies: remember the request backup flag
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (613 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 614/733] mptcp: subflow: no need to copy thmac during ulp_clone Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 616/733] mptcp: options: fix uninit-value in mptcp_write_data_fin Greg Kroah-Hartman
` (129 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit b76c0e28b392620dfbaf92cdeedbf115820b44cb upstream.
Instead of using an uninitialised bit when copying the info in
subflow_ulp_clone().
To fix this, no need to extend the join_entry structure: backup is
coming from struct mptcp_subflow_request_sock, only one bit. Do the same
here by using one bit for both.
Fixes: efd340bf3d77 ("mptcp: distinguish rcv vs sent backup flag in requests")
Cc: stable@vger.kernel.org
Reviewed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-3-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/syncookies.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/net/mptcp/syncookies.c
+++ b/net/mptcp/syncookies.c
@@ -26,7 +26,8 @@ struct join_entry {
u32 local_nonce;
u8 join_id;
u8 local_id;
- u8 backup;
+ u8 backup:1,
+ request_bkup:1;
u8 valid;
};
@@ -63,6 +64,7 @@ static void mptcp_join_store_state(struc
entry->remote_nonce = subflow_req->remote_nonce;
entry->local_nonce = subflow_req->local_nonce;
entry->backup = subflow_req->backup;
+ entry->request_bkup = subflow_req->request_bkup;
entry->join_id = subflow_req->remote_id;
entry->local_id = subflow_req->local_id;
entry->valid = 1;
@@ -117,6 +119,7 @@ bool mptcp_token_join_cookie_init_state(
subflow_req->remote_nonce = e->remote_nonce;
subflow_req->local_nonce = e->local_nonce;
subflow_req->backup = e->backup;
+ subflow_req->request_bkup = e->request_bkup;
subflow_req->remote_id = e->join_id;
subflow_req->local_id = e->local_id;
subflow_req->token = e->token;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 616/733] mptcp: options: fix uninit-value in mptcp_write_data_fin
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (614 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 615/733] mptcp: syncookies: remember the request backup flag Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 617/733] selftests: mptcp: fix an UAF in mptcp_connect.c Greg Kroah-Hartman
` (128 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit b110f1dd6cb6a9930503354a01a315e0a821eaa7 upstream.
When sending a DATA_FIN without data, and because the DATA_FIN occupies
1 octet of the connection-level sequence space [1], it is then required
to add a DSS mapping with specific values.
If the checksum has been negotiated, it also needs to be computed, and
included in the outgoing packet, and thus the initial csum data needs to
be reset to 0 as well. This is no longer the case since commit
cfcceb7a39fc ("tcp: shrink per-packet memset in __tcp_transmit_skb()"),
because the whole ext_copy structure is no longer zeroed by default.
This seems to be the only case where use_map is changed and set
afterwards, so initialising the csum field only in this case, along with
other fields for this specific case.
Fixes: cfcceb7a39fc ("tcp: shrink per-packet memset in __tcp_transmit_skb()")
Cc: stable@vger.kernel.org
Link: https://datatracker.ietf.org/doc/html/rfc8684#section-3.3.3 [1]
Link: https://sashiko.dev/#/patchset/20260812-net-next-mptcp-misc-feat-7-3-v1-0-1905a818f6cb%40kernel.org?part=2
Reviewed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-13-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/options.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/net/mptcp/options.c b/net/mptcp/options.c
index 196a46e7467d..ce0de02f5a3a 100644
--- a/net/mptcp/options.c
+++ b/net/mptcp/options.c
@@ -612,6 +612,7 @@ static void mptcp_write_data_fin(struct mptcp_subflow_context *subflow,
ext->data_seq = data_fin_tx_seq;
ext->subflow_seq = 0;
ext->data_len = 1;
+ ext->csum = 0;
} else if (ext->data_seq + ext->data_len == data_fin_tx_seq) {
/* If there's an existing DSS mapping and it is the
* final mapping, DATA_FIN consumes 1 additional byte of
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 617/733] selftests: mptcp: fix an UAF in mptcp_connect.c
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (615 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 616/733] mptcp: options: fix uninit-value in mptcp_write_data_fin Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 618/733] selftests: mptcp: lib: dump nstat for the right test Greg Kroah-Hartman
` (127 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Gang Yan,
Matthieu Baerts (NGI0), Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gang Yan <yangang@kylinos.cn>
commit 730444f094b12052916ebd7e14fe57bc3d47bf38 upstream.
At the end of 'sock_connect_mptcp()', it calls 'freeaddrinfo(addr)',
the 'peer' pointer (which points into 'addr') remains. Later, the main
loop uses this peer pointer for reconnection attempts. If the memory has
been freed and reused, the address data could be overwritten, resulting
in an invalid remote address.
This patch keeps the addrinfo list allocated for the whole process
lifetime so "peer" remains valid across reconnects; the memory will be
released at exit() time.
Fixes: 05be5e273c84 ("selftests: mptcp: add disconnect tests")
Cc: stable@vger.kernel.org
Suggested-by: Paolo Abeni <pabeni@redhat.com>
Signed-off-by: Gang Yan <yangang@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-7-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/testing/selftests/net/mptcp/mptcp_connect.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/tools/testing/selftests/net/mptcp/mptcp_connect.c
+++ b/tools/testing/selftests/net/mptcp/mptcp_connect.c
@@ -381,6 +381,9 @@ static int sock_connect_mptcp(const char
hints.ai_family = pf;
+ /* Keep the resolved address alive for the whole execution: it is
+ * used again when reconnecting, and will be released at exit time.
+ */
xgetaddrinfo(remoteaddr, port, &hints, &addr);
for (a = addr; a; a = a->ai_next) {
sock = socket(a->ai_family, a->ai_socktype, proto);
@@ -421,7 +424,6 @@ static int sock_connect_mptcp(const char
sock = -1;
}
- freeaddrinfo(addr);
if (sock != -1)
SOCK_TEST_TCPULP(sock, proto);
return sock;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 618/733] selftests: mptcp: lib: dump nstat for the right test
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (616 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 617/733] selftests: mptcp: fix an UAF in mptcp_connect.c Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 619/733] selftests: mptcp: lib: get counters " Greg Kroah-Hartman
` (126 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit e1a56368eac18b3b4b956b794526e8713c48a0ec upstream.
In case of errors, mptcp_lib_pr_nstat is called to dump the nstat
counters, but for some tests, it was dumping the counters for all
subtests, not just the current one.
That's an issue for tests that don't recreate the netns for each
subtest, e.g. mptcp_connect.sh. In this case, 'nstat -a' will look at
the absolute counters since the creation of the netns, making
debugging harder.
Instead, it should dump the counters for the current test, by using the
history recorded in /tmp/<ns>.nstat if available, and not using '-a'
which was dumping the absolute values instead of calculating increments.
While at it, rename the previous 'hist' variable to 'cache' as it was
used to look at the cache, not the nstat history.
Fixes: 658e53141780 ("selftests: mptcp: join: dump stats from history")
Cc: stable@vger.kernel.org
Reviewed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-11-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 10 ++++++----
1 file changed, 6 insertions(+), 4 deletions(-)
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -108,12 +108,14 @@ mptcp_lib_pr_info() {
mptcp_lib_pr_nstat() {
local ns="${1}"
- local hist="/tmp/${ns}.out"
+ local cache="/tmp/${ns}.out"
+ local hist="/tmp/${ns}.nstat"
- if [ -f "${hist}" ]; then
- awk '$2 != 0 { print " "$0 }' "${hist}"
+ if [ -f "${cache}" ]; then
+ awk '$2 != 0 { print " "$0 }' "${cache}"
else
- ip netns exec "${ns}" nstat -as | grep Tcp
+ NSTAT_HISTORY="${hist}" ip netns exec "${ns}" nstat -s |
+ grep Tcp
fi
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 619/733] selftests: mptcp: lib: get counters for the right test
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (617 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 618/733] selftests: mptcp: lib: dump nstat for the right test Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 620/733] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
` (125 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Geliang Tang, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit d23c41366e85f149b48323d66adc36c4a9f18cbd upstream.
When the value for a MIB counter is required, mptcp_lib_get_counter is
called. It tries to use the cache, if available. If not it falls back to
calling 'nstat' directly by looking at the absolute counters.
That's an issue for tests that don't recreate the netns for each
subtest. In this case, 'nstat -a' will look at the counters for the
netns.
Instead, it should look at the increment for the current test, by using
the history recorded in /tmp/<ns>.nstat, if available, and not using
'-a' which was dumping the absolute values.
While at it, rename the previous 'hist' variable to 'cache' as it was
used to look at the cache, not the nstat history.
Fixes: 71388a9f331d ("selftests: mptcp: lib: get counters from nstat history")
Cc: stable@vger.kernel.org
Reviewed-by: Geliang Tang <geliang@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-12-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
tools/testing/selftests/net/mptcp/mptcp_lib.sh | 16 +++++++++-------
1 file changed, 9 insertions(+), 7 deletions(-)
diff --git a/tools/testing/selftests/net/mptcp/mptcp_lib.sh b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
index da1da414c30f..b9d14647f401 100644
--- a/tools/testing/selftests/net/mptcp/mptcp_lib.sh
+++ b/tools/testing/selftests/net/mptcp/mptcp_lib.sh
@@ -416,19 +416,21 @@ mptcp_lib_nstat_get() {
}
# $1: ns, $2: MIB counter
-# Get the counter from the history (mptcp_lib_nstat_{init,get}()) if available.
-# If not, get the counter from nstat ignoring any history.
+# Get the counter from the cache (mptcp_lib_nstat_{init,get}()) if available.
+# If not, get the counter from nstat ignoring any cache, but using the history.
mptcp_lib_get_counter() {
local ns="${1}"
local counter="${2}"
- local hist="/tmp/${ns}.out"
+ local cache="/tmp/${ns}.out"
+ local hist="/tmp/${ns}.nstat"
local count
- if [[ -s "${hist}" && "${counter}" == *"Tcp"* ]]; then
- count=$(awk "/^${counter} / {print \$2; exit}" "${hist}")
+ if [[ -s "${cache}" && "${counter}" == *"Tcp"* ]]; then
+ count=$(awk "/^${counter} / {print \$2; exit}" "${cache}")
else
- count=$(ip netns exec "${ns}" nstat -asz "${counter}" |
- awk 'NR==1 {next} {print $2}')
+ count=$(NSTAT_HISTORY="${hist}" ip netns exec "${ns}" \
+ nstat -sz "${counter}" |
+ awk 'NR==1 {next} {print $2}')
fi
if [ -z "${count}" ]; then
mptcp_lib_fail_if_expected_feature "${counter} counter"
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 620/733] mptcp: prevent race between disconnect() and rtx
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (618 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 619/733] selftests: mptcp: lib: get counters " Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 621/733] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0 Greg Kroah-Hartman
` (124 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paolo Abeni, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paolo Abeni <pabeni@redhat.com>
commit 85c580b0d8590520ae00a15c29e9fb9c99427a3e upstream.
Sashiko noted that the two event can race, leading to inconsistent
status. Prevent the race using the synchronous timer stop operation.
Cc: stable@vger.kernel.org
Fixes: b29fcfb54cd7 ("mptcp: full disconnect implementation")
Signed-off-by: Paolo Abeni <pabeni@redhat.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-6-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/protocol.c | 10 ++++++++--
1 file changed, 8 insertions(+), 2 deletions(-)
--- a/net/mptcp/protocol.c
+++ b/net/mptcp/protocol.c
@@ -3456,6 +3456,7 @@ static void mptcp_destroy_common(struct
static int mptcp_disconnect(struct sock *sk, int flags)
{
+ struct inet_connection_sock *icsk = inet_csk(sk);
struct mptcp_sock *msk = mptcp_sk(sk);
/* We are on the fastopen error path. We can't call straight into the
@@ -3468,8 +3469,13 @@ static int mptcp_disconnect(struct sock
mptcp_check_listen_stop(sk);
mptcp_set_state(sk, TCP_CLOSE);
- mptcp_stop_rtx_timer(sk);
- mptcp_stop_tout_timer(sk);
+ /* The later subflow close can not kick again the tout timer,
+ * as the msk is already in closed status.
+ */
+ msk->timer_ival = icsk->icsk_rto_min;
+ sk_stop_timer_sync(sk, &sk->mptcp_retransmit_timer);
+ icsk->icsk_mtup.probe_timestamp = 0;
+ sk_stop_timer_sync(sk, &icsk->mptcp_tout_timer);
mptcp_pm_connection_closed(msk);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 621/733] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (619 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 620/733] mptcp: prevent race between disconnect() and rtx Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 622/733] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
` (123 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, syzbot+55c2a5c871441261ed14, Tao Cui,
Kalpan Jani, Matthieu Baerts (NGI0), Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
commit 2ac7d6e620764f1fc79eb4edd3610a7a661981ca upstream.
The in-kernel MPTCP path manager can leave a stale ADD_ADDR announcement
entry alive when removing the id 0 endpoint. This happens because the id 0
removal path does not tear down pending announcements, unlike the non-zero
id path.
When the PM later reselects id 0 after adding another signal endpoint, it
finds the stale anno_list entry and hits WARN_ON_ONCE(mptcp_pm_is_kernel())
in mptcp_pm_announced_alloc().
Root cause: asymmetry between removal paths.
- Non-zero id path: mptcp_nl_remove_subflow_and_signal_addr() calls
mptcp_pm_remove_announced() to clean up.
- Id 0 path: mptcp_nl_remove_id_zero_address() skips cleanup entirely.
Fix by making the id 0 path symmetric: call mptcp_pm_announced_remove()
and decrement add_addr_signaled before queuing the RM_ADDR.
Subtle detail: signal endpoints are stored in anno_list with port 0, but
msk_local carries the connection's local port. In other words, entries
linked to ID0 paths should have port == 0. A follow-up patch will ensure
that. mptcp_pm_announced_remove() uses use_port=true for comparison. So
clear the port before the lookup.
Fixes: 740d798e8767 ("mptcp: remove id 0 address")
Cc: stable@vger.kernel.org
Reported-by: syzbot+55c2a5c871441261ed14@syzkaller.appspotmail.com
Closes: https://github.com/multipath-tcp/mptcp_net-next/issues/620
Suggested-by: Tao Cui <cuitao@kylinos.cn>
Signed-off-by: Kalpan Jani <kalpan.jani@mpiricsoftware.com>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-4-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/pm_kernel.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/net/mptcp/pm_kernel.c
+++ b/net/mptcp/pm_kernel.c
@@ -1137,6 +1137,8 @@ static int mptcp_nl_remove_id_zero_addre
while ((msk = mptcp_token_iter_next(net, &s_slot, &s_num)) != NULL) {
struct sock *sk = (struct sock *)msk;
struct mptcp_addr_info msk_local;
+ struct mptcp_addr_info anno_addr;
+ bool announced;
if (list_empty(&msk->conn_list) || mptcp_pm_is_userspace(msk))
goto next;
@@ -1146,7 +1148,13 @@ static int mptcp_nl_remove_id_zero_addre
goto next;
lock_sock(sk);
+ /* Drop a possibly pending ADD_ADDR for this address. */
+ anno_addr = msk_local;
+ anno_addr.port = 0;
+ announced = mptcp_pm_announced_remove(msk, &anno_addr);
spin_lock_bh(&msk->pm.lock);
+ if (announced)
+ msk->pm.add_addr_signaled--;
mptcp_pm_remove_addr(msk, &list);
mptcp_pm_rm_subflow(msk, &list);
__mark_subflow_endp_available(msk, 0);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 622/733] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (620 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 621/733] mptcp: pm: kernel: drop pending ADD_ADDR when removing ID0 Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 623/733] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
` (122 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mat Martineau,
Matthieu Baerts (NGI0), Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthieu Baerts (NGI0) <matttbe@kernel.org>
commit f968190c0b42ea2004dc1426359a53ec365a7a37 upstream.
When an ADD_ADDR entry is reused, the timer is re-armed, because the
goal is to re-announce an ADD_ADDR, and eventually retransmit it if
needed.
In this case, the retransmission counter should be reset as well, so the
re-announced address gets its retransmissions back instead of relying on
what was left before, and possibly not being able to retransmit it.
Fixes: 304ab97f4c7c ("mptcp: allow ADD_ADDR reissuance by userspace PMs")
Cc: stable@vger.kernel.org
Link: https://netdev-ai.bots.linux.dev/sashiko/#/patchset/20260803-net-mptcp-misc-fixes-7-2-rc6-v2-0-b8f496d71664%40kernel.org?part=4
Reviewed-by: Mat Martineau <martineau@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-9-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/pm.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/net/mptcp/pm.c
+++ b/net/mptcp/pm.c
@@ -462,10 +462,10 @@ bool mptcp_pm_announced_alloc(struct mpt
add_entry->addr = *addr;
add_entry->sock = msk;
- add_entry->retrans_times = 0;
timer_setup(&add_entry->timer, mptcp_pm_add_addr_timer, 0);
reset_timer:
+ add_entry->retrans_times = 0;
add_entry->timer_done = false;
timeout = mptcp_adjust_add_addr_timeout(msk);
if (timeout)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 623/733] mptcp: pm: userspace: fix address ID overflow
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (621 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 622/733] mptcp: pm: reset retrans_time when ADD_ADDR entry is reused Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 624/733] smb: client: reject short READ responses in CIFSSMBRead() Greg Kroah-Hartman
` (121 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Qing Luo, Matthieu Baerts (NGI0),
Jakub Kicinski
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qing Luo <luoqing@kylinos.cn>
commit f9f0068e8813d8c10d016b030fc3a320d0b6767c upstream.
When all MPTCP address IDs (1-255) are exhausted in the userspace PM,
find_next_zero_bit() returns MPTCP_PM_MAX_ADDR_ID + 1 (256). This value
overflows when stored in the u8 field e->addr.id, resulting in ID 0
being stored and the entry being incorrectly added to the list.
ID 0 is reserved for the initial connection in MPTCP, so this overflow
can cause address conflicts.
Note: the in-kernel PM already has an 'endpoints == MPTCP_PM_MAX_ADDR_ID'
check in mptcp_pm_nl_append_new_local_addr() that returns -ERANGE before
reaching find_next_zero_bit(), preventing this overflow. So this fix only
addresses the userspace PM path.
Check the find_next_zero_bit() result against MPTCP_PM_MAX_ADDR_ID and
return -ENOSPC if all IDs are truly exhausted. Move the ID allocation
check before the memory allocation so that the error path does not need
to free the allocated entry.
Fixes: 4638de5aefe5 ("mptcp: handle local addrs announced by userspace PMs")
Cc: stable@vger.kernel.org
Signed-off-by: Qing Luo <luoqing@kylinos.cn>
Reviewed-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Signed-off-by: Matthieu Baerts (NGI0) <matttbe@kernel.org>
Link: https://patch.msgid.link/20260908-net-mptcp-misc-fixes-7-3-rc1-v2-8-df1de70348b6@kernel.org
Signed-off-by: Jakub Kicinski <kuba@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
net/mptcp/pm_userspace.c | 18 ++++++++++++++----
1 file changed, 14 insertions(+), 4 deletions(-)
--- a/net/mptcp/pm_userspace.c
+++ b/net/mptcp/pm_userspace.c
@@ -69,6 +69,19 @@ static int mptcp_userspace_pm_append_new
}
if (!addr_match && !id_match) {
+ unsigned int id;
+
+ if (!entry->addr.id && needs_id) {
+ id = find_next_zero_bit(id_bitmap,
+ MPTCP_PM_MAX_ADDR_ID + 1, 1);
+ if (id > MPTCP_PM_MAX_ADDR_ID) {
+ ret = -ENOSPC;
+ goto append_err;
+ }
+ } else {
+ id = entry->addr.id;
+ }
+
/* Memory for the entry is allocated from the
* sock option buffer.
*/
@@ -78,10 +91,7 @@ static int mptcp_userspace_pm_append_new
goto append_err;
}
- if (!e->addr.id && needs_id)
- e->addr.id = find_next_zero_bit(id_bitmap,
- MPTCP_PM_MAX_ADDR_ID + 1,
- 1);
+ e->addr.id = id;
list_add_tail_rcu(&e->list, &msk->pm.userspace_pm_local_addr_list);
msk->pm.local_addr_used++;
ret = e->addr.id;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 624/733] smb: client: reject short READ responses in CIFSSMBRead()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (622 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 623/733] mptcp: pm: userspace: fix address ID overflow Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 625/733] smb: client: reject userspace cifs.idmap descriptions Greg Kroah-Hartman
` (120 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Paulo Alcantara, Diego Oliva,
David Howells
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diego Oliva <diego@bynar.io>
commit e6142a8bfc230c7263eb8b0475249c958ce49367 upstream.
CIFSSMBRead() reads DataLengthHigh, DataLength and DataOffset out of
the READ_RSP returned by the server without first checking that a
whole READ_RSP was actually received. The length of the response is
recorded in rsp_iov.iov_len, but nothing constrains it to be at least
read_rsp_size before those fields are dereferenced.
A malicious or compromised SMB1 server can return a response shorter
than the READ_RSP header, so that parsing the header itself reads past
the end of the receive buffer. SMB1 is not negotiated by default;
reaching this code requires an explicit vers=1.0 mount.
Reject the response unless it is at least read_rsp_size bytes long.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Suggested-by: Paulo Alcantara <pc@manguebit.org>
Cc: stable@vger.kernel.org # 6.19.x
Assisted-by: Bynario AI
Signed-off-by: Diego Oliva <diego@bynar.io>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cifssmb.c | 8 ++++++++
1 file changed, 8 insertions(+)
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -1719,6 +1719,14 @@ CIFSSMBRead(const unsigned int xid, stru
pSMBr = (READ_RSP *)rsp_iov.iov_base;
if (rc) {
cifs_dbg(VFS, "Send error in read = %d\n", rc);
+ } else if (rsp_iov.iov_len < tcon->ses->server->vals->read_rsp_size) {
+ /* check that the received response can hold a whole READ_RSP */
+ cifs_dbg(FYI, "%s: server returned short header. got=%zu expected=%zu\n",
+ __func__, rsp_iov.iov_len,
+ tcon->ses->server->vals->read_rsp_size);
+ rc = smb_EIO2(smb_eio_trace_read_rsp_short,
+ rsp_iov.iov_len, tcon->ses->server->vals->read_rsp_size);
+ *nbytes = 0;
} else {
int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
data_length = data_length << 16;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 625/733] smb: client: reject userspace cifs.idmap descriptions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (623 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 624/733] smb: client: reject short READ responses in CIFSSMBRead() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 626/733] smb: client: reject out-of-bounds DataOffset in CIFSSMBRead() Greg Kroah-Hartman
` (119 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, TencentOS Corvus AI, Aohan Mei,
David Howells, Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aohan Mei <henrymei@tencent.com>
commit d9d7eeb0cea5b55b82888f443622fd8d4ee064f3 upstream.
cifs.idmap key descriptions carry authority-bearing fields (owner and
group SIDs and uid/gid values in "os:"/"gs:"/"oi:"/"gi:" form) that the
cifs.idmap upcall helper treats as kernel-originating inputs. Unlike
its sibling cifs.spnego, the cifs.idmap key type has no vet_description
hook, so userspace can create keys of this type through
request_key(2)/add_key(2) and supply those fields without CIFS origin.
A request_key(2) call with a non-NULL callout then drives a root
usermodehelper upcall (/sbin/request-key -> cifs.idmap) that consumes
the unvetted description in root context.
Only accept cifs.idmap descriptions while CIFS is using its private
root_cred to request the key. id_to_sid()/sid_to_id() already run
under override_creds(root_cred), so the kernel-originated path is
unaffected.
This mirrors commit 3da1fdf4efbc ("smb: client: reject userspace
cifs.spnego descriptions"), which applied the same restriction to
cifs.spnego.
Fixes: 4d79dba0e007 ("cifs: Add idmap key and related data structures and functions (try #17 repost)")
Reported-by: TencentOS Corvus AI <corvus@tencent.com>
Cc: stable@vger.kernel.org
Assisted-by: CodeBuddy:Kimi-K3
Signed-off-by: Aohan Mei <henrymei@tencent.com>
Acked-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cifsacl.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -100,8 +100,23 @@ cifs_idmap_key_destroy(struct key *key)
kfree(key->payload.data[0]);
}
+static int
+cifs_idmap_key_vet_description(const char *description)
+{
+ /*
+ * cifs.idmap descriptions are authority-bearing inputs to the
+ * cifs.idmap upcall helper. Only allow the kernel to create this
+ * type of key using the private root_cred installed in
+ * init_cifs_idmap; reject userspace request_key(2)/add_key(2).
+ */
+ if (current_cred() != root_cred)
+ return -EPERM;
+ return 0;
+}
+
static struct key_type cifs_idmap_key_type = {
.name = "cifs.idmap",
+ .vet_description = cifs_idmap_key_vet_description,
.instantiate = cifs_idmap_key_instantiate,
.destroy = cifs_idmap_key_destroy,
.describe = user_describe,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 626/733] smb: client: reject out-of-bounds DataOffset in CIFSSMBRead()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (624 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 625/733] smb: client: reject userspace cifs.idmap descriptions Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 627/733] smb: client: pin DFS superblock in iterator callback Greg Kroah-Hartman
` (118 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Diego Oliva, David Howells,
Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Diego Oliva <diego@bynar.io>
commit 5be5bdda5863eacc964b609ba927764f253431b3 upstream.
The SMB1 synchronous read helper CIFSSMBRead() validates the server's
DataLength against CIFSMaxBufSize and the caller's count, but never
validates DataOffset. The copy source is formed as
&pSMBr->hdr.Protocol + le16_to_cpu(pSMBr->DataOffset)
and memcpy()'d for DataLength bytes with no check that the
[DataOffset, DataOffset + DataLength) range lies within the response
actually received from the server.
A malicious or compromised SMB1 server can return a response carrying
an in-range DataLength and a large DataOffset, driving the source
pointer past the end of the response buffer. The memcpy() then copies
adjacent kernel heap into the caller's read buffer (information
disclosure), or reads unmapped memory and oopses (denial of service).
SMB1 is not negotiated by default; reaching this code requires an
explicit vers=1.0 mount.
Both DataOffset and the received response length recorded in
rsp_iov.iov_len are relative to the start of the SMB header, so reject
the response unless DataOffset + DataLength fits within that length,
using overflow-safe arithmetic, before forming the source pointer.
The response length has been validated by the previous patch, so the
DataOffset and DataLength fields can be read safely here.
While here, make data_length unsigned. It holds a length derived from
unsigned on-the-wire fields and is only ever compared against unsigned
quantities; print it with %u accordingly, and add __func__ to the
cifs_dbg() calls in this function.
Fixes: 1da177e4c3f4 ("Linux-2.6.12-rc2")
Cc: stable@vger.kernel.org # 6.19.x
Assisted-by: Bynario AI
Signed-off-by: Diego Oliva <diego@bynar.io>
Reviewed-by: David Howells <dhowells@redhat.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cifssmb.c | 18 +++++++++++++-----
fs/smb/client/trace.h | 1 +
2 files changed, 14 insertions(+), 5 deletions(-)
diff --git a/fs/smb/client/cifssmb.c b/fs/smb/client/cifssmb.c
index be13ab37039d..f9aff0712794 100644
--- a/fs/smb/client/cifssmb.c
+++ b/fs/smb/client/cifssmb.c
@@ -1728,7 +1728,8 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
rsp_iov.iov_len, tcon->ses->server->vals->read_rsp_size);
*nbytes = 0;
} else {
- int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
+ unsigned int data_length = le16_to_cpu(pSMBr->DataLengthHigh);
+ __u16 data_offset = le16_to_cpu(pSMBr->DataOffset);
data_length = data_length << 16;
data_length += le16_to_cpu(pSMBr->DataLength);
*nbytes = data_length;
@@ -1736,14 +1737,21 @@ CIFSSMBRead(const unsigned int xid, struct cifs_io_parms *io_parms,
/*check that DataLength would not go beyond end of SMB */
if ((data_length > CIFSMaxBufSize)
|| (data_length > count)) {
- cifs_dbg(FYI, "bad length %d for count %d\n",
- data_length, count);
+ cifs_dbg(FYI, "%s: bad length %u for count %u\n",
+ __func__, data_length, count);
rc = smb_EIO2(smb_eio_trace_read_overlarge,
data_length, count);
*nbytes = 0;
+ } else if (data_offset < sizeof(*pSMBr) ||
+ (size_t)data_offset + data_length > rsp_iov.iov_len) {
+ /* check that the data lies within the received response */
+ cifs_dbg(FYI, "%s: bad data offset %u length %u for response of %zu\n",
+ __func__, data_offset, data_length, rsp_iov.iov_len);
+ rc = smb_EIO2(smb_eio_trace_read_bad_offset,
+ data_offset, data_length);
+ *nbytes = 0;
} else {
- pReadData = (char *) (&pSMBr->hdr.Protocol) +
- le16_to_cpu(pSMBr->DataOffset);
+ pReadData = (char *) (&pSMBr->hdr.Protocol) + data_offset;
/* if (rc = copy_to_user(buf, pReadData, data_length)) {
cifs_dbg(VFS, "Faulting on read rc = %d\n",rc);
rc = -EFAULT;
diff --git a/fs/smb/client/trace.h b/fs/smb/client/trace.h
index 12241abb8e2e..b442cccd1530 100644
--- a/fs/smb/client/trace.h
+++ b/fs/smb/client/trace.h
@@ -79,6 +79,7 @@
EM(smb_eio_trace_qreparse_setup_count, "qreparse_setup_count") \
EM(smb_eio_trace_qreparse_sizes_wrong, "qreparse_sizes_wrong") \
EM(smb_eio_trace_qsym_bcc_too_small, "qsym_bcc_too_small") \
+ EM(smb_eio_trace_read_bad_offset, "read_bad_offset") \
EM(smb_eio_trace_read_mid_state_unknown, "read_mid_state_unknown") \
EM(smb_eio_trace_read_overlarge, "read_overlarge") \
EM(smb_eio_trace_read_rsp_malformed, "read_rsp_malformed") \
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 627/733] smb: client: pin DFS superblock in iterator callback
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (625 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 626/733] smb: client: reject out-of-bounds DataOffset in CIFSSMBRead() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 628/733] smb: client: honor forceuid/forcegid when mapping SIDs to uid/gid Greg Kroah-Hartman
` (117 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Karl Mehltretter, Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Karl Mehltretter <kmehltretter@gmail.com>
commit d806d5a85dcbe2a0f181b2f0f9f61ddfbefa1818 upstream.
tcon_super_cb() stores a raw superblock pointer, but __cifs_get_super()
takes its active reference only after iterate_supers_type() has dropped
s_umount and its passive reference. Concurrent DFS automount expiry can
therefore free the superblock before cifs_sb_active() uses it.
A deterministic KASAN test reproduces the race as:
BUG: KASAN: slab-use-after-free in cifs_sb_active+0x77/0x80
The same test passes with this change applied.
Take the active reference in the callback while iterate_supers_type()
still holds s_umount shared. cifs_put_tcp_super() remains the matching
release.
Fixes: bacd704a95ad ("cifs: handle prefix paths in reconnect")
Cc: stable@vger.kernel.org
Assisted-by: LLM
Signed-off-by: Karl Mehltretter <kmehltretter@gmail.com>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/misc.c | 17 ++++++++---------
1 file changed, 8 insertions(+), 9 deletions(-)
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -891,8 +891,14 @@ static void tcon_super_cb(struct super_b
t1->ses->dfs_root_ses == t2->ses->dfs_root_ses) &&
t1->ses->server == t2->ses->server &&
t2->origin_fullpath &&
- dfs_src_pathname_equal(t2->origin_fullpath, t1->origin_fullpath))
+ dfs_src_pathname_equal(t2->origin_fullpath, t1->origin_fullpath)) {
+ /*
+ * Take the active reference while iterate_supers_type() still
+ * holds s_umount shared.
+ */
+ cifs_sb_active(sb);
sd->sb = sb;
+ }
spin_unlock(&t2->tc_lock);
}
@@ -909,15 +915,8 @@ static struct super_block *__cifs_get_su
for (; *fs_type; fs_type++) {
iterate_supers_type(*fs_type, f, &sd);
- if (sd.sb) {
- /*
- * Grab an active reference in order to prevent automounts (DFS links)
- * of expiring and then freeing up our cifs superblock pointer while
- * we're doing failover.
- */
- cifs_sb_active(sd.sb);
+ if (sd.sb)
return sd.sb;
- }
}
pr_warn_once("%s: could not find dfs superblock\n", __func__);
return ERR_PTR(-EINVAL);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 628/733] smb: client: honor forceuid/forcegid when mapping SIDs to uid/gid
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (626 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 627/733] smb: client: pin DFS superblock in iterator callback Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 629/733] smb: client: fix WSL reparse point uid/gid override Greg Kroah-Hartman
` (116 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit 18a72975e9f35aadecc75b031f693f2d1f49308f upstream.
When the administrator mounts with forceuid or forcegid (uid=/gid=
mount options), they expect all files to appear owned by the specified
user/group. However, several code paths unconditionally called
sid_to_id() to overwrite cf_uid/cf_gid with server-provided values,
ignoring the administrator's explicit override:
- smb311_posix_info_to_fattr() (stat via POSIX extensions)
- cifs_posix_to_fattr() (readdir via POSIX extensions)
- parse_sec_desc() (CIFS ACL ownership mapping)
This allowed an untrusted server to dictate local file ownership even
when the mount was configured to force specific uid/gid values.
Fix all three call sites to check CIFS_MOUNT_OVERR_UID and
CIFS_MOUNT_OVERR_GID before calling sid_to_id(), following the
same pattern already used by cifs_unix_basic_to_fattr() for unix
extensions.
Closes: https://sashiko.dev/#/patchset/20260906155816.603278-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cifsacl.c | 29 ++++++++++++++++++-----------
fs/smb/client/inode.c | 9 +++++++--
fs/smb/client/readdir.c | 9 +++++++--
3 files changed, 32 insertions(+), 15 deletions(-)
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1346,6 +1346,7 @@ static int parse_sec_desc(struct cifs_sb
{
int rc = 0;
struct smb_sid *owner_sid_ptr, *group_sid_ptr;
+ unsigned int sbflags = cifs_sb_flags(cifs_sb);
struct smb_acl *dacl_ptr; /* no need for SACL ptr */
char *end_of_acl;
__u32 dacloffset, osidoffset, gsidoffset;
@@ -1364,17 +1365,21 @@ static int parse_sec_desc(struct cifs_sb
cifs_dbg(NOISY, "revision %d type 0x%x ooffset 0x%x goffset 0x%x sacloffset 0x%x dacloffset 0x%x\n",
pntsd->revision, pntsd->type, osidoffset, gsidoffset,
le32_to_cpu(pntsd->sacloffset), dacloffset);
-/* cifs_dump_mem("owner_sid: ", owner_sid_ptr, 64); */
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
+
rc = sid_from_sd(pntsd, acl_len, osidoffset, &owner_sid_ptr);
if (rc) {
cifs_dbg(FYI, "%s: Error %d parsing Owner SID\n", __func__, rc);
return rc;
}
- rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
- if (rc) {
- cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
- __func__, rc);
- return rc;
+ if (!(sbflags & CIFS_MOUNT_OVERR_UID)) {
+ rc = sid_to_id(cifs_sb, owner_sid_ptr, fattr, SIDOWNER);
+ if (rc) {
+ cifs_dbg(FYI, "%s: Error %d mapping Owner SID to uid\n",
+ __func__, rc);
+ return rc;
+ }
}
rc = sid_from_sd(pntsd, acl_len, gsidoffset, &group_sid_ptr);
@@ -1383,11 +1388,13 @@ static int parse_sec_desc(struct cifs_sb
__func__, rc);
return rc;
}
- rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
- if (rc) {
- cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
- __func__, rc);
- return rc;
+ if (!(sbflags & CIFS_MOUNT_OVERR_GID)) {
+ rc = sid_to_id(cifs_sb, group_sid_ptr, fattr, SIDGROUP);
+ if (rc) {
+ cifs_dbg(FYI, "%s: Error %d mapping Group SID to gid\n",
+ __func__, rc);
+ return rc;
+ }
}
if (dacloffset) {
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -851,6 +851,7 @@ static void smb311_posix_info_to_fattr(s
struct smb311_posix_qinfo *info = &data->posix_fi;
struct cifs_sb_info *cifs_sb = CIFS_SB(sb);
struct cifs_tcon *tcon = cifs_sb_master_tcon(cifs_sb);
+ unsigned int sbflags = cifs_sb_flags(cifs_sb);
memset(fattr, 0, sizeof(*fattr));
@@ -895,8 +896,12 @@ out_reparse:
fattr->cf_symlink_target = data->symlink_target;
data->symlink_target = NULL;
}
- sid_to_id(cifs_sb, &data->posix_owner, fattr, SIDOWNER);
- sid_to_id(cifs_sb, &data->posix_group, fattr, SIDGROUP);
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
+ if (!(sbflags & CIFS_MOUNT_OVERR_UID))
+ sid_to_id(cifs_sb, &data->posix_owner, fattr, SIDOWNER);
+ if (!(sbflags & CIFS_MOUNT_OVERR_GID))
+ sid_to_id(cifs_sb, &data->posix_group, fattr, SIDGROUP);
cifs_dbg(FYI, "POSIX query info: mode 0x%x uniqueid 0x%llx nlink %d\n",
fattr->cf_mode, fattr->cf_uniqueid, fattr->cf_nlink);
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -242,6 +242,7 @@ static void
cifs_posix_to_fattr(struct cifs_fattr *fattr, struct smb2_posix_info *info,
struct cifs_sb_info *cifs_sb)
{
+ unsigned int sbflags = cifs_sb_flags(cifs_sb);
struct smb2_posix_info_parsed parsed;
posix_info_parse(info, NULL, &parsed);
@@ -281,8 +282,12 @@ cifs_posix_to_fattr(struct cifs_fattr *f
le32_to_cpu(info->ReparseTag),
le32_to_cpu(info->Mode));
- sid_to_id(cifs_sb, &parsed.owner, fattr, SIDOWNER);
- sid_to_id(cifs_sb, &parsed.group, fattr, SIDGROUP);
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
+ if (!(sbflags & CIFS_MOUNT_OVERR_UID))
+ sid_to_id(cifs_sb, &parsed.owner, fattr, SIDOWNER);
+ if (!(sbflags & CIFS_MOUNT_OVERR_GID))
+ sid_to_id(cifs_sb, &parsed.group, fattr, SIDGROUP);
}
static void __dir_info_to_fattr(struct cifs_fattr *fattr, const void *info)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 629/733] smb: client: fix WSL reparse point uid/gid override
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (627 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 628/733] smb: client: honor forceuid/forcegid when mapping SIDs to uid/gid Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 630/733] smb: client: fix uid/gid override in getattr with posix extensions Greg Kroah-Hartman
` (115 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit cd2b2b57921d4caa7875e83198bb2aa71254328b upstream.
wsl_to_fattr() unconditionally overwrites cf_uid/cf_gid with values
from WSL extended attributes ($LXUID/$LXGID), ignoring the forceuid
and forcegid mount options.
Fix this by initializing cf_uid/cf_gid to the mount defaults and
gating the $LXUID/$LXGID EA parsing on forceuid/forcegid.
Closes: https://sashiko.dev/#/patchset/20260906190803.667489-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/reparse.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1137,10 +1137,14 @@ static bool wsl_to_fattr(struct cifs_ope
struct cifs_sb_info *cifs_sb,
u32 tag, struct cifs_fattr *fattr)
{
+ unsigned int sbflags = cifs_sb_flags(cifs_sb);
struct smb2_file_full_ea_info *ea;
bool have_xattr_dev = false;
u32 next = 0;
+ fattr->cf_uid = cifs_sb->ctx->linux_uid;
+ fattr->cf_gid = cifs_sb->ctx->linux_gid;
+
switch (tag) {
case IO_REPARSE_TAG_LX_SYMLINK:
fattr->cf_mode |= S_IFLNK;
@@ -1177,11 +1181,13 @@ static bool wsl_to_fattr(struct cifs_ope
nlen = ea->ea_name_length;
v = (void *)((u8 *)ea->ea_data + ea->ea_name_length + 1);
- if (!strncmp(name, SMB2_WSL_XATTR_UID, nlen))
- fattr->cf_uid = wsl_make_kuid(cifs_sb, v);
- else if (!strncmp(name, SMB2_WSL_XATTR_GID, nlen))
- fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
- else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
+ if (!strncmp(name, SMB2_WSL_XATTR_UID, nlen)) {
+ if (!(sbflags & CIFS_MOUNT_OVERR_UID))
+ fattr->cf_uid = wsl_make_kuid(cifs_sb, v);
+ } else if (!strncmp(name, SMB2_WSL_XATTR_GID, nlen)) {
+ if (!(sbflags & CIFS_MOUNT_OVERR_GID))
+ fattr->cf_gid = wsl_make_kgid(cifs_sb, v);
+ } else if (!strncmp(name, SMB2_WSL_XATTR_MODE, nlen)) {
/* File type in reparse point tag and in xattr mode must match. */
if (S_DT(fattr->cf_mode) != S_DT(le32_to_cpu(*(__le32 *)v)))
return false;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 630/733] smb: client: fix uid/gid override in getattr with posix extensions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (628 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 629/733] smb: client: fix WSL reparse point uid/gid override Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 631/733] smb: client: fix one-byte OOB read in smb2_parse_native_symlink() Greg Kroah-Hartman
` (114 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arthur Lesuisse, Namjae Jeon,
Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit cf4d35896621b7298eef51b7a465e5c0cb22f670 upstream.
When mounting with 'multiuser,posix' options, cifs_getattr() overrides
the server-provided uid/gid with the current process's fsuid/fsgid.
This is because the condition only checks for unix extensions
(tcon->unix_ext) but not posix extensions (tcon->posix_extensions).
With SMB3 POSIX extensions, the server provides real uid/gid values
just like with unix extensions, so they should be preserved rather
than replaced with the caller's credentials.
Add a tcon->posix_extensions check to the condition so that uid/gid
from the server are properly reported in stat results.
Reported-by: Arthur Lesuisse <arthur.lesuisse@ulb.be>
Closes: https://lore.kernel.org/r/DB9P190MB2012266F6B8DECBE5D26A1798DB52@DB9P190MB2012.EURP190.PROD.OUTLOOK.COM
Suggested-by: Arthur Lesuisse <arthur.lesuisse@ulb.be>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/inode.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
--- a/fs/smb/client/inode.c
+++ b/fs/smb/client/inode.c
@@ -2988,14 +2988,14 @@ int cifs_getattr(struct mnt_idmap *idmap
stat->attributes |= STATX_ATTR_ENCRYPTED;
/*
- * If on a multiuser mount without unix extensions or cifsacl being
- * enabled, and the admin hasn't overridden them, set the ownership
- * to the fsuid/fsgid of the current process.
+ * If on a multiuser mount without unix extensions, posix extensions
+ * or cifsacl being enabled, and the admin hasn't overridden them,
+ * set the ownership to the fsuid/fsgid of the current process.
*/
sbflags = cifs_sb_flags(cifs_sb);
if ((sbflags & CIFS_MOUNT_MULTIUSER) &&
!(sbflags & CIFS_MOUNT_CIFS_ACL) &&
- !tcon->unix_ext) {
+ !tcon->unix_ext && !tcon->posix_extensions) {
if (!(sbflags & CIFS_MOUNT_OVERR_UID))
stat->uid = current_fsuid();
if (!(sbflags & CIFS_MOUNT_OVERR_GID))
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 631/733] smb: client: fix one-byte OOB read in smb2_parse_native_symlink()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (629 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 630/733] smb: client: fix uid/gid override in getattr with posix extensions Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 632/733] smb: client: fail DACL rewrite when the new DACL exceeds 64K Greg Kroah-Hartman
` (113 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Yuanfu Xie, Pali Rohar, Namjae Jeon,
Paulo Alcantara, Ronnie Sahlberg, Shyam Prasad N, Tom Talpey,
Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit cb26524ef4ac28fcfa554c0656e8dc412c38a8ff upstream.
When parsing a share-root relative native symlink, memcpy copies
smb_target+1 (skipping the leading separator) but uses
strlen(smb_target)+1 as the length, reading one byte past the
allocated buffer.
This fixes the following KASAN splat when accessing an SMB symlink
with a target of '\a\b':
BUG: KASAN: slab-out-of-bounds in smb2_parse_native_symlink+0x4f5/0xca0
Read of size 5 at addr ffff88800878fe21 by task netfsfuzz-execu/1
CPU: 1 UID: 0 PID: 1 Comm: netfsfuzz-execu Tainted: G N
7.2.0-11943-g2709dd5ae32f-dirty #1 PREEMPT(lazy)
Hardware name: QEMU Ubuntu 24.04 PC v2 (i440FX + PIIX, arch_caps fix,
1996)
Call Trace:
<TASK>
dump_stack_lvl+0x7b/0xa0
print_report+0xd0/0x630
kasan_report+0xe5/0x120
kasan_check_range+0x105/0x1b0
__asan_memcpy+0x23/0x60
smb2_parse_native_symlink+0x4f5/0xca0
parse_reparse_point+0x68a/0x1530
reparse_info_to_fattr+0x752/0xa20
cifs_get_fattr+0x873/0x15b0
cifs_get_inode_info+0xc0/0x310
cifs_lookup+0x308/0xa70
__lookup_slow+0x122/0x2b0
lookup_slow+0x50/0x70
path_lookupat+0x525/0xaf0
filename_lookup+0x1f2/0x550
vfs_statx+0xd1/0x1a0
vfs_fstatat+0x65/0xc0
__do_sys_newfstatat+0x9a/0x120
do_syscall_64+0xdd/0x4a0
entry_SYSCALL_64_after_hwframe+0x77/0x7f
Reported-by: Yuanfu Xie <yuanfuxie@stu.pku.edu.cn>
Fixes: 723f4ef90452 ("cifs: Fix parsing native symlinks relative to the export")
Suggested-by: Pali Rohar <pali@kernel.org>
Reviewed-by: Pali Rohar <pali@kernel.org>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/reparse.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -971,7 +971,8 @@ globalroot:
linux_target[i*3 + 1] = '.';
linux_target[i*3 + 2] = sep;
}
- memcpy(linux_target + levels*3, smb_target+1, smb_target_len); /* +1 to skip leading sep */
+ /* +1 to skip leading sep */
+ memcpy(linux_target + levels*3, smb_target+1, smb_target_len-1);
} else {
/*
* This is either an absolute symlink in POSIX-style format
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 632/733] smb: client: fail DACL rewrite when the new DACL exceeds 64K
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (630 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 631/733] smb: client: fix one-byte OOB read in smb2_parse_native_symlink() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 633/733] smb: client: fix cifsFileInfo reference leak in deferred close Greg Kroah-Hartman
` (112 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Bjoern Doebel,
Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjoern Doebel <doebel@amazon.de>
commit d05045177a855386bca5e1909e08d06290e6e3b3 upstream.
replace_sids_and_copy_aces() and set_chmod_dacl() accumulate the size of
the DACL they build in a u16. That accumulator can wrap.
validate_dacl() caps num_aces at (dacl_size - sizeof(struct smb_acl)) /
20, i.e. 3276 for a maximally sized DACL, while each rewritten ACE can
grow to sizeof(struct smb_ace) (76 bytes) once its SID is replaced with
one carrying SID_MAX_SUB_AUTHORITIES sub-authorities. The worst case is
therefore sizeof(struct smb_acl) + 3276 * 76 = 248984 bytes, far beyond
what a u16 can hold. A wraparound is reached with 863 ACEs.
After the wraparound, ndacl_ptr->size becomes meaningless and the offset
will point anywhere in the ACE array. As a result, we will see
corruption of the DACL, which then gets sent to the server. This is not
an out-of-bounds write as the allocation now covers the worst-case
expansion, so writes will always go into the buffer.
Adjust the code to use a u32 internally and return -EOVERFLOW in the
overflow case. The operation must be refused, because a DACL can only
hold 2^16-1 bytes on the wire and larger DACLs cannot be represented.
set_chmod_dacl() carries the same pattern and is fixed the same way. It
only wraps once the source DACL comes within roughly 380 bytes of the
64K ceiling, but the failure mode is identical.
Suggested-by: Namjae Jeon <linkinjeon@kernel.org>
Cc: stable@vger.kernel.org
Fixes: f5065508897a ("cifs: Retain old ACEs when converting between mode bits and ACL.")
Assisted-by: Kiro:claude-opus-5
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cifsacl.c | 39 ++++++++++++++++++++++++++-------------
1 file changed, 26 insertions(+), 13 deletions(-)
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1096,13 +1096,13 @@ unsigned int setup_special_user_owner_AC
static void populate_new_aces(char *nacl_base,
struct smb_sid *pownersid,
struct smb_sid *pgrpsid,
- __u64 *pnmode, u16 *pnum_aces, u16 *pnsize,
+ __u64 *pnmode, u16 *pnum_aces, u32 *pnsize,
bool modefromsid,
bool posix)
{
__u64 nmode;
u16 num_aces = 0;
- u16 nsize = 0;
+ u32 nsize = 0;
__u64 user_mode;
__u64 group_mode;
__u64 other_mode;
@@ -1201,17 +1201,17 @@ set_size:
*pnsize = nsize;
}
-static __u16 replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
- struct smb_sid *pownersid, struct smb_sid *pgrpsid,
- struct smb_sid *pnownersid, struct smb_sid *pngrpsid,
- int *aclflag)
+static int replace_sids_and_copy_aces(struct smb_acl *pdacl, struct smb_acl *pndacl,
+ struct smb_sid *pownersid, struct smb_sid *pgrpsid,
+ struct smb_sid *pnownersid, struct smb_sid *pngrpsid,
+ int *aclflag, u16 *pnsize)
{
int i;
u16 size = 0;
struct smb_ace *pntace = NULL;
char *acl_base = NULL;
u16 src_num_aces = 0;
- u16 nsize = 0;
+ u32 nsize = 0;
struct smb_ace *pnntace = NULL;
char *nacl_base = NULL;
u16 ace_size = 0;
@@ -1240,9 +1240,12 @@ static __u16 replace_sids_and_copy_aces(
size += le16_to_cpu(pntace->size);
nsize += ace_size;
+ if (nsize > U16_MAX)
+ return -EOVERFLOW;
}
- return nsize;
+ *pnsize = nsize;
+ return 0;
}
static int set_chmod_dacl(struct smb_acl *pdacl, struct smb_acl *pndacl,
@@ -1254,7 +1257,7 @@ static int set_chmod_dacl(struct smb_acl
struct smb_ace *pntace = NULL;
char *acl_base = NULL;
u16 src_num_aces = 0;
- u16 nsize = 0;
+ u32 nsize = 0;
struct smb_ace *pnntace = NULL;
char *nacl_base = NULL;
u16 num_aces = 0;
@@ -1305,6 +1308,8 @@ static int set_chmod_dacl(struct smb_acl
nsize += cifs_copy_ace(pnntace, pntace, NULL);
num_aces++;
+ if (nsize > U16_MAX)
+ return -EOVERFLOW;
next_ace:
size += le16_to_cpu(pntace->size);
@@ -1321,6 +1326,10 @@ next_ace:
}
finalize_dacl:
+ /* The DACL size field is 16-bit on the wire, see MS-DTYP 2.4.5 */
+ if (nsize > U16_MAX)
+ return -EOVERFLOW;
+
pndacl->num_aces = cpu_to_le16(num_aces);
pndacl->size = cpu_to_le16(nsize);
@@ -1473,6 +1482,8 @@ static int build_sec_desc(struct smb_nts
rc = set_chmod_dacl(dacl_ptr, ndacl_ptr, owner_sid_ptr, group_sid_ptr,
pnmode, mode_from_sid, posix);
+ if (rc)
+ return rc;
sidsoffset = ndacloffset + le16_to_cpu(ndacl_ptr->size);
/* copy the non-dacl portion of secdesc */
@@ -1548,10 +1559,12 @@ static int build_sec_desc(struct smb_nts
if (dacloffset) {
/* Replace ACEs for old owner with new one */
- size = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
- owner_sid_ptr, group_sid_ptr,
- nowner_sid_ptr, ngroup_sid_ptr,
- aclflag);
+ rc = replace_sids_and_copy_aces(dacl_ptr, ndacl_ptr,
+ owner_sid_ptr, group_sid_ptr,
+ nowner_sid_ptr, ngroup_sid_ptr,
+ aclflag, &size);
+ if (rc)
+ goto chown_chgrp_exit;
ndacl_ptr->size = cpu_to_le16(size);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 633/733] smb: client: fix cifsFileInfo reference leak in deferred close
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (631 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 632/733] smb: client: fail DACL rewrite when the new DACL exceeds 64K Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 634/733] smb: client: fix file type corruption in cifs_reparse_point_to_fattr() Greg Kroah-Hartman
` (111 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Song Li, Fan Wu, Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fan Wu <fanwu01@zju.edu.cn>
commit 5520e89a5a4f834bced64cf2ac927001cc513a40 upstream.
When cifs_close() defers a close, it hands the cifsFileInfo reference
of the closing struct file to the queued work. Each execution of
smb2_deferred_work_close() drops one such reference.
deferred_close_scheduled can be false while the work is pending: the
workqueue clears PENDING when the callback starts to run, before the
callback clears the flag under deferred_lock. A close in that
interval requeues the running work, and the callback then clears the
flag, leaving the requeued work pending with the flag down. A later
cifs_open() can reuse the handle and its cifs_close() reaches the
same branch: queue_delayed_work() fails because the work is still
pending, but cifs_close() returns without dropping the closing file's
reference. The cifsFileInfo count stays pinned and its tlink, dentry
and server handle are leaked.
Check the return value and hand off the reference only when work was
actually queued. Otherwise, use the shared _cifsFileInfo_put(), like
the mod_delayed_work() branch above: the pending execution already
owns its reference.
This issue was found by an in-house static analysis tool.
Fixes: c3f207ab29f7 ("cifs: Deferred close for files")
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6
Co-developed-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Song Li <songl@zju.edu.cn>
Signed-off-by: Fan Wu <fanwu01@zju.edu.cn>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/file.c | 17 ++++++++++++-----
1 file changed, 12 insertions(+), 5 deletions(-)
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -1491,11 +1491,18 @@ int cifs_close(struct inode *inode, stru
trace_smb3_close_cached(tcon->tid, tcon->ses->Suid,
cfile->fid.persistent_fid,
cifs_sb->ctx->closetimeo);
- queue_delayed_work(deferredclose_wq,
- &cfile->deferred, cifs_sb->ctx->closetimeo);
- cfile->deferred_close_scheduled = true;
- spin_unlock(&cinode->deferred_lock);
- return 0;
+ /*
+ * Each queued execution owns one reference.
+ * If nothing was queued, the reference of
+ * the closing file is dropped below.
+ */
+ if (queue_delayed_work(deferredclose_wq,
+ &cfile->deferred,
+ cifs_sb->ctx->closetimeo)) {
+ cfile->deferred_close_scheduled = true;
+ spin_unlock(&cinode->deferred_lock);
+ return 0;
+ }
}
spin_unlock(&cinode->deferred_lock);
_cifsFileInfo_put(cfile, true, false);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 634/733] smb: client: fix file type corruption in cifs_reparse_point_to_fattr()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (632 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 633/733] smb: client: fix cifsFileInfo reference leak in deferred close Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 635/733] smb: client: fix file type corruption in posix_reparse_to_fattr() Greg Kroah-Hartman
` (110 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit 6bd360447941357e959414a525aa62576a448116 upstream.
Setting the file type in cf_mode without clearing the existing S_IFMT
bits first is wrong as it corrupts the file type when cf_mode already
has type bits set (e.g. S_IFREG | S_IFLNK == S_IFDIR | S_IFREG).
Clear S_IFMT before setting S_IFLNK for native and SMB1 symlinks.
Closes: https://sashiko.dev/#/patchset/20260906181540.647469-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/reparse.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1278,6 +1278,7 @@ bool cifs_reparse_point_to_fattr(struct
break;
case 0: /* SMB1 symlink */
case IO_REPARSE_TAG_SYMLINK:
+ fattr->cf_mode &= ~S_IFMT;
fattr->cf_mode |= S_IFLNK;
break;
default:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 635/733] smb: client: fix file type corruption in posix_reparse_to_fattr()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (633 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 634/733] smb: client: fix file type corruption in cifs_reparse_point_to_fattr() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 636/733] smb: client: fix file type corruption in wsl_to_fattr() Greg Kroah-Hartman
` (109 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit 65d5dbdc089be42fc48a6f77bc6b648307f34b17 upstream.
Setting the file type in cf_mode without clearing the existing S_IFMT
bits first is wrong as it corrupts the file type when cf_mode already
has type bits set (e.g. S_IFREG | S_IFCHR == S_IFLNK).
Use a local ftype variable to collect the new file type and apply it
after validation succeeds, clearing S_IFMT and setting the new type in
a single assignment. This avoids stripping cf_mode on malformed
reparse points where the function returns false early.
Closes: https://sashiko.dev/#/patchset/20260906172005.627163-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/reparse.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1212,6 +1212,7 @@ static bool posix_reparse_to_fattr(struc
struct cifs_open_info_data *data)
{
struct reparse_nfs_data_buffer *buf = (struct reparse_nfs_data_buffer *)data->reparse.buf;
+ umode_t ftype;
if (buf == NULL)
return true;
@@ -1227,7 +1228,7 @@ static bool posix_reparse_to_fattr(struc
WARN_ON_ONCE(1);
return false;
}
- fattr->cf_mode |= S_IFCHR;
+ ftype = S_IFCHR;
fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
break;
case NFS_SPECFILE_BLK:
@@ -1235,22 +1236,23 @@ static bool posix_reparse_to_fattr(struc
WARN_ON_ONCE(1);
return false;
}
- fattr->cf_mode |= S_IFBLK;
+ ftype = S_IFBLK;
fattr->cf_rdev = reparse_mkdev(buf->DataBuffer);
break;
case NFS_SPECFILE_FIFO:
- fattr->cf_mode |= S_IFIFO;
+ ftype = S_IFIFO;
break;
case NFS_SPECFILE_SOCK:
- fattr->cf_mode |= S_IFSOCK;
+ ftype = S_IFSOCK;
break;
case NFS_SPECFILE_LNK:
- fattr->cf_mode |= S_IFLNK;
+ ftype = S_IFLNK;
break;
default:
WARN_ON_ONCE(1);
return false;
}
+ fattr->cf_mode = (fattr->cf_mode & ~S_IFMT) | ftype;
return true;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 636/733] smb: client: fix file type corruption in wsl_to_fattr()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (634 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 635/733] smb: client: fix file type corruption in posix_reparse_to_fattr() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 637/733] smb: client: avoid leaking refcount in cifs_queue_oplock_break() Greg Kroah-Hartman
` (108 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit fa7a2cfcf1e6117fc478cae6809c66c518740969 upstream.
Setting the file type in cf_mode without clearing the existing S_IFMT
bits first is wrong as it corrupts the file type when cf_mode already
has type bits set (e.g. S_IFREG | S_IFCHR == S_IFLNK).
Clear S_IFMT before the switch statement.
Closes: https://sashiko.dev/#/patchset/20260906172005.627163-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/reparse.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/smb/client/reparse.c
+++ b/fs/smb/client/reparse.c
@@ -1146,6 +1146,7 @@ static bool wsl_to_fattr(struct cifs_ope
fattr->cf_uid = cifs_sb->ctx->linux_uid;
fattr->cf_gid = cifs_sb->ctx->linux_gid;
+ fattr->cf_mode &= ~S_IFMT;
switch (tag) {
case IO_REPARSE_TAG_LX_SYMLINK:
fattr->cf_mode |= S_IFLNK;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 637/733] smb: client: avoid leaking refcount in cifs_queue_oplock_break()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (635 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 636/733] smb: client: fix file type corruption in wsl_to_fattr() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 638/733] smb: client: avoid leaking refcount when cifs_sb_tlink() fails Greg Kroah-Hartman
` (107 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bjoern Doebel, Namjae Jeon,
Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjoern Doebel <doebel@amazon.de>
commit 9f2e63f1b2d5fc5b5423424902c091123e220e7e upstream.
cifs_queue_oplock_break() unconditionally takes a reference on the
target file before queueing cifs_oplock_break(). Only that work item
decreases the reference counter again.
If another oplock break arrives while that work is still queued,
queue_work() will return false and not queue this second work item. As a
result, we will never reach the point to drop the file reference again
and are leaking this reference. This can be triggered when interacting
with a slow-responding server.
As a result, later unmount operations for this file system will fail with
BUG: Dentry ... still in use (1) [unmount of cifs cifs]
VFS: Busy inodes after unmount of cifs (cifs)
kernel BUG at fs/super.c:777!
Fix this by only incrementing the reference count if the work has been
queued successfully. Taking it after queue_work() is safe because all
three callers hold tcon->open_file_lock across the call and
_cifsFileInfo_put() decrements under that same lock, so a worker that
starts the handler in the window cannot drop the reference before it has
been taken.
Fixes: b98749cac4a69 ("CIFS: keep FileInfo handle live during oplock break")
Cc: stable@vger.kernel.org
Assisted-by: Kiro:claude-opus-5
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/misc.c | 7 ++++---
1 file changed, 4 insertions(+), 3 deletions(-)
--- a/fs/smb/client/misc.c
+++ b/fs/smb/client/misc.c
@@ -378,10 +378,11 @@ void cifs_queue_oplock_break(struct cifs
* open_file_lock to enforce the validity of it for the oplock
* break handler. The matching put is done at the end of the
* handler.
+ *
+ * Only take a reference if the work is actually queued.
*/
- cifsFileInfo_get(cfile);
-
- queue_work(cifsoplockd_wq, &cfile->oplock_break);
+ if (queue_work(cifsoplockd_wq, &cfile->oplock_break))
+ cifsFileInfo_get(cfile);
}
void cifs_done_oplock_break(struct cifsInodeInfo *cinode)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 638/733] smb: client: avoid leaking refcount when cifs_sb_tlink() fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (636 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 637/733] smb: client: avoid leaking refcount in cifs_queue_oplock_break() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 639/733] smb: client: fix heap overflow in DACL owner/group rewrite Greg Kroah-Hartman
` (106 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bjoern Doebel, Namjae Jeon,
Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjoern Doebel <doebel@amazon.de>
commit 23b26f4408ac3f35a482d2e5cf6fc865d4201b71 upstream.
cifs_oplock_break() takes over the reference that
cifs_queue_oplock_break() acquired when it queued the work, and drops it
with _cifsFileInfo_put() once the break has been processed.
Only in setups with "-o multiuser", cifs_sb_tlink() may fail, at which
point cifs_oplock_break() returns without putting the file reference,
mirroring the reference leak we already fixed in the companion patch to
cifs_queue_oplock_break().
This would trigger a crash due to busy inodes on the next unmount:
BUG: Dentry ... still in use (1) [unmount of cifs cifs]
VFS: Busy inodes after unmount of cifs (cifs)
Drop the reference on that path as well. Doing so before the out label
mirrors the normal path, which also puts the reference before
cifs_done_oplock_break().
Found by Sashiko code review. The failure path was not exercised at
runtime.
Fixes: e8f5f849ffce2 ("cifs: fix potential oops in cifs_oplock_break")
Cc: stable@vger.kernel.org
Assisted-by: Kiro:claude-opus-5
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/file.c | 5 ++++-
1 file changed, 4 insertions(+), 1 deletion(-)
--- a/fs/smb/client/file.c
+++ b/fs/smb/client/file.c
@@ -3331,8 +3331,11 @@ void cifs_oplock_break(struct work_struc
TASK_UNINTERRUPTIBLE);
tlink = cifs_sb_tlink(cifs_sb);
- if (IS_ERR(tlink))
+ if (IS_ERR(tlink)) {
+ /* drop the reference taken when the break was queued */
+ _cifsFileInfo_put(cfile, false /* do not wait for ourself */, false);
goto out;
+ }
tcon = tlink_tcon(tlink);
server = tcon->ses->server;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 639/733] smb: client: fix heap overflow in DACL owner/group rewrite
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (637 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 638/733] smb: client: avoid leaking refcount when cifs_sb_tlink() fails Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 640/733] smb: client: avoid using uninitialized SIDs in cifs_posix_to_fattr() Greg Kroah-Hartman
` (105 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Bjoern Doebel, Namjae Jeon,
Paulo Alcantara
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bjoern Doebel <doebel@amazon.de>
commit 0ee150794c75bcd0be0e24ff3394f433cbae18cc upstream.
When id_mode_to_cifs_acl rewrites an existing DACL, it allocates a
buffer sized according to the on-disk DACL length reported by
dacl_ptr->size. However, replace_sids_and_copy_aces may rewrite each
ACE with a new owner/group SID obtained from the cifs.idmap upcall.
Those SIDs can have up to SID_MAX_SUB_AUTHORITIES (15) sub-authorities,
making each ACE up to 76 bytes (sizeof(struct smb_ace)).
If the original DACL contains short SIDs (e.g., 1 sub-authority) while
the replacement SIDs are long, the rewritten ACEs overflow the
allocation.
Fix this by always budgeting for worst-case SID expansion: allocate
sizeof(struct smb_acl) plus num_aces * sizeof(struct smb_ace), which
covers the smb_acl header and room for every ACE at maximum SID size.
This replaces the previous split logic that used dacl_ptr->size for
cifsacl mounts but num_aces * sizeof(struct smb_ace) for mode_from_sid
mounts: both paths can trigger the same rewrite and need the same
headroom.
KASAN reports this as:
BUG: KASAN: slab-out-of-bounds in build_sec_desc+0x1e8a/0x2680 [cifs]
Write of size 4 at addr ffff8881a5e25374 by task chown/5298
...
The buggy address is located 0 bytes to the right of
allocated 884-byte region [ffff8881a5e25000, ffff8881a5e25374)
Cc: stable@vger.kernel.org
Fixes: bc3e9dd9d104 ("cifs: Change SIDs in ACEs while transferring file ownership.")
Assisted-by: Kiro:claude-opus-4.6
Signed-off-by: Bjoern Doebel <doebel@amazon.de>
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Fixes: 5c3564852c58 ("cifs: Minimize the number of cifs_acl memory allocations")
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/cifsacl.c | 12 +++++++-----
1 file changed, 7 insertions(+), 5 deletions(-)
--- a/fs/smb/client/cifsacl.c
+++ b/fs/smb/client/cifsacl.c
@@ -1850,11 +1850,13 @@ id_mode_to_cifs_acl(struct inode *inode,
cifs_put_tlink(tlink);
return rc;
}
- if (mode_from_sid)
- nsecdesclen +=
- le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
- else /* cifsacl */
- nsecdesclen += le16_to_cpu(dacl_ptr->size);
+ /*
+ * Worst case: every ACE is rewritten with a new SID of
+ * SID_MAX_SUB_AUTHORITIES sub-auths -> sizeof(smb_ace) each,
+ * plus the smb_acl header replace_sids_and_copy_aces() emits.
+ */
+ nsecdesclen += sizeof(struct smb_acl) +
+ le16_to_cpu(dacl_ptr->num_aces) * sizeof(struct smb_ace);
}
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 640/733] smb: client: avoid using uninitialized SIDs in cifs_posix_to_fattr()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (638 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 639/733] smb: client: fix heap overflow in DACL owner/group rewrite Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 641/733] xfs: use the rtgroup extent count to find rtrefcount gaps Greg Kroah-Hartman
` (104 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Namjae Jeon, Paulo Alcantara,
Ronnie Sahlberg, Shyam Prasad N, Tom Talpey, Bharath SM
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paulo Alcantara <pc@manguebit.org>
commit da6e25842431982d5a53cf00d925b98c690f4467 upstream.
cifs_posix_to_fattr() ignores the return value of posix_info_parse().
When a malformed POSIX directory entry is encountered (e.g. invalid
SID lengths from an untrusted server), posix_info_parse() returns -1
without populating the 'parsed' struct. The uninitialized stack
memory in parsed.owner and parsed.group is then passed to
sid_to_id(), which processes the garbage bytes and passes them to
request_key() to construct a SID string, potentially leaking kernel
stack contents to the userspace idmap daemon.
Fix this by checking the return value and skipping the SID-to-id
mapping when parsing fails. The remaining fattr fields (timestamps,
mode, etc.) are populated directly from the 'info' pointer so they
are unaffected.
Closes: https://sashiko.dev/#/patchset/20260906172005.627163-1-pc%40manguebit.org
Closes: https://sashiko.dev/#/patchset/20260906181540.647469-1-pc%40manguebit.org
Reviewed-by: Namjae Jeon <linkinjeon@kernel.org>
Signed-off-by: Paulo Alcantara <pc@manguebit.org>
Cc: Ronnie Sahlberg <ronniesahlberg@gmail.com>
Cc: Shyam Prasad N <sprasad@microsoft.com>
Cc: Tom Talpey <tom@talpey.com>
Cc: Bharath SM <bharathsm@microsoft.com>
Cc: stable@vger.kernel.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/smb/client/readdir.c | 16 +++++++++++-----
1 file changed, 11 insertions(+), 5 deletions(-)
--- a/fs/smb/client/readdir.c
+++ b/fs/smb/client/readdir.c
@@ -244,8 +244,9 @@ cifs_posix_to_fattr(struct cifs_fattr *f
{
unsigned int sbflags = cifs_sb_flags(cifs_sb);
struct smb2_posix_info_parsed parsed;
+ int rc;
- posix_info_parse(info, NULL, &parsed);
+ rc = posix_info_parse(info, NULL, &parsed);
memset(fattr, 0, sizeof(*fattr));
fattr->cf_uniqueid = le64_to_cpu(info->Inode);
@@ -284,10 +285,15 @@ cifs_posix_to_fattr(struct cifs_fattr *f
fattr->cf_uid = cifs_sb->ctx->linux_uid;
fattr->cf_gid = cifs_sb->ctx->linux_gid;
- if (!(sbflags & CIFS_MOUNT_OVERR_UID))
- sid_to_id(cifs_sb, &parsed.owner, fattr, SIDOWNER);
- if (!(sbflags & CIFS_MOUNT_OVERR_GID))
- sid_to_id(cifs_sb, &parsed.group, fattr, SIDGROUP);
+ if (rc < 0) {
+ cifs_dbg(VFS, "%s: failed to parse SIDs: %d\n",
+ __func__, rc);
+ } else {
+ if (!(sbflags & CIFS_MOUNT_OVERR_UID))
+ sid_to_id(cifs_sb, &parsed.owner, fattr, SIDOWNER);
+ if (!(sbflags & CIFS_MOUNT_OVERR_GID))
+ sid_to_id(cifs_sb, &parsed.group, fattr, SIDGROUP);
+ }
}
static void __dir_info_to_fattr(struct cifs_fattr *fattr, const void *info)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 641/733] xfs: use the rtgroup extent count to find rtrefcount gaps
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (639 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 640/733] smb: client: avoid using uninitialized SIDs in cifs_posix_to_fattr() Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 642/733] xfs: truncate quota file correctly when repairing quota file Greg Kroah-Hartman
` (103 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit c3085f6c7cca7c162248519ce8d763047cdd8acd upstream.
LOLLM noticed an anachronism from the early days of rtrefcount where the
refcount btree would handle 64-bit block numbers -- we pass rtblocks
into the gap finder, but rtrefcount btrees are sharded by rtgroup now.
This isn't really a problem for us since we're only looking for
overlapping rtrmap records to flag, but let's fix this sillyness.
Also fix some stale comments.
Cc: stable@vger.kernel.org # v6.14
Fixes: 30f47950dc2eba ("xfs: check reference counts of gaps between rt refcount records")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/rtrefcount.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
--- a/fs/xfs/scrub/rtrefcount.c
+++ b/fs/xfs/scrub/rtrefcount.c
@@ -428,7 +428,7 @@ static inline void
xchk_rtrefcountbt_xref_gaps(
struct xfs_scrub *sc,
struct xchk_rtrefcbt_records *rrc,
- xfs_rtblock_t bno)
+ xfs_rgblock_t bno)
{
struct xfs_rmap_irec low;
struct xfs_rmap_irec high;
@@ -538,7 +538,7 @@ xchk_refcount_xref_rmap(
xchk_btree_xref_set_corrupt(sc, sc->sr.rmap_cur, 0);
}
-/* Scrub the refcount btree for some AG. */
+/* Scrub the refcount btree for some rtgroup. */
int
xchk_rtrefcountbt(
struct xfs_scrub *sc)
@@ -564,10 +564,10 @@ xchk_rtrefcountbt(
/*
* Check that all blocks between the last refcount > 1 record and the
- * end of the rt volume have at most one reverse mapping.
+ * end of the rtgroup have at most one reverse mapping.
*/
- xchk_rtrefcountbt_xref_gaps(sc, &rrc, sc->mp->m_sb.sb_rblocks);
-
+ xchk_rtrefcountbt_xref_gaps(sc, &rrc,
+ xfs_rtx_to_rgbno(sc->sr.rtg, sc->mp->m_sb.sb_rgextents));
xchk_refcount_xref_rmap(sc, &btree_oinfo, rrc.cow_blocks);
return 0;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 642/733] xfs: truncate quota file correctly when repairing quota file
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (640 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 641/733] xfs: use the rtgroup extent count to find rtrefcount gaps Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 643/733] xfs: strengthen the "is cow staging" helpers in scrub Greg Kroah-Hartman
` (102 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 0fc67528f54bb91dac22093749b425207c0fc245 upstream.
LOLLM noticed that xrep_quota_data_fork screws up the unit handling when
it computes the offset at which to start truncating the quota file.
max_dquid_off is the file block offset containing the highest possible
dquot, and xfs_bunmapi_range takes the starting file block offset.
Therefore, it makes no sense to multiply max_dquid_off by the blocksize;
all we need to do is start truncating at the next block.
Cc: stable@vger.kernel.org # v6.8
Fixes: a5b91555403e3a ("xfs: repair quotas")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/quota_repair.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -455,8 +455,7 @@ xrep_quota_data_fork(
if (truncate) {
/* Erase everything after the block containing the max dquot */
- error = xfs_bunmapi_range(&sc->tp, sc->ip, 0,
- max_dqid_off * sc->mp->m_sb.sb_blocksize,
+ error = xfs_bunmapi_range(&sc->tp, sc->ip, 0, max_dqid_off + 1,
XFS_MAX_FILEOFF);
if (error)
goto out;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 643/733] xfs: strengthen the "is cow staging" helpers in scrub
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (641 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 642/733] xfs: truncate quota file correctly when repairing quota file Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 644/733] xfs: snapshot scrub stats when rendering them Greg Kroah-Hartman
` (101 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 0d43368844a75ad13561a1198a3b027940730756 upstream.
LOLLM pointed out a bug in both of the refcount scrub predicates that
determine if a range of blocks is marked as CoW staging in the btree.
While it compares blockcount < len, this isn't enough to determine that
the CoW staging record is at least as large as the range passed into the
helper. Fix both of them.
Cc: stable@vger.kernel.org # v4.16
Fixes: f6d5fc21fdc713 ("xfs: cross-reference refcount btree during scrub")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/refcount.c | 6 +++++-
fs/xfs/scrub/rtrefcount.c | 6 +++++-
2 files changed, 10 insertions(+), 2 deletions(-)
--- a/fs/xfs/scrub/refcount.c
+++ b/fs/xfs/scrub/refcount.c
@@ -581,8 +581,12 @@ xchk_xref_is_cow_staging(
if (rc.rc_domain != XFS_REFC_DOMAIN_COW)
xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
+ /* Can't start after bno */
+ if (rc.rc_startblock > agbno)
+ xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
+
/* Must be at least as long as what was passed in */
- if (rc.rc_blockcount < len)
+ if (rc.rc_startblock + rc.rc_blockcount < agbno + len)
xchk_btree_xref_set_corrupt(sc, sc->sa.refc_cur, 0);
}
--- a/fs/xfs/scrub/rtrefcount.c
+++ b/fs/xfs/scrub/rtrefcount.c
@@ -609,8 +609,12 @@ xchk_xref_is_rt_cow_staging(
if (rc.rc_domain != XFS_REFC_DOMAIN_COW)
xchk_btree_xref_set_corrupt(sc, sc->sr.refc_cur, 0);
+ /* Can't start after bno */
+ if (rc.rc_startblock > bno)
+ xchk_btree_xref_set_corrupt(sc, sc->sr.refc_cur, 0);
+
/* Must be at least as long as what was passed in */
- if (rc.rc_blockcount < len)
+ if (rc.rc_startblock + rc.rc_blockcount < bno + len)
xchk_btree_xref_set_corrupt(sc, sc->sr.refc_cur, 0);
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 644/733] xfs: snapshot scrub stats when rendering them
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (642 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 643/733] xfs: strengthen the "is cow staging" helpers in scrub Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 645/733] xfs: snapshot old AGFL before rewriting it Greg Kroah-Hartman
` (100 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 568a1588b906780dc3e9be56a61217afb4f7800e upstream.
LOLLM complains about concurrency problems in the scrub stats code
because xchk_stats_format doesn't synchronize in any way with updates.
These stats are only reported through debugfs so I don't think it really
matters, but I guess I exist to make bots happy now.
Note: We snapshot the entire stats object with a spinlock so that we
don't have to worry about users seeing slightly weird numbers (e.g.
invocations has incremented but none of the outcomes have been yet) if
we race with xchk_stats_merge_one. This isn't a hot path.
Cc: stable@vger.kernel.org # v6.6
Fixes: d7a74cad8f4513 ("xfs: track usage statistics of online fsck")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/stats.c | 32 +++++++++++++++++++-------------
1 file changed, 19 insertions(+), 13 deletions(-)
--- a/fs/xfs/scrub/stats.c
+++ b/fs/xfs/scrub/stats.c
@@ -99,25 +99,31 @@ xchk_stats_format(
int ret = 0;
for (i = 0; i < XFS_SCRUB_TYPE_NR; i++, css++) {
+ struct xchk_scrub_stats fss;
+
if (!name_map[i])
continue;
+ spin_lock(&css->css_lock);
+ memcpy(&fss, css, offsetof(struct xchk_scrub_stats, css_lock));
+ spin_unlock(&css->css_lock);
+
ret = scnprintf(buf, remaining,
"%s %u %u %u %u %u %u %u %u %u %llu %u %u %llu\n",
name_map[i],
- (unsigned int)css->invocations,
- (unsigned int)css->clean,
- (unsigned int)css->corrupt,
- (unsigned int)css->preen,
- (unsigned int)css->xfail,
- (unsigned int)css->xcorrupt,
- (unsigned int)css->incomplete,
- (unsigned int)css->warning,
- (unsigned int)css->retries,
- (unsigned long long)css->checktime_us,
- (unsigned int)css->repair_invocations,
- (unsigned int)css->repair_success,
- (unsigned long long)css->repairtime_us);
+ (unsigned int)fss.invocations,
+ (unsigned int)fss.clean,
+ (unsigned int)fss.corrupt,
+ (unsigned int)fss.preen,
+ (unsigned int)fss.xfail,
+ (unsigned int)fss.xcorrupt,
+ (unsigned int)fss.incomplete,
+ (unsigned int)fss.warning,
+ (unsigned int)fss.retries,
+ (unsigned long long)fss.checktime_us,
+ (unsigned int)fss.repair_invocations,
+ (unsigned int)fss.repair_success,
+ (unsigned long long)fss.repairtime_us);
if (ret <= 0)
break;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 645/733] xfs: snapshot old AGFL before rewriting it
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (643 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 644/733] xfs: snapshot scrub stats when rendering them Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 646/733] xfs: signal inode btree xref error if get_rec returns an error Greg Kroah-Hartman
` (99 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 3466dfef0a20f842363958deea55be9f1d26818a upstream.
LOLLM complains that we can't undo an attempt at fixing the AGFL if
anything goes wrong during the rewrite, so take a snapshot of the whole
buffer so that we can restore it. Move the xrep_agfl_update_agf call so
that we only update the AGF if the AGFL update is 100% successful.
While we're at it, fix leaking the used_extents bitmap if the disunion
operation fails.
Cc: stable@vger.kernel.org # v4.19
Fixes: 0e93d3f43ec7d3 ("xfs: repair the AGFL")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
| 35 +++++++++++++++++++++++++----------
1 file changed, 25 insertions(+), 10 deletions(-)
--- a/fs/xfs/scrub/agheader_repair.c
+++ b/fs/xfs/scrub/agheader_repair.c
@@ -668,14 +668,16 @@ xrep_agfl_init_header(
struct xfs_scrub *sc,
struct xfs_buf *agfl_bp,
struct xagb_bitmap *agfl_extents,
- xfs_agblock_t flcount)
+ xfs_agblock_t flcount,
+ struct xfs_agfl *old_agfl)
{
struct xrep_agfl_fill af = {
.sc = sc,
.flcount = flcount,
};
struct xfs_mount *mp = sc->mp;
- struct xfs_agfl *agfl;
+ struct xfs_agfl *agfl = XFS_BUF_TO_AGFL(agfl_bp);
+ const size_t agfl_sz = BBTOB(agfl_bp->b_length);
int error;
ASSERT(flcount <= xfs_agfl_size(mp));
@@ -684,8 +686,8 @@ xrep_agfl_init_header(
* Start rewriting the header by setting the bno[] array to
* NULLAGBLOCK, then setting AGFL header fields.
*/
- agfl = XFS_BUF_TO_AGFL(agfl_bp);
- memset(agfl, 0xFF, BBTOB(agfl_bp->b_length));
+ memcpy(old_agfl, agfl, agfl_sz);
+ memset(agfl, 0xFF, agfl_sz);
agfl->agfl_magicnum = cpu_to_be32(XFS_AGFL_MAGIC);
agfl->agfl_seqno = cpu_to_be32(pag_agno(sc->sa.pag));
uuid_copy(&agfl->agfl_uuid, &mp->m_sb.sb_meta_uuid);
@@ -700,13 +702,18 @@ xrep_agfl_init_header(
xagb_bitmap_walk(agfl_extents, xrep_agfl_fill, &af);
error = xagb_bitmap_disunion(agfl_extents, &af.used_extents);
if (error)
- return error;
+ goto err_undo;
/* Write new AGFL to disk. */
xfs_trans_buf_set_type(sc->tp, agfl_bp, XFS_BLFT_AGFL_BUF);
- xfs_trans_log_buf(sc->tp, agfl_bp, 0, BBTOB(agfl_bp->b_length) - 1);
+ xfs_trans_log_buf(sc->tp, agfl_bp, 0, agfl_sz - 1);
xagb_bitmap_destroy(&af.used_extents);
return 0;
+
+err_undo:
+ xagb_bitmap_destroy(&af.used_extents);
+ memcpy(agfl, old_agfl, agfl_sz);
+ return error;
}
/* Repair the AGFL. */
@@ -718,6 +725,7 @@ xrep_agfl(
struct xfs_mount *mp = sc->mp;
struct xfs_buf *agf_bp;
struct xfs_buf *agfl_bp;
+ struct xfs_agfl *old_agfl;
xfs_agblock_t flcount;
int error;
@@ -725,6 +733,10 @@ xrep_agfl(
if (!xfs_has_rmapbt(mp))
return -EOPNOTSUPP;
+ old_agfl = kzalloc(BBTOB(XFS_FSS_TO_BB(mp, 1)), XCHK_GFP_FLAGS);
+ if (!old_agfl)
+ return -ENOMEM;
+
xagb_bitmap_init(&agfl_extents);
/*
@@ -734,7 +746,7 @@ xrep_agfl(
*/
error = xfs_alloc_read_agf(sc->sa.pag, sc->tp, 0, &agf_bp);
if (error)
- return error;
+ goto err_old_agfl;
/*
* Make sure we have the AGFL buffer, as scrub might have decided it
@@ -745,7 +757,7 @@ xrep_agfl(
XFS_AGFL_DADDR(mp)),
XFS_FSS_TO_BB(mp, 1), 0, &agfl_bp, NULL);
if (error)
- return error;
+ goto err_old_agfl;
agfl_bp->b_ops = &xfs_agfl_buf_ops;
/* Gather all the extents we're going to put on the new AGFL. */
@@ -762,10 +774,11 @@ xrep_agfl(
* we adjust the AGF flcount (which can fail) so avoid updating any
* buffers until we know that part works.
*/
- xrep_agfl_update_agf(sc, agf_bp, flcount);
- error = xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount);
+ error = xrep_agfl_init_header(sc, agfl_bp, &agfl_extents, flcount,
+ old_agfl);
if (error)
goto err;
+ xrep_agfl_update_agf(sc, agf_bp, flcount);
/*
* Ok, the AGFL should be ready to go now. Roll the transaction to
@@ -785,6 +798,8 @@ xrep_agfl(
err:
xagb_bitmap_destroy(&agfl_extents);
+err_old_agfl:
+ kfree(old_agfl);
return error;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 646/733] xfs: signal inode btree xref error if get_rec returns an error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (644 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 645/733] xfs: snapshot old AGFL before rewriting it Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 647/733] xfs: reset parent pointer args before each dir tree unlink repair Greg Kroah-Hartman
` (98 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 8c71ad4d4f3e20c30b663bd292526fcbc4d3913f upstream.
LOLLM points out that xchk_finobt_xref_inobt and xchk_inobt_xref_finobt
both ignore errors being returned from the xfs_btree_get_rec function
and proceed with a (possibly stale) "true" value for has_record. If the
*simple* btree record checks fail during cross-referencing, we can
immediately conclude that there's a cross-referncing error in the other
btree. On those grounds, we can bubble up the returned error instead of
wasting time cross-referencing with garbage.
Cc: stable@vger.kernel.org # v6.4
Fixes: bc0f3b55467e1b ("xfs: directly cross-reference the inode btrees with each other")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/ialloc.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/fs/xfs/scrub/ialloc.c
+++ b/fs/xfs/scrub/ialloc.c
@@ -85,6 +85,8 @@ xchk_inobt_xref_finobt(
goto no_record;
error = xfs_inobt_get_rec(cur, &frec, &has_record);
+ if (error)
+ return error;
if (!has_record)
return -EFSCORRUPTED;
@@ -188,6 +190,8 @@ xchk_finobt_xref_inobt(
goto no_record;
error = xfs_inobt_get_rec(cur, &irec, &has_record);
+ if (error)
+ return error;
if (!has_record)
return -EFSCORRUPTED;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 647/733] xfs: reset parent pointer args before each dir tree unlink repair
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (645 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 646/733] xfs: signal inode btree xref error if get_rec returns an error Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 648/733] xfs: report nonexistent parents as a filesystem corruption Greg Kroah-Hartman
` (97 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 69e10c2b4a51b4ff3c88a70e90f5180ad58c758f upstream.
LOLLM noticed that xfs_parent_removename only partially initializes the
passed-in parent pointer arguments object. In the directory tree repair
code, we could decide to remove multiple links to a file, so we don't
want state from one call to bleed into the next one. Zero the whole
thing explicitly.
Cc: stable@vger.kernel.org # v6.10
Fixes: 3f31406aef493b ("xfs: fix corruptions in the directory tree")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dirtree_repair.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/xfs/scrub/dirtree_repair.c
+++ b/fs/xfs/scrub/dirtree_repair.c
@@ -479,6 +479,7 @@ again:
}
if (xfs_has_parent(sc->mp)) {
+ memset(&dl->ppargs, 0, sizeof(dl->ppargs));
error = xfs_parent_removename(sc->tp, &dl->ppargs, dp,
&dl->xname, sc->ip);
if (error)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 648/733] xfs: report nonexistent parents as a filesystem corruption
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (646 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 647/733] xfs: reset parent pointer args before each dir tree unlink repair Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 649/733] xfs: report healthy filesystem events in scrub stats Greg Kroah-Hartman
` (96 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 014c1aff607a839b8ddc732da919b94560ae58c2 upstream.
LOLLM noticed that when the directory tree scrubber tries to walk up a
parent pointer but the parent inumber doesn't point to an allocated
inode, we allow the EINVAL/ENOENT error code to bubble up to userspace.
That's not right, we should be reporting that as a cross-referencing
error so that someone runs the parent pointer checker.
Also add a termination check to xchk_dirpath_step_up because it's a loop
body function.
Cc: stable@vger.kernel.org # v6.10
Fixes: 928b721a11789a ("xfs: teach online scrub to find directory tree structure problems")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dirtree.c | 30 ++++++++++++++++++++++++++++--
fs/xfs/scrub/trace.h | 33 +++++++++++++++++++++++++++++++++
2 files changed, 61 insertions(+), 2 deletions(-)
--- a/fs/xfs/scrub/dirtree.c
+++ b/fs/xfs/scrub/dirtree.c
@@ -368,12 +368,38 @@ xchk_dirpath_step_up(
struct xfs_inode *dp;
xfs_ino_t parent_ino = be64_to_cpu(dl->pptr_rec.p_ino);
unsigned int lock_mode;
- int error;
+ int error = 0;
+
+ if (xchk_should_terminate(sc, &error))
+ return error;
/* Grab and lock the parent directory. */
error = xchk_iget(sc, parent_ino, &dp);
- if (error)
+ switch (error) {
+ case -EINVAL:
+ case -ENOENT:
+ mutex_lock(&dl->lock);
+
+ if (dl->stale) {
+ /* live update detected a change in this path */
+ error = -ESTALE;
+ } else {
+ /* inode doesn't exist, path invalid */
+ error = -EFSCORRUPTED;
+
+ trace_xchk_dirpath_badino(dl->sc, path->path_nr,
+ path->nr_steps, &dl->xname,
+ &dl->pptr_rec);
+ }
+
+ mutex_unlock(&dl->lock);
+ return error;
+ case 0:
+ /* keep going */
+ break;
+ default:
return error;
+ }
lock_mode = xfs_ilock_attr_map_shared(dp);
mutex_lock(&dl->lock);
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -1706,6 +1706,39 @@ DEFINE_EVENT(xchk_dirtree_class, name, \
DEFINE_XCHK_DIRTREE_EVENT(xchk_dirtree_create_path);
DEFINE_XCHK_DIRTREE_EVENT(xchk_dirpath_walk_upwards);
+TRACE_EVENT(xchk_dirpath_badino,
+ TP_PROTO(struct xfs_scrub *sc, unsigned int path_nr,
+ unsigned int step_nr, const struct xfs_name *name,
+ const struct xfs_parent_rec *pptr),
+ TP_ARGS(sc, path_nr, step_nr, name, pptr),
+ TP_STRUCT__entry(
+ __field(dev_t, dev)
+ __field(unsigned int, path_nr)
+ __field(unsigned int, step_nr)
+ __field(xfs_ino_t, parent_ino)
+ __field(unsigned int, parent_gen)
+ __field(unsigned int, namelen)
+ __dynamic_array(char, name, name->len)
+ ),
+ TP_fast_assign(
+ __entry->dev = sc->mp->m_super->s_dev;
+ __entry->path_nr = path_nr;
+ __entry->step_nr = step_nr;
+ __entry->parent_ino = be64_to_cpu(pptr->p_ino);
+ __entry->parent_gen = be32_to_cpu(pptr->p_gen);
+ __entry->namelen = name->len;
+ memcpy(__get_str(name), name->name, name->len);
+ ),
+ TP_printk("dev %d:%d path %u step %u parent_ino 0x%llx parent_gen 0x%x name '%.*s'",
+ MAJOR(__entry->dev), MINOR(__entry->dev),
+ __entry->path_nr,
+ __entry->step_nr,
+ __entry->parent_ino,
+ __entry->parent_gen,
+ __entry->namelen,
+ __get_str(name))
+);
+
DECLARE_EVENT_CLASS(xchk_dirpath_class,
TP_PROTO(struct xfs_scrub *sc, struct xfs_inode *ip,
unsigned int path_nr, unsigned int step_nr,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 649/733] xfs: report healthy filesystem events in scrub stats
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (647 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 648/733] xfs: report nonexistent parents as a filesystem corruption Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 650/733] xfs: release alleged child inode on metapath unlink error Greg Kroah-Hartman
` (95 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 0ae61c331ec552ad0c278c5c48a1c4ccb90b4bab upstream.
LOLLM also notices that I forgot to expose the "clean bill of health"
scrub stats. Fix that.
Cc: stable@vger.kernel.org # v6.9
Fixes: a1f3e0cca41036 ("xfs: update health status if we get a clean bill of health")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/stats.c | 1 +
1 file changed, 1 insertion(+)
--- a/fs/xfs/scrub/stats.c
+++ b/fs/xfs/scrub/stats.c
@@ -84,6 +84,7 @@ static const char *name_map[XFS_SCRUB_TY
[XFS_SCRUB_TYPE_RGSUPER] = "rgsuper",
[XFS_SCRUB_TYPE_RTRMAPBT] = "rtrmapbt",
[XFS_SCRUB_TYPE_RTREFCBT] = "rtrefcountbt",
+ [XFS_SCRUB_TYPE_HEALTHY] = "healthy",
};
/* Format the scrub stats into a text buffer, similar to pcp style. */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 650/733] xfs: release alleged child inode on metapath unlink error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (648 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 649/733] xfs: report healthy filesystem events in scrub stats Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:15 ` [PATCH 7.2 651/733] xfs: preserve owner on in-memory btree creation Greg Kroah-Hartman
` (94 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Anuj Gupta, Darrick J. Wong,
Carlos Maiolino, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anuj Gupta <anuj20.g@samsung.com>
commit 48d2b8351bae6d40b44f544fe5540868a55872b2 upstream.
If xchk_metapath_ilock_parent_and_child() fails after xchk_iget()
succeeds, release the inode reference before returning.
Fixes: 0d2c636e489c ("xfs: repair metadata directory file path connectivity")
Cc: stable@vger.kernel.org # v6.13
Signed-off-by: Anuj Gupta <anuj20.g@samsung.com>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/metapath.c | 2 ++
1 file changed, 2 insertions(+)
--- a/fs/xfs/scrub/metapath.c
+++ b/fs/xfs/scrub/metapath.c
@@ -556,6 +556,8 @@ xrep_metapath_try_unlink(
error = xchk_metapath_ilock_parent_and_child(mpath, ip);
if (error) {
xchk_trans_cancel(sc);
+ if (ip)
+ xchk_irele(sc, ip);
return error;
}
xfs_trans_ijoin(sc->tp, mpath->dp, 0);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 651/733] xfs: preserve owner on in-memory btree creation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (649 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 650/733] xfs: release alleged child inode on metapath unlink error Greg Kroah-Hartman
@ 2026-09-17 15:15 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 652/733] xfs: make the rtsummary repair fix the file size too Greg Kroah-Hartman
` (93 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:15 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 5287e56cba3be4a64bff9f73bce5964fda2590dc upstream.
LOLLM points out a minor bug where a higher level function creating an
in-memory btree is required to pass in an owner number, but the creation
function erases that. In-memory btrees are ephemeral so this really
doesn't matter except for debugging. But let's fix this papercut.
Cc: stable@vger.kernel.org # v6.9
Fixes: a095686a238352 ("xfs: support in-memory btrees")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_btree_mem.c | 2 ++
1 file changed, 2 insertions(+)
--- a/fs/xfs/libxfs/xfs_btree_mem.c
+++ b/fs/xfs/libxfs/xfs_btree_mem.c
@@ -117,6 +117,7 @@ xfbtree_init(
struct xfs_buftarg *btp,
const struct xfs_btree_ops *ops)
{
+ unsigned long long owner = xfbt->owner;
unsigned int blocklen = xfbtree_rec_bytes(mp, ops);
unsigned int keyptr_len;
int error;
@@ -133,6 +134,7 @@ xfbtree_init(
memset(xfbt, 0, sizeof(*xfbt));
xfbt->target = btp;
+ xfbt->owner = owner;
/* Set up min/maxrecs for this btree. */
keyptr_len = ops->key_len + sizeof(__be64);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 652/733] xfs: make the rtsummary repair fix the file size too
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (650 preceding siblings ...)
2026-09-17 15:15 ` [PATCH 7.2 651/733] xfs: preserve owner on in-memory btree creation Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 653/733] xfs: log the tempip after we convert it to extents format Greg Kroah-Hartman
` (92 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 6b760b3232b3efc8bcc7c165e76300bc1c9140c5 upstream.
LOLLM noticed that the rtsummary repair code will create a new rtsummary
with the correct file size, but it won't force the new file size to be
set on the existing rtsummary file, leaving the rtsummary corrupt. Fix
this by setting up the tempfile mapping-exchange to run to the end of
both files, which is the magic offset needed to reset the file size.
Cc: stable@vger.kernel.org # v6.10
Fixes: abf039e2e4afde ("xfs: online repair of realtime summaries")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/rtsummary_repair.c | 3 ++-
1 file changed, 2 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/rtsummary_repair.c
+++ b/fs/xfs/scrub/rtsummary_repair.c
@@ -164,9 +164,10 @@ xrep_rtsummary(
/*
* Now exchange the contents. Nothing in repair uses the temporary
* buffer, so we can reuse it for the tempfile exchrange information.
+ * Use XFS_MAX_FILEOFF here so that we correct the rtsummary file size.
*/
error = xrep_tempexch_trans_reserve(sc, XFS_DATA_FORK, 0,
- rts->rsumblocks, &rts->tempexch);
+ XFS_MAX_FILEOFF, &rts->tempexch);
if (error)
return error;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 653/733] xfs: log the tempip after we convert it to extents format
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (651 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 652/733] xfs: make the rtsummary repair fix the file size too Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 654/733] xfs: lock the healthmon when inserting unmount event Greg Kroah-Hartman
` (91 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit ed799148e0d63ef41ab60ce98963a1dc423090d3 upstream.
LOLLM points out that xrep_symlink_swap_prep converts sc->tempip to an
extents format file prior to the atomic swap, but incorrectly logs
sc->ip immediately afterwards. Fix that, and the other problem that
we're supposed to tell xfs_trans_log_inode what to log and don't.
Cc: stable@vger.kernel.org # v6.10
Fixes: 2651923d8d8db0 ("xfs: online repair of symbolic links")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/symlink_repair.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/symlink_repair.c
+++ b/fs/xfs/scrub/symlink_repair.c
@@ -291,7 +291,7 @@ xrep_symlink_swap_prep(
if (error)
return error;
- xfs_trans_log_inode(sc->tp, sc->ip, 0);
+ xfs_trans_log_inode(sc->tp, sc->tempip, logflags);
error = xfs_defer_finish(&sc->tp);
if (error)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 654/733] xfs: lock the healthmon when inserting unmount event
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (652 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 653/733] xfs: log the tempip after we convert it to extents format Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 655/733] xfs: initialise error in xfs_defer_finish_one() Greg Kroah-Hartman
` (90 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 7538ba528cfd6f176076186c1b1678fdca1c197b upstream.
LOLLM complains that xfs_healthmon_unmount does an unlocked insert of
the unmount event into the health monitor's event list. Fix that.
Cc: stable@vger.kernel.org # v7.0
Fixes: 25ca57fa3624ca ("xfs: convey filesystem unmount events to the health monitor")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_healthmon.c | 6 ++++++
1 file changed, 6 insertions(+)
diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c
index 4521ffdab9f1..3ae5f4496ad1 100644
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -272,6 +272,8 @@ __xfs_healthmon_insert(
{
struct timespec64 now;
+ lockdep_assert_held(&hm->lock);
+
ktime_get_coarse_real_ts64(&now);
event->time_ns = (now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
@@ -294,6 +296,8 @@ __xfs_healthmon_push(
{
struct timespec64 now;
+ lockdep_assert_held(&hm->lock);
+
ktime_get_coarse_real_ts64(&now);
event->time_ns = (now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
@@ -415,8 +419,10 @@ xfs_healthmon_unmount(
* There's nothing actionable for userspace after an unmount. Once
* we've inserted the unmount event, hm no longer owns that event.
*/
+ mutex_lock(&hm->lock);
__xfs_healthmon_insert(hm, hm->unmount_event);
hm->unmount_event = NULL;
+ mutex_unlock(&hm->lock);
xfs_healthmon_detach(hm);
xfs_healthmon_put(hm);
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 655/733] xfs: initialise error in xfs_defer_finish_one()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (653 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 654/733] xfs: lock the healthmon when inserting unmount event Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 656/733] xfs: initialise args->total for parent pointer updates Greg Kroah-Hartman
` (89 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Tia, Darrick J. Wong,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Tia <javier@peridio.com>
commit 6176d21d7bd609632c5b7e87a3adb9be29ec1e72 upstream.
xfs_defer_finish_one() declares error without an initialiser and only
assigns it inside the loop over dfp->dfp_work. When that list is empty
the loop body never runs, control falls through to the "Done with the
dfp, free it" path, and the function returns an indeterminate value.
An item-less pending item reaches this through xfs_defer_add_barrier(),
which xfs_reap_ag_blocks() uses on any CONFIG_XFS_ONLINE_REPAIR kernel.
xfs_defer_finish_noroll() treats any non-EAGAIN return as fatal, so a
non-zero stack value turns a successful barrier into a
SHUTDOWN_CORRUPT_INCORE in the middle of a repair. Zero is the correct
result: reaching the free path means the item loop drained without a
non-zero error.
Fixes: 3f3cec031099 ("xfs: force small EFIs for reaping btree extents")
Cc: stable@vger.kernel.org
Signed-off-by: Javier Tia <floss@jetm.me>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_defer.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/libxfs/xfs_defer.c
+++ b/fs/xfs/libxfs/xfs_defer.c
@@ -583,7 +583,7 @@ xfs_defer_finish_one(
const struct xfs_defer_op_type *ops = dfp->dfp_ops;
struct xfs_btree_cur *state = NULL;
struct list_head *li, *n;
- int error;
+ int error = 0;
trace_xfs_defer_pending_finish(tp->t_mountp, dfp);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 656/733] xfs: initialise args->total for parent pointer updates
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (654 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 655/733] xfs: initialise error in xfs_defer_finish_one() Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 657/733] xfs: fix xfs_rtrmapbt_mem_cursor for non-rmap filesystems Greg Kroah-Hartman
` (88 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Javier Tia, Darrick J. Wong,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Javier Tia <javier@peridio.com>
commit 8e4ebb6afaa34bd2e8ce52da231003d24111c2d6 upstream.
xfs_parent_da_args_init() builds an xfs_da_args from a zeroed
xfs_parent_args (kmem_cache_zalloc), leaving args->total == 0.
xfs_da_grow_inode_int() treats that field as a running block reservation
and subtracts from it; because it is an xfs_extlen_t (uint32_t), the
first attr-fork growth wraps it to ~0U. That defeats the free-space
check in xfs_alloc_space_available(), and when it coincides with an AG
that has exactly zero available blocks the allocation is clamped to
maxlen 0 and returns -ENOSPC, which xfs_defer_finish_noroll() escalates
to a filesystem shutdown.
Set args->total the way the log recovery path does
(xfs_attri_recover_work(), xfs_attr_item.c:706), in the add and replace
paths that can grow the fork. Removals and lookups never grow it, so
they leave the field alone, matching that switch.
Fixes: b7c62d90c12c ("xfs: parent pointer attribute creation")
Cc: stable@vger.kernel.org # v6.10
Signed-off-by: Javier Tia <floss@jetm.me>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_parent.c | 12 ++++++++++--
1 file changed, 10 insertions(+), 2 deletions(-)
--- a/fs/xfs/libxfs/xfs_parent.c
+++ b/fs/xfs/libxfs/xfs_parent.c
@@ -193,7 +193,7 @@ xfs_parent_addname(
const struct xfs_name *parent_name,
struct xfs_inode *child)
{
- int error;
+ int error, local;
error = xfs_parent_iread_extents(tp, child);
if (error)
@@ -203,6 +203,10 @@ xfs_parent_addname(
xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
I_INO(child), parent_name);
+ /* Growing the attr fork needs a real reservation in args->total. */
+ ppargs->args.total = xfs_attr_calc_size(&ppargs->args, &local);
+ ASSERT(local);
+
return xfs_attr_setname(&ppargs->args, 0);
}
@@ -239,7 +243,7 @@ xfs_parent_replacename(
const struct xfs_name *new_name,
struct xfs_inode *child)
{
- int error;
+ int error, local;
error = xfs_parent_iread_extents(tp, child);
if (error)
@@ -249,6 +253,10 @@ xfs_parent_replacename(
xfs_parent_da_args_init(&ppargs->args, tp, &ppargs->rec, child,
I_INO(child), old_name);
+ /* Growing the attr fork needs a real reservation in args->total. */
+ ppargs->args.total = xfs_attr_calc_size(&ppargs->args, &local);
+ ASSERT(local);
+
xfs_inode_to_parent_rec(&ppargs->new_rec, new_dp);
ppargs->args.new_name = new_name->name;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 657/733] xfs: fix xfs_rtrmapbt_mem_cursor for non-rmap filesystems
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (655 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 656/733] xfs: initialise args->total for parent pointer updates Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 658/733] xfs: fix unit conversions in per_binval computation Greg Kroah-Hartman
` (87 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 022d5f5fce7f0b6125d404eb74044e6238aef369 upstream.
It's possible to construct an in-memory rtrmap btree for filesystems
that don't have the rmap feature enabled. The kernel doesn't do this,
but xfs_repair will, if asked to reindex a filesystem that has rtreflink
enabled but not rtrmap. Therefore, we must create the cursor with
enough levels to handle a maximally sized btree possible.
Note that the rtrmapbt btree cursor slab creates objects large enough to
handle xfs_rtrmap_maxlevels_ondisk() levels, so setting bc_nlevels to
the same value isn't costing us any extra memory.
Cc: stable@vger.kernel.org # v6.14
Fixes: 4a61f12eb11958 ("xfs: create a shadow rmap btree during realtime rmap repair")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_rtrmap_btree.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c
@@ -618,7 +618,7 @@ xfs_rtrmapbt_mem_cursor(
struct xfs_btree_cur *cur;
cur = xfs_btree_alloc_cursor(mp, tp, &xfs_rtrmapbt_mem_ops,
- mp->m_rtrmap_maxlevels, xfs_rtrmapbt_cur_cache);
+ xfs_rtrmapbt_maxlevels_ondisk(), xfs_rtrmapbt_cur_cache);
cur->bc_mem.xfbtree = xfbt;
cur->bc_nlevels = xfbt->nlevels;
cur->bc_group = xfs_group_hold(rtg_group(rtg));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 658/733] xfs: fix unit conversions in per_binval computation
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (656 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 657/733] xfs: fix xfs_rtrmapbt_mem_cursor for non-rmap filesystems Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 659/733] xfs: fix under-reservation of blocks when repairing sf directories Greg Kroah-Hartman
` (86 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 05cff7c2b79f76c7cfe90613a60e16aaaa051ef7 upstream.
LOLLM noticed that we're doing the unit conversion in the per_binval
computation backwards -- xfs_buf_inval_log_space's second parameter is
supposed to be in bytes, but max_binval is in units of fsblocks. Hence
the conversion should be FSB -> B, not the other way around.
Cc: stable@vger.kernel.org # v6.18
Fixes: b2311ec6778fcd ("xfs: compute per-AG extent reap limits dynamically")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/reap.c | 4 ++--
1 file changed, 2 insertions(+), 2 deletions(-)
--- a/fs/xfs/scrub/reap.c
+++ b/fs/xfs/scrub/reap.c
@@ -601,7 +601,7 @@ xreap_configure_agextent_limits(
/* Maximum overhead of invalidating one buffer. */
const unsigned int per_binval =
- xfs_buf_inval_log_space(1, XFS_B_TO_FSBT(mp, max_binval));
+ xfs_buf_inval_log_space(1, XFS_FSB_TO_B(mp, max_binval));
/*
* For each transaction in a reap chain, we can delete some number of
@@ -680,7 +680,7 @@ xreap_configure_agcow_limits(
/* Overhead of invalidating one buffer */
const unsigned int per_binval =
- xfs_buf_inval_log_space(1, XFS_B_TO_FSBT(mp, max_binval));
+ xfs_buf_inval_log_space(1, XFS_FSB_TO_B(mp, max_binval));
/*
* For each transaction in a reap chain, we can delete some number of
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 659/733] xfs: fix under-reservation of blocks when repairing sf directories
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (657 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 658/733] xfs: fix unit conversions in per_binval computation Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 660/733] xfs: fix the rtrmap and rtrefcount _maxlevels_ondisk functions Greg Kroah-Hartman
` (85 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, floss, dgc, Darrick J. Wong,
Christoph Hellwig, Carlos Maiolino, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 4d3c07591534517c633945c8d8e6526f10e3fabc upstream.
Whilst running QA on XFS for-next as of 7.3-rc2 with MKFS_OPTIONS="-n
size=8192", I observed the following (trimmed) dmesg splat:
XFS: Assertion failed: args->total >= dp->i_nblocks - nblks, file: fs/xfs/libxfs/xfs_da_btree.c, line: 2387
WARNING: fs/xfs/xfs_message.c:104 at assfail+0x46/0x4a [xfs], CPU#0: xfs_scrub/1426511
CPU: 0 UID: 0 PID: 1426511 Comm: xfs_scrub Tainted: G W 7.3.0-rc2-djwx #rc2 PREEMPT(lazy) 6e418570b606a39783b0e7e7b30dc407b965f9e8
Tainted: [W]=WARN
RIP: 0010:assfail+0x46/0x4a [xfs]
RSP: 0018:ffffc900010d7890 EFLAGS: 00010246
RAX: 0000000000000000 RBX: 0000000000000000 RCX: 00000000ffffffd1
RDX: 0000000000000000 RSI: 0000000000000021 RDI: ffffffffa059fd38
RBP: 0000000000000002 R08: 0000000000000000 R09: 0000000000000000
R10: 000000000000000a R11: 000000007fffffff R12: ffffc900010d7940
R13: ffff888368d8f980 R14: ffffc900010d7a48 R15: ffffc900010d78d0
FS: 00007f445c5ce680(0000) GS:ffff8884a97ea000(0000) knlGS:0000000000000000
CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033
CR2: 00007f443803b9a8 CR3: 0000000107a4b000 CR4: 00000000003506f0
Call Trace:
<TASK>
xfs_da_grow_inode_int+0x2e0/0x300 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xfs_dir2_grow_inode+0x6e/0x150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xfs_dir2_sf_to_block+0x149/0x870 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xrep_dir_swap_prep+0xe2/0x110 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xrep_dir_swap+0xfb/0x2f0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xrep_dir_rebuild_tree+0x99/0x100 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xrep_directory+0x83/0x1c0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xrep_attempt+0x4f/0x1e0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xfs_scrub_metadata+0x393/0x5b0 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xfs_ioc_scrubv_metadata+0x306/0x570 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
xfs_file_ioctl+0xa4f/0x1150 [xfs 5de2257e14108c136f11317e6bbb8ac77efd392c]
__x64_sys_ioctl+0x76/0xc0
do_syscall_64+0x7a/0x3b0
entry_SYSCALL_64_after_hwframe+0x4b/0x53
This is a consequence of commit 0fe77e57588b98, which added the
following assertion to xfs_da_grow_inode_int:
ASSERT(args->total >= dp->i_nblocks - nblks);
Tracing this back to xrep_dir_swap_prep, I noticed that the xfs_da_args
object that's passed to xfs_dir2_sf_to_block sets args->total to 1.
This is incorrect because mkfs set the directory block size to 8k and
the filesystem block size to 4k. In other words, args->total should be
2 here, not 1.
Dave Chinner tripped over the same problem with the same branch through
a different channel -- his test setup set the fs block size to 1k, in
which case the directory block size is still set to 4k. Here,
args->total should be 4.
Changing the assignment of args->total to sc->mp->m_dir_geo->fsbcount
makes the assertion go away, but that isn't a complete fix. In
xrep_tempexch_estimate, we also incorrectly assume that a shortform
conversion requires 1 fsblock when it should be m_dir_geo->fsbcount.
Without that, we can under-reserve space in the transaction and cause a
filesystem shutdown.
Note that the xfs_dabuf_nfsb helper will compute the correct value for
directories and xattr, so we use that instead of open-coding the logic.
Also fix xrep_xattr_swap_prep to assign args->total via xfs_dabuf_nfsb
to avoid one logic bomb if we ever support multi-fsblock attrs.
Cc: stable@vger.kernel.org # v6.10
Cc: floss@jetm.me
Reported-by: dgc@kernel.org
Fixes: 629fdaf5f5b1b7 ("xfs: use atomic extent swapping to fix user file fork data")
Tripped-by: 0fe77e57588b98 ("xfs: assert the reservation covers each da fork growth")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_da_btree.c | 2 +-
fs/xfs/libxfs/xfs_da_btree.h | 2 ++
fs/xfs/scrub/attr_repair.c | 2 +-
fs/xfs/scrub/dir_repair.c | 2 +-
fs/xfs/scrub/tempfile.c | 29 ++++++++++++++++++++++-------
5 files changed, 27 insertions(+), 10 deletions(-)
--- a/fs/xfs/libxfs/xfs_da_btree.c
+++ b/fs/xfs/libxfs/xfs_da_btree.c
@@ -130,7 +130,7 @@ xfs_da_state_reset(
state->mp = state->args->dp->i_mount;
}
-static inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
+inline int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork)
{
if (whichfork == XFS_DATA_FORK)
return mp->m_dir_geo->fsbcount;
--- a/fs/xfs/libxfs/xfs_da_btree.h
+++ b/fs/xfs/libxfs/xfs_da_btree.h
@@ -244,4 +244,6 @@ xfs_failaddr_t xfs_da3_node_header_check
extern struct kmem_cache *xfs_da_state_cache;
+int xfs_dabuf_nfsb(struct xfs_mount *mp, int whichfork);
+
#endif /* __XFS_DA_BTREE_H__ */
--- a/fs/xfs/scrub/attr_repair.c
+++ b/fs/xfs/scrub/attr_repair.c
@@ -1294,7 +1294,7 @@ xrep_xattr_swap_prep(
.geo = sc->mp->m_attr_geo,
.whichfork = XFS_ATTR_FORK,
.trans = sc->tp,
- .total = 1,
+ .total = xfs_dabuf_nfsb(sc->mp, XFS_ATTR_FORK),
.owner = I_INO(sc->ip),
};
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -1467,7 +1467,7 @@ xrep_dir_swap_prep(
.geo = sc->mp->m_dir_geo,
.whichfork = XFS_DATA_FORK,
.trans = sc->tp,
- .total = 1,
+ .total = xfs_dabuf_nfsb(sc->mp, XFS_DATA_FORK),
.owner = I_INO(sc->ip),
};
--- a/fs/xfs/scrub/tempfile.c
+++ b/fs/xfs/scrub/tempfile.c
@@ -649,6 +649,19 @@ xrep_tempexch_prep_request(
return 0;
}
+static inline unsigned int
+xrep_tempexch_estimate_sf_resblks(
+ struct xfs_scrub *sc,
+ int whichfork)
+{
+ /* repairing a symlink target */
+ if (S_ISLNK(VFS_I(sc->ip)->i_mode) && whichfork == XFS_DATA_FORK)
+ return 1;
+
+ /* everything else is a directory or an xattr structure */
+ return xfs_dabuf_nfsb(sc->mp, whichfork);
+}
+
/*
* Fill out the mapping exchange resource estimation structures in preparation
* for exchanging the contents of a metadata file that we've rebuilt in the
@@ -663,6 +676,8 @@ xrep_tempexch_estimate(
struct xfs_ifork *ifp;
struct xfs_ifork *tifp;
int whichfork = xfs_exchmaps_reqfork(req);
+ unsigned int sf_resblks =
+ xrep_tempexch_estimate_sf_resblks(sc, whichfork);
int state = 0;
/*
@@ -693,9 +708,9 @@ xrep_tempexch_estimate(
* plus the block we converted.
*/
req->ip1_bcount = sc->tempip->i_nblocks;
- req->ip2_bcount = 1;
+ req->ip2_bcount = sf_resblks;
req->nr_exchanges = 1 + tifp->if_nextents;
- req->resblks = 1;
+ req->resblks = sf_resblks;
break;
case 2:
/*
@@ -707,10 +722,10 @@ xrep_tempexch_estimate(
* is (worst case) the extent count of the file being repaired
* plus the block we converted.
*/
- req->ip1_bcount = 1;
+ req->ip1_bcount = sf_resblks;
req->ip2_bcount = sc->ip->i_nblocks;
req->nr_exchanges = 1 + ifp->if_nextents;
- req->resblks = 1;
+ req->resblks = sf_resblks;
break;
case 3:
/*
@@ -722,10 +737,10 @@ xrep_tempexch_estimate(
* fileoff 0. Presumably, the caller could not exchange the
* two inode fork areas directly.
*/
- req->ip1_bcount = 1;
- req->ip2_bcount = 1;
+ req->ip1_bcount = sf_resblks;
+ req->ip2_bcount = sf_resblks;
req->nr_exchanges = 1;
- req->resblks = 2;
+ req->resblks = 2 * sf_resblks;
break;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 660/733] xfs: fix the rtrmap and rtrefcount _maxlevels_ondisk functions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (658 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 659/733] xfs: fix under-reservation of blocks when repairing sf directories Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 661/733] xfs: fix short ifork reaping computation in xreap_bmapi_binval Greg Kroah-Hartman
` (84 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit aa301322f72f82f26e4ba0826018d41388ab9896 upstream.
The _maxlevels_ondisk functions are used to compute the size of
in-memory btree cursors for each btree type. Unfortunately, LOLLM
noticed that the rtrmap and rtrefcount versions of these functions
forget to account for the inode root, which means that we could access
beyond the end of the cursor given a sufficiently large btree. Fix
this.
Cc: stable@vger.kernel.org # v6.14
Fixes: 9abe03a0e4f978 ("xfs: introduce realtime refcount btree ondisk definitions")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_rtrefcount_btree.c | 7 +++++--
fs/xfs/libxfs/xfs_rtrmap_btree.c | 4 +++-
2 files changed, 8 insertions(+), 3 deletions(-)
--- a/fs/xfs/libxfs/xfs_rtrefcount_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrefcount_btree.c
@@ -489,8 +489,11 @@ xfs_rtrefcountbt_maxlevels_ondisk(void)
minrecs[0] = xfs_rtrefcountbt_block_maxrecs(blocklen, true) / 2;
minrecs[1] = xfs_rtrefcountbt_block_maxrecs(blocklen, false) / 2;
- /* We need at most one record for every block in an rt group. */
- return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_RGBLOCKS);
+ /*
+ * We need at most one record for every block in an rt group, and
+ * one extra level for the inode root.
+ */
+ return xfs_btree_compute_maxlevels(minrecs, XFS_MAX_RGBLOCKS) + 1;
}
int __init
--- a/fs/xfs/libxfs/xfs_rtrmap_btree.c
+++ b/fs/xfs/libxfs/xfs_rtrmap_btree.c
@@ -716,10 +716,12 @@ xfs_rtrmapbt_maxlevels_ondisk(void)
* happens, which means that we must compute the max height based on
* what the btree will look like if it consumes almost all the blocks
* in the data device due to maximal sharing factor.
+ *
+ * Add one extra level for the inode root.
*/
max_dblocks = -1U; /* max ag count */
max_dblocks *= XFS_MAX_CRC_AG_BLOCKS;
- return xfs_btree_space_to_height(minrecs, max_dblocks);
+ return xfs_btree_space_to_height(minrecs, max_dblocks) + 1;
}
int __init
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 661/733] xfs: fix short ifork reaping computation in xreap_bmapi_binval
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (659 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 660/733] xfs: fix the rtrmap and rtrefcount _maxlevels_ondisk functions Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 662/733] xfs: fix rtrmap cross-referencing elision logic Greg Kroah-Hartman
` (83 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit eacb8479507756c3305994e87fb2fb1183827e98 upstream.
LOLLM got really confused about the update to imap->br_blockcount in
xreap_bmapi_binval if xreap_inc_binval returns false. The intent of
this code is that we shorten the imap to whatever length of space we
invalidated so that the next iteration through the loop will start
wherever we left off. Unfortunately, the calculation sets br_blockcount
to the amount of *unfinished* work, which means that we pointlessly
re-scan blocks that we already reaped. This is benign, but we should
fix the computation anyway.
Cc: stable@vger.kernel.org # v6.10
Fixes: 5befb047b9f4de ("xfs: add the ability to reap entire inode forks")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/reap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/reap.c
+++ b/fs/xfs/scrub/reap.c
@@ -1399,7 +1399,7 @@ xreap_bmapi_binval(
* far we've gotten.
*/
if (!xreap_inc_binval(rs)) {
- imap->br_blockcount = agbno_next - bno;
+ imap->br_blockcount = bno - agbno;
goto out;
}
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 662/733] xfs: fix rtrmap cross-referencing elision logic
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (660 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 661/733] xfs: fix short ifork reaping computation in xreap_bmapi_binval Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 663/733] xfs: fix rtrefcount btree block counting in scrub Greg Kroah-Hartman
` (82 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 3bdbf472a608aeb7e8e4dc70ee86738ad5256356 upstream.
LOLLM points out that xchk_bmap_xref_rmap_cow skips the cross-reference
if the data-section rmapbt cursor is not present. However, this is
broken for realtime file data fork scanning, because they will have an
rtrmapbt cursor and not an rmapbt cursor. Fix the behavior by removing
the cursor checks because xchk_bmap_get_rmap already accounts for that.
Cc: stable@vger.kernel.org # v6.14
Fixes: 037a44d8277adf ("xfs: cross-reference the realtime rmapbt")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/bmap.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/bmap.c
+++ b/fs/xfs/scrub/bmap.c
@@ -274,7 +274,7 @@ xchk_bmap_xref_rmap_cow(
unsigned long long rmap_end;
uint64_t owner = XFS_RMAP_OWN_COW;
- if (!info->sc->sa.rmap_cur || xchk_skip_xref(info->sc->sm))
+ if (xchk_skip_xref(info->sc->sm))
return;
/* Find the rmap record for this irec. */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 663/733] xfs: fix rtrefcount btree block counting in scrub
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (661 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 662/733] xfs: fix rtrmap cross-referencing elision logic Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 664/733] xfs: fix replaying dirent removals into the temporary directory Greg Kroah-Hartman
` (81 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 3f9fd694fa429e89fe6de51b22b0ed5fb8b2daf4 upstream.
LOLLM started on a long tangent about how xchk_refcount_xref_rmap
shouldn't nope out if sc->sa.rmap_cur isn't set, because nothing ever
sets that field. It's right about the condition, but misses the bigger
problem, which is that to count the rtrefcount btree blocks, we have to
walk all rmap records in each AG in the data section. That was papered
over by the incorrect !sc->sa.rmap_cur test.
In other words, we need a perag iteration loop here. Restructure the
code to do that, and now it'll all work properly. Fix the confusing
function name prefix.
Cc: stable@vger.kernel.org # v6.14
Fixes: c27929670de144 ("xfs: scrub the realtime refcount btree")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/rtrefcount.c | 64 +++++++++++++++++++++++++++++++++++++++-------
1 file changed, 55 insertions(+), 9 deletions(-)
--- a/fs/xfs/scrub/rtrefcount.c
+++ b/fs/xfs/scrub/rtrefcount.c
@@ -20,6 +20,7 @@
#include "xfs_metafile.h"
#include "xfs_rtrefcount_btree.h"
#include "xfs_rtalloc.h"
+#include "xfs_ag.h"
#include "scrub/scrub.h"
#include "scrub/common.h"
#include "scrub/btree.h"
@@ -504,30 +505,75 @@ xchk_rtrefcountbt_rec(
return 0;
}
+/* Count the number of blocks used by the rtrefcount btree file in this AG. */
+static int
+xchk_rtrefcount_count_agblocks(
+ struct xfs_scrub *sc,
+ xfs_agnumber_t agno,
+ const struct xfs_owner_info *btree_oinfo,
+ xfs_filblks_t *blocks)
+{
+ xfs_filblks_t agblocks = 0;
+ int error;
+
+ error = xchk_ag_init_existing(sc, agno, &sc->sa);
+ if (error)
+ goto out_free;
+
+ /*
+ * If we don't have an rmap cursor, we can't complete the cross
+ * referencing, so return EFSCORRUPTED to end the loop and trigger the
+ * XFAIL flag.
+ */
+ if (!sc->sa.rmap_cur) {
+ error = -EFSCORRUPTED;
+ goto out_free;
+ }
+
+ error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, btree_oinfo,
+ &agblocks);
+ if (error)
+ goto out_free;
+
+ *blocks += agblocks;
+out_free:
+ xchk_ag_free(sc, &sc->sa);
+ return error;
+}
+
/* Make sure we have as many refc blocks as the rmap says. */
STATIC void
-xchk_refcount_xref_rmap(
+xchk_rtrefcount_xref_rmap(
struct xfs_scrub *sc,
const struct xfs_owner_info *btree_oinfo,
xfs_extlen_t cow_blocks)
{
xfs_filblks_t refcbt_blocks = 0;
- xfs_filblks_t blocks;
- int error;
+ xfs_filblks_t blocks = 1; /* one for the iroot */
+ xfs_agnumber_t agno;
+ int error = 0;
- if (!sc->sr.rmap_cur || !sc->sa.rmap_cur || xchk_skip_xref(sc->sm))
+ if (!xfs_has_rmapbt(sc->mp) || xchk_skip_xref(sc->sm))
return;
/* Check that we saw as many refcbt blocks as the rmap knows about. */
error = xfs_btree_count_blocks(sc->sr.refc_cur, &refcbt_blocks);
if (!xchk_btree_process_error(sc, sc->sr.refc_cur, 0, &error))
return;
- error = xchk_count_rmap_ownedby_ag(sc, sc->sa.rmap_cur, btree_oinfo,
- &blocks);
- if (!xchk_should_check_xref(sc, &error, &sc->sa.rmap_cur))
+
+ for (agno = 0; agno < sc->mp->m_sb.sb_agcount; agno++) {
+ error = xchk_rtrefcount_count_agblocks(sc, agno, btree_oinfo,
+ &blocks);
+ if (error)
+ break;
+ }
+ if (!xchk_fblock_xref_process_error(sc, XFS_DATA_FORK, 0, &error))
return;
if (blocks != refcbt_blocks)
- xchk_btree_xref_set_corrupt(sc, sc->sa.rmap_cur, 0);
+ xchk_fblock_xref_set_corrupt(sc, XFS_DATA_FORK, 0);
+
+ if (!sc->sr.rmap_cur || xchk_skip_xref(sc->sm))
+ return;
/* Check that we saw as many cow blocks as the rmap knows about. */
error = xchk_count_rmap_ownedby_ag(sc, sc->sr.rmap_cur,
@@ -568,7 +614,7 @@ xchk_rtrefcountbt(
*/
xchk_rtrefcountbt_xref_gaps(sc, &rrc,
xfs_rtx_to_rgbno(sc->sr.rtg, sc->mp->m_sb.sb_rgextents));
- xchk_refcount_xref_rmap(sc, &btree_oinfo, rrc.cow_blocks);
+ xchk_rtrefcount_xref_rmap(sc, &btree_oinfo, rrc.cow_blocks);
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 664/733] xfs: fix replaying dirent removals into the temporary directory
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (662 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 663/733] xfs: fix rtrefcount btree block counting in scrub Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 665/733] xfs: fix reclaimed page accounting in xfs_buf_free Greg Kroah-Hartman
` (80 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit e854f9a28b1fa08dfa5bf18ee4184fae90106180 upstream.
xrep_dir_replay_removename is the function that replays a directory
entry removal from sc->ip into the temporary directory so that when we
swap the contents of sc->tempip and sc->ip, the directory is correct.
LOLLM noticed that we were passing the wrong inode pointer into
xrep_dir_init_args. It doesn't make sense to set rd->args.dp to
rd->args.dp so let's fix this.
Cc: stable@vger.kernel.org # v6.10
Fixes: 8559b21a64d983 ("xfs: implement live updates for directory repairs")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dir_repair.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -721,7 +721,7 @@ xrep_dir_replay_removename(
const struct xfs_name *name,
xfs_extlen_t total)
{
- struct xfs_inode *dp = rd->args.dp;
+ struct xfs_inode *dp = rd->sc->tempip;
ASSERT(S_ISDIR(VFS_I(dp)->i_mode));
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 665/733] xfs: fix reclaimed page accounting in xfs_buf_free
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (663 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 664/733] xfs: fix replaying dirent removals into the temporary directory Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 666/733] xfs: fix parent rec lookup initialization in xrep_metapath_unlink Greg Kroah-Hartman
` (79 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Eric Sandeen, Christoph Hellwig,
Darrick J. Wong, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Sandeen <sandeen@redhat.com>
commit 4164b1e3d728c7cc05e0c1171068aa046542ecc3 upstream.
To obtain nr. of pages in "size" bytes, we need howmany(size, PAGE_SIZE)
not howmany(size, PAGE_SHIFT). This over-reports reclaim by orders of
magnitude, up to 4096x on a 64k page system.
Fixes: e2874632a621 ("xfs: use vmalloc instead of vm_map_area for buffer backing memory")
Cc: stable@vger.kernel.org # v6.15+
Signed-off-by: Eric Sandeen <sandeen@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_buf.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -108,7 +108,7 @@ xfs_buf_free(
ASSERT(list_empty(&bp->b_lru));
if (!xfs_buftarg_is_mem(bp->b_target) && size >= PAGE_SIZE)
- mm_account_reclaimed_pages(howmany(size, PAGE_SHIFT));
+ mm_account_reclaimed_pages(howmany(size, PAGE_SIZE));
if (is_vmalloc_addr(bp->b_addr))
vfree(bp->b_addr);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 666/733] xfs: fix parent rec lookup initialization in xrep_metapath_unlink
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (664 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 665/733] xfs: fix reclaimed page accounting in xfs_buf_free Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 667/733] xfs: fix name string recording in slowpath pptr tracepoints Greg Kroah-Hartman
` (78 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit cdc4a083adf7bf15a0722c5bd292a35e00112006 upstream.
LOLLM notices that xrep_metapath_unlink looks for a parent pointer in
the child metafile that it's removing, but initializes the parent handle
using the child. This is obviously incorrect, so fix that.
Cc: stable@vger.kernel.org # v6.13
Fixes: 0d2c636e489c11 ("xfs: repair metadata directory file path connectivity")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/metapath.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/metapath.c
+++ b/fs/xfs/scrub/metapath.c
@@ -397,7 +397,7 @@ xrep_metapath_unlink(
/* Figure out if we're removing a parent pointer too. */
if (xfs_has_parent(mp)) {
- xfs_inode_to_parent_rec(&rec, ip);
+ xfs_inode_to_parent_rec(&rec, mpath->dp);
error = xfs_parent_lookup(sc->tp, ip, &mpath->xname, &rec,
&mpath->pptr_args);
switch (error) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 667/733] xfs: fix name string recording in slowpath pptr tracepoints
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (665 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 666/733] xfs: fix parent rec lookup initialization in xrep_metapath_unlink Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 668/733] xfs: fix media verification ioctl for internal rt volumes Greg Kroah-Hartman
` (77 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 72d0a3e4405c1353869bfbbc67c7b8a29df7afd0 upstream.
LOLLM observes that we memcpy from the xfs_name object, not the name
string pointed to by the xfs_name. Fix that.
Cc: stable@vger.kernel.org # v6.10
Fixes: b961c8bf1fc3d0 ("xfs: deferred scrub of dirents")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/trace.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/trace.h
+++ b/fs/xfs/scrub/trace.h
@@ -1640,7 +1640,7 @@ DECLARE_EVENT_CLASS(xchk_pptr_class,
__entry->dev = ip->i_mount->m_super->s_dev;
__entry->ino = I_INO(ip);
__entry->namelen = name->len;
- memcpy(__get_str(name), name, name->len);
+ memcpy(__get_str(name), name->name, name->len);
__entry->far_ino = far_ino;
),
TP_printk("dev %d:%d ino 0x%llx name '%.*s' far_ino 0x%llx",
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 668/733] xfs: fix media verification ioctl for internal rt volumes
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (666 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 667/733] xfs: fix name string recording in slowpath pptr tracepoints Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 669/733] xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN Greg Kroah-Hartman
` (76 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit f789d291bbdac6bc02d9d77e0141e138626c17a8 upstream.
A media scan of a filesystem containing an internal rt volume produced
an error in xfs_scrub phase 6 complaining about a truncated realtime
device. The rt device wasn't truncated, but the media scan code thought
we were trying to start a scan past the end of m_rtdev_targp. That in
turn is an alias for m_ddev_targp, but in xfs_configure_buftarg we set
nr_sectors to the size of the data section. We don't account for an
internal realtime section, so the kernel doesn't scan any part of it.
Oops.
Reproducer:
# mkfs.xfs -f /dev/sda -r zoned=1 -d rtinherit=1
# mount /dev/sda /mnt
# dd if=/dev/zero of=/mnt/a bs=1024k count=100
# sync
# xfs_info /mnt
meta-data=/dev/sda isize=512 agcount=4, agsize=32768 blks
= sectsz=512 attr=2, projid32bit=1
= crc=1 finobt=1, sparse=1, rmapbt=1
= reflink=0 bigtime=1 inobtcount=1 nrext64=1
= exchange=1 metadir=1
data = bsize=4096 blocks=131072, imaxpct=25
= sunit=0 swidth=0 blks
naming =version 2 bsize=4096 ascii-ci=0, ftype=1, parent=1
log =internal log bsize=4096 blocks=16384, version=2
= sectsz=512 sunit=0 blks, lazy-count=1
realtime =internal extsz=4096 blocks=1114112, rtextents=1114112
= rgcount=17 rgsize=65536 extents
= zoned=1 start=131072 reserved=53248
IOWS: 512M data volume, 3.1G internal rt section. Now let's try some
media verification:
# xfs_io -c 'verifymedia -d' -c 'verifymedia -r' /mnt
verified 536870912/536870912 bytes at offset 0
512 MiB, 1 ops; 0.0496 sec (10.067 GiB/sec and 20.1345 ops/sec)
verified 536870912/536870912 bytes at offset 0
512 MiB, 1 ops; 0.0409 sec (12.222 GiB/sec and 24.4439 ops/sec)
Notice how xfs_io says we only verified 512M of the rt volume? If you
run btrace in the background you'll see that we read the first 512M of
the volume (aka the data section) twice and never read anything from the
rt section.
An earlier fix tried messing with the buftarg geometry, but I've decided
on a more targetted fix for the media verification code. All we have to
do is calculate the starting and ending daddr for the device that we're
verifying, and clamp the user's input values to that range. This leads
to some bogosity in the output reporting:
# xfs_io -c 'verifymedia -d' -c 'verifymedia -r' /mnt/t
verified 536870912/536870912 bytes at offset 0
512 MiB, 1 ops; 0.0606 sec (8.248 GiB/sec and 16.4968 ops/sec)
verified 5100273664/5100273664 bytes at offset 0
4.750 GiB, 1 ops; 0.3329 sec (14.267 GiB/sec and 3.0035 ops/sec)
Because we don't have a way to report that we didn't really do anything
at all for that first 512M of address space of the rt "device". But at
least we're no longer ignoring real media.
(Note that the fsmap/bmap/fiemap calls all report physical addresses for
the internal rt volume as offsets from the start of the data device, and
the media verifier call consumes the same. We baked that into the
user-visible behavior in 6.15, so we're stuck with that sparse hole at
the beginning.)
Cc: stable@vger.kernel.org # v6.15
Fixes: bdc03eb5f98f6f ("xfs: allow internal RT devices for zoned mode")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_verify_media.c | 24 +++++++++++++++++-------
1 file changed, 17 insertions(+), 7 deletions(-)
--- a/fs/xfs/xfs_verify_media.c
+++ b/fs/xfs/xfs_verify_media.c
@@ -268,6 +268,8 @@ xfs_verify_media(
struct xfs_buftarg *btp = NULL;
struct bio *bio;
struct folio *folio;
+ xfs_daddr_t dev_start = 0;
+ xfs_daddr_t dev_end = 0;
xfs_daddr_t daddr;
uint64_t bbcount;
int error = 0;
@@ -277,24 +279,33 @@ xfs_verify_media(
switch (me->me_dev) {
case XFS_DEV_DATA:
btp = mp->m_ddev_targp;
+ dev_end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_dblocks);
break;
case XFS_DEV_LOG:
- if (mp->m_logdev_targp != mp->m_ddev_targp)
+ if (mp->m_logdev_targp != mp->m_ddev_targp) {
btp = mp->m_logdev_targp;
+ dev_end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_logblocks);
+ }
break;
case XFS_DEV_RT:
btp = mp->m_rtdev_targp;
+ dev_start = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart);
+ dev_end = XFS_FSB_TO_BB(mp, mp->m_sb.sb_rtstart +
+ mp->m_sb.sb_rblocks);
break;
}
if (!btp)
return -ENODEV;
/*
- * If the caller told us to verify beyond the end of the disk, tell the
- * user exactly where that was.
+ * If the caller told us to verify before the start or beyond the end
+ * of the disk volume, tell the user exactly where the volume starts
+ * and ends.
*/
- if (me->me_end_daddr > btp->bt_nr_sectors)
- me->me_end_daddr = btp->bt_nr_sectors;
+ if (me->me_end_daddr > dev_end)
+ me->me_end_daddr = dev_end;
+ if (me->me_start_daddr < dev_start)
+ me->me_start_daddr = dev_start;
/* start and end have to be aligned to the lba size */
if (!IS_ALIGNED(BBTOB(me->me_start_daddr | me->me_end_daddr),
@@ -323,8 +334,7 @@ xfs_verify_media(
* verifying.
*/
daddr = me->me_start_daddr;
- bbcount = min_t(sector_t, me->me_end_daddr, btp->bt_nr_sectors) -
- me->me_start_daddr;
+ bbcount = me->me_end_daddr - me->me_start_daddr;
folio = xfs_verify_alloc_folio(xfs_verify_iosize(me, btp, bbcount));
if (!folio)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 669/733] xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (667 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 668/733] xfs: fix media verification ioctl for internal rt volumes Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 670/733] xfs: fix bnobt repair space reservation disposal failure Greg Kroah-Hartman
` (75 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lin Jiapeng (TencentOS Red Team),
Darrick J. Wong, Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lin Jiapeng <ljp1205831794@gmail.com>
commit a23eca88448e52eb1a81549862df7adce794fafb upstream.
When exchanging two full-file ranges, xmi_can_exchange_reflink_flags()
can move the reflink inode flag from the file that currently has it to
the other file, as long as exactly one side is marked. This assumes
that the file contents, and therefore all shared extents, are exchanged.
That assumption is not true when XFS_EXCHMAPS_INO1_WRITTEN is set.
xfs_exchmaps_can_skip_mapping() can skip hole and unwritten mappings
from file1, so an exchange can complete without moving every mapping
that the earlier flag-swap decision accounted for. In that case the
post-operation cleanup can clear the reflink flag from an inode that
still owns shared written extents. Later writes then take the
non-reflink write path and may update blocks that should still have
been protected by CoW, which shows up as data corruption between
reflink-related files.
Fix this by disabling the reflink flag exchange whenever
XFS_EXCHMAPS_INO1_WRITTEN is requested. The contents exchange can still
proceed; the conservative outcome is that both inodes keep the reflink
flag. The regular reflink flag cleanup path can drop the extra flag
later once the inode no longer has shared extents.
Reported-by: Lin Jiapeng (TencentOS Red Team) <jiapenglin@tencent.com>
Fixes: 966ceafc7a43 ("xfs: create deferred log items for file mapping exchanges")
Cc: stable@vger.kernel.org # v6.10
Reviewed-by: Darrick J. Wong <djwong@kernel.org>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Lin Jiapeng <jiapenglin@tencent.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_exchmaps.c | 10 ++++++++++
1 file changed, 10 insertions(+)
--- a/fs/xfs/libxfs/xfs_exchmaps.c
+++ b/fs/xfs/libxfs/xfs_exchmaps.c
@@ -969,6 +969,16 @@ xmi_can_exchange_reflink_flags(
if (req->flags & XFS_EXCHMAPS_INO1_WRITTEN)
return false;
+ /*
+ * The INO1_WRITTEN optimization can skip exchanging hole and
+ * unwritten mappings, which means we cannot guarantee that all
+ * shared extents actually moved to the other file. Clearing the
+ * reflink flag of an inode that still holds shared extents breaks
+ * the CoW write path, so refuse to exchange the flags in that case.
+ */
+ if (req->flags & XFS_EXCHMAPS_INO1_WRITTEN)
+ return false;
+
if (hweight32(reflink_state) != 1)
return false;
if (req->startoff1 != 0 || req->startoff2 != 0)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 670/733] xfs: fix bnobt repair space reservation disposal failure
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (668 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 669/733] xfs: fix exchange-range reflink flag clearing issue with INO1_WRITTEN Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 671/733] xfs: fix backwards skipping logic in xrep_quota_block Greg Kroah-Hartman
` (74 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit c83d1ef97ee3b0b92797d4b4932a3a813ba05b86 upstream.
LOLLM complains that we don't bubble failures from xrep_abt_dispose_one
upwards in the callstack. A failure to clean up the space used (or
reserved but not used) by the new bnobt/cntbt should be reported.
Cc: stable@vger.kernel.org # v6.8
Fixes: 4bdfd7d15747b1 ("xfs: repair free space btrees")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/alloc_repair.c | 18 ++++++++++++------
1 file changed, 12 insertions(+), 6 deletions(-)
--- a/fs/xfs/scrub/alloc_repair.c
+++ b/fs/xfs/scrub/alloc_repair.c
@@ -571,7 +571,7 @@ xrep_abt_dispose_one(
* allocation, and blocks that didn't get used can be freed via the usual
* (deferred) means.
*/
-STATIC void
+STATIC int
xrep_abt_dispose_reservations(
struct xrep_abt *ra,
int error)
@@ -582,9 +582,13 @@ xrep_abt_dispose_reservations(
goto junkit;
list_for_each_entry_safe(resv, n, &ra->new_bnobt.resv_list, list) {
- error = xrep_abt_dispose_one(ra, resv);
- if (error)
+ int error2 = xrep_abt_dispose_one(ra, resv);
+
+ if (error2) {
+ if (!error)
+ error = error2;
goto junkit;
+ }
}
junkit:
@@ -596,6 +600,7 @@ junkit:
xrep_newbt_cancel(&ra->new_bnobt);
xrep_newbt_cancel(&ra->new_cntbt);
+ return error;
}
/* Retrieve free space data for bulk load. */
@@ -801,7 +806,9 @@ xrep_abt_build_new_trees(
goto err_newbt;
/* Dispose of any unused blocks and the accounting information. */
- xrep_abt_dispose_reservations(ra, error);
+ error = xrep_abt_dispose_reservations(ra, error);
+ if (error)
+ return error;
return xrep_roll_ag_trans(sc);
@@ -812,8 +819,7 @@ err_cur:
xfs_btree_del_cursor(cnt_cur, error);
xfs_btree_del_cursor(bno_cur, error);
err_newbt:
- xrep_abt_dispose_reservations(ra, error);
- return error;
+ return xrep_abt_dispose_reservations(ra, error);
}
/*
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 671/733] xfs: fix backwards skipping logic in xrep_quota_block
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (669 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 670/733] xfs: fix bnobt repair space reservation disposal failure Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 672/733] xfs: fix backwards mergeability logic in refcount scrubber Greg Kroah-Hartman
` (73 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit d7f97be48cbe3751e44a45373c0e91e93b976f98 upstream.
LOLLM complains about the logic in xrep_quota_block that skips
reinitializing the ondisk dquot if there aren't any problems that would
impede a dqiterate walk later. I got the type checking logic backwards,
which is the source of the problem. Fix that.
Cc: stable@vger.kernel.org # v6.8
Fixes: a5b91555403e3a ("xfs: repair quotas")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/quota_repair.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -325,7 +325,7 @@ xrep_quota_block(
* If there's nothing that would impede a dqiterate, we're
* done.
*/
- if ((ddq->d_type & XFS_DQTYPE_REC_MASK) != dqtype ||
+ if ((ddq->d_type & XFS_DQTYPE_REC_MASK) == dqtype &&
id == be32_to_cpu(ddq->d_id)) {
xfs_trans_brelse(sc->tp, bp);
return 0;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 672/733] xfs: fix backwards mergeability logic in refcount scrubber
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (670 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 671/733] xfs: fix backwards skipping logic in xrep_quota_block Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 673/733] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
` (72 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit e8b01aaafffe6b852325debdf1ef4b13ccea1cd7 upstream.
When we start the refcount or rtrefcount btree scanners, prev_rec is
initialized to all zeroes. This is done so that the record mergeability
checks skip the first record because you must have two records to
compare. Unfortunately, I got the logic backwards, so scrub has never
complained about mergeable refcountbt records. Fix this bug that LOLLM
noticed.
Cc: stable@vger.kernel.org # v6.4
Fixes: db0502b39c21d1 ("xfs: flag refcount btree records that could be merged")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/refcount.c | 2 +-
fs/xfs/scrub/rtrefcount.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
--- a/fs/xfs/scrub/refcount.c
+++ b/fs/xfs/scrub/refcount.c
@@ -410,7 +410,7 @@ xchk_refcount_mergeable(
const struct xfs_refcount_irec *r1 = &rrc->prev_rec;
/* Ignore if prev_rec is not yet initialized. */
- if (r1->rc_blockcount > 0)
+ if (r1->rc_blockcount == 0)
return false;
if (r1->rc_domain != r2->rc_domain)
--- a/fs/xfs/scrub/rtrefcount.c
+++ b/fs/xfs/scrub/rtrefcount.c
@@ -376,7 +376,7 @@ xchk_rtrefcount_mergeable(
const struct xfs_refcount_irec *r1 = &rrc->prev_rec;
/* Ignore if prev_rec is not yet initialized. */
- if (r1->rc_blockcount > 0)
+ if (r1->rc_blockcount == 0)
return false;
if (r1->rc_startblock + r1->rc_blockcount != r2->rc_startblock)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 673/733] xfs: dont stash removename operations with unknown ftype
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (671 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 672/733] xfs: fix backwards mergeability logic in refcount scrubber Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 674/733] xfs: dont spin forever on zero-length dirents when salvaging them Greg Kroah-Hartman
` (71 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 865b751e75039fc07838b3200f9740256653da9a upstream.
LOLLM notices that the behavior of xrep_dir_replay_update changes based
on the ftype recorded in the stashed removename information. It also
notices that the unlink iops sometimes set that ftype to FT_UNKNOWN
because the regular directory tree update code paths don't need to know
the ftype of the child.
Unfortunately, this results in incorrect link counts, which eventually
trips link count errors in later phases of xfs_scrub, or in xfs_repair.
Fix this by creating a second xfs_name with the type set correctly.
Cc: stable@vger.kernel.org # v6.10
Fixes: 8559b21a64d983 ("xfs: implement live updates for directory repairs")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dir_repair.c | 19 +++++++++++++++++--
1 file changed, 17 insertions(+), 2 deletions(-)
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -1375,9 +1375,24 @@ xrep_dir_live_update(
if (p->delta > 0)
error = xrep_dir_stash_createname(rd, p->name,
I_INO(p->ip));
- else
- error = xrep_dir_stash_removename(rd, p->name,
+ else {
+ /*
+ * xfs_dentry_to_name in unlink or rename-exchange can
+ * pass us names with ftype FT_UNKNOWN, but we really
+ * must know the ftype of the child that is being
+ * removed so that we can do nlink updates correctly
+ * without holding inode references.
+ */
+ struct xfs_name name = {
+ .name = p->name->name,
+ .len = p->name->len,
+ .type = xfs_mode_to_ftype(
+ VFS_IC(p->ip)->i_mode),
+ };
+
+ error = xrep_dir_stash_removename(rd, &name,
I_INO(p->ip));
+ }
mutex_unlock(&rd->pscan.lock);
if (error)
goto out_abort;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 674/733] xfs: dont spin forever on zero-length dirents when salvaging them
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (672 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 673/733] xfs: dont stash removename operations with unknown ftype Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 675/733] xfs: dont modify file attributes or poke fsnotify for dry runs Greg Kroah-Hartman
` (70 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 9f84792b40d0c96833341602144574bf0bd14a6a upstream.
LOLLM noticed that xrep_dir_recover_data can spin forever if it
encounters an unused dirent that claims to have length zero. Fix that,
and prevent the same thing from happening with a zero-length entry.
Cc: stable@vger.kernel.org # v6.10
Fixes: b1991ee3e7cf85 ("xfs: online repair of directories")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dir_repair.c | 8 +++++++-
1 file changed, 7 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/dir_repair.c
+++ b/fs/xfs/scrub/dir_repair.c
@@ -484,18 +484,24 @@ xrep_dir_recover_data(
while (offset < end) {
struct xfs_dir2_data_unused *dup = bp->b_addr + offset;
struct xfs_dir2_data_entry *dep = bp->b_addr + offset;
+ unsigned int advance;
if (xchk_should_terminate(rd->sc, &error))
return error;
/* Skip unused entries. */
if (be16_to_cpu(dup->freetag) == XFS_DIR2_DATA_FREE_TAG) {
+ if (!dup->length)
+ break;
offset += be16_to_cpu(dup->length);
continue;
}
/* Don't walk off the end of the block. */
- offset += xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
+ advance = xfs_dir2_data_entsize(rd->sc->mp, dep->namelen);
+ if (!advance)
+ break;
+ offset += advance;
if (offset > end)
break;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 675/733] xfs: dont modify file attributes or poke fsnotify for dry runs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (673 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 674/733] xfs: dont spin forever on zero-length dirents when salvaging them Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 676/733] xfs: dont leak new_bp if xfs_btree_bload_drop_buf fails Greg Kroah-Hartman
` (69 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 365fe37e10ea75840165f13322aa8481ea11dfef upstream.
I noticed that we shouldn't be removing file privileges when doing a dry
run of an exchange-range operation. LOLLM also points out that a dry
run shouldn't poke fsnotify because we don't actually change the files.
Fix both by gating them on !DRY_RUN.
Cc: stable@vger.kernel.org # v6.10
Fixes: 42672471f938cd ("xfs: bind together the front and back ends of the file range exchange code")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_exchrange.c | 12 +++++++++---
1 file changed, 9 insertions(+), 3 deletions(-)
--- a/fs/xfs/xfs_exchrange.c
+++ b/fs/xfs/xfs_exchrange.c
@@ -504,6 +504,9 @@ xfs_exchange_range_finish(
{
int error;
+ if (fxr->flags & XFS_EXCHANGE_RANGE_DRY_RUN)
+ return 0;
+
error = file_remove_privs(fxr->file1);
if (error)
return error;
@@ -783,9 +786,12 @@ xfs_exchange_range(
if (ret)
return ret;
- fsnotify_modify(fxr->file1);
- if (fxr->file2 != fxr->file1)
- fsnotify_modify(fxr->file2);
+ if (!(fxr->flags & XFS_EXCHANGE_RANGE_DRY_RUN)) {
+ fsnotify_modify(fxr->file1);
+ if (fxr->file2 != fxr->file1)
+ fsnotify_modify(fxr->file2);
+ }
+
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 676/733] xfs: dont leak new_bp if xfs_btree_bload_drop_buf fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (674 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 675/733] xfs: dont modify file attributes or poke fsnotify for dry runs Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 677/733] xfs: dont leak dqacct if rhashtable insertion fails Greg Kroah-Hartman
` (68 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit f1930bc578095409c2dcfca6e4e898b24f0f0de6 upstream.
LOLLM observes that in xfs_btree_bload_prep_block,
xfs_btree_bload_drop_buf can hit an IO error if writing the delwri
buffer list to disk fails. In this case, we fail to release new_bp,
which means we lose a locked buffer. Fix that.
Cc: stable@vger.kernel.org # v6.8
Fixes: e069d549705e49 ("xfs: constrain dirty buffers while formatting a staged btree")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/libxfs/xfs_btree_staging.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/xfs/libxfs/xfs_btree_staging.c
+++ b/fs/xfs/libxfs/xfs_btree_staging.c
@@ -337,8 +337,10 @@ xfs_btree_bload_prep_block(
xfs_btree_set_sibling(cur, *blockp, &new_ptr, XFS_BB_RIGHTSIB);
ret = xfs_btree_bload_drop_buf(bbl, buffers_list, bpp);
- if (ret)
+ if (ret) {
+ xfs_buf_relse(new_bp);
return ret;
+ }
/* Initialize the new btree block. */
xfs_btree_init_block_cur(cur, new_bp, level, nr_this_block);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 677/733] xfs: dont leak dqacct if rhashtable insertion fails
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (675 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 676/733] xfs: dont leak new_bp if xfs_btree_bload_drop_buf fails Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 678/733] xfs: destroy seen inode bitmap when we fail to add a dirpath Greg Kroah-Hartman
` (67 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 2eac8d01d2c776fc26b0ac74aebdf91bc4490891 upstream.
LOLLM observes that xqcheck_mod_live_ino_dqtrx doesn't free the newly
allocated dqa object if rhashtable insertion fails. Fix this leak.
Cc: stable@vger.kernel.org # v6.9
Fixes: 200491875ce144 ("xfs: track quota updates during live quotacheck")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/quotacheck.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/quotacheck.c
+++ b/fs/xfs/scrub/quotacheck.c
@@ -263,8 +263,10 @@ xqcheck_mod_live_ino_dqtrx(
dqa->tx_id = p->tx_id;
error = rhashtable_insert_fast(&xqc->shadow_dquot_acct,
&dqa->hash, xqcheck_dqacct_hash_params);
- if (error)
+ if (error) {
+ kfree(dqa);
goto out_abort;
+ }
}
/* Find the shadow dqtrx (or an empty slot) here. */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 678/733] xfs: destroy seen inode bitmap when we fail to add a dirpath
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (676 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 677/733] xfs: dont leak dqacct if rhashtable insertion fails Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 679/733] xfs: cross-reference the rtgroup superblock extent, not block Greg Kroah-Hartman
` (66 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 1a441c6842da75c5b862cc1c9f7969d6a93b54b9 upstream.
LOLLM observes a memory leak in xchk_dirtree_create_path if we create
the directory path object but appending the name to the path fails.
When this happens, we don't tear down the (empty) seen inode bitmap.
This is a pretty trivial error, but let's not leave logic bombs.
Do the same for a similar bug in xrep_dirtree_create_adoption_path.
Cc: stable@vger.kernel.org # v6.10
Fixes: 928b721a11789a ("xfs: teach online scrub to find directory tree structure problems")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/dirtree.c | 1 +
fs/xfs/scrub/dirtree_repair.c | 1 +
2 files changed, 2 insertions(+)
--- a/fs/xfs/scrub/dirtree.c
+++ b/fs/xfs/scrub/dirtree.c
@@ -259,6 +259,7 @@ xchk_dirtree_create_path(
dl->nr_paths++;
return 0;
out_path:
+ xino_bitmap_destroy(&path->seen_inodes);
kfree(path);
return error;
}
--- a/fs/xfs/scrub/dirtree_repair.c
+++ b/fs/xfs/scrub/dirtree_repair.c
@@ -619,6 +619,7 @@ xrep_dirtree_create_adoption_path(
return 0;
out_path:
+ xino_bitmap_destroy(&path->seen_inodes);
kfree(path);
return error;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 679/733] xfs: cross-reference the rtgroup superblock extent, not block
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (677 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 678/733] xfs: destroy seen inode bitmap when we fail to add a dirpath Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 680/733] xfs: count escaped corruption errors in scrub stats Greg Kroah-Hartman
` (65 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 79ab1af2034b2ad10c5f18910937b938d2ad2219 upstream.
LOLLM noticed that when libxfs creates a realtime superblock, it will
create an rtrmapbt record covering the entire rtextent in which the
superblock lives. However, the cross-referencing checks only look for
the first block, which means that we can miss a corrupt rtrmap record.
That will get picked up by the rtrmap scrubber, but we should make the
rgsuper scrubber more robust anyway.
Cc: stable@vger.kernel.org # v6.13
Fixes: 3f1bdf50ab1b9c ("xfs: scrub the realtime group superblock")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/rgsuper.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/fs/xfs/scrub/rgsuper.c
+++ b/fs/xfs/scrub/rgsuper.c
@@ -36,8 +36,10 @@ xchk_rgsuperblock_xref(
if (sc->sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
return;
- xchk_xref_is_used_rt_space(sc, xfs_rgbno_to_rtb(sc->sr.rtg, 0), 1);
- xchk_xref_is_only_rt_owned_by(sc, 0, 1, &XFS_RMAP_OINFO_FS);
+ xchk_xref_is_used_rt_space(sc, xfs_rgbno_to_rtb(sc->sr.rtg, 0),
+ sc->mp->m_sb.sb_rextsize);
+ xchk_xref_is_only_rt_owned_by(sc, 0, sc->mp->m_sb.sb_rextsize,
+ &XFS_RMAP_OINFO_FS);
}
int
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 680/733] xfs: count escaped corruption errors in scrub stats
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (678 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 679/733] xfs: cross-reference the rtgroup superblock extent, not block Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 681/733] xfs: compute dquot checksum after resetting dd_lsn in repair Greg Kroah-Hartman
` (64 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 4d0624679ae29b469016f1ce4714be58582ed06a upstream.
The main scrub code will quietly turn bubbled-up EFSCORRUPTED and
EFSBADCRC errors into corruption errors. These aren't recorded in the
scrub stats code (says LOLLM) so do that now.
Cc: stable@vger.kernel.org # v6.6
Fixes: d7a74cad8f4513 ("xfs: track usage statistics of online fsck")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/scrub.c | 3 +--
fs/xfs/scrub/stats.c | 28 +++++++++++++++++++---------
fs/xfs/scrub/stats.h | 4 ++--
3 files changed, 22 insertions(+), 13 deletions(-)
--- a/fs/xfs/scrub/scrub.c
+++ b/fs/xfs/scrub/scrub.c
@@ -765,8 +765,7 @@ out_nofix:
out_teardown:
error = xchk_teardown(sc, error);
out_sc:
- if (error != -ENOENT)
- xchk_stats_merge(mp, sm, &run);
+ xchk_stats_merge(mp, sm, error, &run);
kfree(sc);
out:
trace_xchk_done(XFS_I(file_inode(file)), sm, error);
--- a/fs/xfs/scrub/stats.c
+++ b/fs/xfs/scrub/stats.c
@@ -195,31 +195,37 @@ STATIC void
xchk_stats_merge_one(
struct xchk_stats *cs,
const struct xfs_scrub_metadata *sm,
+ int error,
const struct xchk_stats_run *run)
{
struct xchk_scrub_stats *css;
+ unsigned int sm_flags = sm->sm_flags;
if (sm->sm_type >= XFS_SCRUB_TYPE_NR) {
ASSERT(sm->sm_type < XFS_SCRUB_TYPE_NR);
return;
}
+ /* caller applies this same transformation after we return */
+ if (error == -EFSCORRUPTED || error == -EFSBADCRC)
+ sm_flags |= XFS_SCRUB_OFLAG_CORRUPT;
+
css = &cs->cs_stats[sm->sm_type];
spin_lock(&css->css_lock);
css->invocations++;
- if (!(sm->sm_flags & XFS_SCRUB_OFLAG_UNCLEAN))
+ if (!(sm_flags & XFS_SCRUB_OFLAG_UNCLEAN))
css->clean++;
- if (sm->sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
+ if (sm_flags & XFS_SCRUB_OFLAG_CORRUPT)
css->corrupt++;
- if (sm->sm_flags & XFS_SCRUB_OFLAG_PREEN)
+ if (sm_flags & XFS_SCRUB_OFLAG_PREEN)
css->preen++;
- if (sm->sm_flags & XFS_SCRUB_OFLAG_XFAIL)
+ if (sm_flags & XFS_SCRUB_OFLAG_XFAIL)
css->xfail++;
- if (sm->sm_flags & XFS_SCRUB_OFLAG_XCORRUPT)
+ if (sm_flags & XFS_SCRUB_OFLAG_XCORRUPT)
css->xcorrupt++;
- if (sm->sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
+ if (sm_flags & XFS_SCRUB_OFLAG_INCOMPLETE)
css->incomplete++;
- if (sm->sm_flags & XFS_SCRUB_OFLAG_WARNING)
+ if (sm_flags & XFS_SCRUB_OFLAG_WARNING)
css->warning++;
css->retries += run->retries;
css->checktime_us += howmany_64(run->scrub_ns, NSEC_PER_USEC);
@@ -237,10 +243,14 @@ void
xchk_stats_merge(
struct xfs_mount *mp,
const struct xfs_scrub_metadata *sm,
+ int error,
const struct xchk_stats_run *run)
{
- xchk_stats_merge_one(&global_stats, sm, run);
- xchk_stats_merge_one(mp->m_scrub_stats, sm, run);
+ if (error == -ENOENT)
+ return;
+
+ xchk_stats_merge_one(&global_stats, sm, error, run);
+ xchk_stats_merge_one(mp->m_scrub_stats, sm, error, run);
}
/* debugfs boilerplate */
--- a/fs/xfs/scrub/stats.h
+++ b/fs/xfs/scrub/stats.h
@@ -27,7 +27,7 @@ void xchk_stats_register(struct xchk_sta
void xchk_stats_unregister(struct xchk_stats *cs);
void xchk_stats_merge(struct xfs_mount *mp, const struct xfs_scrub_metadata *sm,
- const struct xchk_stats_run *run);
+ int error, const struct xchk_stats_run *run);
static inline u64 xchk_stats_now(void) { return ktime_get_ns(); }
static inline u64 xchk_stats_elapsed_ns(u64 since)
@@ -53,7 +53,7 @@ static inline u64 xchk_stats_elapsed_ns(
# define xchk_stats_unregister(cs) ((void)0)
# define xchk_stats_now() (0)
# define xchk_stats_elapsed_ns(x) (0 * (x))
-# define xchk_stats_merge(mp, sm, run) ((void)0)
+# define xchk_stats_merge(mp, sm, error, run) ((void)0)
#endif /* CONFIG_XFS_ONLINE_SCRUB_STATS */
#endif /* __XFS_SCRUB_STATS_H__ */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 681/733] xfs: compute dquot checksum after resetting dd_lsn in repair
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (679 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 680/733] xfs: count escaped corruption errors in scrub stats Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 682/733] xfs: check healthmon outbuffer space correctly Greg Kroah-Hartman
` (63 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit de20f7014917d661afc03d9a1c157d0ae2775b49 upstream.
LOLLM complains that xrep_quota_block updates dd_lsn after calculating
the crc of the ondisk dquot. That's clearly broken, so fix that.
Cc: stable@vger.kernel.org # v6.8
Fixes: a5b91555403e3a ("xfs: repair quotas")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/quota_repair.c | 9 ++++++++-
1 file changed, 8 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/quota_repair.c
+++ b/fs/xfs/scrub/quota_repair.c
@@ -363,11 +363,18 @@ xrep_quota_block(
ddq->d_rtbcount, &ddq->d_rtbtimer,
defq->rtb.time);
+ /*
+ * This transaction operates on raw disk buffers, so we don't
+ * have a dquot log item to assign the LSN for us. Instead,
+ * set it to zero so that log recovery will always replay any
+ * logged dquot item atop this buffer.
+ */
+ dqblk->dd_lsn = 0;
+
/* We only support v5 filesystems so always set these. */
uuid_copy(&dqblk->dd_uuid, &sc->mp->m_sb.sb_meta_uuid);
xfs_update_cksum((char *)dqblk, sizeof(struct xfs_dqblk),
XFS_DQUOT_CRC_OFF);
- dqblk->dd_lsn = 0;
}
switch (dqtype) {
case XFS_DQTYPE_USER:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 682/733] xfs: check healthmon outbuffer space correctly
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (680 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 681/733] xfs: compute dquot checksum after resetting dd_lsn in repair Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 683/733] xfs: bump lost_prev_errors if we lose even the healthmon lost event Greg Kroah-Hartman
` (62 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 74eeb68a628dbc4a8f976351ad2f1ef5463513ee upstream.
LOLLM notices that the outbuf space check in xfs_healthmon_format_pop
isn't quite correct -- it checks that there's enough space to write a
xfs_healthmon_event object, but the outbuffer is supposed to contain
xfs_health_monitor_event objects. Fix this by adding a helper, and
refactoring all three outbuf size checks to use it.
Cc: stable@vger.kernel.org # v7.0
Fixes: b3a289a2a9397b ("xfs: create event queuing, formatting, and discovery infrastructure")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_healthmon.c | 17 ++++++++++++++---
1 file changed, 14 insertions(+), 3 deletions(-)
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -744,6 +744,13 @@ static const unsigned int type_map[] = {
[XFS_HEALTHMON_DATALOST] = XFS_HEALTH_MONITOR_TYPE_DATALOST,
};
+static inline bool
+xfs_healthmon_check_outbuffer_space(const struct xfs_healthmon *hm)
+{
+ return hm->bufhead + sizeof(struct xfs_health_monitor_event) <=
+ hm->bufsize;
+}
+
/* Render event as a V0 structure */
STATIC int
xfs_healthmon_format_v0(
@@ -810,10 +817,10 @@ xfs_healthmon_format_v0(
break;
}
- ASSERT(hm->bufhead + sizeof(hme) <= hm->bufsize);
+ ASSERT(xfs_healthmon_check_outbuffer_space(hm));
/* copy formatted object to the outbuf */
- if (hm->bufhead + sizeof(hme) <= hm->bufsize) {
+ if (xfs_healthmon_check_outbuffer_space(hm)) {
memcpy(hm->buffer + hm->bufhead, &hme, sizeof(hme));
hm->bufhead += sizeof(hme);
}
@@ -896,7 +903,11 @@ xfs_healthmon_format_pop(
{
struct xfs_healthmon_event *event;
- if (hm->bufhead + sizeof(*event) > hm->bufsize)
+ /*
+ * Don't bother if there's not enough space to format even one event in
+ * the outbuffer.
+ */
+ if (!xfs_healthmon_check_outbuffer_space(hm))
return NULL;
mutex_lock(&hm->lock);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 683/733] xfs: bump lost_prev_errors if we lose even the healthmon lost event
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (681 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 682/733] xfs: check healthmon outbuffer space correctly Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 684/733] xfs: bail out on bitmap errors in xrep_agfl_fill Greg Kroah-Hartman
` (61 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 295f2cfd3e2c814c2ecd2c1d522bc31c5288e414 upstream.
LOLLM observes that we don't bump xfs_healthmon::lost_prev_event even if
we can't allocate or queue a LOST event, which means that events can
disappear silently when things are going very wrong. Bump the counter
to avoid this problem.
Cc: stable@vger.kernel.org # v7.0
Fixes: b3a289a2a9397b ("xfs: create event queuing, formatting, and discovery infrastructure")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_healthmon.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -334,8 +334,10 @@ xfs_healthmon_clear_lost_prev(
if (hm->events < XFS_HEALTHMON_MAX_EVENTS)
event = kmemdup(&lost_event, sizeof(struct xfs_healthmon_event),
GFP_NOFS);
- if (!event)
+ if (!event) {
+ xfs_healthmon_bump_lost(hm);
return -ENOMEM;
+ }
__xfs_healthmon_push(hm, event);
cleared:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 684/733] xfs: bail out on bitmap errors in xrep_agfl_fill
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (682 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 683/733] xfs: bump lost_prev_errors if we lose even the healthmon lost event Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 685/733] xfs: always set xfs_healthmon::first_event when inserting at front of list Greg Kroah-Hartman
` (60 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit eaf580538eb1be3d162400d04c4b7dc4c627296b upstream.
LOLLM also points out that the xagb_bitmap_set call in xrep_agfl_fill
can fail, but we don't check the result of xagb_bitmap_walk, so we
silently drop the error and proceed with inconsistent incore data.
That shouldn't be allowed.
Cc: stable@vger.kernel.org # v6.6
Fixes: 014ad53732d2ba ("xfs: use per-AG bitmaps to reap unused AG metadata blocks during repair")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
| 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/fs/xfs/scrub/agheader_repair.c
+++ b/fs/xfs/scrub/agheader_repair.c
@@ -699,7 +699,9 @@ xrep_agfl_init_header(
*/
xagb_bitmap_init(&af.used_extents);
af.agfl_bno = xfs_buf_to_agfl_bno(agfl_bp);
- xagb_bitmap_walk(agfl_extents, xrep_agfl_fill, &af);
+ error = xagb_bitmap_walk(agfl_extents, xrep_agfl_fill, &af);
+ if (error && error != -ECANCELED)
+ goto err_undo;
error = xagb_bitmap_disunion(agfl_extents, &af.used_extents);
if (error)
goto err_undo;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 685/733] xfs: always set xfs_healthmon::first_event when inserting at front of list
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (683 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 684/733] xfs: bail out on bitmap errors in xrep_agfl_fill Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 686/733] xfs: advance the findparent inode scan cursor while holding ILOCK Greg Kroah-Hartman
` (59 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Anuj Gupta, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 58a0c7578b25b578c16dea7db2493cfa3a08ecc2 upstream.
LOLLM complains that while __xfs_healthmon_insert is supposed to insert
an event at the head of the list, it doesn't do that correctly if the
list isn't empty. In that case it *should* make our new event point to
the current head, and then make the head point to the new event, but
it doesn't actually update the head so we never see the new event.
Fix this by always reassigning first_event. A subsequent patch will
clean this up to use a standard list_head, but I felt it important to
call out the bug fix first.
Cc: stable@vger.kernel.org # v7.0
Fixes: b3a289a2a9397b ("xfs: create event queuing, formatting, and discovery infrastructure")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Reviewed-by: Anuj Gupta <anuj20.g@samsung.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_healthmon.c | 3 +--
1 file changed, 1 insertion(+), 2 deletions(-)
diff --git a/fs/xfs/xfs_healthmon.c b/fs/xfs/xfs_healthmon.c
index 3ae5f4496ad1..a4efc084a8fc 100644
--- a/fs/xfs/xfs_healthmon.c
+++ b/fs/xfs/xfs_healthmon.c
@@ -278,8 +278,7 @@ __xfs_healthmon_insert(
event->time_ns = (now.tv_sec * NSEC_PER_SEC) + now.tv_nsec;
event->next = hm->first_event;
- if (!hm->first_event)
- hm->first_event = event;
+ hm->first_event = event;
if (!hm->last_event)
hm->last_event = event;
xfs_healthmon_bump_events(hm);
--
2.55.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 686/733] xfs: advance the findparent inode scan cursor while holding ILOCK
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (684 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 685/733] xfs: always set xfs_healthmon::first_event when inserting at front of list Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 687/733] xfs: actually recover intended file sizes in xfs_xmi_item_recover_intent Greg Kroah-Hartman
` (58 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Christoph Hellwig, Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit ad4497a92caba4630f75c80d49cb947026213280 upstream.
LOLLM pointed out a race condition in xrep_findparent_scan -- the
directory live update hook holds the directory ILOCK when it calls the
xchk_iscan_want_live_update predicate to figure out if it needs to
remember the live update, but xrep_findparent_scan drops the directory
ILOCK before advancing the cursor. Therefore, it's possible for a live
update to check the scan cursor after the scan drops the ILOCK but
before the scan updates its cursor. If this happens, we'll fail to
record the live update. Fix this by moving the cursor update logic
inside xrep_findparent_walk_directory.
Note that for non-directories it's ok to advance the cursor without
holding any ILOCK because the findparent scan only cares about directory
parents, not the children.
Cc: stable@vger.kernel.org # v6.10
Fixes: a07b45576264e7 ("xfs: scan the filesystem to repair a directory dotdot entry")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/scrub/findparent.c | 54 ++++++++++++++++++++++++++++++----------------
1 file changed, 36 insertions(+), 18 deletions(-)
--- a/fs/xfs/scrub/findparent.c
+++ b/fs/xfs/scrub/findparent.c
@@ -139,32 +139,52 @@ xrep_findparent_dirent(
return 0;
}
-/*
- * If this is a directory, walk the dirents looking for any that point to the
- * scrub target inode.
- */
-STATIC int
-xrep_findparent_walk_directory(
- struct xrep_findparent_info *fpi)
+static inline bool
+xrep_findparent_want_scan_file(
+ const struct xrep_findparent_info *fpi)
{
- struct xfs_scrub *sc = fpi->sc;
- struct xfs_inode *dp = fpi->dp;
- unsigned int lock_mode;
- int error = 0;
+ const struct xfs_scrub *sc = fpi->sc;
+ const struct xfs_inode *dp = fpi->dp;
+
+ /* Only directories can be parents */
+ if (!S_ISDIR(VFS_IC(dp)->i_mode))
+ return false;
/*
* The inode being scanned cannot be its own parent, nor can any
* temporary directory we created to stage this repair.
*/
if (dp == sc->ip || dp == sc->tempip)
- return 0;
+ return false;
/*
* Similarly, temporary files created to stage a repair cannot be the
* parent of this inode.
*/
if (xrep_is_tempfile(dp))
+ return false;
+
+ return true;
+}
+
+/*
+ * If this is a directory, walk the dirents looking for any that point to the
+ * scrub target inode.
+ */
+STATIC int
+xrep_findparent_walk_file(
+ struct xrep_findparent_info *fpi)
+{
+ struct xfs_scrub *sc = fpi->sc;
+ struct xfs_inode *dp = fpi->dp;
+ unsigned int lock_mode;
+ int error = 0;
+
+ if (!xrep_findparent_want_scan_file(fpi)) {
+ if (fpi->parent_scan)
+ xchk_iscan_mark_visited(&fpi->parent_scan->iscan, dp);
return 0;
+ }
/*
* Scan the directory to see if there it contains an entry pointing to
@@ -201,6 +221,8 @@ xrep_findparent_walk_directory(
goto out_unlock;
out_unlock:
+ if (fpi->parent_scan)
+ xchk_iscan_mark_visited(&fpi->parent_scan->iscan, dp);
xfs_iunlock(dp, lock_mode);
return error;
}
@@ -308,11 +330,7 @@ xrep_findparent_scan(
ASSERT(S_ISDIR(VFS_IC(sc->ip)->i_mode));
while ((ret = xchk_iscan_iter(&pscan->iscan, &fpi.dp)) == 1) {
- if (S_ISDIR(VFS_I(fpi.dp)->i_mode))
- ret = xrep_findparent_walk_directory(&fpi);
- else
- ret = 0;
- xchk_iscan_mark_visited(&pscan->iscan, fpi.dp);
+ ret = xrep_findparent_walk_file(&fpi);
xchk_irele(sc, fpi.dp);
if (ret)
break;
@@ -401,7 +419,7 @@ xrep_findparent_confirm(
goto out_rele;
}
- error = xrep_findparent_walk_directory(&fpi);
+ error = xrep_findparent_walk_file(&fpi);
if (error)
goto out_rele;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 687/733] xfs: actually recover intended file sizes in xfs_xmi_item_recover_intent
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (685 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 686/733] xfs: advance the findparent inode scan cursor while holding ILOCK Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 688/733] xfs: actually check internal-rtdev fields in the superblock Greg Kroah-Hartman
` (57 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Christoph Hellwig,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit b71ae66863e4320a3b7313b53bb4d65f1718d58b upstream.
LOLLM points out that xfs_xmi_item_recover_intent doesn't actually
restore the isize1 and isize2 fields that were recovered from an
unfinished exchmaps log intent item. Instead, xfs_exchmaps_init_intent
sets the wrong isize values from the recovered inodes, with the result
that the file sizes are not set correctly when item recovery finishes.
Fix this by restoring isize[12] from the log item.
Cc: stable@vger.kernel.org # v6.10
Fixes: 966ceafc7a4371 ("xfs: create deferred log items for file mapping exchanges")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Christoph Hellwig <hch@lst.de>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/xfs/xfs_exchmaps_item.c | 19 ++++++++++++++++++-
1 file changed, 18 insertions(+), 1 deletion(-)
--- a/fs/xfs/xfs_exchmaps_item.c
+++ b/fs/xfs/xfs_exchmaps_item.c
@@ -344,7 +344,17 @@ xfs_xmi_validate(
if (!xfs_verify_fileext(mp, xlf->xmi_startoff1, xlf->xmi_blockcount))
return false;
- return xfs_verify_fileext(mp, xlf->xmi_startoff2, xlf->xmi_blockcount);
+ if (!xfs_verify_fileext(mp, xlf->xmi_startoff2, xlf->xmi_blockcount))
+ return false;
+
+ if (xlf->xmi_flags & XFS_EXCHMAPS_SET_SIZES) {
+ if ((int64_t)xlf->xmi_isize1 < 0)
+ return false;
+ if ((int64_t)xlf->xmi_isize2 < 0)
+ return false;
+ }
+
+ return true;
}
/*
@@ -403,6 +413,13 @@ xfs_xmi_item_recover_intent(
*ipp1 = ip1;
*ipp2 = ip2;
xmi = xfs_exchmaps_init_intent(req);
+
+ /* Restore intended file sizes from recovered logged item */
+ if (req->flags & XFS_EXCHMAPS_SET_SIZES) {
+ xmi->xmi_isize1 = xlf->xmi_isize1;
+ xmi->xmi_isize2 = xlf->xmi_isize2;
+ }
+
xfs_defer_add_item(dfp, &xmi->xmi_list);
return xmi;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 688/733] xfs: actually check internal-rtdev fields in the superblock
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (686 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 687/733] xfs: actually recover intended file sizes in xfs_xmi_item_recover_intent Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 689/733] ASoC: cs35l56: Fix race between kexec and snd_soc_register_component() Greg Kroah-Hartman
` (56 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Darrick J. Wong, Carlos Maiolino,
Carlos Maiolino
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Darrick J. Wong <djwong@kernel.org>
commit 1ee2ce797c360785a3813fef62c90f427f3aed34 upstream.
LOLLM points out that the superblock scrubber doesn't check the new
fields that were added for internal realtime volumes when we added zoned
device support.
Cc: stable@vger.kernel.org # v6.15
Fixes: 2167eaabe2fadd ("xfs: define the zoned on-disk format")
Signed-off-by: Darrick J. Wong <djwong@kernel.org>
Assisted-by: LOLLM # finding obvious bugs
Reviewed-by: Carlos Maiolino <cmaiolino@redhat.com>
Signed-off-by: Carlos Maiolino <cem@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
| 7 +++++++
1 file changed, 7 insertions(+)
--- a/fs/xfs/scrub/agheader.c
+++ b/fs/xfs/scrub/agheader.c
@@ -418,6 +418,13 @@ xchk_superblock(
xchk_block_set_corrupt(sc, bp);
}
+ if (xfs_has_zoned(mp)) {
+ if (sb->sb_rtstart != cpu_to_be64(mp->m_sb.sb_rtstart))
+ xchk_block_set_corrupt(sc, bp);
+ if (sb->sb_rtreserved != cpu_to_be64(mp->m_sb.sb_rtreserved))
+ xchk_block_set_corrupt(sc, bp);
+ }
+
/* Everything else must be zero. */
sblen = xchk_superblock_ondisk_size(mp);
if (memchr_inv((char *)sb + sblen, 0, BBTOB(bp->b_length) - sblen))
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 689/733] ASoC: cs35l56: Fix race between kexec and snd_soc_register_component()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (687 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 688/733] xfs: actually check internal-rtdev fields in the superblock Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 690/733] wifi: ath9k_htc: dont store usb_device_id Greg Kroah-Hartman
` (55 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Richard Fitzgerald, Mark Brown
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Richard Fitzgerald <rf@opensource.cirrus.com>
commit 883e78c9e6007c91be96e99a36c35baf41bc8ed5 upstream.
Use a reboot notifier and a mutex to prevent snd_soc_register_component()
from racing with a kexec reboot. This prevents snd_soc_register_component()
from manipulating device lists while device_shutdown() is walking them.
Commit 1d80a4792f1de ("ASoC: cs35l56: Fix probe deadlock waiting for
SoundWire enumeration") moved snd_soc_register_component() out of probe()
into a workqueue item. See the description in that commit for a
detailed explanation.
That change introduces a race between snd_soc_register_component() and
kexec. The reboot notifier and mutex prevent the shutdown race.
There is one remaining race with KEXEC_JUMP because it does not invoke
reboot notifiers or freeze freezable workqueues. But KEXEC_JUMP is
rarely used and is supported on only two architectures (x86 and SuperH).
It does not appear to be enabled by default in any distro. It is also
unlikely there will be a KEXEC_JUMP before snd_soc_register_component()
has had the opportunity to execute. Fixing this can be deferred to a
future patch.
Fixes: 1d80a4792f1de ("ASoC: cs35l56: Fix probe deadlock waiting for SoundWire enumeration")
Assisted-by: Codex:gpt-5.6-sol
Signed-off-by: Richard Fitzgerald <rf@opensource.cirrus.com>
Link: https://patch.msgid.link/20260907093645.27407-1-rf@opensource.cirrus.com
Signed-off-by: Mark Brown <broonie@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
sound/soc/codecs/cs35l56.c | 45 +++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 45 insertions(+)
--- a/sound/soc/codecs/cs35l56.c
+++ b/sound/soc/codecs/cs35l56.c
@@ -18,9 +18,11 @@
#include <linux/interrupt.h>
#include <linux/math.h>
#include <linux/module.h>
+#include <linux/mutex.h>
#include <linux/pm.h>
#include <linux/pm_runtime.h>
#include <linux/property.h>
+#include <linux/reboot.h>
#include <linux/regmap.h>
#include <linux/regulator/consumer.h>
#include <linux/slab.h>
@@ -37,6 +39,13 @@
#include "wm_adsp.h"
#include "cs35l56.h"
+/*
+ * snd_soc_register_component() can call component_probe() on all instances
+ * in a card, so deferred registration must be protected across all instances.
+ */
+static DEFINE_MUTEX(cs35l56_component_register_lock);
+static bool cs35l56_shutting_down;
+
void cs35l56_mask_soundwire_interrupts(struct sdw_slave *peripheral)
{
/*
@@ -1959,6 +1968,11 @@ static void cs35l56_component_register_w
component_register_work);
int ret;
+ guard(mutex)(&cs35l56_component_register_lock);
+
+ if (cs35l56_shutting_down)
+ return;
+
PM_RUNTIME_ACQUIRE_AUTOSUSPEND(cs35l56->base.dev, pm_err);
ret = PM_RUNTIME_ACQUIRE_ERR(&pm_err);
if (ret) {
@@ -2219,6 +2233,37 @@ EXPORT_NS_GPL_DEV_PM_OPS(cs35l56_pm_ops_
};
#endif
+static int cs35l56_reboot_notify(struct notifier_block *nb,
+ unsigned long action, void *data)
+{
+ guard(mutex)(&cs35l56_component_register_lock);
+ cs35l56_shutting_down = true;
+
+ return NOTIFY_DONE;
+}
+
+static struct notifier_block cs35l56_reboot_notifier = {
+ .notifier_call = cs35l56_reboot_notify,
+};
+
+static int __init cs35l56_modinit(void)
+{
+ /*
+ * Use reboot notifier to prevent race between shutdown and
+ * snd_soc_register_component(). Driver shutdown() callback would
+ * run too late, after device_shutdown() is already walking the
+ * device list that component registration can modify.
+ */
+ return register_reboot_notifier(&cs35l56_reboot_notifier);
+}
+module_init(cs35l56_modinit);
+
+static void __exit cs35l56_modexit(void)
+{
+ unregister_reboot_notifier(&cs35l56_reboot_notifier);
+}
+module_exit(cs35l56_modexit);
+
MODULE_DESCRIPTION("ASoC CS35L56 driver");
MODULE_IMPORT_NS("SND_SOC_CS35L56_SHARED");
MODULE_IMPORT_NS("SND_SOC_CS_AMP_LIB");
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 690/733] wifi: ath9k_htc: dont store usb_device_id
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (688 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 689/733] ASoC: cs35l56: Fix race between kexec and snd_soc_register_component() Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 691/733] media: as102: do not rely on id table address comparison Greg Kroah-Hartman
` (54 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gary Guo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
[ Upstream commit 14d2ac442d660e112efc0ce87ad10085013ed2b1 ]
usb_device_id is not guaranteed to live longer than probe due to presence
of dynamic ID. All information apart from driver_data can be easily
retrieved from usb_device, so just store driver_data.
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-1-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/wireless/ath/ath9k/hif_usb.c | 12 ++++++------
drivers/net/wireless/ath/ath9k/hif_usb.h | 2 +-
2 files changed, 7 insertions(+), 7 deletions(-)
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.c b/drivers/net/wireless/ath/ath9k/hif_usb.c
index 47f904e7e6529..d3491ff08e6ef 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.c
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.c
@@ -1087,7 +1087,7 @@ static int ath9k_hif_usb_download_fw(struct hif_device_usb *hif_dev)
}
kfree(buf);
- if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
+ if (IS_AR7010_DEVICE(hif_dev->id_info))
firm_offset = AR7010_FIRMWARE_TEXT;
else
firm_offset = AR9271_FIRMWARE_TEXT;
@@ -1182,7 +1182,7 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,
if (MAJOR_VERSION_REQ == 1 && hif_dev->fw_minor_index == 3) {
const char *filename;
- if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
+ if (IS_AR7010_DEVICE(hif_dev->id_info))
filename = FIRMWARE_AR7010_1_1;
else
filename = FIRMWARE_AR9271;
@@ -1198,7 +1198,7 @@ static int ath9k_hif_request_firmware(struct hif_device_usb *hif_dev,
return -ENOENT;
} else {
- if (IS_AR7010_DEVICE(hif_dev->usb_device_id->driver_info))
+ if (IS_AR7010_DEVICE(hif_dev->id_info))
chip = "7010";
else
chip = "9271";
@@ -1255,9 +1255,9 @@ static void ath9k_hif_usb_firmware_cb(const struct firmware *fw, void *context)
ret = ath9k_htc_hw_init(hif_dev->htc_handle,
&hif_dev->interface->dev,
- hif_dev->usb_device_id->idProduct,
+ le16_to_cpu(hif_dev->udev->descriptor.idProduct),
hif_dev->udev->product,
- hif_dev->usb_device_id->driver_info);
+ hif_dev->id_info);
if (ret) {
ret = -EINVAL;
goto err_htc_hw_init;
@@ -1369,7 +1369,7 @@ static int ath9k_hif_usb_probe(struct usb_interface *interface,
hif_dev->udev = udev;
hif_dev->interface = interface;
- hif_dev->usb_device_id = id;
+ hif_dev->id_info = id->driver_info;
#ifdef CONFIG_PM
udev->reset_resume = 1;
#endif
diff --git a/drivers/net/wireless/ath/ath9k/hif_usb.h b/drivers/net/wireless/ath/ath9k/hif_usb.h
index dc0b0fa5c3257..b3e7b0fb54b84 100644
--- a/drivers/net/wireless/ath/ath9k/hif_usb.h
+++ b/drivers/net/wireless/ath/ath9k/hif_usb.h
@@ -115,7 +115,7 @@ struct cmd_buf {
struct hif_device_usb {
struct usb_device *udev;
struct usb_interface *interface;
- const struct usb_device_id *usb_device_id;
+ int id_info;
const void *fw_data;
size_t fw_size;
struct completion fw_done;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 691/733] media: as102: do not rely on id table address comparison
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (689 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 690/733] wifi: ath9k_htc: dont store usb_device_id Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 692/733] usb: serial: spcp8x5: dont store usb_device_id Greg Kroah-Hartman
` (53 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gary Guo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
[ Upstream commit 91a8c8c718889fc8ccf5c38b750d790e9f36f92d ]
The driver info should be retrieved using the driver_info field, not by
address comparison.
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-4-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/media/usb/as102/as102_usb_drv.c | 73 ++++++++++---------------
1 file changed, 30 insertions(+), 43 deletions(-)
diff --git a/drivers/media/usb/as102/as102_usb_drv.c b/drivers/media/usb/as102/as102_usb_drv.c
index a11024451cebd..be2f8be560fae 100644
--- a/drivers/media/usb/as102/as102_usb_drv.c
+++ b/drivers/media/usb/as102/as102_usb_drv.c
@@ -24,35 +24,33 @@ static void as102_usb_stop_stream(struct as102_dev_t *dev);
static int as102_open(struct inode *inode, struct file *file);
static int as102_release(struct inode *inode, struct file *file);
-static const struct usb_device_id as102_usb_id_table[] = {
- { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001) },
- { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID) },
- { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID) },
- { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID) },
- { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID) },
- { } /* Terminating entry */
+struct as102_dev_info {
+ const char *name;
+ /*
+ * eLNA configuration: devices built on the reference design work best
+ * with 0xA0, while custom designs seem to require 0xC0
+ */
+ uint8_t elna_cfg;
};
-/* Note that this table must always have the same number of entries as the
- as102_usb_id_table struct */
-static const char * const as102_device_names[] = {
- AS102_REFERENCE_DESIGN,
- AS102_PCTV_74E,
- AS102_ELGATO_EYETV_DTT_NAME,
- AS102_NBOX_DVBT_DONGLE_NAME,
- AS102_SKY_IT_DIGITAL_KEY_NAME,
- NULL /* Terminating entry */
-};
+#define DRIVER_INFO(dev_name, dev_elna_cfg) \
+ .driver_info = (kernel_ulong_t)&(const struct as102_dev_info){ \
+ .name = (dev_name), \
+ .elna_cfg = (dev_elna_cfg), \
+ }
-/* eLNA configuration: devices built on the reference design work best
- with 0xA0, while custom designs seem to require 0xC0 */
-static uint8_t const as102_elna_cfg[] = {
- 0xA0,
- 0xC0,
- 0xC0,
- 0xA0,
- 0xA0,
- 0x00 /* Terminating entry */
+static const struct usb_device_id as102_usb_id_table[] = {
+ { USB_DEVICE(AS102_USB_DEVICE_VENDOR_ID, AS102_USB_DEVICE_PID_0001),
+ DRIVER_INFO(AS102_REFERENCE_DESIGN, 0xA0) },
+ { USB_DEVICE(PCTV_74E_USB_VID, PCTV_74E_USB_PID),
+ DRIVER_INFO(AS102_PCTV_74E, 0xC0) },
+ { USB_DEVICE(ELGATO_EYETV_DTT_USB_VID, ELGATO_EYETV_DTT_USB_PID),
+ DRIVER_INFO(AS102_ELGATO_EYETV_DTT_NAME, 0xC0) },
+ { USB_DEVICE(NBOX_DVBT_DONGLE_USB_VID, NBOX_DVBT_DONGLE_USB_PID),
+ DRIVER_INFO(AS102_NBOX_DVBT_DONGLE_NAME, 0xA0) },
+ { USB_DEVICE(SKY_IT_DIGITAL_KEY_USB_VID, SKY_IT_DIGITAL_KEY_USB_PID),
+ DRIVER_INFO(AS102_SKY_IT_DIGITAL_KEY_NAME, 0xA0) },
+ { } /* Terminating entry */
};
struct usb_driver as102_usb_driver = {
@@ -336,29 +334,18 @@ static int as102_usb_probe(struct usb_interface *intf,
{
int ret;
struct as102_dev_t *as102_dev;
- int i;
-
- /* This should never actually happen */
- if (ARRAY_SIZE(as102_usb_id_table) !=
- (sizeof(as102_device_names) / sizeof(const char *))) {
- pr_err("Device names table invalid size");
- return -EINVAL;
- }
+ const struct as102_dev_info *info = (const struct as102_dev_info *)id->driver_info;
as102_dev = kzalloc_obj(struct as102_dev_t);
if (as102_dev == NULL)
return -ENOMEM;
- /* Assign the user-friendly device name */
- for (i = 0; i < ARRAY_SIZE(as102_usb_id_table); i++) {
- if (id == &as102_usb_id_table[i]) {
- as102_dev->name = as102_device_names[i];
- as102_dev->elna_cfg = as102_elna_cfg[i];
- }
- }
-
- if (as102_dev->name == NULL)
+ if (info) {
+ as102_dev->name = info->name;
+ as102_dev->elna_cfg = info->elna_cfg;
+ } else {
as102_dev->name = "Unknown AS102 device";
+ }
/* set private callback functions */
as102_dev->bus_adap.ops = &as102_priv_ops;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 692/733] usb: serial: spcp8x5: dont store usb_device_id
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (690 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 691/733] media: as102: do not rely on id table address comparison Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 693/733] net: usb: pegasus: dont rely on id table pointer arithmetic Greg Kroah-Hartman
` (52 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manuel Ebner, Danilo Krummrich,
Gary Guo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
[ Upstream commit 934e1322f18c1b58bca431c0d5d01e002060c990 ]
USB probe functions should not keep usb_device_id for longer than probe due
to presence of dynamic ID removal. USB serial does not support ID removal,
however in this case only driver_data is ever needed, there is no reason
keeping the usb_device_id in the first place, so convert it as well.
Reviewed-by: Manuel Ebner <manuelebner@mailbox.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-3-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/serial/spcp8x5.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/usb/serial/spcp8x5.c b/drivers/usb/serial/spcp8x5.c
index f610aef6bf59b..3ef7ca2c0cf44 100644
--- a/drivers/usb/serial/spcp8x5.c
+++ b/drivers/usb/serial/spcp8x5.c
@@ -133,14 +133,14 @@ struct spcp8x5_private {
static int spcp8x5_probe(struct usb_serial *serial,
const struct usb_device_id *id)
{
- usb_set_serial_data(serial, (void *)id);
+ usb_set_serial_data(serial, (void *)id->driver_info);
return 0;
}
static int spcp8x5_port_probe(struct usb_serial_port *port)
{
- const struct usb_device_id *id = usb_get_serial_data(port->serial);
+ unsigned int quirks = (unsigned int)(unsigned long)usb_get_serial_data(port->serial);
struct spcp8x5_private *priv;
priv = kzalloc_obj(*priv);
@@ -148,7 +148,7 @@ static int spcp8x5_port_probe(struct usb_serial_port *port)
return -ENOMEM;
spin_lock_init(&priv->lock);
- priv->quirks = id->driver_info;
+ priv->quirks = quirks;
usb_set_serial_port_data(port, priv);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 693/733] net: usb: pegasus: dont rely on id table pointer arithmetic
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (691 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 692/733] usb: serial: spcp8x5: dont store usb_device_id Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 694/733] usb: xusbatm: " Greg Kroah-Hartman
` (51 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gary Guo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
[ Upstream commit ce8101c331956bbd3e20681331dfd22eb7c1c1ea ]
The current code is broken when dynamic ID is involved; in such cases
usb_device_id parameter of probe lives on the heap and the pointer
arithmetic will get an index that is wildly out of bound. Instead of
keeping a side table for additional information, use driver_info field of
the usb_device_id.
The dynamic ID parsing code needs to be updated for this; convert it to
just write to the reserved entry for dynamic ID and remove the weird loop.
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-5-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/net/usb/pegasus.c | 54 ++++++++++++++++-----------------------
drivers/net/usb/pegasus.h | 3 ---
2 files changed, 22 insertions(+), 35 deletions(-)
diff --git a/drivers/net/usb/pegasus.c b/drivers/net/usb/pegasus.c
index 8700eeb8e22d0..aba1a640fc268 100644
--- a/drivers/net/usb/pegasus.c
+++ b/drivers/net/usb/pegasus.c
@@ -43,21 +43,12 @@ static bool loopback;
static bool mii_mode;
static char *devid;
-static struct usb_eth_dev usb_dev_id[] = {
-#define PEGASUS_DEV(pn, vid, pid, flags) \
- {.name = pn, .vendor = vid, .device = pid, .private = flags},
-#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
- PEGASUS_DEV(pn, vid, pid, flags)
-#include "pegasus.h"
-#undef PEGASUS_DEV
-#undef PEGASUS_DEV_CLASS
- {NULL, 0, 0, 0},
- {NULL, 0, 0, 0}
-};
+static struct usb_eth_dev dynamic_id_info = {};
static struct usb_device_id pegasus_ids[] = {
#define PEGASUS_DEV(pn, vid, pid, flags) \
- {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid},
+ {.match_flags = USB_DEVICE_ID_MATCH_DEVICE, .idVendor = vid, .idProduct = pid, \
+ .driver_info = (kernel_ulong_t)&(const struct usb_eth_dev) {.name = pn, .private = flags}},
/*
* The Belkin F8T012xx1 bluetooth adaptor has the same vendor and product
* IDs as the Belkin F5D5050, so we need to teach the pegasus driver to
@@ -66,7 +57,8 @@ static struct usb_device_id pegasus_ids[] = {
*/
#define PEGASUS_DEV_CLASS(pn, vid, pid, dclass, flags) \
{.match_flags = (USB_DEVICE_ID_MATCH_DEVICE | USB_DEVICE_ID_MATCH_DEV_CLASS), \
- .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass},
+ .idVendor = vid, .idProduct = pid, .bDeviceClass = dclass, \
+ .driver_info = (kernel_ulong_t)&(const struct usb_eth_dev) {.name = pn, .private = flags}},
#include "pegasus.h"
#undef PEGASUS_DEV
#undef PEGASUS_DEV_CLASS
@@ -402,12 +394,12 @@ static inline int reset_mac(pegasus_t *pegasus)
if (i == REG_TIMEOUT)
return -ETIMEDOUT;
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
+ if (le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_LINKSYS ||
+ le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_DLINK) {
set_register(pegasus, Gpio0, 0x24);
set_register(pegasus, Gpio0, 0x26);
}
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_ELCON) {
+ if (le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_ELCON) {
__u16 auxmode;
ret = read_mii_word(pegasus, 3, 0x1b, &auxmode);
if (ret < 0)
@@ -445,9 +437,9 @@ static int enable_net_traffic(struct net_device *dev, struct usb_device *usb)
memcpy(pegasus->eth_regs, data, sizeof(data));
ret = set_registers(pegasus, EthCtrl0, 3, data);
- if (usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_LINKSYS2 ||
- usb_dev_id[pegasus->dev_index].vendor == VENDOR_DLINK) {
+ if (le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_LINKSYS ||
+ le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_LINKSYS2 ||
+ le16_to_cpu(pegasus->usb->descriptor.idVendor) == VENDOR_DLINK) {
u16 auxmode;
ret = read_mii_word(pegasus, 0, 0x1b, &auxmode);
if (ret < 0)
@@ -1153,7 +1145,7 @@ static int pegasus_probe(struct usb_interface *intf,
struct usb_device *dev = interface_to_usbdev(intf);
struct net_device *net;
pegasus_t *pegasus;
- int dev_index = id - pegasus_ids;
+ const struct usb_eth_dev *info = (const struct usb_eth_dev *)id->driver_info;
int res = -ENOMEM;
static const u8 bulk_ep_addr[] = {
PEGASUS_USB_EP_BULK_IN | USB_DIR_IN,
@@ -1178,7 +1170,6 @@ static int pegasus_probe(struct usb_interface *intf,
goto out;
pegasus = netdev_priv(net);
- pegasus->dev_index = dev_index;
pegasus->intf = intf;
res = alloc_urbs(pegasus);
@@ -1206,7 +1197,7 @@ static int pegasus_probe(struct usb_interface *intf,
pegasus->msg_enable = netif_msg_init(msg_level, NETIF_MSG_DRV
| NETIF_MSG_PROBE | NETIF_MSG_LINK);
- pegasus->features = usb_dev_id[dev_index].private;
+ pegasus->features = info ? info->private : DEFAULT_GPIO_RESET;
res = get_interrupt_interval(pegasus);
if (res)
goto out2;
@@ -1235,7 +1226,7 @@ static int pegasus_probe(struct usb_interface *intf,
queue_delayed_work(system_long_wq, &pegasus->carrier_check,
CARRIER_CHECK_DELAY);
dev_info(&intf->dev, "%s, %s, %pM\n", net->name,
- usb_dev_id[dev_index].name, net->dev_addr);
+ info ? info->name : "(unknown)", net->dev_addr);
return 0;
out3:
@@ -1325,8 +1316,9 @@ static struct usb_driver pegasus_driver = {
static void __init parse_id(char *id)
{
- unsigned int vendor_id = 0, device_id = 0, flags = 0, i = 0;
+ unsigned int vendor_id = 0, device_id = 0, flags = 0;
char *token, *name = NULL;
+ int dyn_id_index = ARRAY_SIZE(pegasus_ids) - 2;
token = strsep(&id, ":");
if (token)
@@ -1348,14 +1340,12 @@ static void __init parse_id(char *id)
if (device_id > 0x10000 || device_id == 0)
return;
- for (i = 0; usb_dev_id[i].name; i++);
- usb_dev_id[i].name = name;
- usb_dev_id[i].vendor = vendor_id;
- usb_dev_id[i].device = device_id;
- usb_dev_id[i].private = flags;
- pegasus_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
- pegasus_ids[i].idVendor = vendor_id;
- pegasus_ids[i].idProduct = device_id;
+ dynamic_id_info.name = name;
+ dynamic_id_info.private = flags;
+ pegasus_ids[dyn_id_index].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
+ pegasus_ids[dyn_id_index].idVendor = vendor_id;
+ pegasus_ids[dyn_id_index].idProduct = device_id;
+ pegasus_ids[dyn_id_index].driver_info = (kernel_ulong_t)&dynamic_id_info;
}
static int __init pegasus_init(void)
diff --git a/drivers/net/usb/pegasus.h b/drivers/net/usb/pegasus.h
index a05b143155ba8..ccdedcef52e76 100644
--- a/drivers/net/usb/pegasus.h
+++ b/drivers/net/usb/pegasus.h
@@ -85,7 +85,6 @@ typedef struct pegasus {
unsigned features;
u32 msg_enable;
u32 wolopts;
- int dev_index;
int intr_interval;
struct tasklet_struct rx_tl;
struct delayed_work carrier_check;
@@ -102,8 +101,6 @@ typedef struct pegasus {
struct usb_eth_dev {
char *name;
- __u16 vendor;
- __u16 device;
__u32 private; /* LSB is gpio reset value */
};
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 694/733] usb: xusbatm: dont rely on id table pointer arithmetic
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (692 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 693/733] net: usb: pegasus: dont rely on id table pointer arithmetic Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 695/733] usb: usbtmc: dont store usb_device_id Greg Kroah-Hartman
` (50 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Gary Guo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
[ Upstream commit eb6cd6d3d8abeac5d7e8251b898067184afdad8a ]
The current code is broken when dynamic ID is involved; in such cases
usb_device_id parameter of probe lives on the heap and the pointer
arithmetic will get an index that is wildly out of bound. xusbatm
initialize the USB device IDs dynamically so it can just use driver_info
too.
Even with conversion, xusbatm still cannot support dynamic IDs, so also set
no_dynamic_id.
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-6-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/atm/xusbatm.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/drivers/usb/atm/xusbatm.c b/drivers/usb/atm/xusbatm.c
index 0befbf63d1cc8..5c1e1f5215555 100644
--- a/drivers/usb/atm/xusbatm.c
+++ b/drivers/usb/atm/xusbatm.c
@@ -79,7 +79,7 @@ static int xusbatm_bind(struct usbatm_data *usbatm,
struct usb_interface *intf, const struct usb_device_id *id)
{
struct usb_device *usb_dev = interface_to_usbdev(intf);
- int drv_ix = id - xusbatm_usb_ids;
+ int drv_ix = id->driver_info;
int rx_alt = rx_altsetting[drv_ix];
int tx_alt = tx_altsetting[drv_ix];
struct usb_interface *rx_intf = xusbatm_find_intf(usb_dev, rx_alt, rx_endpoint[drv_ix]);
@@ -168,7 +168,8 @@ static struct usb_driver xusbatm_usb_driver = {
.name = xusbatm_driver_name,
.probe = xusbatm_usb_probe,
.disconnect = usbatm_usb_disconnect,
- .id_table = xusbatm_usb_ids
+ .id_table = xusbatm_usb_ids,
+ .no_dynamic_id = 1,
};
static int __init xusbatm_init(void)
@@ -190,6 +191,7 @@ static int __init xusbatm_init(void)
xusbatm_usb_ids[i].match_flags = USB_DEVICE_ID_MATCH_DEVICE;
xusbatm_usb_ids[i].idVendor = vendor[i];
xusbatm_usb_ids[i].idProduct = product[i];
+ xusbatm_usb_ids[i].driver_info = i;
xusbatm_drivers[i].driver_name = xusbatm_driver_name;
xusbatm_drivers[i].bind = xusbatm_bind;
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 695/733] usb: usbtmc: dont store usb_device_id
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (693 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 694/733] usb: xusbatm: " Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 696/733] hwmon: (asus_rog_ryujin) Add per-device configuration Greg Kroah-Hartman
` (49 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Manuel Ebner, Danilo Krummrich,
Gary Guo, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gary Guo <gary@garyguo.net>
[ Upstream commit fc045acec1a501c97f84ae184aadce9dae4ba9b2 ]
usb_device_id is not guaranteed to live longer than probe due to presence
of dynamic ID. This stored ID is unused so remove it.
Reviewed-by: Manuel Ebner <manuelebner@mailbox.org>
Reviewed-by: Danilo Krummrich <dakr@kernel.org>
Signed-off-by: Gary Guo <gary@garyguo.net>
Link: https://patch.msgid.link/20260707-usb_dyn_id_uaf-v2-2-632dcf3adfba@garyguo.net
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
---
drivers/usb/class/usbtmc.c | 2 --
1 file changed, 2 deletions(-)
diff --git a/drivers/usb/class/usbtmc.c b/drivers/usb/class/usbtmc.c
index af9ae55dae14e..51cd9320a7366 100644
--- a/drivers/usb/class/usbtmc.c
+++ b/drivers/usb/class/usbtmc.c
@@ -71,7 +71,6 @@ struct usbtmc_dev_capabilities {
* allocated for each USBTMC device in the driver's probe function.
*/
struct usbtmc_device_data {
- const struct usb_device_id *id;
struct usb_device *usb_dev;
struct usb_interface *intf;
struct list_head file_list;
@@ -2394,7 +2393,6 @@ static int usbtmc_probe(struct usb_interface *intf,
return -ENOMEM;
data->intf = intf;
- data->id = id;
data->usb_dev = usb_get_dev(interface_to_usbdev(intf));
usb_set_intfdata(intf, data);
kref_init(&data->kref);
--
2.53.0
^ permalink raw reply related [flat|nested] 748+ messages in thread* [PATCH 7.2 696/733] hwmon: (asus_rog_ryujin) Add per-device configuration
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (694 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 695/733] usb: usbtmc: dont store usb_device_id Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 697/733] hwmon: (asus_rog_ryujin) Validate HID report lengths Greg Kroah-Hartman
` (48 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arie Miller, Aleksa Savic,
Guenter Roeck, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arie Miller <renari@arimil.com>
[ Upstream commit b20ee9aee8779427d2f9de99cbb578b048bf7c04 ]
Move model-specific report offsets and capabilities into a device
information structure. This prepares the driver for coolers which use
a different report layout or do not include the external fan
controller, while preserving the existing Ryujin II 360 behavior.
Handles an issue reported by Sashiko where an id could
be missing driver_data.
Link: https://lore.kernel.org/r/5a817284-a9f4-48b2-9f0f-802c5dc6963c@roeck-us.net
Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
Reviewed-by: Aleksa Savic <savicaleksa83@gmail.com>
Link: https://lore.kernel.org/r/20260812103532.395049-2-renari@arimil.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Stable-dep-of: 8042312e73c5 ("hwmon: (asus_rog_ryujin) Validate HID report lengths")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/asus_rog_ryujin.c | 75 +++++++++++++++++++++++++++-------------
1 file changed, 52 insertions(+), 23 deletions(-)
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -18,15 +18,25 @@
#define USB_VENDOR_ID_ASUS_ROG 0x0b05
#define USB_PRODUCT_ID_RYUJIN_AIO 0x1988 /* ASUS ROG RYUJIN II 360 */
+struct rog_ryujin_device_info {
+ u8 temp_offset;
+ u8 pump_speed_offset;
+ u8 fan_speed_offset;
+ u8 duty_channel;
+ bool has_controller;
+};
+
+static const struct rog_ryujin_device_info rog_ryujin_ii_360_info = {
+ .temp_offset = 3,
+ .pump_speed_offset = 5,
+ .fan_speed_offset = 7,
+ .duty_channel = 0,
+ .has_controller = true,
+};
+
#define STATUS_VALIDITY 1500 /* ms */
#define MAX_REPORT_LENGTH 65
-/* Cooler status report offsets */
-#define RYUJIN_TEMP_SENSOR_1 3
-#define RYUJIN_TEMP_SENSOR_2 4
-#define RYUJIN_PUMP_SPEED 5
-#define RYUJIN_INTERNAL_FAN_SPEED 7
-
/* Cooler duty report offsets */
#define RYUJIN_PUMP_DUTY 4
#define RYUJIN_INTERNAL_FAN_DUTY 5
@@ -81,6 +91,7 @@ static const char *const rog_ryujin_spee
struct rog_ryujin_data {
struct hid_device *hdev;
struct device *hwmon_dev;
+ const struct rog_ryujin_device_info *info;
/* For reinitializing the completions below */
spinlock_t status_report_request_lock;
struct completion cooler_status_received;
@@ -112,6 +123,8 @@ static int rog_ryujin_pwm_to_percent(lon
static umode_t rog_ryujin_is_visible(const void *data,
enum hwmon_sensor_types type, u32 attr, int channel)
{
+ const struct rog_ryujin_data *priv = data;
+
switch (type) {
case hwmon_temp:
switch (attr) {
@@ -123,6 +136,8 @@ static umode_t rog_ryujin_is_visible(con
}
break;
case hwmon_fan:
+ if (channel >= 2 && !priv->info->has_controller)
+ return 0;
switch (attr) {
case hwmon_fan_label:
case hwmon_fan_input:
@@ -132,6 +147,8 @@ static umode_t rog_ryujin_is_visible(con
}
break;
case hwmon_pwm:
+ if (channel >= 2 && !priv->info->has_controller)
+ return 0;
switch (attr) {
case hwmon_pwm_input:
return 0644;
@@ -198,12 +215,14 @@ static int rog_ryujin_get_status(struct
if (ret < 0)
return ret;
- /* Retrieve controller status (speeds) */
- ret =
- rog_ryujin_execute_cmd(priv, get_controller_speed_cmd, GET_CMD_LENGTH,
- &priv->controller_status_received);
- if (ret < 0)
- return ret;
+ if (priv->info->has_controller) {
+ /* Retrieve controller status (speeds) */
+ ret = rog_ryujin_execute_cmd(priv, get_controller_speed_cmd,
+ GET_CMD_LENGTH,
+ &priv->controller_status_received);
+ if (ret < 0)
+ return ret;
+ }
/* Retrieve cooler duty */
ret =
@@ -212,12 +231,14 @@ static int rog_ryujin_get_status(struct
if (ret < 0)
return ret;
- /* Retrieve controller duty */
- ret =
- rog_ryujin_execute_cmd(priv, get_controller_duty_cmd, GET_CMD_LENGTH,
- &priv->controller_duty_received);
- if (ret < 0)
- return ret;
+ if (priv->info->has_controller) {
+ /* Retrieve controller duty */
+ ret = rog_ryujin_execute_cmd(priv, get_controller_duty_cmd,
+ GET_CMD_LENGTH,
+ &priv->controller_duty_received);
+ if (ret < 0)
+ return ret;
+ }
priv->updated = jiffies;
return 0;
@@ -289,6 +310,7 @@ static int rog_ryujin_write_fixed_duty(s
return ret;
memcpy(set_cmd, set_cooler_duty_cmd, SET_CMD_LENGTH);
+ set_cmd[2] = priv->info->duty_channel;
/* Cooler duties are set as 0-100% */
val = rog_ryujin_pwm_to_percent(val);
@@ -394,10 +416,12 @@ static int rog_ryujin_raw_event(struct h
if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
/* Received coolant temp and speeds of pump and internal fan */
- priv->temp_input[0] =
- data[RYUJIN_TEMP_SENSOR_1] * 1000 + data[RYUJIN_TEMP_SENSOR_2] * 100;
- priv->speed_input[0] = get_unaligned_le16(data + RYUJIN_PUMP_SPEED);
- priv->speed_input[1] = get_unaligned_le16(data + RYUJIN_INTERNAL_FAN_SPEED);
+ priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
+ data[priv->info->temp_offset + 1] * 100;
+ priv->speed_input[0] =
+ get_unaligned_le16(data + priv->info->pump_speed_offset);
+ priv->speed_input[1] =
+ get_unaligned_le16(data + priv->info->fan_speed_offset);
if (!completion_done(&priv->cooler_status_received))
complete_all(&priv->cooler_status_received);
@@ -471,11 +495,15 @@ static int rog_ryujin_probe(struct hid_d
struct rog_ryujin_data *priv;
int ret;
+ if (!id->driver_data)
+ return -EINVAL;
+
priv = devm_kzalloc(&hdev->dev, sizeof(*priv), GFP_KERNEL);
if (!priv)
return -ENOMEM;
priv->hdev = hdev;
+ priv->info = (const struct rog_ryujin_device_info *)id->driver_data;
hid_set_drvdata(hdev, priv);
/*
@@ -546,7 +574,8 @@ static void rog_ryujin_remove(struct hid
}
static const struct hid_device_id rog_ryujin_table[] = {
- { HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_AIO) },
+ { HID_USB_DEVICE(USB_VENDOR_ID_ASUS_ROG, USB_PRODUCT_ID_RYUJIN_AIO),
+ .driver_data = (kernel_ulong_t)&rog_ryujin_ii_360_info },
{ }
};
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 697/733] hwmon: (asus_rog_ryujin) Validate HID report lengths
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (695 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 696/733] hwmon: (asus_rog_ryujin) Add per-device configuration Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 698/733] hwmon: (asus_rog_ryujin) Synchronize HID command and report handling Greg Kroah-Hartman
` (47 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Arie Miller, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arie Miller <renari@arimil.com>
[ Upstream commit 8042312e73c50de82634ce63eae7cf219464b481 ]
rog_ryujin_raw_event() parses response headers and payload fields without
first checking that they are present in the received report. A short report
can therefore make the driver consume uninitialized bytes from the HID
transport buffer and expose them as sensor values through sysfs.
Validate the response header and the fields used by each response type
before parsing them.
Fixes: ed3e03790c5c ("hwmon: Add driver for ASUS ROG RYUJIN II 360 AIO cooler")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-hwmon/20260812104617.858D01F000E9@smtp.kernel.org/
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
Link: https://patch.msgid.link/20260904022129.97896-2-renari@arimil.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/asus_rog_ryujin.c | 16 +++++++++++++++-
1 file changed, 15 insertions(+), 1 deletion(-)
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -411,10 +411,15 @@ static int rog_ryujin_raw_event(struct h
{
struct rog_ryujin_data *priv = hid_get_drvdata(hdev);
- if (data[0] != RYUJIN_CMD_PREFIX)
+ if (size < 2 || data[0] != RYUJIN_CMD_PREFIX)
return 0;
if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
+ if (size <= priv->info->temp_offset + 1 ||
+ size <= priv->info->pump_speed_offset + 1 ||
+ size <= priv->info->fan_speed_offset + 1)
+ return 0;
+
/* Received coolant temp and speeds of pump and internal fan */
priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
data[priv->info->temp_offset + 1] * 100;
@@ -426,6 +431,9 @@ static int rog_ryujin_raw_event(struct h
if (!completion_done(&priv->cooler_status_received))
complete_all(&priv->cooler_status_received);
} else if (data[1] == RYUJIN_GET_CONTROLLER_SPEED_CMD_RESPONSE) {
+ if (size <= RYUJIN_CONTROLLER_SPEED_3 + 1)
+ return 0;
+
/* Received speeds of four fans attached to the controller */
priv->speed_input[2] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_1);
priv->speed_input[3] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_2);
@@ -435,6 +443,9 @@ static int rog_ryujin_raw_event(struct h
if (!completion_done(&priv->controller_status_received))
complete_all(&priv->controller_status_received);
} else if (data[1] == RYUJIN_GET_COOLER_DUTY_CMD_RESPONSE) {
+ if (size <= RYUJIN_INTERNAL_FAN_DUTY)
+ return 0;
+
/* Received report for pump and internal fan duties (in %) */
if (data[RYUJIN_PUMP_DUTY] == 0 && data[RYUJIN_INTERNAL_FAN_DUTY] == 0) {
/*
@@ -461,6 +472,9 @@ read_cooler_duty:
if (!completion_done(&priv->cooler_duty_received))
complete_all(&priv->cooler_duty_received);
} else if (data[1] == RYUJIN_GET_CONTROLLER_DUTY_CMD_RESPONSE) {
+ if (size <= RYUJIN_CONTROLLER_DUTY)
+ return 0;
+
/* Received report for controller duty for fans (in PWM) */
if (data[RYUJIN_CONTROLLER_DUTY] == 0) {
/*
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 698/733] hwmon: (asus_rog_ryujin) Synchronize HID command and report handling
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (696 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 697/733] hwmon: (asus_rog_ryujin) Validate HID report lengths Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 699/733] media: remove conditional return with no effect Greg Kroah-Hartman
` (46 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Arie Miller, Guenter Roeck,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arie Miller <renari@arimil.com>
[ Upstream commit 06d48355bf41028c1321acda6a4391cd70098be8 ]
rog_ryujin_execute_cmd() holds status_report_request_lock while
reinitializing a completion, intending to exclude raw-event handling.
However, rog_ryujin_raw_event() does not acquire the lock when it updates
the completion. A response can therefore race with reinit_completion() and
be lost, leaving the command to time out.
Hold the lock while parsing reports and updating their completions. Use the
irqsave variants in both paths because raw-event handling may run in
interrupt context.
Fixes: ed3e03790c5c ("hwmon: Add driver for ASUS ROG RYUJIN II 360 AIO cooler")
Reported-by: Sashiko <sashiko-bot@kernel.org>
Closes: https://lore.kernel.org/linux-hwmon/20260812104617.858D01F000E9@smtp.kernel.org/
Cc: stable@vger.kernel.org
Assisted-by: Codex:gpt-5.6-sol sparse
Signed-off-by: Arie Miller <renari@arimil.com>
Link: https://patch.msgid.link/20260904022129.97896-3-renari@arimil.com
Signed-off-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/hwmon/asus_rog_ryujin.c | 22 ++++++++++++++--------
1 file changed, 14 insertions(+), 8 deletions(-)
--- a/drivers/hwmon/asus_rog_ryujin.c
+++ b/drivers/hwmon/asus_rog_ryujin.c
@@ -173,6 +173,7 @@ static int rog_ryujin_write_expanded(str
static int rog_ryujin_execute_cmd(struct rog_ryujin_data *priv, const u8 *cmd, int cmd_length,
struct completion *status_completion)
{
+ unsigned long flags;
int ret;
/*
@@ -180,9 +181,9 @@ static int rog_ryujin_execute_cmd(struct
* completion. Reinit is done because hidraw could have triggered
* the raw event parsing and marked the passed in completion as done.
*/
- spin_lock_bh(&priv->status_report_request_lock);
+ spin_lock_irqsave(&priv->status_report_request_lock, flags);
reinit_completion(status_completion);
- spin_unlock_bh(&priv->status_report_request_lock);
+ spin_unlock_irqrestore(&priv->status_report_request_lock, flags);
/* Send command for getting data */
ret = rog_ryujin_write_expanded(priv, cmd, cmd_length);
@@ -410,15 +411,18 @@ static int rog_ryujin_raw_event(struct h
int size)
{
struct rog_ryujin_data *priv = hid_get_drvdata(hdev);
+ unsigned long flags;
if (size < 2 || data[0] != RYUJIN_CMD_PREFIX)
return 0;
+ spin_lock_irqsave(&priv->status_report_request_lock, flags);
+
if (data[1] == RYUJIN_GET_COOLER_STATUS_CMD_RESPONSE) {
if (size <= priv->info->temp_offset + 1 ||
size <= priv->info->pump_speed_offset + 1 ||
size <= priv->info->fan_speed_offset + 1)
- return 0;
+ goto unlock;
/* Received coolant temp and speeds of pump and internal fan */
priv->temp_input[0] = data[priv->info->temp_offset] * 1000 +
@@ -432,7 +436,7 @@ static int rog_ryujin_raw_event(struct h
complete_all(&priv->cooler_status_received);
} else if (data[1] == RYUJIN_GET_CONTROLLER_SPEED_CMD_RESPONSE) {
if (size <= RYUJIN_CONTROLLER_SPEED_3 + 1)
- return 0;
+ goto unlock;
/* Received speeds of four fans attached to the controller */
priv->speed_input[2] = get_unaligned_le16(data + RYUJIN_CONTROLLER_SPEED_1);
@@ -444,7 +448,7 @@ static int rog_ryujin_raw_event(struct h
complete_all(&priv->controller_status_received);
} else if (data[1] == RYUJIN_GET_COOLER_DUTY_CMD_RESPONSE) {
if (size <= RYUJIN_INTERNAL_FAN_DUTY)
- return 0;
+ goto unlock;
/* Received report for pump and internal fan duties (in %) */
if (data[RYUJIN_PUMP_DUTY] == 0 && data[RYUJIN_INTERNAL_FAN_DUTY] == 0) {
@@ -463,7 +467,7 @@ static int rog_ryujin_raw_event(struct h
* We're expecting a report, so parse it.
*/
goto read_cooler_duty;
- return 0;
+ goto unlock;
}
read_cooler_duty:
priv->duty_input[0] = rog_ryujin_percent_to_pwm(data[RYUJIN_PUMP_DUTY]);
@@ -473,7 +477,7 @@ read_cooler_duty:
complete_all(&priv->cooler_duty_received);
} else if (data[1] == RYUJIN_GET_CONTROLLER_DUTY_CMD_RESPONSE) {
if (size <= RYUJIN_CONTROLLER_DUTY)
- return 0;
+ goto unlock;
/* Received report for controller duty for fans (in PWM) */
if (data[RYUJIN_CONTROLLER_DUTY] == 0) {
@@ -492,7 +496,7 @@ read_cooler_duty:
* We're expecting a report, so parse it.
*/
goto read_controller_duty;
- return 0;
+ goto unlock;
}
read_controller_duty:
priv->duty_input[2] = data[RYUJIN_CONTROLLER_DUTY];
@@ -501,6 +505,8 @@ read_controller_duty:
complete_all(&priv->controller_duty_received);
}
+unlock:
+ spin_unlock_irqrestore(&priv->status_report_request_lock, flags);
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 699/733] media: remove conditional return with no effect
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (697 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 698/733] hwmon: (asus_rog_ryujin) Synchronize HID command and report handling Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 700/733] media: qcom: iris: fix runtime PM reference leaks Greg Kroah-Hartman
` (45 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sang-Heon Jeon,
Niklas Söderlund, Hans Verkuil, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sang-Heon Jeon <ekffu200098@gmail.com>
[ Upstream commit 9508676ad8562368bb1aa7d1991fbd50611ddacb ]
Both branches of the check return the same value, so the check has
no effect. Remove it and return the value directly.
This is the result of running the Coccinelle script from
scripts/coccinelle/misc/cond_return_no_effect.cocci.
Signed-off-by: Sang-Heon Jeon <ekffu200098@gmail.com>
Reviewed-by: Niklas Söderlund <niklas.soderlund+renesas@ragnatech.se>
Signed-off-by: Hans Verkuil <hverkuil+cisco@kernel.org>
Stable-dep-of: f87d7eda07fc ("media: qcom: iris: fix runtime PM reference leaks")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/i2c/mt9p031.c | 6 +-----
drivers/media/platform/microchip/microchip-sama7g5-isc.c | 7 +------
drivers/media/platform/qcom/iris/iris_resources.c | 6 +-----
drivers/media/platform/qcom/venus/pm_helpers.c | 7 +------
drivers/media/platform/renesas/rcar-csi2.c | 6 +-----
drivers/media/platform/samsung/s3c-camif/camif-core.c | 7 +------
drivers/media/usb/dvb-usb-v2/mxl111sf.c | 12 ++----------
drivers/media/usb/gspca/jl2005bcd.c | 7 +------
8 files changed, 9 insertions(+), 49 deletions(-)
--- a/drivers/media/i2c/mt9p031.c
+++ b/drivers/media/i2c/mt9p031.c
@@ -452,11 +452,7 @@ static int mt9p031_set_params(struct mt9
ret = mt9p031_write(client, MT9P031_HORIZONTAL_BLANK, hblank - 1);
if (ret < 0)
return ret;
- ret = mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1);
- if (ret < 0)
- return ret;
-
- return ret;
+ return mt9p031_write(client, MT9P031_VERTICAL_BLANK, vblank - 1);
}
static int mt9p031_s_stream(struct v4l2_subdev *subdev, int enable)
--- a/drivers/media/platform/microchip/microchip-sama7g5-isc.c
+++ b/drivers/media/platform/microchip/microchip-sama7g5-isc.c
@@ -598,13 +598,8 @@ static int __maybe_unused xisc_runtime_s
static int __maybe_unused xisc_runtime_resume(struct device *dev)
{
struct isc_device *isc = dev_get_drvdata(dev);
- int ret;
- ret = clk_prepare_enable(isc->hclock);
- if (ret)
- return ret;
-
- return ret;
+ return clk_prepare_enable(isc->hclock);
}
static const struct dev_pm_ops microchip_xisc_dev_pm_ops = {
--- a/drivers/media/platform/qcom/iris/iris_resources.c
+++ b/drivers/media/platform/qcom/iris/iris_resources.c
@@ -78,11 +78,7 @@ int iris_enable_power_domains(struct iri
if (ret)
return ret;
- ret = pm_runtime_get_sync(pd_dev);
- if (ret < 0)
- return ret;
-
- return ret;
+ return pm_runtime_get_sync(pd_dev);
}
int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev)
--- a/drivers/media/platform/qcom/venus/pm_helpers.c
+++ b/drivers/media/platform/qcom/venus/pm_helpers.c
@@ -781,7 +781,6 @@ static int decide_core(struct venus_inst
unsigned long max_freq = ULONG_MAX;
struct device *dev = core->dev;
struct dev_pm_opp *opp;
- int ret = 0;
if (legacy_binding) {
if (inst->session_type == VIDC_SESSION_TYPE_DEC)
@@ -829,11 +828,7 @@ static int decide_core(struct venus_inst
}
done:
- ret = hfi_session_set_property(inst, ptype, &cu);
- if (ret)
- return ret;
-
- return ret;
+ return hfi_session_set_property(inst, ptype, &cu);
}
static int acquire_core(struct venus_inst *inst)
--- a/drivers/media/platform/renesas/rcar-csi2.c
+++ b/drivers/media/platform/renesas/rcar-csi2.c
@@ -2273,11 +2273,7 @@ static int rcsi2_init_phtw_v3u(struct rc
return ret;
}
- ret = rcsi2_phtw_write_array(priv, step4, ARRAY_SIZE(step4));
- if (ret)
- return ret;
-
- return ret;
+ return rcsi2_phtw_write_array(priv, step4, ARRAY_SIZE(step4));
}
/* -----------------------------------------------------------------------------
--- a/drivers/media/platform/samsung/s3c-camif/camif-core.c
+++ b/drivers/media/platform/samsung/s3c-camif/camif-core.c
@@ -302,7 +302,6 @@ static int camif_media_dev_init(struct c
struct media_device *md = &camif->media_dev;
struct v4l2_device *v4l2_dev = &camif->v4l2_dev;
unsigned int ip_rev = camif->variant->ip_revision;
- int ret;
memset(md, 0, sizeof(*md));
snprintf(md->model, sizeof(md->model), "Samsung S3C%s CAMIF",
@@ -317,11 +316,7 @@ static int camif_media_dev_init(struct c
media_device_init(md);
- ret = v4l2_device_register(camif->dev, v4l2_dev);
- if (ret < 0)
- return ret;
-
- return ret;
+ return v4l2_device_register(camif->dev, v4l2_dev);
}
static void camif_clk_put(struct camif_dev *camif)
--- a/drivers/media/usb/dvb-usb-v2/mxl111sf.c
+++ b/drivers/media/usb/dvb-usb-v2/mxl111sf.c
@@ -987,11 +987,7 @@ static int mxl111sf_frontend_attach_atsc
if (ret < 0)
return ret;
- ret = mxl111sf_lg2160_frontend_attach(adap, 2);
- if (ret < 0)
- return ret;
-
- return ret;
+ return mxl111sf_lg2160_frontend_attach(adap, 2);
}
static int mxl111sf_frontend_attach_mercury(struct dvb_usb_adapter *adap)
@@ -1007,11 +1003,7 @@ static int mxl111sf_frontend_attach_merc
if (ret < 0)
return ret;
- ret = mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
- if (ret < 0)
- return ret;
-
- return ret;
+ return mxl111sf_lg2161_ep6_frontend_attach(adap, 2);
}
static int mxl111sf_frontend_attach_mercury_mh(struct dvb_usb_adapter *adap)
--- a/drivers/media/usb/gspca/jl2005bcd.c
+++ b/drivers/media/usb/gspca/jl2005bcd.c
@@ -148,17 +148,12 @@ static int jl2005c_start_new_frame(struc
static int jl2005c_write_reg(struct gspca_dev *gspca_dev, unsigned char reg,
unsigned char value)
{
- int retval;
u8 instruction[2];
instruction[0] = reg;
instruction[1] = value;
- retval = jl2005c_write2(gspca_dev, instruction);
- if (retval < 0)
- return retval;
-
- return retval;
+ return jl2005c_write2(gspca_dev, instruction);
}
static int jl2005c_get_firmware_id(struct gspca_dev *gspca_dev)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 700/733] media: qcom: iris: fix runtime PM reference leaks
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (698 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 699/733] media: remove conditional return with no effect Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 701/733] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
` (44 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dmitry Baryshkov, Hungyu Lin,
Bryan ODonoghue, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hungyu Lin <dennylin0707@gmail.com>
[ Upstream commit f87d7eda07fca21efe4b96169ae59007db46e60e ]
Use pm_runtime_resume_and_get() in iris_enable_power_domains()
to avoid leaking a runtime PM usage count on failure.
Also ensure pm_runtime_put_sync() is always called in
iris_disable_power_domains(), even when iris_opp_set_rate()
fails, so runtime PM references remain balanced.
Fixes: bb8a95aa038e ("media: iris: implement power management")
Reviewed-by: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Signed-off-by: Hungyu Lin <dennylin0707@gmail.com>
Cc: stable@vger.kernel.org
Signed-off-by: Bryan O'Donoghue <bod@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/media/platform/qcom/iris/iris_resources.c | 11 ++++++-----
1 file changed, 6 insertions(+), 5 deletions(-)
--- a/drivers/media/platform/qcom/iris/iris_resources.c
+++ b/drivers/media/platform/qcom/iris/iris_resources.c
@@ -78,20 +78,21 @@ int iris_enable_power_domains(struct iri
if (ret)
return ret;
- return pm_runtime_get_sync(pd_dev);
+ return pm_runtime_resume_and_get(pd_dev);
}
int iris_disable_power_domains(struct iris_core *core, struct device *pd_dev)
{
int ret;
+ int pm_ret;
ret = iris_opp_set_rate(core->dev, 0);
- if (ret)
- return ret;
- pm_runtime_put_sync(pd_dev);
+ pm_ret = pm_runtime_put_sync(pd_dev);
+ if (!ret)
+ ret = pm_ret;
- return 0;
+ return ret;
}
static struct clk *iris_get_clk_by_type(struct iris_core *core, enum platform_clk_type clk_type)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 701/733] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (699 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 700/733] media: qcom: iris: fix runtime PM reference leaks Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 702/733] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
` (43 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 34a40e0dff940ac5eba494a69b553ea571e24873 ]
qla25xx_free_req_que() and qla25xx_free_rsp_que() have two pre-existing
bugs exposed on the error path of qla25xx_create_{req,rsp}_que():
1. When dma_alloc_coherent() fails during queue creation, the error
path calls the free function with req->ring / rsp->ring still NULL
(from kzalloc). The unconditional dma_free_coherent() with a NULL
cpu_addr is undefined behavior and can panic.
2. The free functions clear req_qid_map / rsp_qid_map under vport_lock,
but the create functions protect the same bitmaps with mq_lock.
This provides no mutual exclusion. Additionally, the create error
path clears the bit and releases mq_lock before calling the free
function, creating a window where another thread can allocate the
same que_id and have its ha->req_q_map entry clobbered by the
subsequent lockless NULL assignment in the free function.
Fix by:
- Guarding dma_free_coherent() with a NULL check on the ring pointer.
- Using mq_lock (the lock held by all creators) in the free functions
to atomically NULL the map entry and clear the bitmap bit.
- Removing the now-redundant clear_bit blocks from the create error
paths since the free functions handle it atomically.
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-41-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Backport adaptation for the stable tree: the 29xx IOCB size-selection
helpers are absent, and queue creation still allocates fixed-size entries.
Initialize the local req_entry_size and rsp_entry_size values with
sizeof(request_t) and sizeof(response_t), respectively, so DMA freeing
continues to match allocation without adding helper functions or 29xx
support. Retain all NULL-ring guards, mq_lock protection, and removal of
the premature bitmap clears.
Keep the response-ring cleanup layout used by upstream so target commit
19788a55cab61d78e33e0914a5a31d27843e8a4a applies unchanged.
Stable-dep-of: 19788a55cab6 ("scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_mid.c | 29 +++++++++++++++--------------
1 file changed, 15 insertions(+), 14 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -574,16 +574,19 @@ qla25xx_free_req_que(struct scsi_qla_hos
{
struct qla_hw_data *ha = vha->hw;
uint16_t que_id = req->id;
+ size_t req_entry_size = sizeof(request_t);
- dma_free_coherent(&ha->pdev->dev, (req->length + 1) *
- sizeof(request_t), req->ring, req->dma);
+ if (req->ring)
+ dma_free_coherent(&ha->pdev->dev,
+ (req->length + 1) * req_entry_size,
+ req->ring, req->dma);
req->ring = NULL;
req->dma = 0;
if (que_id) {
+ mutex_lock(&ha->mq_lock);
ha->req_q_map[que_id] = NULL;
- mutex_lock(&ha->vport_lock);
clear_bit(que_id, ha->req_qid_map);
- mutex_unlock(&ha->vport_lock);
+ mutex_unlock(&ha->mq_lock);
}
kfree(req->outstanding_cmds);
kfree(req);
@@ -594,6 +597,7 @@ qla25xx_free_rsp_que(struct scsi_qla_hos
{
struct qla_hw_data *ha = vha->hw;
uint16_t que_id = rsp->id;
+ size_t rsp_entry_size = sizeof(response_t);
if (rsp->msix && rsp->msix->have_irq) {
free_irq(rsp->msix->vector, rsp->msix->handle);
@@ -601,15 +605,18 @@ qla25xx_free_rsp_que(struct scsi_qla_hos
rsp->msix->in_use = 0;
rsp->msix->handle = NULL;
}
- dma_free_coherent(&ha->pdev->dev, (rsp->length + 1) *
- sizeof(response_t), rsp->ring, rsp->dma);
+
+ if (rsp->ring)
+ dma_free_coherent(&ha->pdev->dev,
+ (rsp->length + 1) * rsp_entry_size,
+ rsp->ring, rsp->dma);
rsp->ring = NULL;
rsp->dma = 0;
if (que_id) {
+ mutex_lock(&ha->mq_lock);
ha->rsp_q_map[que_id] = NULL;
- mutex_lock(&ha->vport_lock);
clear_bit(que_id, ha->rsp_qid_map);
- mutex_unlock(&ha->vport_lock);
+ mutex_unlock(&ha->mq_lock);
}
kfree(rsp);
}
@@ -794,9 +801,6 @@ qla25xx_create_req_que(struct qla_hw_dat
if (ret != QLA_SUCCESS) {
ql_log(ql_log_fatal, base_vha, 0x00df,
"%s failed.\n", __func__);
- mutex_lock(&ha->mq_lock);
- clear_bit(que_id, ha->req_qid_map);
- mutex_unlock(&ha->mq_lock);
goto que_failed;
}
vha->flags.qpairs_req_created = 1;
@@ -908,9 +912,6 @@ qla25xx_create_rsp_que(struct qla_hw_dat
if (ret != QLA_SUCCESS) {
ql_log(ql_log_fatal, base_vha, 0x00e7,
"%s failed.\n", __func__);
- mutex_lock(&ha->mq_lock);
- clear_bit(que_id, ha->rsp_qid_map);
- mutex_unlock(&ha->mq_lock);
goto que_failed;
}
vha->flags.qpairs_rsp_created = 1;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 702/733] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (700 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 701/733] scsi: qla2xxx: Fix queue teardown NULL dma_free and bitmap locking Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 703/733] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size Greg Kroah-Hartman
` (42 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 19788a55cab61d78e33e0914a5a31d27843e8a4a ]
The response queue MSI-X handler qla2xxx_msix_rsp_q() schedules
qla_do_work() via queue_work(ha->wq, &qpair->q_work). qla_do_work()
dereferences the qpair (vha, rsp) and takes qpair->qp_lock.
During teardown, qla2xxx_delete_qpair() deletes the response queue, which
calls free_irq() in qla25xx_free_rsp_que(), and then frees the queue and
the qpair. free_irq() waits for running hardirq handlers but does not
cancel work already placed on ha->wq. A still-pending q_work then runs
qla_do_work() against the freed qpair and response queue, causing a
use-after-free. This is especially likely during full adapter teardown,
where destroy_workqueue(ha->wq) forces pending work to run after the queue
pairs have been freed.
Flush the work item with cancel_work_sync() in qla25xx_free_rsp_que()
after free_irq() has released the interrupt (so no new work can be
queued) and before the response queue and qpair memory are freed (so the
flushed handler still sees valid memory). Guard on rsp->qpair and ha->wq
to match the INIT_WORK() condition and avoid operating on an
uninitialized work_struct.
Fixes: 68ca949cdb04 ("[SCSI] qla2xxx: Add CPU affinity support.")
Reported-by: Sashiko <sashiko-dev@google.com>
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-5-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_mid.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -606,6 +606,10 @@ qla25xx_free_rsp_que(struct scsi_qla_hos
rsp->msix->handle = NULL;
}
+ /* Flush any queued response work before freeing the queue/qpair. */
+ if (rsp->qpair && ha->wq)
+ cancel_work_sync(&rsp->qpair->q_work);
+
if (rsp->ring)
dma_free_coherent(&ha->pdev->dev,
(rsp->length + 1) * rsp_entry_size,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 703/733] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (701 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 702/733] scsi: qla2xxx: Fix use-after-free of qpair work on queue teardown Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 704/733] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs Greg Kroah-Hartman
` (41 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 878613ecb5a36db26859c4fd83daf9283a334fa2 ]
The VP control IOCB selects its target virtual port by setting one bit
in vp_idx_map, a fixed 16-byte (128-bit) array in both
vp_ctrl_entry_24xx and vp_ctrl_entry_24xx_ext. qla25xx_ctrlvp_iocb()
computes map = (vp_index - 1) / 8 and writes vce->vp_idx_map[map]
without checking that map stays within the array.
max_npiv_vports is taken from firmware and only sanitized to a
MIN_MULTI_ID_FABRIC-aligned boundary, so it can legitimately be 191 or
255, and qla24xx_control_vp() only rejects vp_index >= max_npiv_vports.
A vp_index above 128 therefore yields map >= 16 and an out-of-bounds
write of up to 16 bytes past vp_idx_map, corrupting the trailing IOCB
fields (or the adjacent request-ring slot on the 64-byte layout).
Reject a vp_index that cannot be represented in the IOCB bitmap in
qla24xx_control_vp(), and add a defensive ARRAY_SIZE() guard in
qla25xx_ctrlvp_iocb() before the write. Adapters that report the usual
63 or 127 NPIV vports are unaffected.
Fixes: 2853192e154b ("scsi: qla2xxx: Use IOCB path to submit Control VP MBX command")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-49-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Adjusted guard placement in qla25xx_ctrlvp_iocb() to match the older initialization order. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_iocb.c | 6 ++++++
drivers/scsi/qla2xxx/qla_mid.c | 8 ++++++++
2 files changed, 14 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -3826,6 +3826,12 @@ qla25xx_ctrlvp_iocb(srb_t *sp, struct vp
*/
map = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) / 8;
pos = (sp->u.iocb_cmd.u.ctrlvp.vp_index - 1) & 7;
+ if (map >= ARRAY_SIZE(vce->vp_idx_map)) {
+ ql_log(ql_log_warn, sp->vha, 0x307c,
+ "ctrlvp: vp_index %u exceeds vp_idx_map capacity\n",
+ sp->u.iocb_cmd.u.ctrlvp.vp_index);
+ return;
+ }
vce->vp_idx_map[map] |= 1 << pos;
}
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -962,6 +962,14 @@ int qla24xx_control_vp(scsi_qla_host_t *
if (vp_index == 0 || vp_index >= ha->max_npiv_vports)
return QLA_PARAMETER_ERROR;
+ /*
+ * The VP_CTRL IOCB selects the target VP through a fixed 128-bit
+ * (16-byte) vp_idx_map bitmap, so vp_index must fit within it even
+ * if firmware advertises more NPIV vports.
+ */
+ if (vp_index > sizeof_field(struct vp_ctrl_entry_24xx, vp_idx_map) * 8)
+ return QLA_PARAMETER_ERROR;
+
/* ref: INIT */
sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
if (!sp)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 704/733] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (702 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 703/733] scsi: qla2xxx: Bound VP index against VP_CTRL IOCB bitmap size Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 705/733] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
` (40 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 7e51b6d2d8f6b7f48d9cef1cf87471b55b12f6de ]
__qla2x00_alloc_iocbs() open-codes ring pointer selection and entry size
based on IS_QLA29XX(ha): 29xx reaches the slot via ring_ext_ptr and
zeroes REQUEST_ENTRY_SIZE_EXT bytes, while other adapters use ring_ptr
with REQUEST_ENTRY_SIZE bytes.
Replace the two branches with the qla_req_ring_slot() and
qla_req_entry_size() helpers, and initialise pkt at declaration. The
IS_QLAFX00 register-mapped writes remain guarded because IS_QLAFX00 and
IS_QLA29XX cannot be true simultaneously.
No functional change: the bytes written to the firmware-visible IOCB are
identical.
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-24-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Stable adaptation:
This tree has no QLA29xx support, extended request ring, or ring-slot
helpers. Provide file-local macro helpers mapping to req->ring_ptr and
REQUEST_ENTRY_SIZE, preserving the existing 64-byte ring behavior without
adding functions or importing the unrelated QLA29xx support series.
Retain the helper calls and declaration initialization from this change.
Use a multiline packet-preparation comment so commit 626e44f3d8a9
("scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot")
applies unchanged, including its leading context. That commit remains
responsible for changing the FX00 clearing operation to memset_io().
Stable-dep-of: 626e44f3d8a9 ("scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_iocb.c | 15 ++++++++++-----
1 file changed, 10 insertions(+), 5 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -11,6 +11,10 @@
#include <scsi/scsi_tcq.h>
+/* All adapters supported by this tree use the 64-byte request ring. */
+#define qla_req_ring_slot(ha, req) ((req)->ring_ptr)
+#define qla_req_entry_size(ha) REQUEST_ENTRY_SIZE
+
static int qla_start_scsi_type6(srb_t *sp);
/**
* qla2x00_get_cmd_direction() - Determine control_flag data direction.
@@ -2286,10 +2290,9 @@ __qla2x00_alloc_iocbs(struct qla_qpair *
struct req_que *req = qpair->req;
device_reg_t *reg = ISP_QUE_REG(ha, req->id);
uint32_t handle;
- request_t *pkt;
uint16_t cnt, req_cnt;
+ request_t *pkt = NULL;
- pkt = NULL;
req_cnt = 1;
handle = 0;
@@ -2343,10 +2346,12 @@ __qla2x00_alloc_iocbs(struct qla_qpair *
sp->handle = handle;
}
- /* Prep packet */
+ /*
+ * Prep the current request-ring slot.
+ */
req->cnt -= req_cnt;
- pkt = req->ring_ptr;
- memset(pkt, 0, REQUEST_ENTRY_SIZE);
+ pkt = qla_req_ring_slot(ha, req);
+ memset(pkt, 0, qla_req_entry_size(ha));
if (IS_QLAFX00(ha)) {
wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 705/733] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (703 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 704/733] scsi: qla2xxx: Use ring-slot helpers in __qla2x00_alloc_iocbs Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 706/733] f2fs: accurately adjust free_sections during free_segment_range Greg Kroah-Hartman
` (39 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 626e44f3d8a924a97a3848a9fd45833947e081e9 ]
For QLAFX00 the request ring is ioremapped device I/O memory
(ha->iobase + req_que_off), not DMA-coherent RAM, which is why the rest
of the FX00 path accesses it through memcpy_toio() and the wrt_reg_*
helpers. __qla2x00_alloc_iocbs() however zeroed the producer slot with a
plain memset(). On architectures such as ARM64 a regular memset() may
emit unaligned or block-zeroing instructions (e.g. DC ZVA) that are
invalid on Device memory, leading to a synchronous external abort.
Use memset_io() to clear the slot for QLAFX00, matching the I/O
accessors used elsewhere on this ring. Other adapters keep the plain
memset() on their DMA-coherent rings. The zero-fill is retained for FX00
because its IOCB builders (e.g. qlafx00_fxdisc_iocb()) copy only part of
the entry and rely on the unused tail being pre-zeroed.
Fixes: 8ae6d9c7eb10 ("[SCSI] qla2xxx: Enhancements to support ISPFx00.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-12-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_iocb.c | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
--- a/drivers/scsi/qla2xxx/qla_iocb.c
+++ b/drivers/scsi/qla2xxx/qla_iocb.c
@@ -2351,11 +2351,13 @@ __qla2x00_alloc_iocbs(struct qla_qpair *
*/
req->cnt -= req_cnt;
pkt = qla_req_ring_slot(ha, req);
- memset(pkt, 0, qla_req_entry_size(ha));
if (IS_QLAFX00(ha)) {
+ memset_io((void __iomem __force *)pkt, 0,
+ qla_req_entry_size(ha));
wrt_reg_byte((u8 __force __iomem *)&pkt->entry_count, req_cnt);
wrt_reg_dword((__le32 __force __iomem *)&pkt->handle, handle);
} else {
+ memset(pkt, 0, qla_req_entry_size(ha));
pkt->entry_count = req_cnt;
pkt->handle = handle;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 706/733] f2fs: accurately adjust free_sections during free_segment_range
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (704 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 705/733] scsi: qla2xxx: Use memset_io() to clear QLAFX00 request ring slot Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 707/733] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range() Greg Kroah-Hartman
` (38 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daeho Jeong, Sunmin Jeong, Chao Yu,
Jaegeuk Kim, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daeho Jeong <daehojeong@google.com>
[ Upstream commit 8c963d1738fdca400082ff5f9d99e083de4f4e70 ]
In free_segment_range(), MAIN_SECS(sbi) is temporarily reduced by `secs`
to restrict block allocation to the safe remaining main area while valid
blocks in the truncated range are evacuated by GC.
However, FREE_I(sbi)->free_sections tracks the total number of free
sections across the whole filesystem. If any sections within the
truncated range were already free upon entering free_segment_range(),
failing to deduct them from free_sections causes the filesystem to
overestimate available free sections in the active, reduced main area.
This leads to inconsistent free section accounting during GC data
migration and can trigger unexpected allocation failures or assertion
errors when space is tight.
Fix this by calculating the number of already-free sections in the
truncated range, deducting them from free_sections upon entering
free_segment_range(), and restoring them on exit.
Fixes: b4b10061ef98 ("f2fs: refactor resize_fs to avoid meta updates in progress")
Cc: stable@vger.kernel.org
Signed-off-by: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Sunmin Jeong <s_min.jeong@samsung.com>
Reviewed-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
[ retained gc_mode and gc_type declarations needed by the older inline GC reset logic. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/f2fs/gc.c | 15 ++++++++++++++-
1 file changed, 14 insertions(+), 1 deletion(-)
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2194,8 +2194,9 @@ int f2fs_gc_range(struct f2fs_sb_info *s
static int free_segment_range(struct f2fs_sb_info *sbi,
unsigned int secs, bool dry_run)
{
- unsigned int next_inuse, start, end;
+ unsigned int secno, next_inuse, start, end, end_secno;
struct cp_control cpc = { CP_RESIZE, 0, 0, 0 };
+ unsigned int freed_secs = 0;
int gc_mode, gc_type;
int err = 0;
int type;
@@ -2204,6 +2205,7 @@ static int free_segment_range(struct f2f
MAIN_SECS(sbi) -= secs;
start = MAIN_SECS(sbi) * SEGS_PER_SEC(sbi);
end = MAIN_SEGS(sbi) - 1;
+ end_secno = GET_SEC_FROM_SEG(sbi, end);
mutex_lock(&DIRTY_I(sbi)->seglist_lock);
for (gc_mode = 0; gc_mode < MAX_GC_POLICY; gc_mode++)
@@ -2215,6 +2217,14 @@ static int free_segment_range(struct f2f
sbi->next_victim_seg[gc_type] = NULL_SEGNO;
mutex_unlock(&DIRTY_I(sbi)->seglist_lock);
+ spin_lock(&FREE_I(sbi)->segmap_lock);
+ for (secno = MAIN_SECS(sbi); secno <= end_secno; secno++) {
+ if (!test_bit(secno, FREE_I(sbi)->free_secmap))
+ freed_secs++;
+ }
+ FREE_I(sbi)->free_sections -= freed_secs;
+ spin_unlock(&FREE_I(sbi)->segmap_lock);
+
/* Move out cursegs from the target range */
for (type = CURSEG_HOT_DATA; type < NR_CURSEG_TYPE; type++) {
err = f2fs_allocate_segment_for_resize(sbi, type, start, end);
@@ -2239,6 +2249,9 @@ static int free_segment_range(struct f2f
f2fs_bug_on(sbi, 1);
}
out:
+ spin_lock(&FREE_I(sbi)->segmap_lock);
+ FREE_I(sbi)->free_sections += freed_secs;
+ spin_unlock(&FREE_I(sbi)->segmap_lock);
MAIN_SECS(sbi) += secs;
return err;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 707/733] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (705 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 706/733] f2fs: accurately adjust free_sections during free_segment_range Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 708/733] f2fs: fix to reset all pinned status during fggc Greg Kroah-Hartman
` (37 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Daeho Jeong, Chao Yu, Jaegeuk Kim,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 5d49025a4e596c4c9ac0c519ef9f9a2c91396856 ]
In f2fs_allocate_pinning_section(), we will hold gc_lock before calling
f2fs_gc_range() to migrate section in conventional zone, we may suffer
worse case because we may need to traverse and migrate multiple sections
if we failed to move blocks in section due to lot of reasons: ENOMEM,
fail to migrate block of pinfile, racing on i_gc_rwsem.
To avoid hold gc_lock for long time to block checkpoint, let's hold
the lock and only try to migrate one section.
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Backport notes for Linux 7.2:
The stable tree lacks eae3faf210bdc ("f2fs: support dynamic
reserve/release for device aliasing"). Drop the file.c hunk for the absent
f2fs_ioc_reserve_dev_alias() caller and omit the unrelated
f2fs_reset_gc_victim_resource() declaration from the header resolution.
Keep the per-section gc_lock handling, updated f2fs_gc_range() prototype,
and both callers present in this tree. No functions are added.
This preserves the context needed for 2b8704b6a8b2 ("f2fs: fix to reset
all pinned status during fggc"); its patch applies without conflicts.
[ sashal: Reduced backport -- upstream 5d49025a4e596 touches 4 file(s), this
backport carries 3. Not backported here:
fs/f2fs/file.c
This note is generated from the file lists only; see the resolution record
for the reasoning. ]
Stable-dep-of: 2b8704b6a8b2 ("f2fs: fix to reset all pinned status during fggc")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/f2fs/f2fs.h | 2 +-
fs/f2fs/gc.c | 34 +++++++++++++++++++++++++---------
fs/f2fs/segment.c | 4 +---
3 files changed, 27 insertions(+), 13 deletions(-)
--- a/fs/f2fs/f2fs.h
+++ b/fs/f2fs/f2fs.h
@@ -4271,7 +4271,7 @@ int f2fs_gc(struct f2fs_sb_info *sbi, st
void f2fs_build_gc_manager(struct f2fs_sb_info *sbi);
int f2fs_gc_range(struct f2fs_sb_info *sbi,
unsigned int start_seg, unsigned int end_seg,
- bool dry_run, unsigned int dry_run_sections);
+ bool dry_run, unsigned int dry_run_sections, bool lock);
int f2fs_resize_fs(struct file *filp, __u64 block_count);
int __init f2fs_create_garbage_collection_cache(void);
void f2fs_destroy_garbage_collection_cache(void);
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2150,8 +2150,9 @@ void f2fs_build_gc_manager(struct f2fs_s
int f2fs_gc_range(struct f2fs_sb_info *sbi,
unsigned int start_seg, unsigned int end_seg,
- bool dry_run, unsigned int dry_run_sections)
+ bool dry_run, unsigned int dry_run_sections, bool lock)
{
+ struct f2fs_lock_context lc;
unsigned int segno;
unsigned int gc_secs = dry_run_sections;
@@ -2164,28 +2165,43 @@ int f2fs_gc_range(struct f2fs_sb_info *s
.ilist = LIST_HEAD_INIT(gc_list.ilist),
.iroot = RADIX_TREE_INIT(gc_list.iroot, GFP_NOFS),
};
+ int err = 0;
+
+ if (lock)
+ f2fs_down_write_trace(&sbi->gc_lock, &lc);
/*
* avoid migrating empty section, as it can be allocated by
* log in parallel.
*/
if (!get_valid_blocks(sbi, segno, true))
- continue;
+ goto next;
if (is_cursec(sbi, GET_SEC_FROM_SEG(sbi, segno)))
- continue;
+ goto next;
do_garbage_collect(sbi, segno, &gc_list, FG_GC, true, false);
put_gc_inode(&gc_list);
- if (!dry_run && get_valid_blocks(sbi, segno, true))
- return -EAGAIN;
+ if (!dry_run && get_valid_blocks(sbi, segno, true)) {
+ err = -EAGAIN;
+ goto next;
+ }
if (dry_run && dry_run_sections &&
- !get_valid_blocks(sbi, segno, true) && --gc_secs == 0)
- break;
+ !get_valid_blocks(sbi, segno, true)) {
+ --gc_secs;
+ goto next;
+ }
if (fatal_signal_pending(current))
- return -ERESTARTSYS;
+ err = -ERESTARTSYS;
+next:
+ if (lock)
+ f2fs_up_write_trace(&sbi->gc_lock, &lc);
+ if (err)
+ return err;
+ if (dry_run && dry_run_sections && !gc_secs)
+ return 0;
}
return 0;
@@ -2233,7 +2249,7 @@ static int free_segment_range(struct f2f
}
/* do GC to move out valid blocks in the range */
- err = f2fs_gc_range(sbi, start, end, dry_run, 0);
+ err = f2fs_gc_range(sbi, start, end, dry_run, 0, false);
if (err || dry_run)
goto out;
--- a/fs/f2fs/segment.c
+++ b/fs/f2fs/segment.c
@@ -3357,10 +3357,8 @@ retry:
f2fs_unlock_op(sbi, &lc);
if (f2fs_sb_has_blkzoned(sbi) && err == -EAGAIN && gc_required) {
- f2fs_down_write_trace(&sbi->gc_lock, &lc);
err = f2fs_gc_range(sbi, 0, sbi->first_seq_zone_segno - 1,
- true, ZONED_PIN_SEC_REQUIRED_COUNT);
- f2fs_up_write_trace(&sbi->gc_lock, &lc);
+ true, ZONED_PIN_SEC_REQUIRED_COUNT, true);
if (err)
return err;
err = f2fs_sync_fs(sbi->sb, 1);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 708/733] f2fs: fix to reset all pinned status during fggc
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (706 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 707/733] f2fs: fix to shrink gc_lock coverage in f2fs_gc_range() Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 709/733] drm/i915/cdclk: Avoid spurious cdclk sanitization on PTL+ Greg Kroah-Hartman
` (36 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, stable, Daeho Jeong, Chao Yu,
Jaegeuk Kim, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chao Yu <chao@kernel.org>
[ Upstream commit 2b8704b6a8b2896ccad1f5941d9a3e2c5031a470 ]
Otherwise, the pinned status may affect latter flow of fggc.
Cc: stable@kernel.org
Fixes: 9703d69d9d15 ("f2fs: support file pinning for zoned devices")
Cc: Daeho Jeong <daehojeong@google.com>
Signed-off-by: Chao Yu <chao@kernel.org>
Signed-off-by: Jaegeuk Kim <jaegeuk@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
fs/f2fs/gc.c | 3 +++
1 file changed, 3 insertions(+)
--- a/fs/f2fs/gc.c
+++ b/fs/f2fs/gc.c
@@ -2183,6 +2183,9 @@ int f2fs_gc_range(struct f2fs_sb_info *s
do_garbage_collect(sbi, segno, &gc_list, FG_GC, true, false);
put_gc_inode(&gc_list);
+ /* reset all pinned status during fggc */
+ f2fs_unpin_all_sections(sbi, true);
+
if (!dry_run && get_valid_blocks(sbi, segno, true)) {
err = -EAGAIN;
goto next;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 709/733] drm/i915/cdclk: Avoid spurious cdclk sanitization on PTL+
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (707 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 708/733] f2fs: fix to reset all pinned status during fggc Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 710/733] accel/amdxdna: Disable device buffer exporting Greg Kroah-Hartman
` (35 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Ville Syrjälä,
Suraj Kandpal, Jani Nikula, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <ville.syrjala@linux.intel.com>
[ Upstream commit aad969968824e97ba8d70dd7a95691f750438ebd ]
Apparently PTL+ no longer has the cd2x pipe select field in
CDCLK_CTL. Take that into account during CDCLK sanitization.
This currently triggers a spurious CDCLK sanitization during
driver load on PTL+ which will causes a visible glitch on all
active displays.
Cc: stable@vger.kernel.org
Closes: https://gitlab.freedesktop.org/drm/xe/kernel/-/work_items/8550
Fixes: 2ee8dbd880b1 ("drm/i915/cdclk: Fix up CDCLK_FREQ_DECIMAL without a full PLL re-enable")
Signed-off-by: Ville Syrjälä <ville.syrjala@linux.intel.com>
Link: https://patch.msgid.link/20260717155107.17801-1-ville.syrjala@linux.intel.com
Reviewed-by: Suraj Kandpal <suraj.kandpal@intel.com>
(cherry picked from commit 1786d26887817a779641d3a093c66ac91382113b)
Signed-off-by: Jani Nikula <jani.nikula@intel.com>
[ Replaced bxt_cdclk_cd2x_pipe_mask(display) with the equivalent bxt_cdclk_cd2x_pipe(display, INVALID_PIPE). ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/i915/display/intel_cdclk.c | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
--- a/drivers/gpu/drm/i915/display/intel_cdclk.c
+++ b/drivers/gpu/drm/i915/display/intel_cdclk.c
@@ -2366,8 +2366,10 @@ static void bxt_sanitize_cdclk(struct in
* dividers both syncing to an active pipe, or asynchronously
* (PIPE_NONE).
*/
- cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
- cdctl |= bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
+ if (DISPLAY_VER(display) < 30) {
+ cdctl &= ~bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
+ cdctl |= bxt_cdclk_cd2x_pipe(display, INVALID_PIPE);
+ }
if (cdctl != expected) {
if (DISPLAY_VER(display) < 20) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 710/733] accel/amdxdna: Disable device buffer exporting
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (708 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 709/733] drm/i915/cdclk: Avoid spurious cdclk sanitization on PTL+ Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:16 ` [PATCH 7.2 711/733] i2c: designware: Global register definitions Greg Kroah-Hartman
` (34 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Mario Limonciello (AMD), Lizhi Hou,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lizhi Hou <lizhi.hou@amd.com>
[ Upstream commit 9480dd7ec3fcadd4217503e4bb32c16e19e4b21f ]
Device buffers are never intended to be exported. Disable exporting
support explicitly.
Reviewed-by: Mario Limonciello (AMD) <superm1@kernel.org>
Signed-off-by: Lizhi Hou <lizhi.hou@amd.com>
Link: https://patch.msgid.link/20260526185058.1780869-1-lizhi.hou@amd.com
Stable-dep-of: f43fa4b8522b ("drm/xe/i2c: Fix the interrupt handling")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/accel/amdxdna/amdxdna_gem.c | 6 ++++++
1 file changed, 6 insertions(+)
--- a/drivers/accel/amdxdna/amdxdna_gem.c
+++ b/drivers/accel/amdxdna/amdxdna_gem.c
@@ -758,9 +758,15 @@ static int amdxdna_gem_dev_obj_vmap(stru
return 0;
}
+static struct dma_buf *amdxdna_gem_dev_obj_export(struct drm_gem_object *gobj, int flags)
+{
+ return ERR_PTR(-EOPNOTSUPP);
+}
+
static const struct drm_gem_object_funcs amdxdna_gem_dev_obj_funcs = {
.free = amdxdna_gem_dev_obj_free,
.vmap = amdxdna_gem_dev_obj_vmap,
+ .export = amdxdna_gem_dev_obj_export,
};
static const struct drm_gem_object_funcs amdxdna_gem_shmem_funcs = {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 711/733] i2c: designware: Global register definitions
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (709 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 710/733] accel/amdxdna: Disable device buffer exporting Greg Kroah-Hartman
@ 2026-09-17 15:16 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 712/733] drm/xe/i2c: Fix the interrupt handling Greg Kroah-Hartman
` (33 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:16 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Andy Shevchenko, Raag Jadav,
Mika Westerberg, Heikki Krogerus, Rodrigo Vivi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
[ Upstream commit 874ef9a6f2fc45d3f6021842d92fa5420fa4c825 ]
Moving the register definitions to a global header file
include/linux/designware_i2c.h. That removes the need to
duplicate them in the adaptation layers for this driver
outside of drivers/i2c/busses/. There is at least one of
those in drivers/gpu/drm/xe/xe_i2c.c.
Suggested-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Suggested-by: Raag Jadav <raag.jadav@intel.com>
Reviewed-by: Raag Jadav <raag.jadav@intel.com>
Reviewed-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Reviewed-by: Andy Shevchenko <andriy.shevchenko@linux.intel.com>
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Acked-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Link: https://patch.msgid.link/20260811121008.1493015-2-heikki.krogerus@linux.intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(cherry picked from commit 2ab2fb31411a494e4579dfacda986a2672f80e65)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Stable-dep-of: f43fa4b8522b ("drm/xe/i2c: Fix the interrupt handling")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
MAINTAINERS | 1
drivers/i2c/busses/i2c-designware-common.c | 2
drivers/i2c/busses/i2c-designware-core.h | 85 -----------------------
drivers/i2c/busses/i2c-designware-master.c | 2
drivers/i2c/busses/i2c-designware-slave.c | 2
include/linux/designware_i2c.h | 107 +++++++++++++++++++++++++++++
6 files changed, 116 insertions(+), 83 deletions(-)
create mode 100644 include/linux/designware_i2c.h
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -26241,6 +26241,7 @@ R: Andy Shevchenko <andriy.shevchenko@li
L: linux-i2c@vger.kernel.org
S: Supported
F: drivers/i2c/busses/i2c-designware-*
+F: include/linux/designware_i2c.h
SYNOPSYS DESIGNWARE I2C DRIVER - AMDISP
M: Nirujogi Pratap <pratap.nirujogi@amd.com>
--- a/drivers/i2c/busses/i2c-designware-common.c
+++ b/drivers/i2c/busses/i2c-designware-common.c
@@ -33,6 +33,8 @@
#include <linux/types.h>
#include <linux/units.h>
+#include <linux/designware_i2c.h>
+
#include "i2c-designware-core.h"
#define DW_IC_DEFAULT_BUS_CAPACITANCE_pF 100
--- a/drivers/i2c/busses/i2c-designware-core.h
+++ b/drivers/i2c/busses/i2c-designware-core.h
@@ -18,6 +18,8 @@
#include <linux/regmap.h>
#include <linux/types.h>
+#include <linux/designware_i2c.h>
+
#define DW_IC_DEFAULT_FUNCTIONALITY (I2C_FUNC_I2C | \
I2C_FUNC_SMBUS_BYTE | \
I2C_FUNC_SMBUS_BYTE_DATA | \
@@ -25,23 +27,6 @@
I2C_FUNC_SMBUS_BLOCK_DATA | \
I2C_FUNC_SMBUS_I2C_BLOCK)
-#define DW_IC_CON_MASTER BIT(0)
-#define DW_IC_CON_SPEED_STD (1 << 1)
-#define DW_IC_CON_SPEED_FAST (2 << 1)
-#define DW_IC_CON_SPEED_HIGH (3 << 1)
-#define DW_IC_CON_SPEED_MASK GENMASK(2, 1)
-#define DW_IC_CON_10BITADDR_SLAVE BIT(3)
-#define DW_IC_CON_10BITADDR_MASTER BIT(4)
-#define DW_IC_CON_RESTART_EN BIT(5)
-#define DW_IC_CON_SLAVE_DISABLE BIT(6)
-#define DW_IC_CON_STOP_DET_IFADDRESSED BIT(7)
-#define DW_IC_CON_TX_EMPTY_CTRL BIT(8)
-#define DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9)
-#define DW_IC_CON_BUS_CLEAR_CTRL BIT(11)
-
-#define DW_IC_DATA_CMD_DAT GENMASK(7, 0)
-#define DW_IC_DATA_CMD_FIRST_DATA_BYTE BIT(11)
-
/*
* Register access parameters
*/
@@ -55,65 +40,9 @@
#define DW_IC_FIFO_RX_FIELD GENMASK(15, 8)
#define DW_IC_FIFO_MIN_DEPTH 2
-/*
- * Registers offset
- */
-#define DW_IC_CON 0x00
-#define DW_IC_TAR 0x04
-#define DW_IC_SAR 0x08
-#define DW_IC_DATA_CMD 0x10
-#define DW_IC_SS_SCL_HCNT 0x14
-#define DW_IC_SS_SCL_LCNT 0x18
-#define DW_IC_FS_SCL_HCNT 0x1c
-#define DW_IC_FS_SCL_LCNT 0x20
-#define DW_IC_HS_SCL_HCNT 0x24
-#define DW_IC_HS_SCL_LCNT 0x28
-#define DW_IC_INTR_STAT 0x2c
-#define DW_IC_INTR_MASK 0x30
-#define DW_IC_RAW_INTR_STAT 0x34
-#define DW_IC_RX_TL 0x38
-#define DW_IC_TX_TL 0x3c
-#define DW_IC_CLR_INTR 0x40
-#define DW_IC_CLR_RX_UNDER 0x44
-#define DW_IC_CLR_RX_OVER 0x48
-#define DW_IC_CLR_TX_OVER 0x4c
-#define DW_IC_CLR_RD_REQ 0x50
-#define DW_IC_CLR_TX_ABRT 0x54
-#define DW_IC_CLR_RX_DONE 0x58
-#define DW_IC_CLR_ACTIVITY 0x5c
-#define DW_IC_CLR_STOP_DET 0x60
-#define DW_IC_CLR_START_DET 0x64
-#define DW_IC_CLR_GEN_CALL 0x68
-#define DW_IC_ENABLE 0x6c
-#define DW_IC_STATUS 0x70
-#define DW_IC_TXFLR 0x74
-#define DW_IC_RXFLR 0x78
-#define DW_IC_SDA_HOLD 0x7c
-#define DW_IC_TX_ABRT_SOURCE 0x80
-#define DW_IC_ENABLE_STATUS 0x9c
-#define DW_IC_CLR_RESTART_DET 0xa8
-#define DW_IC_SMBUS_INTR_MASK 0xcc
-#define DW_IC_COMP_PARAM_1 0xf4
-#define DW_IC_COMP_VERSION 0xf8
#define DW_IC_SDA_HOLD_MIN_VERS 0x3131312A /* "111*" == v1.11* */
-#define DW_IC_COMP_TYPE 0xfc
#define DW_IC_COMP_TYPE_VALUE 0x44570140 /* "DW" + 0x0140 */
-#define DW_IC_INTR_RX_UNDER BIT(0)
-#define DW_IC_INTR_RX_OVER BIT(1)
-#define DW_IC_INTR_RX_FULL BIT(2)
-#define DW_IC_INTR_TX_OVER BIT(3)
-#define DW_IC_INTR_TX_EMPTY BIT(4)
-#define DW_IC_INTR_RD_REQ BIT(5)
-#define DW_IC_INTR_TX_ABRT BIT(6)
-#define DW_IC_INTR_RX_DONE BIT(7)
-#define DW_IC_INTR_ACTIVITY BIT(8)
-#define DW_IC_INTR_STOP_DET BIT(9)
-#define DW_IC_INTR_START_DET BIT(10)
-#define DW_IC_INTR_GEN_CALL BIT(11)
-#define DW_IC_INTR_RESTART_DET BIT(12)
-#define DW_IC_INTR_MST_ON_HOLD BIT(13)
-
#define DW_IC_INTR_DEFAULT_MASK (DW_IC_INTR_RX_FULL | \
DW_IC_INTR_TX_ABRT | \
DW_IC_INTR_STOP_DET)
@@ -123,16 +52,6 @@
DW_IC_INTR_RX_UNDER | \
DW_IC_INTR_RD_REQ)
-#define DW_IC_ENABLE_ENABLE BIT(0)
-#define DW_IC_ENABLE_ABORT BIT(1)
-
-#define DW_IC_STATUS_ACTIVITY BIT(0)
-#define DW_IC_STATUS_TFE BIT(2)
-#define DW_IC_STATUS_RFNE BIT(3)
-#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5)
-#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6)
-#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7)
-
#define DW_IC_SDA_HOLD_RX_SHIFT 16
#define DW_IC_SDA_HOLD_RX_MASK GENMASK(23, 16)
--- a/drivers/i2c/busses/i2c-designware-master.c
+++ b/drivers/i2c/busses/i2c-designware-master.c
@@ -25,6 +25,8 @@
#include <linux/regmap.h>
#include <linux/reset.h>
+#include <linux/designware_i2c.h>
+
#include "i2c-designware-core.h"
#define AMD_TIMEOUT_MIN_US 25
--- a/drivers/i2c/busses/i2c-designware-slave.c
+++ b/drivers/i2c/busses/i2c-designware-slave.c
@@ -19,6 +19,8 @@
#include <linux/pm_runtime.h>
#include <linux/regmap.h>
+#include <linux/designware_i2c.h>
+
#include "i2c-designware-core.h"
int i2c_dw_reg_slave(struct i2c_client *slave)
--- /dev/null
+++ b/include/linux/designware_i2c.h
@@ -0,0 +1,107 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/*
+ * Synopsys DesignWare I2C register definitions
+ *
+ * Copyright (C) 2026, Intel Corporation
+ */
+
+#ifndef __LINUX_DESIGNWARE_I2C_H
+#define __LINUX_DESIGNWARE_I2C_H
+
+#include <linux/bits.h>
+
+/*
+ * Registers offset
+ */
+#define DW_IC_CON 0x00
+#define DW_IC_TAR 0x04
+#define DW_IC_SAR 0x08
+#define DW_IC_DATA_CMD 0x10
+#define DW_IC_SS_SCL_HCNT 0x14
+#define DW_IC_SS_SCL_LCNT 0x18
+#define DW_IC_FS_SCL_HCNT 0x1c
+#define DW_IC_FS_SCL_LCNT 0x20
+#define DW_IC_HS_SCL_HCNT 0x24
+#define DW_IC_HS_SCL_LCNT 0x28
+#define DW_IC_INTR_STAT 0x2c
+#define DW_IC_INTR_MASK 0x30
+#define DW_IC_RAW_INTR_STAT 0x34
+#define DW_IC_RX_TL 0x38
+#define DW_IC_TX_TL 0x3c
+#define DW_IC_CLR_INTR 0x40
+#define DW_IC_CLR_RX_UNDER 0x44
+#define DW_IC_CLR_RX_OVER 0x48
+#define DW_IC_CLR_TX_OVER 0x4c
+#define DW_IC_CLR_RD_REQ 0x50
+#define DW_IC_CLR_TX_ABRT 0x54
+#define DW_IC_CLR_RX_DONE 0x58
+#define DW_IC_CLR_ACTIVITY 0x5c
+#define DW_IC_CLR_STOP_DET 0x60
+#define DW_IC_CLR_START_DET 0x64
+#define DW_IC_CLR_GEN_CALL 0x68
+#define DW_IC_ENABLE 0x6c
+#define DW_IC_STATUS 0x70
+#define DW_IC_TXFLR 0x74
+#define DW_IC_RXFLR 0x78
+#define DW_IC_SDA_HOLD 0x7c
+#define DW_IC_TX_ABRT_SOURCE 0x80
+#define DW_IC_ENABLE_STATUS 0x9c
+#define DW_IC_CLR_RESTART_DET 0xa8
+#define DW_IC_SMBUS_INTR_STAT 0xc8
+#define DW_IC_SMBUS_INTR_MASK 0xcc
+#define DW_IC_CLR_SMBUS_INTR 0xd4
+#define DW_IC_COMP_PARAM_1 0xf4
+#define DW_IC_COMP_VERSION 0xf8
+#define DW_IC_COMP_TYPE 0xfc
+
+/* DW_IC_CON bits */
+#define DW_IC_CON_MASTER BIT(0)
+#define DW_IC_CON_SPEED_STD (1 << 1)
+#define DW_IC_CON_SPEED_FAST (2 << 1)
+#define DW_IC_CON_SPEED_HIGH (3 << 1)
+#define DW_IC_CON_SPEED_MASK GENMASK(2, 1)
+#define DW_IC_CON_10BITADDR_SLAVE BIT(3)
+#define DW_IC_CON_10BITADDR_MASTER BIT(4)
+#define DW_IC_CON_RESTART_EN BIT(5)
+#define DW_IC_CON_SLAVE_DISABLE BIT(6)
+#define DW_IC_CON_STOP_DET_IFADDRESSED BIT(7)
+#define DW_IC_CON_TX_EMPTY_CTRL BIT(8)
+#define DW_IC_CON_RX_FIFO_FULL_HLD_CTRL BIT(9)
+#define DW_IC_CON_BUS_CLEAR_CTRL BIT(11)
+
+/* DW_IC_DATA_CMD bits */
+#define DW_IC_DATA_CMD_DAT GENMASK(7, 0)
+#define DW_IC_DATA_CMD_FIRST_DATA_BYTE BIT(11)
+
+/* DW_IC_INTR_* bits */
+#define DW_IC_INTR_RX_UNDER BIT(0)
+#define DW_IC_INTR_RX_OVER BIT(1)
+#define DW_IC_INTR_RX_FULL BIT(2)
+#define DW_IC_INTR_TX_OVER BIT(3)
+#define DW_IC_INTR_TX_EMPTY BIT(4)
+#define DW_IC_INTR_RD_REQ BIT(5)
+#define DW_IC_INTR_TX_ABRT BIT(6)
+#define DW_IC_INTR_RX_DONE BIT(7)
+#define DW_IC_INTR_ACTIVITY BIT(8)
+#define DW_IC_INTR_STOP_DET BIT(9)
+#define DW_IC_INTR_START_DET BIT(10)
+#define DW_IC_INTR_GEN_CALL BIT(11)
+#define DW_IC_INTR_RESTART_DET BIT(12)
+#define DW_IC_INTR_MST_ON_HOLD BIT(13)
+
+/* DW_IC_ENABLE bits */
+#define DW_IC_ENABLE_ENABLE BIT(0)
+#define DW_IC_ENABLE_ABORT BIT(1)
+
+/* DW_IC_STATUS bits */
+#define DW_IC_STATUS_ACTIVITY BIT(0)
+#define DW_IC_STATUS_TFE BIT(2)
+#define DW_IC_STATUS_RFNE BIT(3)
+#define DW_IC_STATUS_MASTER_ACTIVITY BIT(5)
+#define DW_IC_STATUS_SLAVE_ACTIVITY BIT(6)
+#define DW_IC_STATUS_MASTER_HOLD_TX_FIFO_EMPTY BIT(7)
+
+/* DW_IC_SMBUS_INTR_* bits */
+#define DW_IC_SMBUS_INTR_ALERT BIT(10)
+
+#endif /* __LINUX_DESIGNWARE_I2C_H */
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 712/733] drm/xe/i2c: Fix the interrupt handling
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (710 preceding siblings ...)
2026-09-17 15:16 ` [PATCH 7.2 711/733] i2c: designware: Global register definitions Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 713/733] platform/x86: hp-wmi: Introduce board-specific feature data Greg Kroah-Hartman
` (32 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Raag Jadav, Ramesh Babu B,
Heikki Krogerus, Rodrigo Vivi, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <heikki.krogerus@linux.intel.com>
[ Upstream commit f43fa4b8522ba6038b77e86e5f0d94be35effcde ]
The platforms that support the interrupt from the I2C
adapter can not handle the amount of interrupts the adapter
generates because of the way the IRQ is routed in the
hardware. The I2C controller driver has to be kept in
polling mode because of that.
The AMC MCU can still generate critical alerts that have to
be handled. The interrupt from SMBus Alert is left enabled
and handled separately in the Xe. The alerts from the AMC
will cause the device to be declared wedged for now.
Fixes: f0e53aadd702 ("drm/xe: Support for I2C attached MCUs")
Cc: stable@vger.kernel.org
Reviewed-by: Raag Jadav <raag.jadav@intel.com>
Co-developed-by: Ramesh Babu B <ramesh.babu.b@intel.com>
Signed-off-by: Ramesh Babu B <ramesh.babu.b@intel.com>
Signed-off-by: Heikki Krogerus <heikki.krogerus@linux.intel.com>
Link: https://patch.msgid.link/20260811121008.1493015-3-heikki.krogerus@linux.intel.com
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
(cherry picked from commit a55b76b8bc2c49b11d753c1c6d06ec3a2c61c85e)
Signed-off-by: Rodrigo Vivi <rodrigo.vivi@intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/xe/Makefile | 4
drivers/gpu/drm/xe/regs/xe_i2c_regs.h | 2
drivers/gpu/drm/xe/xe_amc.c | 197 ++++++++++++++++++++++++++++++++++
drivers/gpu/drm/xe/xe_amc.h | 25 ++++
drivers/gpu/drm/xe/xe_i2c.c | 128 ++++++++--------------
drivers/gpu/drm/xe/xe_i2c.h | 13 +-
6 files changed, 282 insertions(+), 87 deletions(-)
create mode 100644 drivers/gpu/drm/xe/xe_amc.c
create mode 100644 drivers/gpu/drm/xe/xe_amc.h
--- a/drivers/gpu/drm/xe/Makefile
+++ b/drivers/gpu/drm/xe/Makefile
@@ -152,7 +152,9 @@ xe-y += xe_bb.o \
xe_wait_user_fence.o \
xe_wopcm.o
-xe-$(CONFIG_I2C) += xe_i2c.o
+xe-$(CONFIG_I2C) += xe_i2c.o \
+ xe_amc.o
+
xe-$(CONFIG_DRM_XE_GPUSVM) += xe_svm.o
xe-$(CONFIG_DRM_GPUSVM) += xe_userptr.o
--- a/drivers/gpu/drm/xe/regs/xe_i2c_regs.h
+++ b/drivers/gpu/drm/xe/regs/xe_i2c_regs.h
@@ -20,4 +20,6 @@
#define I2C_CONFIG_CMD XE_REG(I2C_CONFIG_SPACE_OFFSET + PCI_COMMAND)
#define I2C_CONFIG_PMCSR XE_REG(I2C_CONFIG_SPACE_OFFSET + 0x84)
+#define I2C_REG(reg) XE_REG((reg) + I2C_MEM_SPACE_OFFSET)
+
#endif /* _XE_I2C_REGS_H_ */
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_amc.c
@@ -0,0 +1,197 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Copyright (C) 2026 Intel Corporation.
+ */
+
+#include <linux/delay.h>
+#include <linux/dev_printk.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/pci_ids.h>
+#include <linux/slab.h>
+#include <linux/string.h>
+#include <linux/workqueue.h>
+
+#include "regs/xe_i2c_regs.h"
+
+#include "xe_amc.h"
+#include "xe_device.h"
+#include "xe_i2c.h"
+#include "xe_mmio.h"
+
+/**
+ * DOC: Add-In Management Controller (AMC)
+ *
+ * Handler for the SMBus Alerts from the AMC. All the alerts from AMC will cause
+ * the device to be declared wedged.
+ */
+
+#define AMC_COMMAND 0x0f
+#define AMC_GPU_I2C_ADDR 0x8f
+#define AMC_VERSION_V1 0x01
+#define AMC_DESTINATION_ID 12
+#define AMC_SOURCE_ID 8
+#define AMC_FLAGS 0xc8
+
+#define AMC_MSG_TYPE 0x7e
+#define AMC_GET_ALERT_REASON 0x01
+
+enum xe_amc_alert {
+ AMC_ALERT_UNKNOWN,
+ AMC_ALERT_FW_DOWNLOAD,
+ AMC_ALERT_THERMAL_TRIP,
+ AMC_ALERT_OOB_REQUEST,
+ AMC_ALERT_OOB_RESET,
+ AMC_ALERT_CATERR,
+};
+
+static const char * const amc_alert[] = {
+ [AMC_ALERT_FW_DOWNLOAD] = "Firmware Download",
+ [AMC_ALERT_THERMAL_TRIP] = "Thermal Trip",
+ [AMC_ALERT_OOB_REQUEST] = "OOB Request",
+ [AMC_ALERT_OOB_RESET] = "OOB Reset",
+ [AMC_ALERT_CATERR] = "Catastrophic",
+};
+
+struct xe_amc {
+ struct xe_i2c *i2c;
+ struct work_struct work;
+};
+
+struct amc_header {
+ u8 command;
+ u8 len;
+ u8 address;
+ u8 version;
+ u8 destination;
+ u8 source;
+ u8 flags;
+} __packed;
+
+struct amc_message {
+ u8 type;
+ u16 vendor;
+ u8 command;
+} __packed;
+
+struct amc_request {
+ struct amc_header header;
+ struct amc_message message;
+ u32 reserved;
+} __packed;
+
+struct amc_response {
+ struct amc_header header;
+ struct amc_message message;
+ u8 error;
+ u8 value;
+} __packed;
+
+static const struct amc_request amc_get_alert_reason = {
+ .header = {
+ .command = AMC_COMMAND,
+ .len = sizeof(struct amc_request) - 2,
+ .address = AMC_GPU_I2C_ADDR,
+ .version = AMC_VERSION_V1,
+ .destination = AMC_DESTINATION_ID,
+ .source = AMC_SOURCE_ID,
+ .flags = AMC_FLAGS,
+ },
+ .message = {
+ .type = AMC_MSG_TYPE,
+ .vendor = htons(PCI_VENDOR_ID_INTEL),
+ .command = AMC_GET_ALERT_REASON,
+ },
+};
+
+static void xe_amc_work(struct work_struct *work)
+{
+ const struct amc_request *request = &amc_get_alert_reason;
+ struct xe_amc *amc = from_work(amc, work, work);
+ u8 alert_reason = AMC_ALERT_UNKNOWN;
+ struct amc_response response;
+ struct i2c_client *client;
+ int ret;
+
+ client = amc->i2c->client[XE_I2C_CLIENT_AMC];
+ if (IS_ERR_OR_NULL(client))
+ goto out_reassert_interrupt;
+
+ ret = i2c_master_send(client, (u8 *)request, sizeof(*request));
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to send request (%d)\n", ret);
+ goto out_reassert_interrupt;
+ }
+
+ /* AMC needs 20ms to generate the response. */
+ fsleep(20 * USEC_PER_MSEC);
+
+ ret = i2c_master_recv(client, (u8 *)&response, sizeof(response));
+ if (ret < 0) {
+ dev_err(&client->dev, "failed to read response (%d)\n", ret);
+ goto out_reassert_interrupt;
+ }
+
+ if (!response.header.len) {
+ dev_err(&client->dev, "empty response from AMC\n");
+ goto out_reassert_interrupt;
+ }
+
+ if (memcmp(&response.message, &request->message, sizeof(struct amc_message))) {
+ dev_err(&client->dev, "response does not match the request\n");
+ goto out_reassert_interrupt;
+ }
+
+ if (response.error) {
+ dev_err(&client->dev, "AMC error 0x%02x\n", response.error);
+ goto out_reassert_interrupt;
+ }
+
+ alert_reason = response.value;
+ dev_dbg(&client->dev, "Alert reason: %d\n", alert_reason);
+
+out_reassert_interrupt:
+ xe_mmio_rmw32(amc->i2c->mmio, I2C_CONFIG_CMD, PCI_COMMAND_INTX_DISABLE, 0);
+
+ switch (alert_reason) {
+ case AMC_ALERT_FW_DOWNLOAD:
+ case AMC_ALERT_THERMAL_TRIP:
+ case AMC_ALERT_OOB_REQUEST:
+ case AMC_ALERT_OOB_RESET:
+ case AMC_ALERT_CATERR:
+ dev_warn(amc->i2c->drm_dev, "AMC Alert: %s\n", amc_alert[alert_reason]);
+ xe_device_declare_wedged(i2c_client_to_xe_device(client));
+ break;
+ default:
+ dev_warn(amc->i2c->drm_dev, "unknown AMC alert: %d\n", alert_reason);
+ break;
+ }
+}
+
+void xe_amc_handle_alert(struct xe_i2c *i2c)
+{
+ queue_work(system_long_wq, &i2c->amc->work);
+}
+
+int xe_amc_init(struct xe_i2c *i2c)
+{
+ struct xe_amc *amc;
+
+ amc = kzalloc(sizeof(*amc), GFP_KERNEL);
+ if (!amc)
+ return -ENOMEM;
+
+ INIT_WORK(&amc->work, xe_amc_work);
+ i2c->amc = amc;
+ amc->i2c = i2c;
+
+ return 0;
+}
+
+void xe_amc_exit(struct xe_i2c *i2c)
+{
+ if (i2c->amc) {
+ cancel_work_sync(&i2c->amc->work);
+ kfree(i2c->amc);
+ }
+}
--- /dev/null
+++ b/drivers/gpu/drm/xe/xe_amc.h
@@ -0,0 +1,25 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+#ifndef _XE_AMC_H_
+#define _XE_AMC_H_
+
+#include <linux/i2c.h>
+
+#include "xe_device.h"
+
+struct xe_i2c;
+
+static inline struct xe_device *i2c_adapter_to_xe_device(struct i2c_adapter *adapter)
+{
+ return kdev_to_xe_device(adapter->dev.parent->parent);
+}
+
+static inline struct xe_device *i2c_client_to_xe_device(struct i2c_client *client)
+{
+ return i2c_adapter_to_xe_device(client->adapter);
+}
+
+int xe_amc_init(struct xe_i2c *i2c);
+void xe_amc_exit(struct xe_i2c *i2c);
+void xe_amc_handle_alert(struct xe_i2c *i2c);
+
+#endif /* _XE_AMC_H_ */
--- a/drivers/gpu/drm/xe/xe_i2c.c
+++ b/drivers/gpu/drm/xe/xe_i2c.c
@@ -12,8 +12,6 @@
#include <linux/err.h>
#include <linux/i2c.h>
#include <linux/ioport.h>
-#include <linux/irq.h>
-#include <linux/irqdomain.h>
#include <linux/notifier.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
@@ -24,9 +22,12 @@
#include <linux/types.h>
#include <linux/workqueue.h>
+#include <linux/designware_i2c.h>
+
#include "regs/xe_i2c_regs.h"
#include "regs/xe_irq_regs.h"
+#include "xe_amc.h"
#include "xe_device.h"
#include "xe_i2c.h"
#include "xe_mmio.h"
@@ -61,16 +62,32 @@ static inline void xe_i2c_read_endpoint(
val[1] = xe_mmio_read32(mmio, REG_SG_REMAP_ADDR_POSTFIX);
}
+static void xe_i2c_handle_smbus_alert(struct xe_i2c *i2c)
+{
+ u32 stat;
+
+ stat = xe_mmio_read32(i2c->mmio, I2C_REG(DW_IC_SMBUS_INTR_STAT));
+ if (!stat)
+ return;
+
+ xe_mmio_write32(i2c->mmio, I2C_REG(DW_IC_CLR_SMBUS_INTR), stat);
+
+ if (stat & DW_IC_SMBUS_INTR_ALERT && i2c->amc)
+ xe_amc_handle_alert(i2c);
+ else
+ xe_mmio_rmw32(i2c->mmio, I2C_CONFIG_CMD, PCI_COMMAND_INTX_DISABLE, 0);
+}
+
static void xe_i2c_client_work(struct work_struct *work)
{
struct xe_i2c *i2c = container_of(work, struct xe_i2c, work);
struct i2c_board_info info = {
.type = "amc",
.flags = I2C_CLIENT_HOST_NOTIFY,
- .addr = i2c->ep.addr[1],
+ .addr = i2c->ep.addr[XE_I2C_CLIENT_AMC],
};
- i2c->client[0] = i2c_new_client_device(i2c->adapter, &info);
+ i2c->client[XE_I2C_CLIENT_AMC] = i2c_new_client_device(i2c->adapter, &info);
}
static int xe_i2c_notifier(struct notifier_block *nb, unsigned long action, void *data)
@@ -115,16 +132,6 @@ static int xe_i2c_register_adapter(struc
goto err_fwnode_remove;
}
- if (i2c->adapter_irq) {
- struct resource res;
-
- res = DEFINE_RES_IRQ_NAMED(i2c->adapter_irq, "xe_i2c");
-
- ret = platform_device_add_resources(pdev, &res, 1);
- if (ret)
- goto err_pdev_put;
- }
-
pdev->dev.parent = i2c->drm_dev;
pdev->dev.fwnode = fwnode;
i2c->adapter_node = fwnode;
@@ -166,7 +173,8 @@ bool xe_i2c_present(struct xe_device *xe
static bool xe_i2c_irq_present(struct xe_device *xe)
{
- return xe->i2c && xe->i2c->adapter_irq;
+ return xe->i2c && xe->i2c->ep.capabilities & XE_I2C_EP_CAP_IRQ &&
+ !xe_survivability_mode_is_boot_enabled(xe);
}
/**
@@ -179,18 +187,10 @@ static bool xe_i2c_irq_present(struct xe
*/
void xe_i2c_irq_handler(struct xe_device *xe, u32 master_ctl)
{
- struct xe_mmio *mmio = xe_root_tile_mmio(xe);
-
if (!(master_ctl & I2C_IRQ) || !xe_i2c_irq_present(xe))
return;
- /* Forward interrupt to I2C adapter */
- generic_handle_irq_safe(xe->i2c->adapter_irq);
-
- /* Deassert after I2C adapter clears the interrupt */
- xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, 0, PCI_COMMAND_INTX_DISABLE);
- /* Reassert to allow subsequent interrupt generation */
- xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, PCI_COMMAND_INTX_DISABLE, 0);
+ xe_i2c_handle_smbus_alert(xe->i2c);
}
void xe_i2c_irq_reset(struct xe_device *xe)
@@ -215,45 +215,6 @@ void xe_i2c_irq_postinstall(struct xe_de
xe_mmio_rmw32(mmio, I2C_CONFIG_CMD, PCI_COMMAND_INTX_DISABLE, 0);
}
-static int xe_i2c_irq_map(struct irq_domain *h, unsigned int virq,
- irq_hw_number_t hw_irq_num)
-{
- irq_set_chip_and_handler(virq, &dummy_irq_chip, handle_simple_irq);
- return 0;
-}
-
-static const struct irq_domain_ops xe_i2c_irq_ops = {
- .map = xe_i2c_irq_map,
-};
-
-static int xe_i2c_create_irq(struct xe_device *xe)
-{
- struct xe_i2c *i2c = xe->i2c;
- struct irq_domain *domain;
-
- if (!(i2c->ep.capabilities & XE_I2C_EP_CAP_IRQ) ||
- xe_survivability_mode_is_boot_enabled(xe))
- return 0;
-
- domain = irq_domain_create_linear(dev_fwnode(i2c->drm_dev), 1, &xe_i2c_irq_ops, NULL);
- if (!domain)
- return -ENOMEM;
-
- i2c->adapter_irq = irq_create_mapping(domain, 0);
- i2c->irqdomain = domain;
-
- return 0;
-}
-
-static void xe_i2c_remove_irq(struct xe_i2c *i2c)
-{
- if (!i2c->irqdomain)
- return;
-
- irq_dispose_mapping(i2c->adapter_irq);
- irq_domain_remove(i2c->irqdomain);
-}
-
static int xe_i2c_read(void *context, unsigned int reg, unsigned int *val)
{
struct xe_i2c *i2c = context;
@@ -267,8 +228,16 @@ static int xe_i2c_write(void *context, u
{
struct xe_i2c *i2c = context;
- xe_mmio_write32(i2c->mmio, XE_REG(reg + I2C_MEM_SPACE_OFFSET), val);
+ switch (reg) {
+ case DW_IC_SMBUS_INTR_MASK:
+ /* Make sure the Alert is never masked. */
+ val |= DW_IC_SMBUS_INTR_ALERT;
+ break;
+ default:
+ break;
+ }
+ xe_mmio_write32(i2c->mmio, I2C_REG(reg), val);
return 0;
}
@@ -310,12 +279,15 @@ static void xe_i2c_remove(void *data)
struct xe_i2c *i2c = data;
unsigned int i;
- for (i = 0; i < XE_I2C_MAX_CLIENTS; i++)
+ xe_amc_exit(i2c);
+
+ for (i = 0; i < XE_I2C_MAX_CLIENTS; i++) {
i2c_unregister_device(i2c->client[i]);
+ i2c->client[i] = NULL;
+ }
bus_unregister_notifier(&i2c_bus_type, &i2c->bus_notifier);
xe_i2c_unregister_adapter(i2c);
- xe_i2c_remove_irq(i2c);
}
/**
@@ -366,22 +338,18 @@ int xe_i2c_probe(struct xe_device *xe)
if (ret)
return ret;
- ret = xe_i2c_create_irq(xe);
- if (ret)
- goto err_unregister_notifier;
-
ret = xe_i2c_register_adapter(i2c);
- if (ret)
- goto err_remove_irq;
+ if (ret) {
+ bus_unregister_notifier(&i2c_bus_type, &i2c->bus_notifier);
+ return ret;
+ }
+
+ ret = xe_amc_init(i2c);
+ if (ret) {
+ xe_i2c_remove(i2c);
+ return ret;
+ }
xe_i2c_irq_postinstall(xe);
return devm_add_action_or_reset(drm_dev, xe_i2c_remove, i2c);
-
-err_remove_irq:
- xe_i2c_remove_irq(i2c);
-
-err_unregister_notifier:
- bus_unregister_notifier(&i2c_bus_type, &i2c->bus_notifier);
-
- return ret;
}
--- a/drivers/gpu/drm/xe/xe_i2c.h
+++ b/drivers/gpu/drm/xe/xe_i2c.h
@@ -11,18 +11,21 @@ struct device;
struct fwnode_handle;
struct i2c_adapter;
struct i2c_client;
-struct irq_domain;
struct platform_device;
+struct xe_amc;
struct xe_device;
struct xe_mmio;
-#define XE_I2C_MAX_CLIENTS 3
-
#define XE_I2C_EP_COOKIE_DEVICE 0xde
/* Endpoint Capabilities */
#define XE_I2C_EP_CAP_IRQ BIT(0)
+enum XE_I2C_CLIENT {
+ XE_I2C_CLIENT_AMC = 1,
+ XE_I2C_MAX_CLIENTS = 3,
+};
+
struct xe_i2c_endpoint {
u8 cookie;
u8 capabilities;
@@ -38,13 +41,11 @@ struct xe_i2c {
struct notifier_block bus_notifier;
struct work_struct work;
- struct irq_domain *irqdomain;
- int adapter_irq;
-
struct xe_i2c_endpoint ep;
struct device *drm_dev;
struct xe_mmio *mmio;
+ struct xe_amc *amc;
};
#if IS_ENABLED(CONFIG_I2C)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 713/733] platform/x86: hp-wmi: Introduce board-specific feature data
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (711 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 712/733] drm/xe/i2c: Fix the interrupt handling Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 714/733] platform/x86: hp-wmi: Fix board_params typo for 8DD6 board Greg Kroah-Hartman
` (31 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Radhey Kalra, Ilpo Järvinen,
Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Radhey Kalra <radheykalra901@gmail.com>
[ Upstream commit 08ecf6d131f38595a1e7f5441c8e1d29302cc718 ]
The hp_wmi DMI table is about to carry more than thermal-profile data.
Replace the direct thermal_profile_params .driver_data pointers with
hp_wmi_board_params and rename the table/setup helper accordingly.
No functional changes intended.
Signed-off-by: Radhey Kalra <radheykalra901@gmail.com>
Link: https://patch.msgid.link/20260615091034.987029-2-radheykalra901@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Stable-dep-of: ee02ed6308fb ("platform/x86: hp-wmi: Fix board_params typo for 8DD6 board")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/platform/x86/hp/hp-wmi.c | 127 ++++++++++++++++++++++++---------------
1 file changed, 80 insertions(+), 47 deletions(-)
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -133,11 +133,35 @@ static const struct thermal_profile_para
.ec_tp_offset = HP_NO_THERMAL_PROFILE_OFFSET,
};
-/*
- * A generic pointer for the currently-active board's thermal profile
- * parameters.
- */
-static struct thermal_profile_params *active_thermal_profile_params;
+struct hp_wmi_board_params {
+ const struct thermal_profile_params *thermal_profile;
+};
+
+static const struct hp_wmi_board_params victus_s_board_params = {
+ .thermal_profile = &victus_s_thermal_params,
+};
+
+static const struct hp_wmi_board_params omen_v1_board_params = {
+ .thermal_profile = &omen_v1_thermal_params,
+};
+
+static const struct hp_wmi_board_params omen_v1_legacy_board_params = {
+ .thermal_profile = &omen_v1_legacy_thermal_params,
+};
+
+static const struct hp_wmi_board_params omen_v1_no_ec_board_params = {
+ .thermal_profile = &omen_v1_no_ec_thermal_params,
+};
+
+static const struct hp_wmi_board_params *active_board_params;
+
+static const struct thermal_profile_params *hp_wmi_thermal_profile(void)
+{
+ if (!active_board_params)
+ return NULL;
+
+ return active_board_params->thermal_profile;
+}
/* DMI board names of devices that should use the omen specific path for
* thermal profiles.
@@ -187,83 +211,83 @@ static const char * const victus_thermal
"8A25",
};
-/* DMI Board names of Victus 16-r and Victus 16-s laptops */
-static const struct dmi_system_id victus_s_thermal_profile_boards[] __initconst = {
+/* DMI board-specific feature data for Omen and Victus laptops. */
+static const struct dmi_system_id hp_wmi_feature_boards[] __initconst = {
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8902") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8A44") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8A4D") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BAB") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8B2F") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BBE") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BC2") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCA") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BCD") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD4") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8BD5") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C76") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C77") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C78") },
- .driver_data = (void *)&omen_v1_thermal_params,
+ .driver_data = (void *)&omen_v1_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C99") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8C9C") },
- .driver_data = (void *)&victus_s_thermal_params,
+ .driver_data = (void *)&victus_s_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8D26") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8D41") },
- .driver_data = (void *)&omen_v1_no_ec_thermal_params,
+ .driver_data = (void *)&omen_v1_no_ec_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8D87") },
- .driver_data = (void *)&omen_v1_no_ec_thermal_params,
+ .driver_data = (void *)&omen_v1_no_ec_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8DD6") },
@@ -271,7 +295,7 @@ static const struct dmi_system_id victus
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8E35") },
- .driver_data = (void *)&omen_v1_legacy_thermal_params,
+ .driver_data = (void *)&omen_v1_legacy_board_params,
},
{},
};
@@ -1878,7 +1902,10 @@ static int platform_profile_victus_s_get
u8 current_dstate, current_gpu_slowdown_temp, tp;
const struct thermal_profile_params *params;
- params = active_thermal_profile_params;
+ params = hp_wmi_thermal_profile();
+ if (!params)
+ return -ENODEV;
+
if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
*profile = active_platform_profile;
@@ -1890,10 +1917,10 @@ static int platform_profile_victus_s_get
return ret;
/*
- * We cannot use active_thermal_profile_params here, because boards
- * like 8C78 have tp == 0x0 || tp == 0x1 after cold boot, but logically
- * it should have tp == 0x30 || tp == 0x31, as corrected by the Omen
- * Gaming Hub on windows. Hence accept both of these values.
+ * Boards like 8C78 have tp == 0x0 || tp == 0x1 after cold boot,
+ * but logically it should have tp == 0x30 || tp == 0x31, as
+ * corrected by the Omen Gaming Hub on windows. Hence accept both
+ * of these values.
*/
if (tp == victus_s_thermal_params.performance ||
tp == omen_v1_thermal_params.performance) {
@@ -1928,12 +1955,12 @@ static int platform_profile_victus_s_get
static int platform_profile_victus_s_set_ec(enum platform_profile_option profile)
{
- struct thermal_profile_params *params;
+ const struct thermal_profile_params *params;
bool gpu_ctgp_enable, gpu_ppab_enable;
u8 gpu_dstate; /* Test shows 1 = 100%, 2 = 50%, 3 = 25%, 4 = 12.5% */
int err, tp;
- params = active_thermal_profile_params;
+ params = hp_wmi_thermal_profile();
if (!params)
return -ENODEV;
@@ -2199,6 +2226,7 @@ static const struct platform_profile_ops
static int thermal_profile_setup(struct platform_device *device)
{
const struct platform_profile_ops *ops;
+ const struct thermal_profile_params *params;
int err, tp;
if (is_omen_thermal_profile()) {
@@ -2230,13 +2258,17 @@ static int thermal_profile_setup(struct
ops = &platform_profile_victus_ops;
} else if (is_victus_s_thermal_profile()) {
+ params = hp_wmi_thermal_profile();
+ if (!params)
+ return -ENODEV;
+
/*
* For an unknown EC layout board, platform_profile_victus_s_get_ec(),
* behaves like a wrapper around active_platform_profile, to avoid using
* uninitialized data, we default to PLATFORM_PROFILE_BALANCED.
*/
- if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
- active_thermal_profile_params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
+ if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN ||
+ params->ec_tp_offset == HP_NO_THERMAL_PROFILE_OFFSET) {
active_platform_profile = PLATFORM_PROFILE_BALANCED;
} else {
err = platform_profile_victus_s_get_ec(&active_platform_profile);
@@ -2697,24 +2729,25 @@ static int hp_wmi_hwmon_init(void)
return 0;
}
-static void __init setup_active_thermal_profile_params(void)
+static void __init setup_active_board_params(void)
{
const struct dmi_system_id *id;
+ const struct thermal_profile_params *params;
- /*
- * Currently only victus_s devices use the
- * active_thermal_profile_params
- */
- id = dmi_first_match(victus_s_thermal_profile_boards);
+ id = dmi_first_match(hp_wmi_feature_boards);
if (id) {
+ active_board_params = id->driver_data;
+ params = hp_wmi_thermal_profile();
+ if (!params)
+ return;
+
/*
* Marking this boolean is required to ensure that
* is_victus_s_thermal_profile() behaves like a valid
* wrapper.
*/
is_victus_s_board = true;
- active_thermal_profile_params = id->driver_data;
- if (active_thermal_profile_params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
+ if (params->ec_tp_offset == HP_EC_OFFSET_UNKNOWN) {
pr_warn("Unknown EC layout for board %s. Thermal profile readback will be disabled. Please report this to platform-driver-x86@vger.kernel.org\n",
dmi_get_system_info(DMI_BOARD_NAME));
}
@@ -2749,10 +2782,10 @@ static int __init hp_wmi_init(void)
}
/*
- * Setup active board's thermal profile parameters before
- * starting platform driver probe.
+ * Setup active board feature data before starting platform
+ * driver probe.
*/
- setup_active_thermal_profile_params();
+ setup_active_board_params();
err = platform_driver_probe(&hp_wmi_driver, hp_wmi_bios_setup);
if (err)
goto err_unregister_device;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 714/733] platform/x86: hp-wmi: Fix board_params typo for 8DD6 board
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (712 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 713/733] platform/x86: hp-wmi: Introduce board-specific feature data Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 715/733] x86/mm/pat: Dont gate cpa_lock on debug_pagealloc_enabled() Greg Kroah-Hartman
` (30 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arda Doğu Ari, Krishna Chomal,
Ilpo Järvinen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arda Doğu Ari <arfeliousheres@gmail.com>
[ Upstream commit ee02ed6308fbbd851c4e5c1f642d029617049a12 ]
When adding support for board 8DD6, &omen_v1_no_ec_thermal_params
was passed as driver_data instead of &omen_v1_no_ec_board_params.
Because active_board_params expects a pointer to struct
hp_wmi_board_params, dereferencing active_board_params->thermal_profile
results in a type confusion bug and invalid memory access. Update the entry
to point to omen_v1_no_ec_board_params.
Fixes: a7320d6eb9c42 ("platform/x86: hp-wmi: Add support for OMEN MAX 16-ak0xxx (8DD6)")
Cc: stable@vger.kernel.org
Signed-off-by: Arda Doğu Ari <arfeliousheres@gmail.com>
Reviewed-by: Krishna Chomal <krishna.chomal108@gmail.com>
Link: https://patch.msgid.link/20260827235139.154462-1-arfeliousheres@gmail.com
Reviewed-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Ilpo Järvinen <ilpo.jarvinen@linux.intel.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/platform/x86/hp/hp-wmi.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
--- a/drivers/platform/x86/hp/hp-wmi.c
+++ b/drivers/platform/x86/hp/hp-wmi.c
@@ -291,7 +291,7 @@ static const struct dmi_system_id hp_wmi
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8DD6") },
- .driver_data = (void *)&omen_v1_no_ec_thermal_params,
+ .driver_data = (void *)&omen_v1_no_ec_board_params,
},
{
.matches = { DMI_MATCH(DMI_BOARD_NAME, "8E35") },
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 715/733] x86/mm/pat: Dont gate cpa_lock on debug_pagealloc_enabled()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (713 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 714/733] platform/x86: hp-wmi: Fix board_params typo for 8DD6 board Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 716/733] x86/mm/pat: Acquire init_mm read lock on attribute changes to avoid UAF Greg Kroah-Hartman
` (29 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Dave Hansen,
Mike Rapoport (Microsoft), Dave Hansen, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Mike Rapoport (Microsoft)" <rppt@kernel.org>
[ Upstream commit 5fce67641a3ed9a0782eaa228ddece526461a367 ]
The splitting and merging of kernel page table mappings between small and
large is protected by cpa_lock. The merging is relatively new but the
splitting is ancient.
The splitting has a locking optimization: since DEBUG_PAGEALLOC forces all
mappings to 4k, there are no large pages to split. So the code that *might*
cause a split can just skip the locking (and a few other things).
This is entertaining, but it adds complexity and makes for weird locking
rules. Plus it's all for a debugging feature which makes the kernel super
slow in the first place. Optimizing something which is already super slow
and not used in production is not the best way to spend our complexity
budget.
Stop gating cpa_lock on debug_pagealloc_enabled() to simplify the code
and the locking rules.
[ dhansen: flesh out changelog ]
Suggested-by: Dave Hansen <dave.hansen@intel.com>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Link: https://patch.msgid.link/20260715144519.934289-1-rppt@kernel.org
Link: https://lore.kernel.org/all/aab44f08-89f8-47fe-bee4-0ab6b25968c6@intel.com/
Stable-dep-of: d5d8b8662e6e ("x86/mm/pat: Acquire init_mm read lock on attribute changes to avoid UAF")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/mm/pat/set_memory.c | 19 +++++++------------
1 file changed, 7 insertions(+), 12 deletions(-)
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -63,10 +63,9 @@ enum cpa_warn {
static const int cpa_warn_level = CPA_PROTECT;
/*
- * Serialize cpa() (for !DEBUG_PAGEALLOC which uses large identity mappings)
- * using cpa_lock. So that we don't allow any other cpu, with stale large tlb
- * entries change the page attribute in parallel to some other cpu
- * splitting a large page entry along with changing the attribute.
+ * Serialize cpa() using cpa_lock so that we don't allow any other cpu, with
+ * stale large tlb entries, to change the page attribute in parallel to some
+ * other cpu splitting a large page entry along with changing the attribute.
*/
static DEFINE_SPINLOCK(cpa_lock);
@@ -1254,11 +1253,9 @@ static int split_large_page(struct cpa_d
{
struct ptdesc *ptdesc;
- if (!debug_pagealloc_enabled())
- spin_unlock(&cpa_lock);
+ spin_unlock(&cpa_lock);
ptdesc = pagetable_alloc(GFP_KERNEL, 0);
- if (!debug_pagealloc_enabled())
- spin_lock(&cpa_lock);
+ spin_lock(&cpa_lock);
if (!ptdesc)
return -ENOMEM;
@@ -2042,11 +2039,9 @@ static int __change_page_attr_set_clr(st
if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY))
cpa->numpages = 1;
- if (!debug_pagealloc_enabled())
- spin_lock(&cpa_lock);
+ spin_lock(&cpa_lock);
ret = __change_page_attr(cpa, primary);
- if (!debug_pagealloc_enabled())
- spin_unlock(&cpa_lock);
+ spin_unlock(&cpa_lock);
if (ret)
goto out;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 716/733] x86/mm/pat: Acquire init_mm read lock on attribute changes to avoid UAF
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (714 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 715/733] x86/mm/pat: Dont gate cpa_lock on debug_pagealloc_enabled() Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 717/733] EDAC/altera: Use parent device for devres in altr_portb_setup() Greg Kroah-Hartman
` (28 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
Mike Rapoport (Microsoft), Dave Hansen, Ingo Molnar, Atish Patra,
Nikunj A Dadhania, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
[ Upstream commit d5d8b8662e6e5a565b47a0388640e88402f23274 ]
A previous commit protected against races between ptdump and CPA collapse,
however one still exists between attribute changes and collapse as reported
by Denis V. Lunev (linked).
When an attribute change arises, a lockless page table walker obtains a PTE
entry, which is later written to via set_pte_atomic():
...
-> change_page_attr_set_clr()
-> __change_page_attr_set_clr()
-> __change_page_attr()
-> _lookup_address_cpa()
-> lookup_address_in_pgd_attr()
-> [ lockless page table walker ]
-> set_pte_atomic()
There is nothing preventing a concurrent CPA collapse which can free the
PTE that was retrieved here, resulting in a use-after-free.
With the mmap write lock taken on init_mm over CPA collapse, resolve this
race by acquiring an mmap read lock on init_mm over
__change_page_attr_set_clr().
This locks across the whole operation over which the walk and the PTE
entry write occurs, solving the race.
It is safe to do this here, as no spinlocks are held upon entry to
__change_page_attr_set_clr().
However, the lock must not be held over an allocation, as allocation can
trigger reclaim and shrinkers may call into CPA recursively, making
deadlocks possible (init_mm -> ... -> fs_reclaim -> init_mm).
A page table is allocated when a huge page needs to be split:
-> change_page_attr_set_clr()
-> __change_page_attr_set_clr()
-> __change_page_attr()
-> split_large_page()
[ pagetable_alloc() ]
-> __split_large_page()
Avoid deadlocks by dropping the mmap lock across pagetable_alloc() in
split_large_page() and track whether this is needed by adding a new
'init_mm_read_locked' flag to struct cpa_data.
This is safe as __split_large_page() (called with locks re-established)
revalidates that the page table entry is the same as it was prior to the
locks being dropped and __change_page_attr() repeats the entire page table
walk whenever a split occurs, so concurrent split and collapse are
accounted for.
Concurrent ptdump is also safe as the lock is only dropped over page table
allocation during which time the page table has not yet been modified.
The CPA_COLLAPSE flag is only set by set_memory_rox(), which exclusively
operates upon vmalloc ranges, and on x86 only within the module mapping
space.
This is important, because some callers directly invoke
__change_page_attr_set_clr(), bypassing this lock. However, none of these
operate within the module mapping space.
* cpa_process_alias() - a recursive helper called by
__change_page_attr_set_clr().
* __set_memory_enc_pgtable() - operates on the direct mapping and (via
__vmbus_establish_gpadl()) the vmalloc mapping space.
* __set_pages_[n]p() - called by set_direct_map_[invalid, default,
valid]_noflush(), __kernel_map_pages() - operates on the direct map.
* kernel_[un]map_pages_in_pgd() - operates on EFI ranges.
This work is based upon Denis V. Lunev's excellent analysis of the bug
with gratitude.
[ dhansen: move to imperative voice in changelog ]
Fixes: 41d88484c71c ("x86/mm/pat: restore large ROX pages after fragmentation")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Tested-by: Atish Patra <atishp@meta.com>
Tested-by: Nikunj A Dadhania <nikunj@amd.com>
Link: https://lore.kernel.org/all/20260626163213.2284080-1-den@openvz.org/
Cc:stable@vger.kernel.org
Link: https://patch.msgid.link/20260813-cpa-fixes-v2-2-39b4ff90f91d@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/mm/pat/set_memory.c | 13 +++++++++++--
1 file changed, 11 insertions(+), 2 deletions(-)
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -50,7 +50,8 @@ struct cpa_data {
unsigned int flags;
unsigned int force_split : 1,
force_static_prot : 1,
- force_flush_all : 1;
+ force_flush_all : 1,
+ init_mm_read_locked : 1;
struct page **pages;
};
@@ -1254,7 +1255,11 @@ static int split_large_page(struct cpa_d
struct ptdesc *ptdesc;
spin_unlock(&cpa_lock);
+ if (cpa->init_mm_read_locked)
+ mmap_read_unlock(&init_mm);
ptdesc = pagetable_alloc(GFP_KERNEL, 0);
+ if (cpa->init_mm_read_locked)
+ mmap_read_lock(&init_mm);
spin_lock(&cpa_lock);
if (!ptdesc)
return -ENOMEM;
@@ -2123,7 +2128,11 @@ static int change_page_attr_set_clr(unsi
cpa.curpage = 0;
cpa.force_split = force_split;
- ret = __change_page_attr_set_clr(&cpa, 1);
+ /* Avoid race with concurrent CPA collapse. */
+ cpa.init_mm_read_locked = true;
+ scoped_guard(mmap_read_lock, &init_mm)
+ ret = __change_page_attr_set_clr(&cpa, 1);
+ cpa.init_mm_read_locked = false;
/*
* Check whether we really changed something:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 717/733] EDAC/altera: Use parent device for devres in altr_portb_setup()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (715 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 716/733] x86/mm/pat: Acquire init_mm read lock on attribute changes to avoid UAF Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 718/733] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
` (27 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Borislav Petkov (AMD), Dinh Nguyen
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dinh Nguyen <dinguyen@kernel.org>
commit 9868f5c077dfe0b606331f2e782484f91a5789a5 upstream.
Anchor the devres group and the devm-managed IRQ requests in altr_portb_setup()
to the actual parent device (device->edac->dev) instead of the embedded struct
device inside the copied per-port altr_edac_device_dev.
This keeps devres_open_group(), devm_request_irq(), devres_remove_group() and
devres_release_group() all referring to the same long-lived device so the
group and the resources allocated inside it are torn down together.
Fixes: 911049845d70 ("EDAC, altera: Add Arria10 SD-MMC EDAC support")
Closes: https://sashiko.dev/#/patchset/20260503212558.2811480-1-dbgh9129%40gmail.com
Assisted-by: LLM
Signed-off-by: Borislav Petkov (AMD) <bp@alien8.de>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260617164303.585555-1-dinguyen@kernel.org
Signed-off-by: Dinh Nguyen <dinguyen@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/edac/altera_edac.c | 10 +++++-----
1 file changed, 5 insertions(+), 5 deletions(-)
--- a/drivers/edac/altera_edac.c
+++ b/drivers/edac/altera_edac.c
@@ -1533,7 +1533,7 @@ static int altr_portb_setup(struct altr_
altdev = dci->pvt_info;
*altdev = *device;
- if (!devres_open_group(&altdev->ddev, altr_portb_setup, GFP_KERNEL))
+ if (!devres_open_group(device->edac->dev, altr_portb_setup, GFP_KERNEL))
return -ENOMEM;
/* Update PortB specific values */
@@ -1562,7 +1562,7 @@ static int altr_portb_setup(struct altr_
rc = -ENODEV;
goto err_release_group_1;
}
- rc = devm_request_irq(&altdev->ddev, altdev->sb_irq,
+ rc = devm_request_irq(device->edac->dev, altdev->sb_irq,
prv->ecc_irq_handler, IRQF_TRIGGER_HIGH,
ecc_name, altdev);
if (rc) {
@@ -1585,7 +1585,7 @@ static int altr_portb_setup(struct altr_
rc = -ENODEV;
goto err_release_group_1;
}
- rc = devm_request_irq(&altdev->ddev, altdev->db_irq,
+ rc = devm_request_irq(device->edac->dev, altdev->db_irq,
prv->ecc_irq_handler, IRQF_TRIGGER_HIGH,
ecc_name, altdev);
if (rc) {
@@ -1605,13 +1605,13 @@ static int altr_portb_setup(struct altr_
list_add(&altdev->next, &altdev->edac->a10_ecc_devices);
- devres_remove_group(&altdev->ddev, altr_portb_setup);
+ devres_remove_group(device->edac->dev, altr_portb_setup);
return 0;
err_release_group_1:
edac_device_free_ctl_info(dci);
- devres_release_group(&altdev->ddev, altr_portb_setup);
+ devres_release_group(device->edac->dev, altr_portb_setup);
edac_printk(KERN_ERR, EDAC_DEVICE,
"%s:Error setting up EDAC device: %d\n", ecc_name, rc);
return rc;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 718/733] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (716 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 717/733] EDAC/altera: Use parent device for devres in altr_portb_setup() Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 719/733] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
` (26 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 6d90f0feb929f6c0f3010f9af4747c7230b75993 ]
When qla2x00_mem_alloc() fails, qla2x00_probe_one() jumps to
probe_hw_failed and calls qla2x00_mem_free(). Several error labels in
qla2x00_mem_alloc() freed adapter members (elsrej.c, purex_dma_pool,
flt, sfp_data, loop_id_map, async_pd, sf_init_cb, ex_init_cb, npiv_info)
but left the pointers dangling. qla2x00_mem_free() then freed them a
second time. Worse, for the dma_pool members it issued
dma_pool_free(ha->s_dma_pool, ...) after s_dma_pool had already been
destroyed and set to NULL at fail_s_dma_pool, dereferencing a NULL pool.
Clear each freed pointer (and its DMA handle) in the error labels so the
subsequent qla2x00_mem_free() skips them.
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-13-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adjusted cleanup context for the missing fail_flt_data block. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_os.c | 15 +++++++++++++++
1 file changed, 15 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -4484,25 +4484,40 @@ qla2x00_mem_alloc(struct qla_hw_data *ha
fail_lsrjt:
dma_free_coherent(&ha->pdev->dev, ha->elsrej.size,
ha->elsrej.c, ha->elsrej.cdma);
+ ha->elsrej.c = NULL;
+ ha->elsrej.cdma = 0;
fail_elsrej:
dma_pool_destroy(ha->purex_dma_pool);
+ ha->purex_dma_pool = NULL;
fail_flt:
dma_free_coherent(&ha->pdev->dev, sizeof(struct qla_flt_header) + FLT_REGIONS_SIZE,
ha->flt, ha->flt_dma);
+ ha->flt = NULL;
+ ha->flt_dma = 0;
fail_flt_buffer:
dma_free_coherent(&ha->pdev->dev, SFP_DEV_SIZE,
ha->sfp_data, ha->sfp_data_dma);
+ ha->sfp_data = NULL;
+ ha->sfp_data_dma = 0;
fail_sfp_data:
kfree(ha->loop_id_map);
+ ha->loop_id_map = NULL;
fail_loop_id_map:
dma_pool_free(ha->s_dma_pool, ha->async_pd, ha->async_pd_dma);
+ ha->async_pd = NULL;
+ ha->async_pd_dma = 0;
fail_async_pd:
dma_pool_free(ha->s_dma_pool, ha->sf_init_cb, ha->sf_init_cb_dma);
+ ha->sf_init_cb = NULL;
+ ha->sf_init_cb_dma = 0;
fail_sf_init_cb:
dma_pool_free(ha->s_dma_pool, ha->ex_init_cb, ha->ex_init_cb_dma);
+ ha->ex_init_cb = NULL;
+ ha->ex_init_cb_dma = 0;
fail_ex_init_cb:
kfree(ha->npiv_info);
+ ha->npiv_info = NULL;
fail_npiv_info:
dma_free_coherent(&ha->pdev->dev, ((*rsp)->length + 1) *
sizeof(response_t), (*rsp)->ring, (*rsp)->dma);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 719/733] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (717 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 718/733] scsi: qla2xxx: Null out freed pointers in qla2x00_mem_alloc() error path Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 720/733] scsi: qla2xxx: Skip vport under deletion in report ID acquisition Greg Kroah-Hartman
` (25 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Nilesh Javali, Hannes Reinecke,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 52fba32317ee631faa878725b2f7cd5c08acacd3 ]
qla2x00_get_data_rate() skips updating ha->link_data_rate when the
firmware returns mcp->mb[1] == 0x7. That value was a legacy sentinel
from before 64G hardware existed, but PORT_SPEED_64GB is now defined as
0x07 and ha->link_data_rate is decoded with the PORT_SPEED_* encoding.
On a 64G-capable adapter a genuine 64G link is therefore dropped, and
the port speed is misreported (port_speed sysfs, fc_host speed, FDMI).
Only 28xx and 29xx support 64G, so accept 0x07 on those adapters while
keeping the legacy filter for older ones. Also drop the duplicate copy
of the check at the end of the success branch; it repeated the first
assignment with no intervening change.
Fixes: ecc89f25e225 ("scsi: qla2xxx: Add Device ID for ISP28XX")
Cc: stable@vger.kernel.org
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Reviewed-by: Hannes Reinecke <hare@kernel.org>
Link: https://patch.msgid.link/20260723050413.3897522-46-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Omitted IS_QLA29XX() checks because this branch lacks 29xx adapter support. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_mbx.c | 4 +---
1 file changed, 1 insertion(+), 3 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -5715,7 +5715,7 @@ qla2x00_get_data_rate(scsi_qla_host_t *v
ql_dbg(ql_dbg_mbx, vha, 0x1107,
"Failed=%x mb[0]=%x.\n", rval, mcp->mb[0]);
} else {
- if (mcp->mb[1] != 0x7)
+ if (mcp->mb[1] != 0x7 || IS_QLA28XX(ha))
ha->link_data_rate = mcp->mb[1];
if (IS_QLA83XX(ha) || IS_QLA27XX(ha) || IS_QLA28XX(ha)) {
@@ -5726,8 +5726,6 @@ qla2x00_get_data_rate(scsi_qla_host_t *v
ql_dbg(ql_dbg_mbx + ql_dbg_verbose, vha, 0x1108,
"Done %s.\n", __func__);
- if (mcp->mb[1] != 0x7)
- ha->link_data_rate = mcp->mb[1];
}
return rval;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 720/733] scsi: qla2xxx: Skip vport under deletion in report ID acquisition
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (718 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 719/733] scsi: qla2xxx: Fix 64G link speed reporting in get_data_rate Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 721/733] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
` (24 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 23582731afa35031c94fadb71a4f3b4afd094649 ]
qla24xx_report_id_acquisition() format-1 handling walks ha->vp_list under
vport_slock, takes a vref_count on the matching vport and calls
qla_update_host_map() to register its port id.
A vport teardown via qla24xx_vport_delete() sets VPORT_DELETE, then
qla24xx_disable_vp() removes the vport from the host_map btree and zeroes
vha->d_id (RESET_AL_PA). The vport is only unlinked from vp_list later,
in qla24xx_deallocate_vp_id(), which clears vp_map[idx] (RESET_VP_IDX)
but does not touch host_map. In the window in between, report ID
acquisition can still find the vport on vp_list and call
qla_update_host_map(); with d_id already zeroed it takes the
btree_insert32() path and re-inserts the dying vport into host_map.
Nothing cleans that entry afterwards, so once scsi_host_put() frees the
vha a later host_map lookup dereferences freed memory.
Skip a vport that has VPORT_DELETE set before taking the reference, so it
is neither re-registered nor scheduled for DPC re-registration. This
mirrors the existing guard in qla2x00_alert_all_vps().
Fixes: 41dc529a4602 ("qla2xxx: Improve RSCN handling in driver")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-22-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ Adjusted context to use rptid_entry->vp_idx instead of the missing local vp_idx variable. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_mbx.c | 2 ++
1 file changed, 2 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_mbx.c
+++ b/drivers/scsi/qla2xxx/qla_mbx.c
@@ -4204,6 +4204,8 @@ qla24xx_report_id_acquisition(scsi_qla_h
spin_lock_irqsave(&ha->vport_slock, flags);
list_for_each_entry(vp, &ha->vp_list, list) {
if (rptid_entry->vp_idx == vp->vp_idx) {
+ if (test_bit(VPORT_DELETE, &vp->dpc_flags))
+ break;
found = 1;
atomic_inc(&vp->vref_count);
break;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 721/733] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (719 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 720/733] scsi: qla2xxx: Skip vport under deletion in report ID acquisition Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 722/733] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity Greg Kroah-Hartman
` (23 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit d7e3fa7d06bf7fcaac186d3c4d635caac166d36c ]
qla27xx_copy_multiple_pkt() and qla27xx_copy_fpin_pkt() poll
rsp_q->ring_ptr->signature for RESPONSE_PROCESSED (0xDEADDEAD) to decide
whether the next continuation IOCB has arrived, spinning on cpu_relax()
without advancing the ring or decrementing the entry count while it has
not. response_t::signature lives at byte offset 60, but a continuation
IOCB (sts_cont_entry_t / struct sts_cont_entry_ext) carries raw FC frame
payload at that offset (data[56..59]). A received frame whose payload
bytes happen to equal 0xDEADDEAD is therefore misread as "not yet
arrived", and the loop spins forever in interrupt/DPC context, causing a
CPU soft lockup.
The poll is also unnecessary: callers of qla27xx_copy_multiple_pkt()
(PT_LS4_UNSOL and the NVMe purls path) already gate on
qla_chk_cont_iocb_avail(), which guarantees all entry_count IOCBs are
present before copying begins. The sibling helper
__qla_copy_purex_to_buffer() already drops the signature poll and relies
on the entry_type == STATUS_CONT_TYPE guard instead.
Remove the signature busy-wait from both helpers, keeping the entry_type
guard, and gate the FPIN path with qla_chk_cont_iocb_avail() so it defers
and re-processes on the next interrupt once all continuation IOCBs have
arrived, mirroring the ELS_AUTH_ELS and PT_LS4_UNSOL arms. With this the
signature field is never read on a continuation IOCB, eliminating the
payload-aliasing lockup.
Fixes: 9f2475fe7406 ("scsi: qla2xxx: SAN congestion management implementation")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-15-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ replaced unavailable qla_rsp_ring_rewind_to() with direct ring pointer and index assignments ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_isr.c | 33 ++++++++++++++++-----------------
1 file changed, 16 insertions(+), 17 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_isr.c
+++ b/drivers/scsi/qla2xxx/qla_isr.c
@@ -921,14 +921,6 @@ qla27xx_copy_multiple_pkt(struct scsi_ql
do {
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
- if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
- ql_dbg(ql_dbg_async, vha, 0x5084,
- "Ran out of IOCBs, partial data 0x%x\n",
- buffer_copy_offset);
- cpu_relax();
- continue;
- }
-
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
@@ -1205,14 +1197,6 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_ho
do {
while ((total_bytes > 0) && (entry_count_remaining > 0)) {
- if (rsp_q->ring_ptr->signature == RESPONSE_PROCESSED) {
- ql_dbg(ql_dbg_async, vha, 0x5084,
- "Ran out of IOCBs, partial data 0x%x\n",
- buffer_copy_offset);
- cpu_relax();
- continue;
- }
-
new_pkt = (sts_cont_entry_t *)rsp_q->ring_ptr;
*pkt = new_pkt;
@@ -4142,9 +4126,24 @@ process_err:
"SCM not active for this port\n");
break;
}
+ if (qla_chk_cont_iocb_avail(vha, rsp,
+ (response_t *)pkt, rsp_in)) {
+ /*
+ * ring_ptr and ring_index were
+ * pre-incremented above. Reset them
+ * back to current. Wait for next
+ * interrupt with all IOCBs to arrive
+ * and re-process.
+ */
+ rsp->ring_ptr = (response_t *)pkt;
+ rsp->ring_index = cur_ring_index;
+
+ ql_dbg(ql_dbg_init, vha, 0x5095,
+ "Defer processing FPIN...\n");
+ return;
+ }
pure_item = qla27xx_copy_fpin_pkt(vha,
(void **)&pkt, &rsp);
- __update_rsp_in(is_shadow_hba, rsp, rsp_in);
if (!pure_item)
break;
qla24xx_queue_purex_item(vha, pure_item,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 722/733] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (720 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 721/733] scsi: qla2xxx: Fix soft lockup polling continuation IOCB signature Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 723/733] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
` (22 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 2ac6a829843cf3df522d19e091276109b94c4c7a ]
ha->max_npiv_vports is taken from firmware (mcp->mb[11]) and only
constrained so that (max_npiv_vports + 1) is a multiple of
MIN_MULTI_ID_FABRIC, which permits values of 63, 127, 191 and 255.
NPIV vports are then allocated up to that count.
VP enable uses the VP_CONFIG IOCB, which addresses a vport through a
plain vp_index byte, so a vp_index beyond 128 is enabled without issue.
VP disable, however, uses the VP_CTRL IOCB, which selects target vports
through the fixed 128-bit vp_idx_map bitmap. qla24xx_control_vp()
rejects a vp_index past that bitmap and the IOCB builder cannot set a bit
beyond 127, yet qla24xx_vport_delete() frees the local state regardless.
A vport with vp_index > 128 can therefore be created and enabled but
never disabled, leaving it permanently active in firmware: a resource
leak.
Cap ha->max_npiv_vports at init to the vp_idx_map capacity so such
vports are never created. This collapses 191/255 to 127 (still
modulo-valid) and leaves the real-world 63/127 cases unaffected.
Fixes: 4d0ea24769c8 ("[SCSI] qla2xxx: Retrieve max-NPIV support capabilities from FW.")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-20-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ adapted the qla24xx_control_vp() hunk to include the prerequisite bounds-check block missing from this branch. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_fw.h | 4 ++++
drivers/scsi/qla2xxx/qla_init.c | 13 +++++++++++++
drivers/scsi/qla2xxx/qla_mid.c | 8 ++++++++
3 files changed, 25 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_fw.h
+++ b/drivers/scsi/qla2xxx/qla_fw.h
@@ -1442,6 +1442,10 @@ struct vp_ctrl_entry_24xx {
uint8_t reserved_5[24];
};
+/* vp_idx_map is a 128-bit (16-byte) bitmap selecting target VPs. */
+#define VP_CTRL_IDX_MAP_BITS \
+ (sizeof_field(struct vp_ctrl_entry_24xx, vp_idx_map) * 8)
+
/*
* Modify Virtual Port Configuration IOCB
*/
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -4421,6 +4421,19 @@ enable_82xx_npiv:
MIN_MULTI_ID_FABRIC))
ha->max_npiv_vports =
MIN_MULTI_ID_FABRIC - 1;
+
+ /*
+ * The VP_CTRL IOCB selects target VPs
+ * through the fixed vp_idx_map bitmap,
+ * so a vp_index beyond it can be enabled
+ * via VP_CONFIG but never disabled via
+ * VP_CTRL, leaking the VP. Cap the count
+ * to the bitmap capacity.
+ */
+ if (ha->max_npiv_vports >=
+ VP_CTRL_IDX_MAP_BITS)
+ ha->max_npiv_vports =
+ VP_CTRL_IDX_MAP_BITS - 1;
}
qlt_config_nvram_with_fw_version(vha);
qla2x00_get_resource_cnts(vha);
--- a/drivers/scsi/qla2xxx/qla_mid.c
+++ b/drivers/scsi/qla2xxx/qla_mid.c
@@ -970,6 +970,14 @@ int qla24xx_control_vp(scsi_qla_host_t *
if (vp_index > sizeof_field(struct vp_ctrl_entry_24xx, vp_idx_map) * 8)
return QLA_PARAMETER_ERROR;
+ /*
+ * The VP_CTRL IOCB selects the target VP through a fixed 128-bit
+ * (16-byte) vp_idx_map bitmap, so vp_index must fit within it even
+ * if firmware advertises more NPIV vports.
+ */
+ if (vp_index > VP_CTRL_IDX_MAP_BITS)
+ return QLA_PARAMETER_ERROR;
+
/* ref: INIT */
sp = qla2x00_get_sp(base_vha, NULL, GFP_KERNEL);
if (!sp)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 723/733] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[]
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (721 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 722/733] scsi: qla2xxx: Clamp max_npiv_vports to VP_CTRL bitmap capacity Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 724/733] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error Greg Kroah-Hartman
` (21 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 4cf38dd9465736141263ebb63375868311a0ec81 ]
The FC BSG transport allocates job->request via memdup_user() using the
exact user-supplied request_len. For FC_BSG_HST_VENDOR,
fc_bsg_host_dispatch() only guarantees request_len covers msgcode and
vendor_id; it does not account for the vendor_cmd[] flexible array.
qla2xxx then reads the command selector vendor_cmd[0] and, in several
sub-handlers, vendor_cmd[1]/[2] or structures overlaid on the vendor
command area without verifying request_len. A caller holding
CAP_SYS_RAWIO can submit a short request whose vendor_id matches the
host, triggering out-of-bounds heap reads (KASAN-detectable, and able to
mis-select a command or panic).
Add a central guard in qla2x00_process_vendor_specific() so the selector
is always in bounds, restrict the early vendor_cmd[0] read in
qla24xx_bsg_request() to sufficiently long vendor messages, and add
request_len checks to the sub-handlers that read further:
qla24xx_proc_fcp_prio_cfg_cmd(), qla2x00_process_loopback(),
qla84xx_reset(), qla84xx_updatefw(), qla2x00_read_optrom(),
qla2x00_update_optrom(), qlafx00_mgmt_cmd() and
qla28xx_validate_flash_image().
Fixes: 01e0e15c8b3b ("scsi: don't use fc_bsg_job::request and fc_bsg_job::reply directly")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-31-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
[ omitted OPTROM start declaration and assignment changes because qla2x00_optrom_setup() still reads vendor_cmd[1] internally. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_bsg.c | 49 +++++++++++++++++++++++++++++++++++++++--
1 file changed, 47 insertions(+), 2 deletions(-)
--- a/drivers/scsi/qla2xxx/qla_bsg.c
+++ b/drivers/scsi/qla2xxx/qla_bsg.c
@@ -160,6 +160,12 @@ qla24xx_proc_fcp_prio_cfg_cmd(struct bsg
goto exit_fcp_prio_cfg;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t)) {
+ ret = -EINVAL;
+ goto exit_fcp_prio_cfg;
+ }
+
/* Get the sub command */
oper = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
@@ -758,6 +764,10 @@ qla2x00_process_loopback(struct bsg_job
return -EIO;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 3 * sizeof(uint32_t))
+ return -EINVAL;
+
memset(&elreq, 0, sizeof(elreq));
elreq.req_sg_cnt = dma_map_sg(&ha->pdev->dev,
@@ -990,6 +1000,10 @@ qla84xx_reset(struct bsg_job *bsg_job)
return -EINVAL;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
flag = bsg_request->rqst_data.h_vendor.vendor_cmd[1];
rval = qla84xx_reset_chip(vha, flag == A84_ISSUE_RESET_DIAG_FW);
@@ -1034,6 +1048,10 @@ qla84xx_updatefw(struct bsg_job *bsg_job
return -EINVAL;
}
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
sg_cnt = dma_map_sg(&ha->pdev->dev, bsg_job->request_payload.sg_list,
bsg_job->request_payload.sg_cnt, DMA_TO_DEVICE);
if (!sg_cnt) {
@@ -1484,6 +1502,10 @@ qla2x00_read_optrom(struct bsg_job *bsg_
struct qla_hw_data *ha = vha->hw;
int rval = 0;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
if (ha->flags.nic_core_reset_hdlr_active)
return -EBUSY;
@@ -1521,6 +1543,10 @@ qla2x00_update_optrom(struct bsg_job *bs
struct qla_hw_data *ha = vha->hw;
int rval = 0;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
mutex_lock(&ha->optrom_mutex);
rval = qla2x00_optrom_setup(bsg_job, vha, 1);
if (rval) {
@@ -2012,6 +2038,11 @@ qlafx00_mgmt_cmd(struct bsg_job *bsg_job
struct fc_port *fcport;
char *type = "FC_BSG_HST_FX_MGMT";
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + sizeof(uint32_t) +
+ sizeof(struct qla_mt_iocb_rqst_fx00))
+ return -EINVAL;
+
/* Copy the IOCB specific information */
piocb_rqst = (struct qla_mt_iocb_rqst_fx00 *)
&bsg_request->rqst_data.h_vendor.vendor_cmd[1];
@@ -2925,6 +2956,13 @@ qla2x00_process_vendor_specific(struct s
{
struct fc_bsg_request *bsg_request = bsg_job->request;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + sizeof(uint32_t)) {
+ ql_log(ql_log_warn, vha, 0x7000,
+ "BSG request too small for vendor cmd.\n");
+ return -EINVAL;
+ }
+
ql_dbg(ql_dbg_edif, vha, 0x911b, "%s FC_BSG_HST_VENDOR cmd[0]=0x%x\n",
__func__, bsg_request->rqst_data.h_vendor.vendor_cmd[0]);
@@ -3056,8 +3094,11 @@ qla24xx_bsg_request(struct bsg_job *bsg_
}
/* Disable port will bring down the chip, allow enable command */
- if (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
- bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS)
+ if (bsg_request->msgcode == FC_BSG_HST_VENDOR &&
+ bsg_job->request_len >=
+ sizeof(struct fc_bsg_request) + sizeof(uint32_t) &&
+ (bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_MANAGE_HOST_PORT ||
+ bsg_request->rqst_data.h_vendor.vendor_cmd[0] == QL_VND_GET_HOST_STATS))
goto skip_chip_chk;
if (vha->hw->flags.port_isolated) {
@@ -3366,6 +3407,10 @@ static int qla28xx_validate_flash_image(
if (!IS_QLA28XX(ha) || vha->vp_idx != 0)
return -EPERM;
+ if (bsg_job->request_len <
+ sizeof(struct fc_bsg_request) + 2 * sizeof(uint32_t))
+ return -EINVAL;
+
mutex_lock(&ha->optrom_mutex);
rval = qla28xx_do_validate_flash_image(bsg_job, &state);
if (rval)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 724/733] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (722 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 723/733] scsi: qla2xxx: Validate BSG request_len before reading vendor_cmd[] Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 725/733] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock Greg Kroah-Hartman
` (20 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit e46160a5d4fa59bf4d5f3412b6b5cb79edb967dd ]
qla_nvme_xmt_ls_rsp() obtains uctx, which was linked into
fcport->unsol_ctx_head by qla2xxx_process_purls_iocb() and is still linked
when the NVMe transport calls back to transmit the LS response. On the
error (out:) path the function frees uctx with kfree() but never removes
it from the list. This leaves a freed node in fcport->unsol_ctx_head: the
next list_add_tail() for that fcport writes through the freed node, and a
subsequent list_del() can corrupt the list or panic.
Unlink uctx with list_del() before kfree() on the error path, matching the
other free sites in qla_nvme_release_lsrsp_cmd_kref() and
qla2xxx_process_purls_pkt(). qla2x00_rel_sp() in the failure path only
returns the SRB to its pool and does not invoke sp->put_fn, so the out:
path is the sole free and uctx is always still linked there.
Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-27-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Stable-dep-of: 76da0c43c63e ("scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_nvme.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -446,6 +446,7 @@ out:
qla_nvme_ls_reject_iocb(vha, ha->base_qpair, &a, true);
spin_unlock_irqrestore(ha->base_qpair->qp_lock_ptr, flags);
}
+ list_del(&uctx->elem);
kfree(uctx);
return rval;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 725/733] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (723 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 724/733] scsi: qla2xxx: Unlink NVMe unsol ctx before freeing on LS reject error Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 726/733] drm/amd/display: Propagate HDMI RGB quantization selectability Greg Kroah-Hartman
` (19 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Sashiko, Nilesh Javali,
Martin K. Petersen (Oracle), Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilesh Javali <njavali@marvell.com>
[ Upstream commit 76da0c43c63eb0496649e372ac64466364d0fe7d ]
The fcport->unsol_ctx_head list is modified from several contexts without
a common lock. Entries are added in qla2xxx_process_purls_iocb() from the
response queue ISR (under the qpair qp_lock), while they are removed from
qla2xxx_process_purls_pkt() (DPC/purex worker), qla_nvme_xmt_ls_rsp()
(NVMe-FC transport callback) and qla_nvme_release_lsrsp_cmd_kref() (SRB
completion). The qpair qp_lock cannot serialize this per-fcport list since
multiqueue adapters add entries through different qpairs, so a concurrent
add and delete (or two concurrent deletes) can corrupt the list pointers.
Introduce a dedicated per-fcport spinlock, unsol_ctx_lock, initialized in
qla2x00_alloc_fcport(), and take it around every list_add_tail()/list_del()
on unsol_ctx_head. The add nests under the existing qp_lock; no delete path
takes qp_lock, so the lock order is consistent and deadlock free.
Fixes: 875386b98857 ("scsi: qla2xxx: Add Unsolicited LS Request and Response Support for NVMe")
Cc: stable@vger.kernel.org
Reported-by: Sashiko <sashiko-dev@google.com>
Signed-off-by: Nilesh Javali <njavali@marvell.com>
Link: https://patch.msgid.link/20260730155838.2119230-28-njavali@marvell.com
Signed-off-by: Martin K. Petersen (Oracle) <mkp@kernel.org>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/scsi/qla2xxx/qla_def.h | 2 ++
drivers/scsi/qla2xxx/qla_init.c | 1 +
drivers/scsi/qla2xxx/qla_nvme.c | 9 +++++++++
3 files changed, 12 insertions(+)
--- a/drivers/scsi/qla2xxx/qla_def.h
+++ b/drivers/scsi/qla2xxx/qla_def.h
@@ -2591,6 +2591,8 @@ typedef struct fc_port {
struct list_head list;
struct scsi_qla_host *vha;
struct list_head unsol_ctx_head;
+ /* Serializes unsol_ctx_head against ISR, DPC and NVMe transport. */
+ spinlock_t unsol_ctx_lock;
unsigned int conf_compl_supported:1;
unsigned int deleted:2;
--- a/drivers/scsi/qla2xxx/qla_init.c
+++ b/drivers/scsi/qla2xxx/qla_init.c
@@ -5663,6 +5663,7 @@ qla2x00_alloc_fcport(scsi_qla_host_t *vh
INIT_LIST_HEAD(&fcport->gnl_entry);
INIT_LIST_HEAD(&fcport->list);
INIT_LIST_HEAD(&fcport->unsol_ctx_head);
+ spin_lock_init(&fcport->unsol_ctx_lock);
INIT_LIST_HEAD(&fcport->sess_cmd_list);
spin_lock_init(&fcport->sess_cmd_lock);
--- a/drivers/scsi/qla2xxx/qla_nvme.c
+++ b/drivers/scsi/qla2xxx/qla_nvme.c
@@ -257,7 +257,9 @@ static void qla_nvme_release_lsrsp_cmd_k
fd_rsp = uctx->fd_rsp;
+ spin_lock_irqsave(&uctx->fcport->unsol_ctx_lock, flags);
list_del(&uctx->elem);
+ spin_unlock_irqrestore(&uctx->fcport->unsol_ctx_lock, flags);
fd_rsp->done(fd_rsp);
kfree(uctx);
@@ -446,7 +448,9 @@ out:
qla_nvme_ls_reject_iocb(vha, ha->base_qpair, &a, true);
spin_unlock_irqrestore(ha->base_qpair->qp_lock_ptr, flags);
}
+ spin_lock_irqsave(&uctx->fcport->unsol_ctx_lock, flags);
list_del(&uctx->elem);
+ spin_unlock_irqrestore(&uctx->fcport->unsol_ctx_lock, flags);
kfree(uctx);
return rval;
}
@@ -1216,7 +1220,9 @@ qla2xxx_process_purls_pkt(struct scsi_ql
spin_unlock_irqrestore(vha->hw->base_qpair->qp_lock_ptr,
flags);
}
+ spin_lock_irqsave(&uctx->fcport->unsol_ctx_lock, flags);
list_del(&uctx->elem);
+ spin_unlock_irqrestore(&uctx->fcport->unsol_ctx_lock, flags);
kfree(uctx);
}
}
@@ -1258,6 +1264,7 @@ void qla2xxx_process_purls_iocb(void **p
struct purex_item *item;
port_id_t d_id = {0};
port_id_t id = {0};
+ unsigned long flags;
u8 *opcode;
bool xmt_reject = false;
@@ -1323,7 +1330,9 @@ void qla2xxx_process_purls_iocb(void **p
uctx->ox_id = p->ox_id;
qla_rport->uctx = uctx;
INIT_LIST_HEAD(&uctx->elem);
+ spin_lock_irqsave(&fcport->unsol_ctx_lock, flags);
list_add_tail(&uctx->elem, &fcport->unsol_ctx_head);
+ spin_unlock_irqrestore(&fcport->unsol_ctx_lock, flags);
item->purls_context = (void *)uctx;
ql_dbg(ql_dbg_unsol, vha, 0x2121,
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 726/733] drm/amd/display: Propagate HDMI RGB quantization selectability
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (724 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 725/733] scsi: qla2xxx: Serialize NVMe unsol ctx list with a per-fcport lock Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 727/733] drm/amd/display: Honor Broadcast RGB for BT.2020 RGB output Greg Kroah-Hartman
` (18 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Satyajit Roy, Alex Hung,
Daniel Wheeler, Alex Deucher, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satyajit Roy <sroy14@alum.utk.edu>
[ Upstream commit bdcd0411d7d186225a52458fd42bb70d54ca917a ]
DC uses dc_edid_caps.qs_bit when constructing the HDMI AVI InfoFrame
quantization-range field. Although DRM parses the sink capability into
drm_display_info, DM never copies it into the DC EDID capabilities. The
field therefore remains zero and the AVI quantization range stays at its
default value.
Copy rgb_quant_range_selectable for HDMI sinks and extend the existing
EDID-capability KUnit test to cover it.
Fixes: 6eb4c13a3845 ("drm/amd/display: Support "Broadcast RGB" drm property")
Signed-off-by: Satyajit Roy <sroy14@alum.utk.edu>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 892659399f64642e33072562a11ec1b2e7bd2263)
Cc: stable@vger.kernel.org
[ Omitted KUnit test additions because amdgpu_dm_helpers_test.c and its supporting infrastructure are absent. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c | 1 +
1 file changed, 1 insertion(+)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm_helpers.c
@@ -197,6 +197,7 @@ enum dc_edid_status dm_helpers_parse_edi
edid_caps->edid_hdmi = connector->display_info.is_hdmi;
if (edid_caps->edid_hdmi) {
+ edid_caps->qs_bit = connector->display_info.rgb_quant_range_selectable;
populate_hdmi_info_from_connector(link->dc->config.enable_frl, &connector->display_info.hdmi, edid_caps);
drm_dbg_driver(connector->dev, "%s: HDMI_FRL [%s] max_frl_rate %d\n", __func__, connector->name, edid_caps->max_frl_rate);
if (edid_caps->frl_dsc_support)
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 727/733] drm/amd/display: Honor Broadcast RGB for BT.2020 RGB output
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (725 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 726/733] drm/amd/display: Propagate HDMI RGB quantization selectability Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 728/733] s390/pai: Use PAI PMU index as parameter replacing event Greg Kroah-Hartman
` (17 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Satyajit Roy, Alex Hung,
Daniel Wheeler, Alex Deucher, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Satyajit Roy <sroy14@alum.utk.edu>
[ Upstream commit 7fca7acd60a228b62b4e9efa5f184738041e9564 ]
amdgpu_dm_get_output_color_space() applies the Broadcast RGB connector
property to default RGB output, but always selects full-range output for
BT.2020 RGB. Consequently, explicitly selecting Limited has no effect on
the output CSC or AVI InfoFrame when HDR uses BT.2020 RGB.
Select COLOR_SPACE_2020_RGB_LIMITEDRANGE when the output encoding is RGB
and Broadcast RGB is Limited. Keep Automatic and Full at full range, and
leave YCbCr output unchanged.
Add KUnit coverage for limited-range RGB output through both BT.2020
connector colorspace values.
Fixes: 6eb4c13a3845 ("drm/amd/display: Support "Broadcast RGB" drm property")
Signed-off-by: Satyajit Roy <sroy14@alum.utk.edu>
Reviewed-by: Alex Hung <alex.hung@amd.com>
Tested-by: Daniel Wheeler <daniel.wheeler@amd.com>
Signed-off-by: Alex Deucher <alexander.deucher@amd.com>
(cherry picked from commit 022236eaa63bbf65761aa8aec43f661451a94654)
Cc: stable@vger.kernel.org
[ adapted the hunk to the older get_output_color_space() function in amdgpu_dm.c. ]
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c | 10 +++++++---
1 file changed, 7 insertions(+), 3 deletions(-)
--- a/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
+++ b/drivers/gpu/drm/amd/display/amdgpu_dm/amdgpu_dm.c
@@ -6895,10 +6895,14 @@ get_output_color_space(const struct dc_c
break;
case DRM_MODE_COLORIMETRY_BT2020_RGB:
case DRM_MODE_COLORIMETRY_BT2020_YCC:
- if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB)
- color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
- else
+ if (dc_crtc_timing->pixel_encoding == PIXEL_ENCODING_RGB) {
+ if (connector_state->hdmi.broadcast_rgb == DRM_HDMI_BROADCAST_RGB_LIMITED)
+ color_space = COLOR_SPACE_2020_RGB_LIMITEDRANGE;
+ else
+ color_space = COLOR_SPACE_2020_RGB_FULLRANGE;
+ } else {
color_space = COLOR_SPACE_2020_YCBCR_LIMITED;
+ }
break;
case DRM_MODE_COLORIMETRY_DEFAULT: // ITU601
default:
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 728/733] s390/pai: Use PAI PMU index as parameter replacing event
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (726 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 727/733] drm/amd/display: Honor Broadcast RGB for BT.2020 RGB output Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 729/733] s390/pai: Move locking to event init and delete Greg Kroah-Hartman
` (16 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Richter, Sumanth Korikkar,
Heiko Carstens, Vasily Gorbik, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <tmricht@linux.ibm.com>
[ Upstream commit 4eef4ab3aa3a32725e5bc79032c722f9f4a90172 ]
Use PAI PMU index value as function argument instead of pointer
to struct perf_event. Only that index value is used inside
functions pai_alloc_cpu() and pai_event_destroy_cpu().
No functional change.
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Stable-dep-of: 9ecc4d033879 ("s390/pai: Support CPU hotplug for PMU PAI")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/kernel/perf_pai.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
--- a/arch/s390/kernel/perf_pai.c
+++ b/arch/s390/kernel/perf_pai.c
@@ -140,16 +140,14 @@ static void pai_free(struct pai_mapptr *
/* Adjust usage counters and remove allocated memory when all users are
* gone.
*/
-static void pai_event_destroy_cpu(struct perf_event *event, int cpu)
+static void pai_event_destroy_cpu(int idx, int cpu)
{
- int idx = PAI_PMU_IDX(event);
struct pai_mapptr *mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
struct pai_map *cpump = mp->mapptr;
mutex_lock(&pai_reserve_mutex);
- debug_sprintf_event(paidbg, 5, "%s event %#llx idx %d cpu %d users %d "
- "refcnt %u\n", __func__, event->attr.config, idx,
- event->cpu, cpump->active_events,
+ debug_sprintf_event(paidbg, 5, "%s users %d refcnt %u\n",
+ __func__, cpump->active_events,
refcount_read(&cpump->refcnt));
if (refcount_dec_and_test(&cpump->refcnt))
pai_free(mp);
@@ -159,17 +157,17 @@ static void pai_event_destroy_cpu(struct
static void pai_event_destroy(struct perf_event *event)
{
- int cpu;
+ int cpu = 0, idx = PAI_PMU_IDX(event);
free_page(PAI_SAVE_AREA(event));
if (event->cpu == -1) {
struct cpumask *mask = PAI_CPU_MASK(event);
for_each_cpu(cpu, mask)
- pai_event_destroy_cpu(event, cpu);
+ pai_event_destroy_cpu(idx, cpu);
kfree(mask);
} else {
- pai_event_destroy_cpu(event, event->cpu);
+ pai_event_destroy_cpu(idx, event->cpu);
}
}
@@ -241,12 +239,12 @@ static u64 paicrypt_getall(struct perf_e
*
* Allocate the memory for the event.
*/
-static int pai_alloc_cpu(struct perf_event *event, int cpu)
+static int pai_alloc_cpu(int idx, int cpu)
{
- int rc, idx = PAI_PMU_IDX(event);
struct pai_map *cpump = NULL;
bool need_paiext_cb = false;
struct pai_mapptr *mp;
+ int rc;
mutex_lock(&pai_reserve_mutex);
/* Allocate root node */
@@ -318,6 +316,7 @@ unlock:
static int pai_alloc(struct perf_event *event)
{
+ int idx = PAI_PMU_IDX(event);
struct cpumask *maskptr;
int cpu, rc = -ENOMEM;
@@ -326,10 +325,10 @@ static int pai_alloc(struct perf_event *
goto out;
for_each_online_cpu(cpu) {
- rc = pai_alloc_cpu(event, cpu);
+ rc = pai_alloc_cpu(idx, cpu);
if (rc) {
for_each_cpu(cpu, maskptr)
- pai_event_destroy_cpu(event, cpu);
+ pai_event_destroy_cpu(idx, cpu);
kfree(maskptr);
goto out;
}
@@ -392,7 +391,7 @@ static int pai_event_init(struct perf_ev
}
if (event->cpu >= 0)
- rc = pai_alloc_cpu(event, event->cpu);
+ rc = pai_alloc_cpu(idx, event->cpu);
else
rc = pai_alloc(event);
if (rc) {
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 729/733] s390/pai: Move locking to event init and delete
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (727 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 728/733] s390/pai: Use PAI PMU index as parameter replacing event Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 730/733] s390/pai: Support CPU hotplug for PMU PAI Greg Kroah-Hartman
` (15 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Richter, Sumanth Korikkar,
Heiko Carstens, Vasily Gorbik, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <tmricht@linux.ibm.com>
[ Upstream commit e8df39dacb7d98d2b2aea431ca652d9fadf5efa3 ]
Move mutex locking from per CPU allocation to event allocation.
No functional change.
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Sumanth Korikkar <sumanthk@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Stable-dep-of: 9ecc4d033879 ("s390/pai: Support CPU hotplug for PMU PAI")
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/kernel/perf_pai.c | 25 ++++++++++++-------------
1 file changed, 12 insertions(+), 13 deletions(-)
--- a/arch/s390/kernel/perf_pai.c
+++ b/arch/s390/kernel/perf_pai.c
@@ -138,21 +138,19 @@ static void pai_free(struct pai_mapptr *
}
/* Adjust usage counters and remove allocated memory when all users are
- * gone.
+ * gone. Called under mutex_lock.
*/
static void pai_event_destroy_cpu(int idx, int cpu)
{
struct pai_mapptr *mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
struct pai_map *cpump = mp->mapptr;
- mutex_lock(&pai_reserve_mutex);
debug_sprintf_event(paidbg, 5, "%s users %d refcnt %u\n",
__func__, cpump->active_events,
refcount_read(&cpump->refcnt));
if (refcount_dec_and_test(&cpump->refcnt))
pai_free(mp);
pai_root_free(idx);
- mutex_unlock(&pai_reserve_mutex);
}
static void pai_event_destroy(struct perf_event *event)
@@ -160,6 +158,7 @@ static void pai_event_destroy(struct per
int cpu = 0, idx = PAI_PMU_IDX(event);
free_page(PAI_SAVE_AREA(event));
+ mutex_lock(&pai_reserve_mutex);
if (event->cpu == -1) {
struct cpumask *mask = PAI_CPU_MASK(event);
@@ -169,6 +168,7 @@ static void pai_event_destroy(struct per
} else {
pai_event_destroy_cpu(idx, event->cpu);
}
+ mutex_unlock(&pai_reserve_mutex);
}
static void paicrypt_event_destroy(struct perf_event *event)
@@ -232,12 +232,10 @@ static u64 paicrypt_getall(struct perf_e
return sum;
}
-/* Check concurrent access of counting and sampling for crypto events.
- * This function is called in process context and it is save to block.
- * When the event initialization functions fails, no other call back will
- * be invoked.
- *
- * Allocate the memory for the event.
+/* Allocate all per-CPU data structures. This function is called in
+ * process context and can block. In case of error all partly allocated
+ * memory is released and the reference counters adjusted correctly.
+ * Called under mutex_lock.
*/
static int pai_alloc_cpu(int idx, int cpu)
{
@@ -246,11 +244,10 @@ static int pai_alloc_cpu(int idx, int cp
struct pai_mapptr *mp;
int rc;
- mutex_lock(&pai_reserve_mutex);
/* Allocate root node */
rc = pai_root_alloc(idx);
if (rc)
- goto unlock;
+ goto out;
/* Allocate node for this event */
mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
@@ -308,12 +305,12 @@ undo:
*/
pai_root_free(idx);
}
-unlock:
- mutex_unlock(&pai_reserve_mutex);
+out:
/* If rc is non-zero, no increment of counter/sampler was done. */
return rc;
}
+/* Called under mutex_lock */
static int pai_alloc(struct perf_event *event)
{
int idx = PAI_PMU_IDX(event);
@@ -390,10 +387,12 @@ static int pai_event_init(struct perf_ev
}
}
+ mutex_lock(&pai_reserve_mutex);
if (event->cpu >= 0)
rc = pai_alloc_cpu(idx, event->cpu);
else
rc = pai_alloc(event);
+ mutex_unlock(&pai_reserve_mutex);
if (rc) {
free_page(PAI_SAVE_AREA(event));
goto out;
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 730/733] s390/pai: Support CPU hotplug for PMU PAI
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (728 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 729/733] s390/pai: Move locking to event init and delete Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 731/733] x86/mm/pat: Allocate split page tables as kernel page tables Greg Kroah-Hartman
` (14 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Thomas Richter, Jan Polensky,
Heiko Carstens, Vasily Gorbik, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <tmricht@linux.ibm.com>
[ Upstream commit 9ecc4d033879f7761f2df07e20cd2fbec00fd90b ]
The command 'perf stat -e pai_crypto/CRYPTO_ALL/ -- <command>'
crashes the kernel when CPUs are hotplug added during that run.
Root cause is the missing allocation of per-CPU data structures
for that new CPU. The allocation is dynamic and the first
event that has task context creates such a structure for
each online CPU. This is not sufficient. CPUs may be offline
during event creation and can be set online during the
perf run time. For example commands
# echo 0 > /sys/devices/system/cpu/cpu1/online
# perf stat -e cycles -i -- stress-ng -t10s --matrix X
# sleep 1
# echo 1 > /sys/devices/system/cpu/cpu1/online
Currently without a CPU hotplug handler, that new CPU has no
per-CPU data infrastructure. The scheduler runs PMU call back
function pai_add() to install the PMU support for that CPU before
the task is being scheduled on that new CPU.
In pai_add() instructions
mp = this_cpu_ptr(pai_root[idx].mapptr);
cpump = mp->mapptr;
return a NULL pointer and the result is a kernel panic as variable
cpump is used inside that function.
Add CPU hotplug support for CPU add and delete and create
the necessary per-CPU data infrastructure during CPU hotplug
add processing. Same for CPU hotplug remove.
This is done when the CPU is offline to ensure the data structures
are available when CPU is made online and tasks are scheduled on it.
[hca@linux.ibm.com: fixup error path in pai_init()]
Cc: stable@vger.kernel.org # v6.19
Fixes: 582cc1b28e8c ("s390/pai_ext: Enable per-task and system-wide sampling event")
Fixes: 9f66572f2889 ("s390/pai_crypto: Enable per-task and system-wide sampling event")
Signed-off-by: Thomas Richter <tmricht@linux.ibm.com>
Reviewed-by: Jan Polensky <japo@linux.ibm.com>
Signed-off-by: Heiko Carstens <hca@linux.ibm.com>
Signed-off-by: Vasily Gorbik <gor@linux.ibm.com>
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/s390/include/asm/pai.h | 1
arch/s390/kernel/perf_pai.c | 178 +++++++++++++++++++++++++++++++-------------
2 files changed, 128 insertions(+), 51 deletions(-)
--- a/arch/s390/include/asm/pai.h
+++ b/arch/s390/include/asm/pai.h
@@ -76,7 +76,6 @@ static __always_inline void pai_kernel_e
}
#define PAI_SAVE_AREA(x) ((x)->hw.event_base)
-#define PAI_CPU_MASK(x) ((x)->hw.addr_filters)
#define PAI_PMU_IDX(x) ((x)->hw.last_tag)
#define PAI_SWLIST(x) (&(x)->hw.tp_list)
--- a/arch/s390/kernel/perf_pai.c
+++ b/arch/s390/kernel/perf_pai.c
@@ -67,6 +67,7 @@ struct pai_mapptr {
static struct pai_root { /* Anchor to per CPU data */
refcount_t refcnt; /* Overall active events */
+ atomic_t tskctx; /* Overall per-task events */
struct pai_mapptr __percpu *mapptr;
} pai_root[PAI_PMU_MAX];
@@ -93,14 +94,15 @@ struct pai_pmu { /* Define PAI PMU cha
static struct pai_pmu pai_pmu[]; /* Forward declaration */
/* Free per CPU data when the last event is removed. */
-static void pai_root_free(int idx)
+static void pai_root_free(int idx, int tasks)
{
- if (refcount_dec_and_test(&pai_root[idx].refcnt)) {
+ if (refcount_sub_and_test(tasks, &pai_root[idx].refcnt)) {
free_percpu(pai_root[idx].mapptr);
pai_root[idx].mapptr = NULL;
}
- debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d\n", __func__,
- idx, refcount_read(&pai_root[idx].refcnt));
+ debug_sprintf_event(paidbg, 5, "%s root[%d].refcount %d tskctx %d\n",
+ __func__, idx, refcount_read(&pai_root[idx].refcnt),
+ atomic_read(&pai_root[idx].tskctx));
}
/*
@@ -137,20 +139,36 @@ static void pai_free(struct pai_mapptr *
mp->mapptr = NULL;
}
-/* Adjust usage counters and remove allocated memory when all users are
- * gone. Called under mutex_lock.
- */
-static void pai_event_destroy_cpu(int idx, int cpu)
+/* Called under mutex_lock */
+static void pai_event_destroy_cpu(int idx, int cpu, bool hotplug)
{
- struct pai_mapptr *mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
- struct pai_map *cpump = mp->mapptr;
+ struct pai_mapptr *mp;
+ struct pai_map *cpump;
+ int tasks = 1;
- debug_sprintf_event(paidbg, 5, "%s users %d refcnt %u\n",
- __func__, cpump->active_events,
- refcount_read(&cpump->refcnt));
- if (refcount_dec_and_test(&cpump->refcnt))
+ /* Check reference count and return when all gone.
+ * 1. An event is installed on online CPU X.
+ * 2. CPU x is offlined and the per-CPU data is removed.
+ * 3. Event is destroyed via close system call.
+ */
+ if (!refcount_read(&pai_root[idx].refcnt))
+ return; /* No events at all */
+ mp = per_cpu_ptr(pai_root[idx].mapptr, cpu);
+ if (!mp || !mp->mapptr) /* No events on that CPU */
+ return;
+
+ /* When hotplug is true, invocation is from CPU hotplug callback.
+ * Delete per-CPU resource and adjust refcnt when per-task events
+ * are currently active. This can be more than one.
+ * In this case adjust counters.
+ */
+ if (hotplug)
+ tasks = atomic_read(&pai_root[idx].tskctx);
+
+ cpump = mp->mapptr;
+ if (refcount_sub_and_test(tasks, &cpump->refcnt))
pai_free(mp);
- pai_root_free(idx);
+ pai_root_free(idx, tasks);
}
static void pai_event_destroy(struct perf_event *event)
@@ -158,17 +176,17 @@ static void pai_event_destroy(struct per
int cpu = 0, idx = PAI_PMU_IDX(event);
free_page(PAI_SAVE_AREA(event));
+ cpus_read_lock();
mutex_lock(&pai_reserve_mutex);
if (event->cpu == -1) {
- struct cpumask *mask = PAI_CPU_MASK(event);
-
- for_each_cpu(cpu, mask)
- pai_event_destroy_cpu(idx, cpu);
- kfree(mask);
+ atomic_dec(&pai_root[idx].tskctx);
+ for_each_online_cpu(cpu)
+ pai_event_destroy_cpu(idx, cpu, false);
} else {
- pai_event_destroy_cpu(idx, event->cpu);
+ pai_event_destroy_cpu(idx, event->cpu, false);
}
mutex_unlock(&pai_reserve_mutex);
+ cpus_read_unlock();
}
static void paicrypt_event_destroy(struct perf_event *event)
@@ -232,17 +250,25 @@ static u64 paicrypt_getall(struct perf_e
return sum;
}
-/* Allocate all per-CPU data structures. This function is called in
- * process context and can block. In case of error all partly allocated
- * memory is released and the reference counters adjusted correctly.
- * Called under mutex_lock.
- */
-static int pai_alloc_cpu(int idx, int cpu)
+/* Called under mutex_lock */
+static int pai_alloc_cpu(int idx, int cpu, bool hotplug)
{
struct pai_map *cpump = NULL;
bool need_paiext_cb = false;
struct pai_mapptr *mp;
- int rc;
+ int tasks = 1, rc = 0;
+
+ /* When hotplug is true, invocation is from CPU hotplug callback.
+ * Allocate per-CPU resource when per-task events are currently active.
+ * This can be more than one. In this case adjust all reference
+ * counters. Otherwise return, this ensures memory is only allocated
+ * when needed.
+ */
+ if (hotplug) {
+ tasks = atomic_read(&pai_root[idx].tskctx);
+ if (!tasks)
+ goto out;
+ }
/* Allocate root node */
rc = pai_root_alloc(idx);
@@ -291,26 +317,42 @@ static int pai_alloc_cpu(int idx, int cp
goto undo;
}
INIT_LIST_HEAD(&cpump->syswide_list);
- refcount_set(&cpump->refcnt, 1);
+ refcount_set(&cpump->refcnt, tasks);
rc = 0;
} else {
- refcount_inc(&cpump->refcnt);
+ refcount_add(tasks, &cpump->refcnt);
}
+ /* If tasks is greater than 1, we are called from CPU hotplug path
+ * and need to adjust the pai_root[idx].refcnt by the number of
+ * per-process events. Function pai_root_alloc(idx) already
+ * incremented by one. Adjust for the rest.
+ */
+ if (tasks > 1)
+ refcount_add(tasks - 1, &pai_root[idx].refcnt);
undo:
if (rc) {
/* Error in allocation of event, decrement anchor. Since
* the event in not created, its destroy() function is never
* invoked. Adjust the reference counter for the anchor.
+ * The failure happened in the case of variable
+ * cpump == NULL branch above. The pai_root[XXX].refcnt has
+ * been incremented by one. Then the per-CPU allocation
+ * failed, so decrement it by one, regardless of tasks.
*/
- pai_root_free(idx);
+ pai_root_free(idx, 1);
}
out:
/* If rc is non-zero, no increment of counter/sampler was done. */
return rc;
}
-/* Called under mutex_lock */
+/* Check concurrent access of counting and sampling for PAI events.
+ * This function is called in process context and it is safe to block.
+ * When the event initialization functions fails, no other call back will
+ * be invoked.
+ * Called under mutex_lock.
+ */
static int pai_alloc(struct perf_event *event)
{
int idx = PAI_PMU_IDX(event);
@@ -322,24 +364,20 @@ static int pai_alloc(struct perf_event *
goto out;
for_each_online_cpu(cpu) {
- rc = pai_alloc_cpu(idx, cpu);
+ rc = pai_alloc_cpu(idx, cpu, false);
if (rc) {
for_each_cpu(cpu, maskptr)
- pai_event_destroy_cpu(idx, cpu);
- kfree(maskptr);
- goto out;
+ pai_event_destroy_cpu(idx, cpu, false);
+ goto undo;
}
cpumask_set_cpu(cpu, maskptr);
}
- /*
- * On error all cpumask are freed and all events have been destroyed.
- * Save of which CPUs data structures have been allocated for.
- * Release them in pai_event_destroy call back function
- * for this event.
- */
- PAI_CPU_MASK(event) = maskptr;
rc = 0;
+ /* Trace per-task events for CPU hotplug. */
+ atomic_inc(&pai_root[idx].tskctx);
+undo:
+ kfree(maskptr);
out:
return rc;
}
@@ -387,12 +425,14 @@ static int pai_event_init(struct perf_ev
}
}
+ cpus_read_lock();
mutex_lock(&pai_reserve_mutex);
if (event->cpu >= 0)
- rc = pai_alloc_cpu(idx, event->cpu);
+ rc = pai_alloc_cpu(idx, event->cpu, false);
else
rc = pai_alloc(event);
mutex_unlock(&pai_reserve_mutex);
+ cpus_read_unlock();
if (rc) {
free_page(PAI_SAVE_AREA(event));
goto out;
@@ -1216,8 +1256,35 @@ static int __init paipmu_setup(void)
return install_ok;
}
+static int pai_online_cpu(unsigned int cpu)
+{
+ int rc;
+
+ mutex_lock(&pai_reserve_mutex);
+ rc = pai_alloc_cpu(PAI_PMU_CRYPTO, cpu, true);
+ if (rc)
+ goto out;
+ rc = pai_alloc_cpu(PAI_PMU_EXT, cpu, true);
+ if (rc)
+ pai_event_destroy_cpu(PAI_PMU_CRYPTO, cpu, true);
+out:
+ mutex_unlock(&pai_reserve_mutex);
+ return rc;
+}
+
+static int pai_offline_cpu(unsigned int cpu)
+{
+ mutex_lock(&pai_reserve_mutex);
+ pai_event_destroy_cpu(PAI_PMU_CRYPTO, cpu, true);
+ pai_event_destroy_cpu(PAI_PMU_EXT, cpu, true);
+ mutex_unlock(&pai_reserve_mutex);
+ return 0;
+}
+
static int __init pai_init(void)
{
+ int state, rc;
+
/* Setup s390dbf facility */
paidbg = debug_register("pai", 1, 1, 128);
if (!paidbg) {
@@ -1226,13 +1293,24 @@ static int __init pai_init(void)
}
debug_register_view(paidbg, &debug_sprintf_view);
- if (!paipmu_setup()) {
- /* No PMU registration, no need for debug buffer */
- debug_unregister_view(paidbg, &debug_sprintf_view);
- debug_unregister(paidbg);
- return -ENODEV;
- }
+ /* CPUHP_BP_PREPARE_DYN --> before CPU is brought online */
+ state = cpuhp_setup_state(CPUHP_BP_PREPARE_DYN, "perf/pai:prepare",
+ pai_online_cpu, pai_offline_cpu);
+ rc = state < 0 ? state : 0;
+ if (rc < 0)
+ goto out_debug;
+
+ rc = -ENODEV;
+ if (!paipmu_setup())
+ goto out_cpuhp;
return 0;
+
+out_cpuhp:
+ cpuhp_remove_state(state);
+out_debug:
+ debug_unregister_view(paidbg, &debug_sprintf_view);
+ debug_unregister(paidbg);
+ return rc;
}
device_initcall(pai_init);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 731/733] x86/mm/pat: Allocate split page tables as kernel page tables
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (729 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 730/733] s390/pai: Support CPU hotplug for PMU PAI Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 732/733] misc: amd-sbi: Add null check for devm_kasprintf() Greg Kroah-Hartman
` (13 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Lorenzo Stoakes (ARM),
Mike Rapoport (Microsoft), Dave Hansen, Ingo Molnar, Vishal Moola,
Atish Patra, Nikunj A Dadhania, Sasha Levin
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Lorenzo Stoakes (ARM)" <ljs@kernel.org>
[ Upstream commit 9e4a3ec3411bb6bb59e3c1f29b75609f1e87aac4 ]
A PTE is allocated directly without going through the standard page table
allocation routines (such as pte_alloc_one_kernel()) when the CPA code
splits a large page (__split_large_page()).
This means the page table constructor is never called nor is the page table
marked as a kernel page table.
The former results in the folio associated with the page table not being
marked as a page table (__pagetable_ctor() is never called thus neither is
__folio_set_pgtable()) nor are statistics updated to reflect
it (lruvec_stat_add_folio() is never called).
The latter issue of failing to mark the page table as a kernel page
table (ptdesc_set_kernel() is never called) is far more problematic.
Since commit:
5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables")
kernel page table freeing has been batched and since the
subsequent commit:
e37d5a2d60a3 ("iommu/sva: invalidate stale IOTLB entries for kernel address space")
IOTLB cache entries for kernel page tables have been invalidated upon
being freed.
Since split page tables are freed without this invalidation, the IOTLB
can contain stale entries for them.
Resolve the issue by using the ordinary PTE allocation API at split time.
This results in these kernel page tables invoking a page table constructor,
and thus requires a page table destructor.
Destructors are not always present, like for early allocated direct map
page tables). Conditionally call pagetable_dtor_free() if the PG_table
folio flag for the ptdesc is set, otherwise we free the page table via
pagetable_free().
Regardless of which path is taken page tables marked as kernel page tables,
which now includes split page tables, take the correct route through
pagetable_free_kernel().
There is a user-visible side effect in that split page tables will appear
in nr_page_table_pages in /proc/vmstat (as do other kernel page tables
allocated after early boot), however this is a positive change.
This issue started being markedly problematic after commit:
5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables")
so choose this as the Fixes target.
[ dhansen: rephrase in imperative mood ]
Fixes: 5ba2f0a15564 ("mm: introduce deferred freeing for kernel page tables")
Signed-off-by: Lorenzo Stoakes (ARM) <ljs@kernel.org>
Signed-off-by: Mike Rapoport (Microsoft) <rppt@kernel.org>
Signed-off-by: Dave Hansen <dave.hansen@linux.intel.com>
Signed-off-by: Ingo Molnar <mingo@kernel.org>
Acked-by: Vishal Moola <vishal.moola@gmail.com>
Tested-by: Atish Patra <atishp@meta.com>
Tested-by: Nikunj A Dadhania <nikunj@amd.com>
Cc: stable@vger.kernel.org
Link: https://patch.msgid.link/20260813-cpa-fixes-v2-4-39b4ff90f91d@kernel.org
Signed-off-by: Sasha Levin <sashal@kernel.org>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/mm/pat/set_memory.c | 25 ++++++++++++++++---------
1 file changed, 16 insertions(+), 9 deletions(-)
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -443,7 +443,15 @@ static void __cpa_collapse_large_pages(s
list_for_each_entry_safe(ptdesc, tmp, &pgtables, pt_list) {
list_del(&ptdesc->pt_list);
- pagetable_free(ptdesc);
+ /*
+ * Only early alloc'd direct map should not be flagged PG_table
+ * here and those shouldn't be collapsed. However be abundantly
+ * cautious and handle the !PG_table case too.
+ */
+ if (PageTable((ptdesc_page(ptdesc))))
+ pagetable_dtor_free(ptdesc);
+ else
+ pagetable_free(ptdesc);
}
spin_unlock(&cpa_lock);
@@ -1144,11 +1152,10 @@ set:
static int
__split_large_page(struct cpa_data *cpa, pte_t *kpte, unsigned long address,
- struct ptdesc *ptdesc)
+ pte_t *pbase)
{
unsigned long lpaddr, lpinc, ref_pfn, pfn, pfninc = 1;
- struct page *base = ptdesc_page(ptdesc);
- pte_t *pbase = (pte_t *)page_address(base);
+ struct page *base = virt_to_page(pbase);
unsigned int i, level;
pgprot_t ref_prot;
bool nx, rw;
@@ -1252,20 +1259,20 @@ __split_large_page(struct cpa_data *cpa,
static int split_large_page(struct cpa_data *cpa, pte_t *kpte,
unsigned long address)
{
- struct ptdesc *ptdesc;
+ pte_t *pte;
spin_unlock(&cpa_lock);
if (cpa->init_mm_read_locked)
mmap_read_unlock(&init_mm);
- ptdesc = pagetable_alloc(GFP_KERNEL, 0);
+ pte = pte_alloc_one_kernel(&init_mm);
if (cpa->init_mm_read_locked)
mmap_read_lock(&init_mm);
spin_lock(&cpa_lock);
- if (!ptdesc)
+ if (!pte)
return -ENOMEM;
- if (__split_large_page(cpa, kpte, address, ptdesc))
- pagetable_free(ptdesc);
+ if (__split_large_page(cpa, kpte, address, pte))
+ pte_free_kernel(&init_mm, pte);
return 0;
}
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 732/733] misc: amd-sbi: Add null check for devm_kasprintf()
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (730 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 731/733] x86/mm/pat: Allocate split page tables as kernel page tables Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 15:17 ` [PATCH 7.2 733/733] x86/mm: Fix and document DEBUG_PAGEALLOC Greg Kroah-Hartman
` (12 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable
Cc: Greg Kroah-Hartman, patches, Arnd Bergmann,
Naveen Krishna Chatradhi, Akshay Gupta, Griffin Kroah-Hartman
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Griffin Kroah-Hartman <griffin@kroah.com>
commit 1bb5c324b872c2e71fa1b12a5f59615b994501da upstream.
Add two checks for devm_kasprintf() errors in create_misc_rmi_device(),
returning -ENOMEM if the function failed.
Assisted-by: gkh_clanker_t1000
CC: Arnd Bergmann <arnd@arndb.de>
CC: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
CC: Naveen Krishna Chatradhi <naveenkrishna.chatradhi@amd.com>
CC: Akshay Gupta <Akshay.Gupta@amd.com>
Signed-off-by: Griffin Kroah-Hartman <griffin@kroah.com>
Link: https://patch.msgid.link/20260709132052.211683-1-griffin@kroah.com
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
drivers/misc/amd-sbi/rmi-core.c | 4 ++++
1 file changed, 4 insertions(+)
--- a/drivers/misc/amd-sbi/rmi-core.c
+++ b/drivers/misc/amd-sbi/rmi-core.c
@@ -581,6 +581,8 @@ int create_misc_rmi_device(struct sbrmi_
GFP_KERNEL,
"sbrmi-%x",
data->dev_static_addr);
+ if (!data->sbrmi_misc_dev.name)
+ return -ENOMEM;
data->sbrmi_misc_dev.minor = MISC_DYNAMIC_MINOR;
data->sbrmi_misc_dev.fops = &sbrmi_fops;
data->sbrmi_misc_dev.parent = dev;
@@ -588,6 +590,8 @@ int create_misc_rmi_device(struct sbrmi_
GFP_KERNEL,
"sbrmi-%x",
data->dev_static_addr);
+ if (!data->sbrmi_misc_dev.nodename)
+ return -ENOMEM;
data->sbrmi_misc_dev.mode = 0600;
return misc_register(&data->sbrmi_misc_dev);
^ permalink raw reply [flat|nested] 748+ messages in thread* [PATCH 7.2 733/733] x86/mm: Fix and document DEBUG_PAGEALLOC
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (731 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 732/733] misc: amd-sbi: Add null check for devm_kasprintf() Greg Kroah-Hartman
@ 2026-09-17 15:17 ` Greg Kroah-Hartman
2026-09-17 16:00 ` [PATCH 7.2 000/733] 7.2.7-rc1 review Ronald Warsow
` (11 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Greg Kroah-Hartman @ 2026-09-17 15:17 UTC (permalink / raw)
To: stable; +Cc: Greg Kroah-Hartman, patches, Peter Zijlstra (Intel)
7.2-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <peterz@infradead.org>
commit 7da514d819a0afb148634aac92b3d190f34947c3 upstream.
It turns out that commit 5fce67641a3e ("x86/mm/pat: Don't gate
cpa_lock on debug_pagealloc_enabled()") was a little too quick to
remove the debug_pagealloc exception for cpa_lock.
Notably __kernel_map_pages() is used by the page-allocator from any
context the page-allocator itself is used, which violates the cpa_lock
rules.
Re-instate the exception, except make it specific to the
__kernel_map_pages() such that any other cpa() usage is still fully
serialized by cpa_lock. Also note that since cpa() should not be used
on memory that isn't allocated, the page-allocator locking and cpa are
infact mutually exclusive and all cpa usage in fully serialized.
Add a comment explaining this and other 'funnies' surrounding
DEBUG_PAGEALLOC, including how pgd_lock is not affected and the TLB
trickery.
Fixes: 5fce67641a3e ("x86/mm/pat: Don't gate cpa_lock on debug_pagealloc_enabled()")
Signed-off-by: Peter Zijlstra (Intel) <peterz@infradead.org>
Link: https://patch.msgid.link/20260729111119.604452135@infradead.org
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
---
arch/x86/mm/pat/set_memory.c | 80 +++++++++++++++++++++++++++++++------------
1 file changed, 58 insertions(+), 22 deletions(-)
--- a/arch/x86/mm/pat/set_memory.c
+++ b/arch/x86/mm/pat/set_memory.c
@@ -70,11 +70,12 @@ static const int cpa_warn_level = CPA_PR
*/
static DEFINE_SPINLOCK(cpa_lock);
-#define CPA_FLUSHTLB 1
-#define CPA_ARRAY 2
-#define CPA_PAGES_ARRAY 4
-#define CPA_NO_CHECK_ALIAS 8 /* Do not search for aliases */
-#define CPA_COLLAPSE 16 /* try to collapse large pages */
+#define CPA_FLUSHTLB 0x01
+#define CPA_ARRAY 0x02
+#define CPA_PAGES_ARRAY 0x04
+#define CPA_NO_CHECK_ALIAS 0x08 /* Do not search for aliases */
+#define CPA_COLLAPSE 0x10 /* try to collapse large pages */
+#define CPA_DEBUG_PAGEALLOC 0x20
static inline pgprot_t cachemode2pgprot(enum page_cache_mode pcm)
{
@@ -2032,6 +2033,7 @@ static int __change_page_attr_set_clr(st
{
unsigned long numpages = cpa->numpages;
unsigned long rempages = numpages;
+ bool lock = true;
int ret = 0;
/*
@@ -2041,6 +2043,29 @@ static int __change_page_attr_set_clr(st
!cpa->force_split)
return ret;
+ /*
+ * DEBUG_PAGEALLOC is special; it is called from any context the
+ * page-allocator is, which violates the normal cpa_lock locking
+ * rules.
+ *
+ * However, since it is part of the page-allocator, things are still
+ * properly serialized by the page-allocator locking and the fact that
+ * when a page is owned by the page-allocator, it isn't owned by
+ * anybody else. That is, you *SHOULD NOT* be calling cpa() on memory
+ * that isn't allocated.
+ *
+ * Additionally, DEBUG_PAGEALLOC ensures (per probe_page_size_mask())
+ * that the kernel mapping is 4k pages, therefore there are no large
+ * pages to split/collapse.
+ *
+ * Furthermore, the page-allocator strictly manages pages that
+ * *exist*, avoiding pgd_lock.
+ *
+ * Therefore, it is safe to not take cpa_lock.
+ */
+ if (debug_pagealloc_enabled() && (cpa->flags & CPA_DEBUG_PAGEALLOC))
+ lock = false;
+
while (rempages) {
/*
* Store the remaining nr of pages for the large page
@@ -2051,9 +2076,12 @@ static int __change_page_attr_set_clr(st
if (cpa->flags & (CPA_ARRAY | CPA_PAGES_ARRAY))
cpa->numpages = 1;
- spin_lock(&cpa_lock);
- ret = __change_page_attr(cpa, primary);
- spin_unlock(&cpa_lock);
+ if (lock) {
+ guard(spinlock)(&cpa_lock);
+ ret = __change_page_attr(cpa, primary);
+ } else {
+ ret = __change_page_attr(cpa, primary);
+ }
if (ret)
goto out;
@@ -2636,7 +2664,7 @@ int set_pages_rw(struct page *page, int
return set_memory_rw(addr, numpages);
}
-static int __set_pages_p(struct page *page, int numpages)
+static int __set_pages_p(struct page *page, int numpages, unsigned int cpa_flags)
{
unsigned long tempaddr = (unsigned long) page_address(page);
struct cpa_data cpa = { .vaddr = &tempaddr,
@@ -2644,7 +2672,7 @@ static int __set_pages_p(struct page *pa
.numpages = numpages,
.mask_set = __pgprot(_PAGE_PRESENT | _PAGE_RW),
.mask_clr = __pgprot(0),
- .flags = CPA_NO_CHECK_ALIAS };
+ .flags = CPA_NO_CHECK_ALIAS | cpa_flags };
/*
* No alias checking needed for setting present flag. otherwise,
@@ -2655,7 +2683,7 @@ static int __set_pages_p(struct page *pa
return __change_page_attr_set_clr(&cpa, 1);
}
-static int __set_pages_np(struct page *page, int numpages)
+static int __set_pages_np(struct page *page, int numpages, unsigned int cpa_flags)
{
unsigned long tempaddr = (unsigned long) page_address(page);
struct cpa_data cpa = { .vaddr = &tempaddr,
@@ -2663,7 +2691,7 @@ static int __set_pages_np(struct page *p
.numpages = numpages,
.mask_set = __pgprot(0),
.mask_clr = __pgprot(_PAGE_PRESENT | _PAGE_RW | _PAGE_DIRTY),
- .flags = CPA_NO_CHECK_ALIAS };
+ .flags = CPA_NO_CHECK_ALIAS | cpa_flags };
/*
* No alias checking needed for setting not present flag. otherwise,
@@ -2676,20 +2704,20 @@ static int __set_pages_np(struct page *p
int set_direct_map_invalid_noflush(struct page *page)
{
- return __set_pages_np(page, 1);
+ return __set_pages_np(page, 1, 0);
}
int set_direct_map_default_noflush(struct page *page)
{
- return __set_pages_p(page, 1);
+ return __set_pages_p(page, 1, 0);
}
int set_direct_map_valid_noflush(struct page *page, unsigned nr, bool valid)
{
if (valid)
- return __set_pages_p(page, nr);
+ return __set_pages_p(page, nr, 0);
- return __set_pages_np(page, nr);
+ return __set_pages_np(page, nr, 0);
}
#ifdef CONFIG_DEBUG_PAGEALLOC
@@ -2708,15 +2736,23 @@ void __kernel_map_pages(struct page *pag
* and hence no memory allocations during large page split.
*/
if (enable)
- __set_pages_p(page, numpages);
+ __set_pages_p(page, numpages, CPA_DEBUG_PAGEALLOC);
else
- __set_pages_np(page, numpages);
+ __set_pages_np(page, numpages, CPA_DEBUG_PAGEALLOC);
/*
- * We should perform an IPI and flush all tlbs,
- * but that can deadlock->flush only current cpu.
- * Preemption needs to be disabled around __flush_tlb_all() due to
- * CR3 reload in __native_flush_tlb().
+ * We should perform an IPI and flush all tlbs, but that can
+ * deadlock, settle for a local flush.
+ *
+ * Not doing a global TLB flush means that remote CPUs will retain
+ * stale TLB entries. In case of P->NP (on free) this means the remote
+ * CPUs will not take the faults, making the debug scheme less
+ * reliable. On the NP->P (on alloc) this means the remote CPUs can
+ * take a spurious fault. However spurious_kernel_fault() will observe
+ * *_present() and fix it up.
+ *
+ * Preemption needs to be disabled around __flush_tlb_all() due to CR3
+ * reload in __native_flush_tlb().
*/
preempt_disable();
__flush_tlb_all();
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (732 preceding siblings ...)
2026-09-17 15:17 ` [PATCH 7.2 733/733] x86/mm: Fix and document DEBUG_PAGEALLOC Greg Kroah-Hartman
@ 2026-09-17 16:00 ` Ronald Warsow
2026-09-17 16:19 ` Florian Fainelli
` (10 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Ronald Warsow @ 2026-09-17 16:00 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
conor, hargar, broonie, achill, sr
Hi
kernel build / boot test on x86_64 (Intel).
No regressions here.
Thanks
Tested-by: Ronald Warsow <rwarsow@gmx.de>
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (733 preceding siblings ...)
2026-09-17 16:00 ` [PATCH 7.2 000/733] 7.2.7-rc1 review Ronald Warsow
@ 2026-09-17 16:19 ` Florian Fainelli
2026-09-17 17:10 ` Brett A C Sheffield
` (9 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Florian Fainelli @ 2026-09-17 16:19 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, sudipm.mukherjee, rwarsow, conor,
hargar, broonie, achill, sr
On 9/17/26 08:05, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sat, 19 Sep 2026 15:12:28 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.7-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on
BMIPS_GENERIC:
Tested-by: Florian Fainelli <florian.fainelli@broadcom.com>
--
Florian
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (734 preceding siblings ...)
2026-09-17 16:19 ` Florian Fainelli
@ 2026-09-17 17:10 ` Brett A C Sheffield
2026-09-17 20:06 ` Pavel Machek
` (8 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Brett A C Sheffield @ 2026-09-17 17:10 UTC (permalink / raw)
To: gregkh
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr,
Brett A C Sheffield
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 7.2.7-rc1-gb4c9ab9b68c7 #2 SMP PREEMPT_DYNAMIC Thu Sep 17 17:08:06 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Tested-by: Brett A C Sheffield <bacs@librecast.net>
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (735 preceding siblings ...)
2026-09-17 17:10 ` Brett A C Sheffield
@ 2026-09-17 20:06 ` Pavel Machek
2026-09-17 22:45 ` Peter Schneider
` (7 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Pavel Machek @ 2026-09-17 20:06 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
[-- Attachment #1: Type: text/plain, Size: 501 bytes --]
Hi!
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
CIP testing did not find any problems here:
https://gitlab.com/cip-project/cip-testing/linux-stable-rc-ci/-/tree/linux-7.2.y
Tested-by: Pavel Machek (CIP) <pavel@nabladev.com>
Best regards,
Pavel
[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 195 bytes --]
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (736 preceding siblings ...)
2026-09-17 20:06 ` Pavel Machek
@ 2026-09-17 22:45 ` Peter Schneider
2026-09-18 7:15 ` Wentao Guan
` (6 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Peter Schneider @ 2026-09-17 22:45 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
Am 17.09.2026 um 17:05 schrieb Greg Kroah-Hartman:
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697v2 server. No dmesg oddities or regressions found.
Tested-by: Peter Schneider <pschneider1968@googlemail.com>
Beste Grüße,
Peter Schneider
--
Climb the mountain not to plant your flag, but to embrace the challenge,
enjoy the air and behold the view. Climb it so you can see the world,
not so the world can see you. -- David McCullough Jr.
OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244
Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@googlemail.com
https://keys.mailvelope.com/pks/lookup?op=get&search=pschneider1968@gmail.com
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (737 preceding siblings ...)
2026-09-17 22:45 ` Peter Schneider
@ 2026-09-18 7:15 ` Wentao Guan
2026-09-18 8:16 ` Jeffrin Thalakkottoor
` (5 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Wentao Guan @ 2026-09-18 7:15 UTC (permalink / raw)
To: gregkh
Cc: achill, akpm, broonie, conor, f.fainelli, hargar, jonathanh,
linux-kernel, linux, lkft-triage, patches, patches, pavel,
rwarsow, shuah, sr, stable, sudipm.mukherjee, torvalds,
Wentao Guan
Build tested in our x86,arm64,loongarch,riscv config successfully without error.
Tested-by: Wentao Guan <guanwentao@uniontech.com>
Best Regards
Wentao Guan
Log:
Linux version 7.2.7-rc1-gb4c9ab9b68c7 (guanwentao@uos-PC) (aarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #2 SMP PREEMPT_DYNAMIC Fri Sep 18 07:06:00 CST 2026
Linux version 7.2.7-rc1-gb4c9ab9b68c7 (guanwentao@uos-PC) (loongarch64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #3 SMP PREEMPT_DYNAMIC Fri Sep 18 07:24:55 CST 2026
Linux version 7.2.7-rc1+ (guanwentao@uos-PC) (riscv64-linux-gnu-gcc-12 (Deepin 12.3.0-17deepin8) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #4 SMP PREEMPT Fri Sep 18 07:42:35 CST 2026
Linux version 7.2.7-rc1-gb4c9ab9b68c7 (guanwentao@uos-PC) (gcc (Deepin 12.3.0-17deepin18) 12.3.0, GNU ld (GNU Binutils for Deepin) 2.41) #1 SMP PREEMPT_DYNAMIC Fri Sep 18 06:40:08 CST 2026
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (738 preceding siblings ...)
2026-09-18 7:15 ` Wentao Guan
@ 2026-09-18 8:16 ` Jeffrin Thalakkottoor
2026-09-18 8:40 ` Ron Economos
` (4 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Jeffrin Thalakkottoor @ 2026-09-18 8:16 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
hello,
Compiled and booted 7.2.7-rc1 (using qemu-system-x86_64)
No new typical dmesg regressions .
Tested-by: Jeffrin Jose T <jeffrin@rajagiritech.edu.in>
--
software engineer
rajagiri school of engineering and technology
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (739 preceding siblings ...)
2026-09-18 8:16 ` Jeffrin Thalakkottoor
@ 2026-09-18 8:40 ` Ron Economos
2026-09-18 11:43 ` Takeshi Ogasawara
` (3 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Ron Economos @ 2026-09-18 8:40 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
On 9/17/26 08:05, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sat, 19 Sep 2026 15:12:28 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.7-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Tested-by: Ron Economos <re@w6rz.net>
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (740 preceding siblings ...)
2026-09-18 8:40 ` Ron Economos
@ 2026-09-18 11:43 ` Takeshi Ogasawara
2026-09-18 15:42 ` Barry K. Nathan
` (2 subsequent siblings)
744 siblings, 0 replies; 748+ messages in thread
From: Takeshi Ogasawara @ 2026-09-18 11:43 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
Hi Greg
On Fri, Sep 18, 2026 at 12:35 AM Greg Kroah-Hartman
<gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sat, 19 Sep 2026 15:12:28 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.7-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
>
Linux version 7.2.7-rc1 tested.
Build successfully completed.
Boot successfully completed.
No dmesg regressions.
Video output normal.
Sound output normal.
Lenovo ThinkPad X1 Carbon Gen10(Intel i7-1260P(x86_64) arch linux)
[ 0.000000] Linux version 7.2.7-rc1rv-gb4c9ab9b68c7
(takeshi@ThinkPadX1Gen10J0764) (gcc (GCC) 16.2.1 20260810, GNU ld (GNU
Binutils) 2.47) #1 SMP PREEMPT_DYNAMIC Fri Sep 18 19:56:17 JST 2026
Tested-by: Takeshi Ogasawara <takeshi.ogasawara@futuring-girl.com>
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (741 preceding siblings ...)
2026-09-18 11:43 ` Takeshi Ogasawara
@ 2026-09-18 15:42 ` Barry K. Nathan
2026-09-19 9:08 ` Benjamin Boortz
2026-09-19 12:05 ` Miguel Ojeda
744 siblings, 0 replies; 748+ messages in thread
From: Barry K. Nathan @ 2026-09-18 15:42 UTC (permalink / raw)
To: Greg Kroah-Hartman, stable
Cc: patches, linux-kernel, torvalds, akpm, linux, shuah, patches,
lkft-triage, pavel, jonathanh, f.fainelli, sudipm.mukherjee,
rwarsow, conor, hargar, broonie, achill, sr
On 9/17/26 8:05 AM, Greg Kroah-Hartman wrote:
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sat, 19 Sep 2026 15:12:28 +0000.
> Anything received after that time might be too late.
>
> The whole patch series can be found in one patch at:
> https://www.kernel.org/pub/linux/kernel/v7.x/stable-review/patch-7.2.7-rc1.gz
> or in the git tree and branch at:
> git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.git linux-7.2.y
> and the diffstat can be found below.
>
> thanks,
>
> greg k-h
Tested on an amd64 laptop (Lenovo ThinkPad T14 Gen 1). Working well,
no regressions observed.
Tested-by: Barry K. Nathan <barryn@pobox.com>
--
-Barry K. Nathan <barryn@pobox.com>
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (742 preceding siblings ...)
2026-09-18 15:42 ` Barry K. Nathan
@ 2026-09-19 9:08 ` Benjamin Boortz
2026-09-19 12:05 ` Miguel Ojeda
744 siblings, 0 replies; 748+ messages in thread
From: Benjamin Boortz @ 2026-09-19 9:08 UTC (permalink / raw)
To: Greg Kroah-Hartman
Cc: stable, patches, linux-kernel, torvalds, akpm, linux, shuah,
patches, lkft-triage, pavel, jonathanh, f.fainelli,
sudipm.mukherjee, rwarsow, conor, hargar, broonie, achill, sr
On Thu, Sep 17, 2026 at 04:05:08PM +0100, Greg Kroah-Hartman wrote:
>This is the start of the stable review cycle for the 7.2.7 release.
>There are 733 patches in this series, all will be posted as a response
>to this one. If anyone has any issues with these being applied, please
>let me know.
Build and boot tested with QEMU for x86_64, i386, arm64, and riscv
across multiple configurations, and boots on AMD Ryzen 7 5800H.
No regressions observed.
Tested-by: Benjamin Boortz <bennib@mailbox.org>
^ permalink raw reply [flat|nested] 748+ messages in thread* Re: [PATCH 7.2 000/733] 7.2.7-rc1 review
2026-09-17 15:05 [PATCH 7.2 000/733] 7.2.7-rc1 review Greg Kroah-Hartman
` (743 preceding siblings ...)
2026-09-19 9:08 ` Benjamin Boortz
@ 2026-09-19 12:05 ` Miguel Ojeda
744 siblings, 0 replies; 748+ messages in thread
From: Miguel Ojeda @ 2026-09-19 12:05 UTC (permalink / raw)
To: gregkh
Cc: achill, akpm, broonie, conor, f.fainelli, hargar, jonathanh,
linux-kernel, linux, lkft-triage, patches, patches, pavel,
rwarsow, shuah, sr, stable, sudipm.mukherjee, torvalds,
Miguel Ojeda
On Thu, 17 Sep 2026 16:05:08 +0100 Greg Kroah-Hartman <gregkh@linuxfoundation.org> wrote:
>
> This is the start of the stable review cycle for the 7.2.7 release.
> There are 733 patches in this series, all will be posted as a response
> to this one. If anyone has any issues with these being applied, please
> let me know.
>
> Responses should be made by Sat, 19 Sep 2026 15:12:28 +0000.
> Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64, arm64 and riscv64; built-tested
for loongarch64 and arm32:
Tested-by: Miguel Ojeda <ojeda@kernel.org>
Thanks!
Cheers,
Miguel
^ permalink raw reply [flat|nested] 748+ messages in thread