From 38bc604f7cd4d6375853d17f9841f19c27d5c85c Mon Sep 17 00:00:00 2001 From: Sasha Levin Date: Thu, 15 Jan 2026 07:58:53 -0500 Subject: [PATCH] Fixes for all trees Signed-off-by: Sasha Levin --- ...d-missing-registers-to-cache-default.patch | 55 ++++ ...1939_session_activate-fail-if-device.patch | 51 ++++ ...e-condition-in-register_control_type.patch | 65 +++++ ...x-sscanf-error-return-value-handling.patch | 67 +++++ ...sional-bogus-elapsed-time-that-excee.patch | 152 ++++++++++ queue-5.10/series | 5 + ...d-missing-registers-to-cache-default.patch | 55 ++++ ...1939_session_activate-fail-if-device.patch | 51 ++++ ...e-condition-in-register_control_type.patch | 65 +++++ ...x-sscanf-error-return-value-handling.patch | 67 +++++ ...sional-bogus-elapsed-time-that-excee.patch | 152 ++++++++++ queue-5.15/series | 5 + ...d-quirk-for-honor-magicbook-x16-2025.patch | 42 +++ ...d-missing-registers-to-cache-default.patch | 55 ++++ ...-in-bpf_prog_test_run_xdp-when-page-.patch | 220 ++++++++++++++ ...e-count-leak-in-bpf_prog_test_run_xd.patch | 79 ++++++ ...es-in-bpf_prog_test_run_xdp-less-con.patch | 101 +++++++ ...ifying-linear-xdp-packet-data-size-f.patch | 130 +++++++++ ...tract-size-of-xdp_frame-from-allowed.patch | 87 ++++++ ...1939_session_activate-fail-if-device.patch | 51 ++++ ...e-condition-in-register_control_type.patch | 65 +++++ ...x-sscanf-error-return-value-handling.patch | 67 +++++ ...sional-bogus-elapsed-time-that-excee.patch | 152 ++++++++++ queue-6.1/series | 11 + ...-enable-woofer-speakers-on-medion-nm.patch | 37 +++ ...update-for-native-dsd-support-quirks.patch | 60 ++++ ...d-quirk-for-honor-magicbook-x16-2025.patch | 42 +++ ...d-missing-registers-to-cache-default.patch | 55 ++++ ...re-disable-lpm-on-st2000dm008-2fr102.patch | 37 +++ ...-in-bpf_prog_test_run_xdp-when-page-.patch | 220 ++++++++++++++ ...e-count-leak-in-bpf_prog_test_run_xd.patch | 79 ++++++ ...es-in-bpf_prog_test_run_xdp-less-con.patch | 101 +++++++ ...ifying-linear-xdp-packet-data-size-f.patch | 130 +++++++++ ...tract-size-of-xdp_frame-from-allowed.patch | 87 ++++++ ...1939_session_activate-fail-if-device.patch | 51 ++++ ...rm-amd-display-fix-dp-no-audio-issue.patch | 49 ++++ ...mproper-null-termination-of-queue-re.patch | 40 +++ ...otron-xgspon-quirk-to-cover-addition.patch | 44 +++ ...les-avoid-chain-re-validation-if-pos.patch | 268 ++++++++++++++++++ ...e-condition-in-register_control_type.patch | 65 +++++ ...x-sscanf-error-return-value-handling.patch | 67 +++++ ...sional-bogus-elapsed-time-that-excee.patch | 152 ++++++++++ queue-6.12/series | 20 ++ ...spi-prevent-lost-complete-call-durin.patch | 63 ++++ ...x-use-irqf_oneshot-with-threaded-irq.patch | 43 +++ ...dna-block-running-under-a-hypervisor.patch | 49 ++++ ...-enable-woofer-speakers-on-medion-nm.patch | 37 +++ ...update-for-native-dsd-support-quirks.patch | 60 ++++ ...d-quirk-for-honor-magicbook-x16-2025.patch | 42 +++ ...d-missing-registers-to-cache-default.patch | 55 ++++ ...re-disable-lpm-on-st2000dm008-2fr102.patch | 37 +++ ...k-validate-pi_offset-integrity-limit.patch | 42 +++ ...e-count-leak-in-bpf_prog_test_run_xd.patch | 79 ++++++ ...tract-size-of-xdp_frame-from-allowed.patch | 87 ++++++ ...1939_session_activate-fail-if-device.patch | 51 ++++ ...rm-amd-display-fix-dp-no-audio-issue.patch | 49 ++++ ...mproper-null-termination-of-queue-re.patch | 40 +++ ...otron-xgspon-quirk-to-cover-addition.patch | 44 +++ ...les-avoid-chain-re-validation-if-pos.patch | 268 ++++++++++++++++++ ...e-condition-in-register_control_type.patch | 65 +++++ ...x-sscanf-error-return-value-handling.patch | 67 +++++ ...sional-bogus-elapsed-time-that-excee.patch | 152 ++++++++++ queue-6.18/series | 19 ++ ...spi-prevent-lost-complete-call-durin.patch | 63 ++++ ...x-use-irqf_oneshot-with-threaded-irq.patch | 43 +++ ...update-for-native-dsd-support-quirks.patch | 60 ++++ ...d-quirk-for-honor-magicbook-x16-2025.patch | 42 +++ ...d-missing-registers-to-cache-default.patch | 55 ++++ ...-in-bpf_prog_test_run_xdp-when-page-.patch | 220 ++++++++++++++ ...e-count-leak-in-bpf_prog_test_run_xd.patch | 79 ++++++ ...es-in-bpf_prog_test_run_xdp-less-con.patch | 101 +++++++ ...ifying-linear-xdp-packet-data-size-f.patch | 130 +++++++++ ...tract-size-of-xdp_frame-from-allowed.patch | 87 ++++++ ...1939_session_activate-fail-if-device.patch | 51 ++++ ...rm-amd-display-fix-dp-no-audio-issue.patch | 49 ++++ ...les-avoid-chain-re-validation-if-pos.patch | 268 ++++++++++++++++++ ...e-condition-in-register_control_type.patch | 65 +++++ ...x-sscanf-error-return-value-handling.patch | 67 +++++ ...sional-bogus-elapsed-time-that-excee.patch | 152 ++++++++++ queue-6.6/series | 14 + 80 files changed, 6349 insertions(+) create mode 100644 queue-5.10/asoc-fsl_sai-add-missing-registers-to-cache-default.patch create mode 100644 queue-5.10/can-j1939-make-j1939_session_activate-fail-if-device.patch create mode 100644 queue-5.10/powercap-fix-race-condition-in-register_control_type.patch create mode 100644 queue-5.10/powercap-fix-sscanf-error-return-value-handling.patch create mode 100644 queue-5.10/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch create mode 100644 queue-5.15/asoc-fsl_sai-add-missing-registers-to-cache-default.patch create mode 100644 queue-5.15/can-j1939-make-j1939_session_activate-fail-if-device.patch create mode 100644 queue-5.15/powercap-fix-race-condition-in-register_control_type.patch create mode 100644 queue-5.15/powercap-fix-sscanf-error-return-value-handling.patch create mode 100644 queue-5.15/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch create mode 100644 queue-6.1/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch create mode 100644 queue-6.1/asoc-fsl_sai-add-missing-registers-to-cache-default.patch create mode 100644 queue-6.1/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch create mode 100644 queue-6.1/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch create mode 100644 queue-6.1/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch create mode 100644 queue-6.1/bpf-support-specifying-linear-xdp-packet-data-size-f.patch create mode 100644 queue-6.1/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch create mode 100644 queue-6.1/can-j1939-make-j1939_session_activate-fail-if-device.patch create mode 100644 queue-6.1/powercap-fix-race-condition-in-register_control_type.patch create mode 100644 queue-6.1/powercap-fix-sscanf-error-return-value-handling.patch create mode 100644 queue-6.1/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch create mode 100644 queue-6.12/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch create mode 100644 queue-6.12/alsa-usb-audio-update-for-native-dsd-support-quirks.patch create mode 100644 queue-6.12/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch create mode 100644 queue-6.12/asoc-fsl_sai-add-missing-registers-to-cache-default.patch create mode 100644 queue-6.12/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch create mode 100644 queue-6.12/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch create mode 100644 queue-6.12/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch create mode 100644 queue-6.12/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch create mode 100644 queue-6.12/bpf-support-specifying-linear-xdp-packet-data-size-f.patch create mode 100644 queue-6.12/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch create mode 100644 queue-6.12/can-j1939-make-j1939_session_activate-fail-if-device.patch create mode 100644 queue-6.12/drm-amd-display-fix-dp-no-audio-issue.patch create mode 100644 queue-6.12/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch create mode 100644 queue-6.12/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch create mode 100644 queue-6.12/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch create mode 100644 queue-6.12/powercap-fix-race-condition-in-register_control_type.patch create mode 100644 queue-6.12/powercap-fix-sscanf-error-return-value-handling.patch create mode 100644 queue-6.12/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch create mode 100644 queue-6.12/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch create mode 100644 queue-6.12/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch create mode 100644 queue-6.18/accel-amdxdna-block-running-under-a-hypervisor.patch create mode 100644 queue-6.18/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch create mode 100644 queue-6.18/alsa-usb-audio-update-for-native-dsd-support-quirks.patch create mode 100644 queue-6.18/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch create mode 100644 queue-6.18/asoc-fsl_sai-add-missing-registers-to-cache-default.patch create mode 100644 queue-6.18/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch create mode 100644 queue-6.18/block-validate-pi_offset-integrity-limit.patch create mode 100644 queue-6.18/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch create mode 100644 queue-6.18/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch create mode 100644 queue-6.18/can-j1939-make-j1939_session_activate-fail-if-device.patch create mode 100644 queue-6.18/drm-amd-display-fix-dp-no-audio-issue.patch create mode 100644 queue-6.18/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch create mode 100644 queue-6.18/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch create mode 100644 queue-6.18/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch create mode 100644 queue-6.18/powercap-fix-race-condition-in-register_control_type.patch create mode 100644 queue-6.18/powercap-fix-sscanf-error-return-value-handling.patch create mode 100644 queue-6.18/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch create mode 100644 queue-6.18/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch create mode 100644 queue-6.18/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch create mode 100644 queue-6.6/alsa-usb-audio-update-for-native-dsd-support-quirks.patch create mode 100644 queue-6.6/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch create mode 100644 queue-6.6/asoc-fsl_sai-add-missing-registers-to-cache-default.patch create mode 100644 queue-6.6/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch create mode 100644 queue-6.6/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch create mode 100644 queue-6.6/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch create mode 100644 queue-6.6/bpf-support-specifying-linear-xdp-packet-data-size-f.patch create mode 100644 queue-6.6/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch create mode 100644 queue-6.6/can-j1939-make-j1939_session_activate-fail-if-device.patch create mode 100644 queue-6.6/drm-amd-display-fix-dp-no-audio-issue.patch create mode 100644 queue-6.6/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch create mode 100644 queue-6.6/powercap-fix-race-condition-in-register_control_type.patch create mode 100644 queue-6.6/powercap-fix-sscanf-error-return-value-handling.patch create mode 100644 queue-6.6/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch diff --git a/queue-5.10/asoc-fsl_sai-add-missing-registers-to-cache-default.patch b/queue-5.10/asoc-fsl_sai-add-missing-registers-to-cache-default.patch new file mode 100644 index 0000000000..288eb9201a --- /dev/null +++ b/queue-5.10/asoc-fsl_sai-add-missing-registers-to-cache-default.patch @@ -0,0 +1,55 @@ +From b5a17a0d8248e491b13bbe2398dc8a6acb415b79 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 11:22:45 +0100 +Subject: ASoC: fsl_sai: Add missing registers to cache default + +From: Alexander Stein + +[ Upstream commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb ] + +Drivers does cache sync during runtime resume, setting all writable +registers. Not all writable registers are set in cache default, resulting +in the erorr message: + fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause + unexpected behavior + +Fix this by adding missing writable register defaults. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index 0314d4257b2de..60df490cb7647 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -773,6 +773,7 @@ static struct reg_default fsl_sai_reg_defaults_ofs0[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(0), 0}, + {FSL_SAI_RCR2(0), 0}, + {FSL_SAI_RCR3(0), 0}, +@@ -796,12 +797,14 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(8), 0}, + {FSL_SAI_RCR2(8), 0}, + {FSL_SAI_RCR3(8), 0}, + {FSL_SAI_RCR4(8), 0}, + {FSL_SAI_RCR5(8), 0}, + {FSL_SAI_RMR, 0}, ++ {FSL_SAI_RTCTL, 0}, + {FSL_SAI_MCTL, 0}, + {FSL_SAI_MDIV, 0}, + }; +-- +2.51.0 + diff --git a/queue-5.10/can-j1939-make-j1939_session_activate-fail-if-device.patch b/queue-5.10/can-j1939-make-j1939_session_activate-fail-if-device.patch new file mode 100644 index 0000000000..c66d0e4331 --- /dev/null +++ b/queue-5.10/can-j1939-make-j1939_session_activate-fail-if-device.patch @@ -0,0 +1,51 @@ +From 9e95bfd6b62f3c155d89ebb918af1836d30ea3bf Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 22:39:59 +0900 +Subject: can: j1939: make j1939_session_activate() fail if device is no longer + registered + +From: Tetsuo Handa + +[ Upstream commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d ] + +syzbot is still reporting + + unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 + +even after commit 93a27b5891b8 ("can: j1939: add missing calls in +NETDEV_UNREGISTER notification handler") was added. A debug printk() patch +found that j1939_session_activate() can succeed even after +j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) +has completed. + +Since j1939_cancel_active_session() is processed with the session list lock +held, checking ndev->reg_state in j1939_session_activate() with the session +list lock held can reliably close the race window. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Signed-off-by: Tetsuo Handa +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index c433b49f8715c..25e4cdf2df22c 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1555,6 +1555,8 @@ int j1939_session_activate(struct j1939_session *session) + if (active) { + j1939_session_put(active); + ret = -EAGAIN; ++ } else if (priv->ndev->reg_state != NETREG_REGISTERED) { ++ ret = -ENODEV; + } else { + WARN_ON_ONCE(session->state != J1939_SESSION_NEW); + list_add_tail(&session->active_session_list_entry, +-- +2.51.0 + diff --git a/queue-5.10/powercap-fix-race-condition-in-register_control_type.patch b/queue-5.10/powercap-fix-race-condition-in-register_control_type.patch new file mode 100644 index 0000000000..06ed792c63 --- /dev/null +++ b/queue-5.10/powercap-fix-race-condition-in-register_control_type.patch @@ -0,0 +1,65 @@ +From b1804d14d83cf718e3cde1d1886764c63e918826 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 00:32:16 +0530 +Subject: powercap: fix race condition in register_control_type() + +From: Sumeet Pawnikar + +[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] + +The device becomes visible to userspace via device_register() +even before it fully initialized by idr_init(). If userspace +or another thread tries to register a zone immediately after +device_register(), the control_type_valid() will fail because +the control_type is not yet in the list. The IDR is not yet +initialized, so this race condition causes zone registration +failure. + +Move idr_init() and list addition before device_register() +fix the race condition. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject adjustment, empty line added ] +Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index fe5d05da7ce7a..2019b61e7b901 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type( + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, "%s", name); +- result = device_register(&control_type->dev); +- if (result) { +- put_device(&control_type->dev); +- return ERR_PTR(result); +- } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + ++ result = device_register(&control_type->dev); ++ if (result) { ++ mutex_lock(&powercap_cntrl_list_lock); ++ list_del(&control_type->node); ++ mutex_unlock(&powercap_cntrl_list_lock); ++ ++ idr_destroy(&control_type->idr); ++ put_device(&control_type->dev); ++ return ERR_PTR(result); ++ } ++ + return control_type; + } + EXPORT_SYMBOL_GPL(powercap_register_control_type); +-- +2.51.0 + diff --git a/queue-5.10/powercap-fix-sscanf-error-return-value-handling.patch b/queue-5.10/powercap-fix-sscanf-error-return-value-handling.patch new file mode 100644 index 0000000000..826ced5616 --- /dev/null +++ b/queue-5.10/powercap-fix-sscanf-error-return-value-handling.patch @@ -0,0 +1,67 @@ +From a409b2c7c00accddbbeb5f8db00093a370542d20 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 20:45:48 +0530 +Subject: powercap: fix sscanf() error return value handling + +From: Sumeet Pawnikar + +[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ] + +Fix inconsistent error handling for sscanf() return value check. + +Implicit boolean conversion is used instead of explicit return +value checks. The code checks if (!sscanf(...)) which is incorrect +because: + 1. sscanf returns the number of successfully parsed items + 2. On success, it returns 1 (one item passed) + 3. On failure, it returns 0 or EOF + 4. The check 'if (!sscanf(...))' is wrong because it treats + success (1) as failure + +All occurrences of sscanf() now uses explicit return value check. +With this behavior it returns '-EINVAL' when parsing fails (returns +0 or EOF), and continues when parsing succeeds (returns 1). + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject and changelog edits ] +Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index 2019b61e7b901..40cf6e337bdef 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -67,7 +67,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -92,7 +92,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -161,7 +161,7 @@ static ssize_t show_constraint_name(struct device *dev, + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-5.10/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch b/queue-5.10/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch new file mode 100644 index 0000000000..34a4209c91 --- /dev/null +++ b/queue-5.10/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch @@ -0,0 +1,152 @@ +From 245cccd2c9dc050771a0ec28c91d69eb2ae67cbe Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:08:23 +0100 +Subject: scsi: sg: Fix occasional bogus elapsed time that exceeds timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Rábek + +[ Upstream commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 ] + +A race condition was found in sg_proc_debug_helper(). It was observed on +a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring +/proc/scsi/sg/debug every second. A very large elapsed time would +sometimes appear. This is caused by two race conditions. + +We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 +architecture. A patched kernel was built, and the race condition could +not be observed anymore after the application of this patch. A +reproducer C program utilising the scsi_debug module was also built by +Changhui Zhong and can be viewed here: + +https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c + +The first race happens between the reading of hp->duration in +sg_proc_debug_helper() and request completion in sg_rq_end_io(). The +hp->duration member variable may hold either of two types of +information: + + #1 - The start time of the request. This value is present while + the request is not yet finished. + + #2 - The total execution time of the request (end_time - start_time). + +If sg_proc_debug_helper() executes *after* the value of hp->duration was +changed from #1 to #2, but *before* srp->done is set to 1 in +sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the +elapsed time (value type #2) is subtracted from a timestamp, which +cannot yield a valid elapsed time (which is a type #2 value as well). + +To fix this issue, the value of hp->duration must change under the +protection of the sfp->rq_list_lock in sg_rq_end_io(). Since +sg_proc_debug_helper() takes this read lock, the change to srp->done and +srp->header.duration will happen atomically from the perspective of +sg_proc_debug_helper() and the race condition is thus eliminated. + +The second race condition happens between sg_proc_debug_helper() and +sg_new_write(). Even though hp->duration is set to the current time +stamp in sg_add_request() under the write lock's protection, it gets +overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() +to copy struct sg_io_hdr from userspace into kernel space. hp->duration +is set to the start time again in sg_common_write(). If +sg_proc_debug_helper() is called between these two calls, an arbitrary +value set by userspace (usually zero) is used to compute the elapsed +time. + +To fix this issue, hp->duration must be set to the current timestamp +again after get_sg_io_hdr() returns successfully. A small race window +still exists between get_sg_io_hdr() and setting hp->duration, but this +window is only a few instructions wide and does not result in observable +issues in practice, as confirmed by testing. + +Additionally, we fix the format specifier from %d to %u for printing +unsigned int values in sg_proc_debug_helper(). + +Signed-off-by: Michal Rábek +Suggested-by: Tomas Henzl +Tested-by: Changhui Zhong +Reviewed-by: Ewan D. Milne +Reviewed-by: John Meneghini +Reviewed-by: Tomas Henzl +Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sg.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 646bf8e998a04..b24e80a9c8cac 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -732,6 +732,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, + sg_remove_request(sfp, srp); + return -EFAULT; + } ++ hp->duration = jiffies_to_msecs(jiffies); ++ + if (hp->interface_id != 'S') { + sg_remove_request(sfp, srp); + return -ENOSYS; +@@ -817,7 +819,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, + return -ENODEV; + } + +- hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != '\0' && /* v3 (or later) interface */ + (SG_FLAG_Q_AT_TAIL & hp->flags)) + at_head = 0; +@@ -1361,9 +1362,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + "sg_cmd_done: pack_id=%d, res=0x%x\n", + srp->header.pack_id, result)); + srp->header.resid = resid; +- ms = jiffies_to_msecs(jiffies); +- srp->header.duration = (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; + if (0 != result) { + struct scsi_sense_hdr sshdr; + +@@ -1413,6 +1411,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + done = 0; + } + srp->done = done; ++ ms = jiffies_to_msecs(jiffies); ++ srp->header.duration = (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { +@@ -2560,6 +2561,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + const sg_io_hdr_t *hp; + const char * cp; + unsigned int ms; ++ unsigned int duration; + + k = 0; + list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { +@@ -2598,13 +2600,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " id=%d blen=%d", + srp->header.pack_id, blen); + if (srp->done) +- seq_printf(s, " dur=%d", hp->duration); ++ seq_printf(s, " dur=%u", hp->duration); + else { + ms = jiffies_to_msecs(jiffies); +- seq_printf(s, " t_o/elap=%d/%d", ++ duration = READ_ONCE(hp->duration); ++ if (duration) ++ duration = (ms > duration ? ++ ms - duration : 0); ++ seq_printf(s, " t_o/elap=%u/%u", + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), +- (ms > hp->duration ? ms - hp->duration : 0)); ++ duration); + } + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); +-- +2.51.0 + diff --git a/queue-5.10/series b/queue-5.10/series index c3674375bc..4f8a716e7a 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -446,3 +446,8 @@ net-usb-pegasus-fix-memory-leak-in-update_eth_regs_a.patch arp-do-not-assume-dev_hard_header-does-not-change-sk.patch blk-throttle-set-bio_throttled-when-bio-has-been-throttled.patch nfsd-provide-locking-for-v4_end_grace.patch +powercap-fix-race-condition-in-register_control_type.patch +powercap-fix-sscanf-error-return-value-handling.patch +can-j1939-make-j1939_session_activate-fail-if-device.patch +asoc-fsl_sai-add-missing-registers-to-cache-default.patch +scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch diff --git a/queue-5.15/asoc-fsl_sai-add-missing-registers-to-cache-default.patch b/queue-5.15/asoc-fsl_sai-add-missing-registers-to-cache-default.patch new file mode 100644 index 0000000000..c68361a2de --- /dev/null +++ b/queue-5.15/asoc-fsl_sai-add-missing-registers-to-cache-default.patch @@ -0,0 +1,55 @@ +From ba9de1e524d8d61a1634c26b434ac78bcbcfcbd3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 11:22:45 +0100 +Subject: ASoC: fsl_sai: Add missing registers to cache default + +From: Alexander Stein + +[ Upstream commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb ] + +Drivers does cache sync during runtime resume, setting all writable +registers. Not all writable registers are set in cache default, resulting +in the erorr message: + fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause + unexpected behavior + +Fix this by adding missing writable register defaults. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index 45d8ef029a638..82911e5ed1796 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -779,6 +779,7 @@ static struct reg_default fsl_sai_reg_defaults_ofs0[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(0), 0}, + {FSL_SAI_RCR2(0), 0}, + {FSL_SAI_RCR3(0), 0}, +@@ -802,12 +803,14 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(8), 0}, + {FSL_SAI_RCR2(8), 0}, + {FSL_SAI_RCR3(8), 0}, + {FSL_SAI_RCR4(8), 0}, + {FSL_SAI_RCR5(8), 0}, + {FSL_SAI_RMR, 0}, ++ {FSL_SAI_RTCTL, 0}, + {FSL_SAI_MCTL, 0}, + {FSL_SAI_MDIV, 0}, + }; +-- +2.51.0 + diff --git a/queue-5.15/can-j1939-make-j1939_session_activate-fail-if-device.patch b/queue-5.15/can-j1939-make-j1939_session_activate-fail-if-device.patch new file mode 100644 index 0000000000..faad9e7e64 --- /dev/null +++ b/queue-5.15/can-j1939-make-j1939_session_activate-fail-if-device.patch @@ -0,0 +1,51 @@ +From 9f663950c7e149e6bedfd8d462f8c3b7c559fd53 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 22:39:59 +0900 +Subject: can: j1939: make j1939_session_activate() fail if device is no longer + registered + +From: Tetsuo Handa + +[ Upstream commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d ] + +syzbot is still reporting + + unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 + +even after commit 93a27b5891b8 ("can: j1939: add missing calls in +NETDEV_UNREGISTER notification handler") was added. A debug printk() patch +found that j1939_session_activate() can succeed even after +j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) +has completed. + +Since j1939_cancel_active_session() is processed with the session list lock +held, checking ndev->reg_state in j1939_session_activate() with the session +list lock held can reliably close the race window. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Signed-off-by: Tetsuo Handa +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index 76d625c668e05..0522c223570c7 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1571,6 +1571,8 @@ int j1939_session_activate(struct j1939_session *session) + if (active) { + j1939_session_put(active); + ret = -EAGAIN; ++ } else if (priv->ndev->reg_state != NETREG_REGISTERED) { ++ ret = -ENODEV; + } else { + WARN_ON_ONCE(session->state != J1939_SESSION_NEW); + list_add_tail(&session->active_session_list_entry, +-- +2.51.0 + diff --git a/queue-5.15/powercap-fix-race-condition-in-register_control_type.patch b/queue-5.15/powercap-fix-race-condition-in-register_control_type.patch new file mode 100644 index 0000000000..bb4a8126ad --- /dev/null +++ b/queue-5.15/powercap-fix-race-condition-in-register_control_type.patch @@ -0,0 +1,65 @@ +From a8c569bdc4df6a0ce3704ab57e5186688b9864a8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 00:32:16 +0530 +Subject: powercap: fix race condition in register_control_type() + +From: Sumeet Pawnikar + +[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] + +The device becomes visible to userspace via device_register() +even before it fully initialized by idr_init(). If userspace +or another thread tries to register a zone immediately after +device_register(), the control_type_valid() will fail because +the control_type is not yet in the list. The IDR is not yet +initialized, so this race condition causes zone registration +failure. + +Move idr_init() and list addition before device_register() +fix the race condition. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject adjustment, empty line added ] +Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index fd475e463d1fa..d7dadcaa3736b 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -624,17 +624,23 @@ struct powercap_control_type *powercap_register_control_type( + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, "%s", name); +- result = device_register(&control_type->dev); +- if (result) { +- put_device(&control_type->dev); +- return ERR_PTR(result); +- } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + ++ result = device_register(&control_type->dev); ++ if (result) { ++ mutex_lock(&powercap_cntrl_list_lock); ++ list_del(&control_type->node); ++ mutex_unlock(&powercap_cntrl_list_lock); ++ ++ idr_destroy(&control_type->idr); ++ put_device(&control_type->dev); ++ return ERR_PTR(result); ++ } ++ + return control_type; + } + EXPORT_SYMBOL_GPL(powercap_register_control_type); +-- +2.51.0 + diff --git a/queue-5.15/powercap-fix-sscanf-error-return-value-handling.patch b/queue-5.15/powercap-fix-sscanf-error-return-value-handling.patch new file mode 100644 index 0000000000..0877521542 --- /dev/null +++ b/queue-5.15/powercap-fix-sscanf-error-return-value-handling.patch @@ -0,0 +1,67 @@ +From 65229ea06c738facfeafd5b6d2e5d09d75c54651 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 20:45:48 +0530 +Subject: powercap: fix sscanf() error return value handling + +From: Sumeet Pawnikar + +[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ] + +Fix inconsistent error handling for sscanf() return value check. + +Implicit boolean conversion is used instead of explicit return +value checks. The code checks if (!sscanf(...)) which is incorrect +because: + 1. sscanf returns the number of successfully parsed items + 2. On success, it returns 1 (one item passed) + 3. On failure, it returns 0 or EOF + 4. The check 'if (!sscanf(...))' is wrong because it treats + success (1) as failure + +All occurrences of sscanf() now uses explicit return value check. +With this behavior it returns '-EINVAL' when parsing fails (returns +0 or EOF), and continues when parsing succeeds (returns 1). + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject and changelog edits ] +Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index d7dadcaa3736b..72fa1f5affcea 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -67,7 +67,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -92,7 +92,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -161,7 +161,7 @@ static ssize_t show_constraint_name(struct device *dev, + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-5.15/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch b/queue-5.15/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch new file mode 100644 index 0000000000..aa03e687e2 --- /dev/null +++ b/queue-5.15/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch @@ -0,0 +1,152 @@ +From 838d32d8cde5ecae2e5ee98a1fd250579e79b2ec Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:08:23 +0100 +Subject: scsi: sg: Fix occasional bogus elapsed time that exceeds timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Rábek + +[ Upstream commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 ] + +A race condition was found in sg_proc_debug_helper(). It was observed on +a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring +/proc/scsi/sg/debug every second. A very large elapsed time would +sometimes appear. This is caused by two race conditions. + +We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 +architecture. A patched kernel was built, and the race condition could +not be observed anymore after the application of this patch. A +reproducer C program utilising the scsi_debug module was also built by +Changhui Zhong and can be viewed here: + +https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c + +The first race happens between the reading of hp->duration in +sg_proc_debug_helper() and request completion in sg_rq_end_io(). The +hp->duration member variable may hold either of two types of +information: + + #1 - The start time of the request. This value is present while + the request is not yet finished. + + #2 - The total execution time of the request (end_time - start_time). + +If sg_proc_debug_helper() executes *after* the value of hp->duration was +changed from #1 to #2, but *before* srp->done is set to 1 in +sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the +elapsed time (value type #2) is subtracted from a timestamp, which +cannot yield a valid elapsed time (which is a type #2 value as well). + +To fix this issue, the value of hp->duration must change under the +protection of the sfp->rq_list_lock in sg_rq_end_io(). Since +sg_proc_debug_helper() takes this read lock, the change to srp->done and +srp->header.duration will happen atomically from the perspective of +sg_proc_debug_helper() and the race condition is thus eliminated. + +The second race condition happens between sg_proc_debug_helper() and +sg_new_write(). Even though hp->duration is set to the current time +stamp in sg_add_request() under the write lock's protection, it gets +overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() +to copy struct sg_io_hdr from userspace into kernel space. hp->duration +is set to the start time again in sg_common_write(). If +sg_proc_debug_helper() is called between these two calls, an arbitrary +value set by userspace (usually zero) is used to compute the elapsed +time. + +To fix this issue, hp->duration must be set to the current timestamp +again after get_sg_io_hdr() returns successfully. A small race window +still exists between get_sg_io_hdr() and setting hp->duration, but this +window is only a few instructions wide and does not result in observable +issues in practice, as confirmed by testing. + +Additionally, we fix the format specifier from %d to %u for printing +unsigned int values in sg_proc_debug_helper(). + +Signed-off-by: Michal Rábek +Suggested-by: Tomas Henzl +Tested-by: Changhui Zhong +Reviewed-by: Ewan D. Milne +Reviewed-by: John Meneghini +Reviewed-by: Tomas Henzl +Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sg.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 4d54f2697bb4e..d74bb7b42de89 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -736,6 +736,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, + sg_remove_request(sfp, srp); + return -EFAULT; + } ++ hp->duration = jiffies_to_msecs(jiffies); ++ + if (hp->interface_id != 'S') { + sg_remove_request(sfp, srp); + return -ENOSYS; +@@ -821,7 +823,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, + return -ENODEV; + } + +- hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != '\0' && /* v3 (or later) interface */ + (SG_FLAG_Q_AT_TAIL & hp->flags)) + at_head = 0; +@@ -1343,9 +1344,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + "sg_cmd_done: pack_id=%d, res=0x%x\n", + srp->header.pack_id, result)); + srp->header.resid = resid; +- ms = jiffies_to_msecs(jiffies); +- srp->header.duration = (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; + if (0 != result) { + struct scsi_sense_hdr sshdr; + +@@ -1395,6 +1393,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + done = 0; + } + srp->done = done; ++ ms = jiffies_to_msecs(jiffies); ++ srp->header.duration = (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { +@@ -2523,6 +2524,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + const sg_io_hdr_t *hp; + const char * cp; + unsigned int ms; ++ unsigned int duration; + + k = 0; + list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { +@@ -2560,13 +2562,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " id=%d blen=%d", + srp->header.pack_id, blen); + if (srp->done) +- seq_printf(s, " dur=%d", hp->duration); ++ seq_printf(s, " dur=%u", hp->duration); + else { + ms = jiffies_to_msecs(jiffies); +- seq_printf(s, " t_o/elap=%d/%d", ++ duration = READ_ONCE(hp->duration); ++ if (duration) ++ duration = (ms > duration ? ++ ms - duration : 0); ++ seq_printf(s, " t_o/elap=%u/%u", + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), +- (ms > hp->duration ? ms - hp->duration : 0)); ++ duration); + } + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); +-- +2.51.0 + diff --git a/queue-5.15/series b/queue-5.15/series index eff6734a62..e6732e24c1 100644 --- a/queue-5.15/series +++ b/queue-5.15/series @@ -551,3 +551,8 @@ counter-interrupt-cnt-drop-irqf_no_thread-flag.patch pinctrl-qcom-lpass-lpi-remove-duplicate-assignment-of-of_gpio_n_cells.patch pinctrl-qcom-lpass-lpi-mark-the-gpio-controller-as-sleeping.patch blk-throttle-set-bio_throttled-when-bio-has-been-throttled.patch +powercap-fix-race-condition-in-register_control_type.patch +powercap-fix-sscanf-error-return-value-handling.patch +can-j1939-make-j1939_session_activate-fail-if-device.patch +asoc-fsl_sai-add-missing-registers-to-cache-default.patch +scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch diff --git a/queue-6.1/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch b/queue-6.1/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch new file mode 100644 index 0000000000..f8941ac6f5 --- /dev/null +++ b/queue-6.1/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch @@ -0,0 +1,42 @@ +From 31456b8432f0cd04b7786ba411d0e866002b5326 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 23:38:00 +0300 +Subject: ASoC: amd: yc: Add quirk for Honor MagicBook X16 2025 + +From: Andrew Elantsev + +[ Upstream commit e2cb8ef0372665854fca6fa7b30b20dd35acffeb ] + +Add a DMI quirk for the Honor MagicBook X16 2025 laptop +fixing the issue where the internal microphone was +not detected. + +Signed-off-by: Andrew Elantsev +Link: https://patch.msgid.link/20251210203800.142822-1-elantsew.andrew@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index fce918a089e37..cbb2a1d1a823c 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -521,6 +521,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7UCX"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "HONOR"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"), ++ } ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.1/asoc-fsl_sai-add-missing-registers-to-cache-default.patch b/queue-6.1/asoc-fsl_sai-add-missing-registers-to-cache-default.patch new file mode 100644 index 0000000000..db5fbb60c3 --- /dev/null +++ b/queue-6.1/asoc-fsl_sai-add-missing-registers-to-cache-default.patch @@ -0,0 +1,55 @@ +From dee3582c09210fee903be06d49ba01ca7629b87b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 11:22:45 +0100 +Subject: ASoC: fsl_sai: Add missing registers to cache default + +From: Alexander Stein + +[ Upstream commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb ] + +Drivers does cache sync during runtime resume, setting all writable +registers. Not all writable registers are set in cache default, resulting +in the erorr message: + fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause + unexpected behavior + +Fix this by adding missing writable register defaults. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index f5266be2bbc22..9a5be1d72a907 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -979,6 +979,7 @@ static struct reg_default fsl_sai_reg_defaults_ofs0[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(0), 0}, + {FSL_SAI_RCR2(0), 0}, + {FSL_SAI_RCR3(0), 0}, +@@ -1002,12 +1003,14 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(8), 0}, + {FSL_SAI_RCR2(8), 0}, + {FSL_SAI_RCR3(8), 0}, + {FSL_SAI_RCR4(8), 0}, + {FSL_SAI_RCR5(8), 0}, + {FSL_SAI_RMR, 0}, ++ {FSL_SAI_RTCTL, 0}, + {FSL_SAI_MCTL, 0}, + {FSL_SAI_MDIV, 0}, + }; +-- +2.51.0 + diff --git a/queue-6.1/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch b/queue-6.1/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch new file mode 100644 index 0000000000..f85466450c --- /dev/null +++ b/queue-6.1/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch @@ -0,0 +1,220 @@ +From fd9e3f2f5363412cd8cfe0f639604f39aecc0db4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 20:50:32 -0700 +Subject: bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater + than 4K + +From: Yonghong Song + +[ Upstream commit 4fc012daf9c074772421c904357abf586336b1ca ] + +The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on +arm64 with 64KB page: + xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL + +In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on +when constructing frags, with 64K page size, the frag data_len could +be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail(). + +To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel +can test different page size properly. With the kernel change, the user +space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default +value is 17, so for 4K page, the maximum packet size will be less than 68K. +To test 64K page, a bigger maximum packet size than 68K is desired. So two +different functions are implemented for subtest xdp_adjust_frags_tail_grow. +Depending on different page size, different data input/output sizes are used +to adapt with different page size. + +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20250612035032.2207498-1-yonghong.song@linux.dev +Signed-off-by: Alexei Starovoitov +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 2 +- + .../bpf/prog_tests/xdp_adjust_tail.c | 96 +++++++++++++++++-- + .../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +- + 3 files changed, 97 insertions(+), 9 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 77b386b76d463..939bd0d866aba 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1322,7 +1322,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + headroom -= ctx->data; + } + +- max_data_sz = 4096 - headroom - tailroom; ++ max_data_sz = PAGE_SIZE - headroom - tailroom; + if (size > max_data_sz) { + /* disallow live data mode for jumbo frames */ + if (do_live) +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +index 89366913a251c..df907798d59d3 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +@@ -37,21 +37,26 @@ static void test_xdp_adjust_tail_shrink(void) + bpf_object__close(obj); + } + +-static void test_xdp_adjust_tail_grow(void) ++static void test_xdp_adjust_tail_grow(bool is_64k_pagesize) + { + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + struct bpf_object *obj; +- char buf[4096]; /* avoid segfault: large buf to hold grow results */ ++ char buf[8192]; /* avoid segfault: large buf to hold grow results */ + __u32 expect_sz; + int err, prog_fd; + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, +- .data_size_in = sizeof(pkt_v4), + .data_out = buf, + .data_size_out = sizeof(buf), + .repeat = 1, + ); + ++ /* topts.data_size_in as a special signal to bpf prog */ ++ if (is_64k_pagesize) ++ topts.data_size_in = sizeof(pkt_v4) - 1; ++ else ++ topts.data_size_in = sizeof(pkt_v4); ++ + err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); + if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow")) + return; +@@ -201,7 +206,7 @@ static void test_xdp_adjust_frags_tail_shrink(void) + bpf_object__close(obj); + } + +-static void test_xdp_adjust_frags_tail_grow(void) ++static void test_xdp_adjust_frags_tail_grow_4k(void) + { + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + __u32 exp_size; +@@ -266,16 +271,93 @@ static void test_xdp_adjust_frags_tail_grow(void) + bpf_object__close(obj); + } + ++static void test_xdp_adjust_frags_tail_grow_64k(void) ++{ ++ const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; ++ __u32 exp_size; ++ struct bpf_program *prog; ++ struct bpf_object *obj; ++ int err, i, prog_fd; ++ __u8 *buf; ++ LIBBPF_OPTS(bpf_test_run_opts, topts); ++ ++ obj = bpf_object__open(file); ++ if (libbpf_get_error(obj)) ++ return; ++ ++ prog = bpf_object__next_program(obj, NULL); ++ if (bpf_object__load(obj)) ++ goto out; ++ ++ prog_fd = bpf_program__fd(prog); ++ ++ buf = malloc(262144); ++ if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb")) ++ goto out; ++ ++ /* Test case add 10 bytes to last frag */ ++ memset(buf, 1, 262144); ++ exp_size = 90000 + 10; ++ ++ topts.data_in = buf; ++ topts.data_out = buf; ++ topts.data_size_in = 90000; ++ topts.data_size_out = 262144; ++ err = bpf_prog_test_run_opts(prog_fd, &topts); ++ ++ ASSERT_OK(err, "90Kb+10b"); ++ ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval"); ++ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); ++ ++ for (i = 0; i < 90000; i++) { ++ if (buf[i] != 1) ++ ASSERT_EQ(buf[i], 1, "90Kb+10b-old"); ++ } ++ ++ for (i = 90000; i < 90010; i++) { ++ if (buf[i] != 0) ++ ASSERT_EQ(buf[i], 0, "90Kb+10b-new"); ++ } ++ ++ for (i = 90010; i < 262144; i++) { ++ if (buf[i] != 1) ++ ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched"); ++ } ++ ++ /* Test a too large grow */ ++ memset(buf, 1, 262144); ++ exp_size = 90001; ++ ++ topts.data_in = topts.data_out = buf; ++ topts.data_size_in = 90001; ++ topts.data_size_out = 262144; ++ err = bpf_prog_test_run_opts(prog_fd, &topts); ++ ++ ASSERT_OK(err, "90Kb+10b"); ++ ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval"); ++ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); ++ ++ free(buf); ++out: ++ bpf_object__close(obj); ++} ++ + void test_xdp_adjust_tail(void) + { ++ int page_size = getpagesize(); ++ + if (test__start_subtest("xdp_adjust_tail_shrink")) + test_xdp_adjust_tail_shrink(); + if (test__start_subtest("xdp_adjust_tail_grow")) +- test_xdp_adjust_tail_grow(); ++ test_xdp_adjust_tail_grow(page_size == 65536); + if (test__start_subtest("xdp_adjust_tail_grow2")) + test_xdp_adjust_tail_grow2(); + if (test__start_subtest("xdp_adjust_frags_tail_shrink")) + test_xdp_adjust_frags_tail_shrink(); +- if (test__start_subtest("xdp_adjust_frags_tail_grow")) +- test_xdp_adjust_frags_tail_grow(); ++ if (test__start_subtest("xdp_adjust_frags_tail_grow")) { ++ if (page_size == 65536) ++ test_xdp_adjust_frags_tail_grow_64k(); ++ else ++ test_xdp_adjust_frags_tail_grow_4k(); ++ } + } +diff --git a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +index 53b64c9994500..706a8d4c6e2ca 100644 +--- a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c ++++ b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +@@ -13,7 +13,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) + /* Data length determine test case */ + + if (data_len == 54) { /* sizeof(pkt_v4) */ +- offset = 4096; /* test too large offset */ ++ offset = 4096; /* test too large offset, 4k page size */ ++ } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */ ++ offset = 65536; /* test too large offset, 64k page size */ + } else if (data_len == 74) { /* sizeof(pkt_v6) */ + offset = 40; + } else if (data_len == 64) { +@@ -25,6 +27,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) + offset = 10; + } else if (data_len == 9001) { + offset = 4096; ++ } else if (data_len == 90000) { ++ offset = 10; /* test a small offset, 64k page size */ ++ } else if (data_len == 90001) { ++ offset = 65536; /* test too large offset, 64k page size */ + } else { + return XDP_ABORTED; /* No matching test */ + } +-- +2.51.0 + diff --git a/queue-6.1/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch b/queue-6.1/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch new file mode 100644 index 0000000000..aae3d7146a --- /dev/null +++ b/queue-6.1/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch @@ -0,0 +1,79 @@ +From 3fca0307eee80a040c227ab1c31d600683fad404 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Jan 2026 21:36:48 +0900 +Subject: bpf: Fix reference count leak in bpf_prog_test_run_xdp() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tetsuo Handa + +[ Upstream commit ec69daabe45256f98ac86c651b8ad1b2574489a7 ] + +syzbot is reporting + + unregister_netdevice: waiting for sit0 to become free. Usage count = 2 + +problem. A debug printk() patch found that a refcount is obtained at +xdp_convert_md_to_buff() from bpf_prog_test_run_xdp(). + +According to commit ec94670fcb3b ("bpf: Support specifying ingress via +xdp_md context in BPF_PROG_TEST_RUN"), the refcount obtained by +xdp_convert_md_to_buff() will be released by xdp_convert_buff_to_md(). + +Therefore, we can consider that the error handling path introduced by +commit 1c1949982524 ("bpf: introduce frags support to +bpf_prog_test_run_xdp()") forgot to call xdp_convert_buff_to_md(). + +Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Fixes: 1c1949982524 ("bpf: introduce frags support to bpf_prog_test_run_xdp()") +Signed-off-by: Tetsuo Handa +Reviewed-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/af090e53-9d9b-4412-8acb-957733b3975c@I-love.SAKURA.ne.jp +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 88fdcfb2fdd30..59edba6994c34 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1373,13 +1373,13 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (sinfo->nr_frags == MAX_SKB_FRAGS) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + frag = &sinfo->frags[sinfo->nr_frags++]; +@@ -1392,7 +1392,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (copy_from_user(page_address(page), data_in + size, + data_len)) { + ret = -EFAULT; +- goto out; ++ goto out_put_dev; + } + sinfo->xdp_frags_size += data_len; + size += data_len; +@@ -1407,6 +1407,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + ret = bpf_test_run_xdp_live(prog, &xdp, repeat, batch_size, &duration); + else + ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); ++out_put_dev: + /* We convert the xdp_buff back to an xdp_md before checking the return + * code so the reference count of any held netdevice will be decremented + * even if the test run failed. +-- +2.51.0 + diff --git a/queue-6.1/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch b/queue-6.1/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch new file mode 100644 index 0000000000..c5488e47da --- /dev/null +++ b/queue-6.1/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch @@ -0,0 +1,101 @@ +From 6e40f894e8d0d842cd60b3299c80325410bb8fe8 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:33:53 -0700 +Subject: bpf: Make variables in bpf_prog_test_run_xdp less confusing + +From: Amery Hung + +[ Upstream commit 7eb83bff02ad5e82e8c456c58717ef181c220870 ] + +Change the variable naming in bpf_prog_test_run_xdp() to make the +overall logic less confusing. As different modes were added to the +function over the time, some variables got overloaded, making +it hard to understand and changing the code becomes error-prone. + +Replace "size" with "linear_sz" where it refers to the size of metadata +and data. If "size" refers to input data size, use test.data_size_in +directly. + +Replace "max_data_sz" with "max_linear_sz" to better reflect the fact +that it is the maximum size of metadata and data (i.e., linear_sz). Also, +xdp_rxq.frags_size is always PAGE_SIZE, so just set it directly instead +of subtracting headroom and tailroom and adding them back. + +Signed-off-by: Amery Hung +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250922233356.3356453-6-ameryhung@gmail.com +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 939bd0d866aba..397736cc2d786 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1277,9 +1277,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + { + bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); + u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ u32 retval = 0, duration, max_linear_sz, size; ++ u32 linear_sz = kattr->test.data_size_in; + u32 batch_size = kattr->test.batch_size; +- u32 retval = 0, duration, max_data_sz; +- u32 size = kattr->test.data_size_in; + u32 headroom = XDP_PACKET_HEADROOM; + u32 repeat = kattr->test.repeat; + struct netdev_rx_queue *rxqueue; +@@ -1313,7 +1313,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (ctx) { + /* There can't be user provided data before the meta data */ +- if (ctx->data_meta || ctx->data_end != size || ++ if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) +@@ -1322,30 +1322,30 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + headroom -= ctx->data; + } + +- max_data_sz = PAGE_SIZE - headroom - tailroom; +- if (size > max_data_sz) { +- /* disallow live data mode for jumbo frames */ +- if (do_live) +- goto free_ctx; +- size = max_data_sz; +- } ++ max_linear_sz = PAGE_SIZE - headroom - tailroom; ++ linear_sz = min_t(u32, linear_sz, max_linear_sz); ++ ++ /* disallow live data mode for jumbo frames */ ++ if (do_live && kattr->test.data_size_in > linear_sz) ++ goto free_ctx; + +- data = bpf_test_init(kattr, size, max_data_sz, headroom, tailroom); ++ data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); + if (IS_ERR(data)) { + ret = PTR_ERR(data); + goto free_ctx; + } + + rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0); +- rxqueue->xdp_rxq.frag_size = headroom + max_data_sz + tailroom; ++ rxqueue->xdp_rxq.frag_size = PAGE_SIZE; + xdp_init_buff(&xdp, rxqueue->xdp_rxq.frag_size, &rxqueue->xdp_rxq); +- xdp_prepare_buff(&xdp, data, headroom, size, true); ++ xdp_prepare_buff(&xdp, data, headroom, linear_sz, true); + sinfo = xdp_get_shared_info_from_buff(&xdp); + + ret = xdp_convert_md_to_buff(ctx, &xdp); + if (ret) + goto free_data; + ++ size = linear_sz; + if (unlikely(kattr->test.data_size_in > size)) { + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + +-- +2.51.0 + diff --git a/queue-6.1/bpf-support-specifying-linear-xdp-packet-data-size-f.patch b/queue-6.1/bpf-support-specifying-linear-xdp-packet-data-size-f.patch new file mode 100644 index 0000000000..26284b98b9 --- /dev/null +++ b/queue-6.1/bpf-support-specifying-linear-xdp-packet-data-size-f.patch @@ -0,0 +1,130 @@ +From c108fabecfecd2513626eb1c07e6a65b16c42b99 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:33:54 -0700 +Subject: bpf: Support specifying linear xdp packet data size for + BPF_PROG_TEST_RUN + +From: Amery Hung + +[ Upstream commit fe9544ed1a2e9217b2c5285c3a4ac0dc5a38bd7b ] + +To test bpf_xdp_pull_data(), an xdp packet containing fragments as well +as free linear data area after xdp->data_end needs to be created. +However, bpf_prog_test_run_xdp() always fills the linear area with +data_in before creating fragments, leaving no space to pull data. This +patch will allow users to specify the linear data size through +ctx->data_end. + +Currently, ctx_in->data_end must match data_size_in and will not be the +final ctx->data_end seen by xdp programs. This is because ctx->data_end +is populated according to the xdp_buff passed to test_run. The linear +data area available in an xdp_buff, max_linear_sz, is alawys filled up +before copying data_in into fragments. + +This patch will allow users to specify the size of data that goes into +the linear area. When ctx_in->data_end is different from data_size_in, +only ctx_in->data_end bytes of data will be put into the linear area when +creating the xdp_buff. + +While ctx_in->data_end will be allowed to be different from data_size_in, +it cannot be larger than the data_size_in as there will be no data to +copy from user space. If it is larger than the maximum linear data area +size, the layout suggested by the user will not be honored. Data beyond +max_linear_sz bytes will still be copied into fragments. + +Finally, since it is possible for a NIC to produce a xdp_buff with empty +linear data area, allow it when calling bpf_test_init() from +bpf_prog_test_run_xdp() so that we can test XDP kfuncs with such +xdp_buff. This is done by moving lower-bound check to callers as most of +them already do except bpf_prog_test_run_skb(). The change also fixes a +bug that allows passing an xdp_buff with data < ETH_HLEN. This can +happen when ctx is used and metadata is at least ETH_HLEN. + +Signed-off-by: Amery Hung +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250922233356.3356453-7-ameryhung@gmail.com +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 15 ++++++++++++--- + .../bpf/prog_tests/xdp_context_test_run.c | 4 +--- + 2 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 397736cc2d786..2bc83525986f3 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -768,7 +768,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + void *data; + +- if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) ++ if (user_size > PAGE_SIZE - headroom - tailroom) + return ERR_PTR(-EINVAL); + + size = SKB_DATA_ALIGN(size); +@@ -1097,6 +1097,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, + if (kattr->test.flags || kattr->test.cpu || kattr->test.batch_size) + return -EINVAL; + ++ if (size < ETH_HLEN) ++ return -EINVAL; ++ + data = bpf_test_init(kattr, kattr->test.data_size_in, + size, NET_SKB_PAD + NET_IP_ALIGN, + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); +@@ -1277,7 +1280,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + { + bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); + u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- u32 retval = 0, duration, max_linear_sz, size; ++ u32 retval = 0, meta_sz = 0, duration, max_linear_sz, size; + u32 linear_sz = kattr->test.data_size_in; + u32 batch_size = kattr->test.batch_size; + u32 headroom = XDP_PACKET_HEADROOM; +@@ -1313,13 +1316,16 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (ctx) { + /* There can't be user provided data before the meta data */ +- if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || ++ if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; + /* Meta data is allocated from the headroom */ + headroom -= ctx->data; ++ ++ meta_sz = ctx->data; ++ linear_sz = ctx->data_end; + } + + max_linear_sz = PAGE_SIZE - headroom - tailroom; +@@ -1329,6 +1335,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (do_live && kattr->test.data_size_in > linear_sz) + goto free_ctx; + ++ if (kattr->test.data_size_in - meta_sz < ETH_HLEN) ++ return -EINVAL; ++ + data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); + if (IS_ERR(data)) { + ret = PTR_ERR(data); +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +index ab4952b9fb1d4..eab8625aad3b6 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +@@ -80,9 +80,7 @@ void test_xdp_context_test_run(void) + /* Meta data must be 32 bytes or smaller */ + test_xdp_context_error(prog_fd, opts, 0, 36, sizeof(data), 0, 0, 0); + +- /* Total size of data must match data_end - data_meta */ +- test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), +- sizeof(data) - 1, 0, 0, 0); ++ /* Total size of data must be data_end - data_meta or larger */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), + sizeof(data) + 1, 0, 0, 0); + +-- +2.51.0 + diff --git a/queue-6.1/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch b/queue-6.1/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch new file mode 100644 index 0000000000..8bff6fc8b2 --- /dev/null +++ b/queue-6.1/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch @@ -0,0 +1,87 @@ +From 517debb5bc85ccd8285486d4091d91e9d344b1b5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jan 2026 12:47:45 +0100 +Subject: bpf, test_run: Subtract size of xdp_frame from allowed metadata size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit e558cca217790286e799a8baacd1610bda31b261 ] + +The xdp_frame structure takes up part of the XDP frame headroom, +limiting the size of the metadata. However, in bpf_test_run, we don't +take this into account, which makes it possible for userspace to supply +a metadata size that is too large (taking up the entire headroom). + +If userspace supplies such a large metadata size in live packet mode, +the xdp_update_frame_from_buff() call in xdp_test_run_init_page() call +will fail, after which packet transmission proceeds with an +uninitialised frame structure, leading to the usual Bad Stuff. + +The commit in the Fixes tag fixed a related bug where the second check +in xdp_update_frame_from_buff() could fail, but did not add any +additional constraints on the metadata size. Complete the fix by adding +an additional check on the metadata size. Reorder the checks slightly to +make the logic clearer and add a comment. + +Link: https://lore.kernel.org/r/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn +Fixes: b6f1f780b393 ("bpf, test_run: Fix packet size check for live packet mode") +Reported-by: Yinhao Hu +Reported-by: Kaiyan Mei +Signed-off-by: Toke Høiland-Jørgensen +Reviewed-by: Amery Hung +Link: https://lore.kernel.org/r/20260105114747.1358750-1-toke@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 2bc83525986f3..88fdcfb2fdd30 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1304,8 +1304,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + batch_size = NAPI_POLL_WEIGHT; + else if (batch_size > TEST_XDP_MAX_BATCH) + return -E2BIG; +- +- headroom += sizeof(struct xdp_page_head); + } else if (batch_size) { + return -EINVAL; + } +@@ -1318,16 +1316,26 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + /* There can't be user provided data before the meta data */ + if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || +- unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; +- /* Meta data is allocated from the headroom */ +- headroom -= ctx->data; + + meta_sz = ctx->data; ++ if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame)) ++ goto free_ctx; ++ ++ /* Meta data is allocated from the headroom */ ++ headroom -= meta_sz; + linear_sz = ctx->data_end; + } + ++ /* The xdp_page_head structure takes up space in each page, limiting the ++ * size of the packet data; add the extra size to headroom here to make ++ * sure it's accounted in the length checks below, but not in the ++ * metadata size check above. ++ */ ++ if (do_live) ++ headroom += sizeof(struct xdp_page_head); ++ + max_linear_sz = PAGE_SIZE - headroom - tailroom; + linear_sz = min_t(u32, linear_sz, max_linear_sz); + +-- +2.51.0 + diff --git a/queue-6.1/can-j1939-make-j1939_session_activate-fail-if-device.patch b/queue-6.1/can-j1939-make-j1939_session_activate-fail-if-device.patch new file mode 100644 index 0000000000..7096e2afab --- /dev/null +++ b/queue-6.1/can-j1939-make-j1939_session_activate-fail-if-device.patch @@ -0,0 +1,51 @@ +From adb650481985679cf3c4db1c43f543ee85a4356c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 22:39:59 +0900 +Subject: can: j1939: make j1939_session_activate() fail if device is no longer + registered + +From: Tetsuo Handa + +[ Upstream commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d ] + +syzbot is still reporting + + unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 + +even after commit 93a27b5891b8 ("can: j1939: add missing calls in +NETDEV_UNREGISTER notification handler") was added. A debug printk() patch +found that j1939_session_activate() can succeed even after +j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) +has completed. + +Since j1939_cancel_active_session() is processed with the session list lock +held, checking ndev->reg_state in j1939_session_activate() with the session +list lock held can reliably close the race window. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Signed-off-by: Tetsuo Handa +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index 76d625c668e05..0522c223570c7 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1571,6 +1571,8 @@ int j1939_session_activate(struct j1939_session *session) + if (active) { + j1939_session_put(active); + ret = -EAGAIN; ++ } else if (priv->ndev->reg_state != NETREG_REGISTERED) { ++ ret = -ENODEV; + } else { + WARN_ON_ONCE(session->state != J1939_SESSION_NEW); + list_add_tail(&session->active_session_list_entry, +-- +2.51.0 + diff --git a/queue-6.1/powercap-fix-race-condition-in-register_control_type.patch b/queue-6.1/powercap-fix-race-condition-in-register_control_type.patch new file mode 100644 index 0000000000..dc03ea83f0 --- /dev/null +++ b/queue-6.1/powercap-fix-race-condition-in-register_control_type.patch @@ -0,0 +1,65 @@ +From 72a888c400624d2f6b956dd6eaaf99407e6e452b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 00:32:16 +0530 +Subject: powercap: fix race condition in register_control_type() + +From: Sumeet Pawnikar + +[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] + +The device becomes visible to userspace via device_register() +even before it fully initialized by idr_init(). If userspace +or another thread tries to register a zone immediately after +device_register(), the control_type_valid() will fail because +the control_type is not yet in the list. The IDR is not yet +initialized, so this race condition causes zone registration +failure. + +Move idr_init() and list addition before device_register() +fix the race condition. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject adjustment, empty line added ] +Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index fd475e463d1fa..d7dadcaa3736b 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -624,17 +624,23 @@ struct powercap_control_type *powercap_register_control_type( + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, "%s", name); +- result = device_register(&control_type->dev); +- if (result) { +- put_device(&control_type->dev); +- return ERR_PTR(result); +- } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + ++ result = device_register(&control_type->dev); ++ if (result) { ++ mutex_lock(&powercap_cntrl_list_lock); ++ list_del(&control_type->node); ++ mutex_unlock(&powercap_cntrl_list_lock); ++ ++ idr_destroy(&control_type->idr); ++ put_device(&control_type->dev); ++ return ERR_PTR(result); ++ } ++ + return control_type; + } + EXPORT_SYMBOL_GPL(powercap_register_control_type); +-- +2.51.0 + diff --git a/queue-6.1/powercap-fix-sscanf-error-return-value-handling.patch b/queue-6.1/powercap-fix-sscanf-error-return-value-handling.patch new file mode 100644 index 0000000000..ab156fa22a --- /dev/null +++ b/queue-6.1/powercap-fix-sscanf-error-return-value-handling.patch @@ -0,0 +1,67 @@ +From 2262750d9cfa22c44bd9daff45ae16de29e015a0 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 20:45:48 +0530 +Subject: powercap: fix sscanf() error return value handling + +From: Sumeet Pawnikar + +[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ] + +Fix inconsistent error handling for sscanf() return value check. + +Implicit boolean conversion is used instead of explicit return +value checks. The code checks if (!sscanf(...)) which is incorrect +because: + 1. sscanf returns the number of successfully parsed items + 2. On success, it returns 1 (one item passed) + 3. On failure, it returns 0 or EOF + 4. The check 'if (!sscanf(...))' is wrong because it treats + success (1) as failure + +All occurrences of sscanf() now uses explicit return value check. +With this behavior it returns '-EINVAL' when parsing fails (returns +0 or EOF), and continues when parsing succeeds (returns 1). + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject and changelog edits ] +Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index d7dadcaa3736b..72fa1f5affcea 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -67,7 +67,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -92,7 +92,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -161,7 +161,7 @@ static ssize_t show_constraint_name(struct device *dev, + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-6.1/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch b/queue-6.1/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch new file mode 100644 index 0000000000..29c9e4b1d6 --- /dev/null +++ b/queue-6.1/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch @@ -0,0 +1,152 @@ +From e83c504a134fb9bf11ed967ba61de4db3c61f186 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:08:23 +0100 +Subject: scsi: sg: Fix occasional bogus elapsed time that exceeds timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Rábek + +[ Upstream commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 ] + +A race condition was found in sg_proc_debug_helper(). It was observed on +a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring +/proc/scsi/sg/debug every second. A very large elapsed time would +sometimes appear. This is caused by two race conditions. + +We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 +architecture. A patched kernel was built, and the race condition could +not be observed anymore after the application of this patch. A +reproducer C program utilising the scsi_debug module was also built by +Changhui Zhong and can be viewed here: + +https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c + +The first race happens between the reading of hp->duration in +sg_proc_debug_helper() and request completion in sg_rq_end_io(). The +hp->duration member variable may hold either of two types of +information: + + #1 - The start time of the request. This value is present while + the request is not yet finished. + + #2 - The total execution time of the request (end_time - start_time). + +If sg_proc_debug_helper() executes *after* the value of hp->duration was +changed from #1 to #2, but *before* srp->done is set to 1 in +sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the +elapsed time (value type #2) is subtracted from a timestamp, which +cannot yield a valid elapsed time (which is a type #2 value as well). + +To fix this issue, the value of hp->duration must change under the +protection of the sfp->rq_list_lock in sg_rq_end_io(). Since +sg_proc_debug_helper() takes this read lock, the change to srp->done and +srp->header.duration will happen atomically from the perspective of +sg_proc_debug_helper() and the race condition is thus eliminated. + +The second race condition happens between sg_proc_debug_helper() and +sg_new_write(). Even though hp->duration is set to the current time +stamp in sg_add_request() under the write lock's protection, it gets +overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() +to copy struct sg_io_hdr from userspace into kernel space. hp->duration +is set to the start time again in sg_common_write(). If +sg_proc_debug_helper() is called between these two calls, an arbitrary +value set by userspace (usually zero) is used to compute the elapsed +time. + +To fix this issue, hp->duration must be set to the current timestamp +again after get_sg_io_hdr() returns successfully. A small race window +still exists between get_sg_io_hdr() and setting hp->duration, but this +window is only a few instructions wide and does not result in observable +issues in practice, as confirmed by testing. + +Additionally, we fix the format specifier from %d to %u for printing +unsigned int values in sg_proc_debug_helper(). + +Signed-off-by: Michal Rábek +Suggested-by: Tomas Henzl +Tested-by: Changhui Zhong +Reviewed-by: Ewan D. Milne +Reviewed-by: John Meneghini +Reviewed-by: Tomas Henzl +Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sg.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 7a5d73f89f459..b63f7c09c97a1 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -735,6 +735,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, + sg_remove_request(sfp, srp); + return -EFAULT; + } ++ hp->duration = jiffies_to_msecs(jiffies); ++ + if (hp->interface_id != 'S') { + sg_remove_request(sfp, srp); + return -ENOSYS; +@@ -819,7 +821,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, + return -ENODEV; + } + +- hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != '\0' && /* v3 (or later) interface */ + (SG_FLAG_Q_AT_TAIL & hp->flags)) + at_head = 0; +@@ -1342,9 +1343,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + "sg_cmd_done: pack_id=%d, res=0x%x\n", + srp->header.pack_id, result)); + srp->header.resid = resid; +- ms = jiffies_to_msecs(jiffies); +- srp->header.duration = (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; + if (0 != result) { + struct scsi_sense_hdr sshdr; + +@@ -1393,6 +1391,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + done = 0; + } + srp->done = done; ++ ms = jiffies_to_msecs(jiffies); ++ srp->header.duration = (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { +@@ -2529,6 +2530,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + const sg_io_hdr_t *hp; + const char * cp; + unsigned int ms; ++ unsigned int duration; + + k = 0; + list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { +@@ -2566,13 +2568,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " id=%d blen=%d", + srp->header.pack_id, blen); + if (srp->done) +- seq_printf(s, " dur=%d", hp->duration); ++ seq_printf(s, " dur=%u", hp->duration); + else { + ms = jiffies_to_msecs(jiffies); +- seq_printf(s, " t_o/elap=%d/%d", ++ duration = READ_ONCE(hp->duration); ++ if (duration) ++ duration = (ms > duration ? ++ ms - duration : 0); ++ seq_printf(s, " t_o/elap=%u/%u", + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), +- (ms > hp->duration ? ms - hp->duration : 0)); ++ duration); + } + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); +-- +2.51.0 + diff --git a/queue-6.1/series b/queue-6.1/series index 0eefb78846..ce950af1ed 100644 --- a/queue-6.1/series +++ b/queue-6.1/series @@ -58,3 +58,14 @@ nfsd-provide-locking-for-v4_end_grace.patch nfs-trace-show-timedout-instead-of-0x6e.patch nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch nfsd-remove-nfserr_eagain.patch +bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch +bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch +bpf-support-specifying-linear-xdp-packet-data-size-f.patch +bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch +bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch +powercap-fix-race-condition-in-register_control_type.patch +powercap-fix-sscanf-error-return-value-handling.patch +can-j1939-make-j1939_session_activate-fail-if-device.patch +asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch +asoc-fsl_sai-add-missing-registers-to-cache-default.patch +scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch diff --git a/queue-6.12/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch b/queue-6.12/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch new file mode 100644 index 0000000000..a1470242ee --- /dev/null +++ b/queue-6.12/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch @@ -0,0 +1,37 @@ +From 09ba5b051ff5246df1fd0a7b6c881cc5d0b415e5 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 19:46:58 +0200 +Subject: ALSA: hda/realtek: enable woofer speakers on Medion NM14LNL + +From: Kai Vehmanen + +[ Upstream commit e64826e5e367ad45539ab245b92f009ee165025c ] + +The ALC233 codec on these Medion NM14LNL (SPRCHRGD 14 S2) systems +requires a quirk to enable all speakers. + +Tested-by: davplsm +Link: https://github.com/thesofproject/linux/issues/5611 +Signed-off-by: Kai Vehmanen +Link: https://patch.msgid.link/20251212174658.752641-1-kai.vehmanen@linux.intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/pci/hda/patch_realtek.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c +index 3b754259d2eb6..7b3658e01c95e 100644 +--- a/sound/pci/hda/patch_realtek.c ++++ b/sound/pci/hda/patch_realtek.c +@@ -11350,6 +11350,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1e39, 0xca14, "MEDION NM14LNL", ALC233_FIXUP_MEDION_MTL_SPK), + SND_PCI_QUIRK(0x1ee7, 0x2078, "HONOR BRB-X M1010", ALC2XX_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x2014, 0x800a, "Positivo ARN50", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), +-- +2.51.0 + diff --git a/queue-6.12/alsa-usb-audio-update-for-native-dsd-support-quirks.patch b/queue-6.12/alsa-usb-audio-update-for-native-dsd-support-quirks.patch new file mode 100644 index 0000000000..32e62a2932 --- /dev/null +++ b/queue-6.12/alsa-usb-audio-update-for-native-dsd-support-quirks.patch @@ -0,0 +1,60 @@ +From 816744356c93e5437385a96c91f8729189dce315 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Dec 2025 17:22:21 +0200 +Subject: ALSA: usb-audio: Update for native DSD support quirks + +From: Jussi Laako + +[ Upstream commit da3a7efff64ec0d63af4499eea3a46a2e13b5797 ] + +Maintenance patch for native DSD support. + +Add set of missing device and vendor quirks; TEAC, Esoteric, Luxman and +Musical Fidelity. + +Signed-off-by: Jussi Laako +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20251211152224.1780782-1-jussi@sonarnerd.net +Signed-off-by: Sasha Levin +--- + sound/usb/quirks.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index a74bb3a2f9e03..8fa840df46210 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2225,6 +2225,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_IFACE_DELAY), ++ DEVICE_FLG(0x0644, 0x807d, /* TEAC UD-507 */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | ++ QUIRK_FLAG_IFACE_DELAY), ++ DEVICE_FLG(0x0644, 0x806c, /* Esoteric XD */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | ++ QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ +@@ -2377,6 +2383,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), ++ DEVICE_FLG(0x3255, 0x0000, /* Luxman D-10X */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), + DEVICE_FLG(0x339b, 0x3a07, /* Synaptics HONOR USB-C HEADSET */ + QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ +@@ -2420,6 +2428,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2622, /* IAG Limited devices */ + QUIRK_FLAG_DSD_RAW), ++ VENDOR_FLG(0x2772, /* Musical Fidelity devices */ ++ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x278b, /* Rotel? */ + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x292b, /* Gustard/Ess based devices */ +-- +2.51.0 + diff --git a/queue-6.12/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch b/queue-6.12/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch new file mode 100644 index 0000000000..1fc01b3bcd --- /dev/null +++ b/queue-6.12/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch @@ -0,0 +1,42 @@ +From 545b8197b9aed0c96ee20d28ab6f6608252aad7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 23:38:00 +0300 +Subject: ASoC: amd: yc: Add quirk for Honor MagicBook X16 2025 + +From: Andrew Elantsev + +[ Upstream commit e2cb8ef0372665854fca6fa7b30b20dd35acffeb ] + +Add a DMI quirk for the Honor MagicBook X16 2025 laptop +fixing the issue where the internal microphone was +not detected. + +Signed-off-by: Andrew Elantsev +Link: https://patch.msgid.link/20251210203800.142822-1-elantsew.andrew@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index e362c2865ec13..3dcd29c9ad9b2 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -654,6 +654,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7UCX"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "HONOR"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"), ++ } ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.12/asoc-fsl_sai-add-missing-registers-to-cache-default.patch b/queue-6.12/asoc-fsl_sai-add-missing-registers-to-cache-default.patch new file mode 100644 index 0000000000..4374b0b5da --- /dev/null +++ b/queue-6.12/asoc-fsl_sai-add-missing-registers-to-cache-default.patch @@ -0,0 +1,55 @@ +From a74c5c9acb74c666c3f1351c8384faaff9c75253 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 11:22:45 +0100 +Subject: ASoC: fsl_sai: Add missing registers to cache default + +From: Alexander Stein + +[ Upstream commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb ] + +Drivers does cache sync during runtime resume, setting all writable +registers. Not all writable registers are set in cache default, resulting +in the erorr message: + fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause + unexpected behavior + +Fix this by adding missing writable register defaults. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index bc3bf1c55d3c1..88547621bcdbe 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -1041,6 +1041,7 @@ static struct reg_default fsl_sai_reg_defaults_ofs0[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(0), 0}, + {FSL_SAI_RCR2(0), 0}, + {FSL_SAI_RCR3(0), 0}, +@@ -1064,12 +1065,14 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(8), 0}, + {FSL_SAI_RCR2(8), 0}, + {FSL_SAI_RCR3(8), 0}, + {FSL_SAI_RCR4(8), 0}, + {FSL_SAI_RCR5(8), 0}, + {FSL_SAI_RMR, 0}, ++ {FSL_SAI_RTCTL, 0}, + {FSL_SAI_MCTL, 0}, + {FSL_SAI_MDIV, 0}, + }; +-- +2.51.0 + diff --git a/queue-6.12/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch b/queue-6.12/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch new file mode 100644 index 0000000000..39faf5de8e --- /dev/null +++ b/queue-6.12/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch @@ -0,0 +1,37 @@ +From 39c4877facf86e5b6954f989f8dedcbdbe3bc7cb Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Dec 2025 05:24:00 +0100 +Subject: ata: libata-core: Disable LPM on ST2000DM008-2FR102 + +From: Niklas Cassel + +[ Upstream commit ba624ba88d9f5c3e2ace9bb6697dbeb05b2dbc44 ] + +According to a user report, the ST2000DM008-2FR102 has problems with LPM. + +Reported-by: Emerson Pinter +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220693 +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index 0cb97181d10a9..802967eabc344 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4064,6 +4064,9 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { + { "ST3320[68]13AS", "SD1[5-9]", ATA_QUIRK_NONCQ | + ATA_QUIRK_FIRMWARE_WARN }, + ++ /* Seagate disks with LPM issues */ ++ { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM }, ++ + /* drives which fail FPDMA_AA activation (some may freeze afterwards) + the ST disks also have LPM issues */ + { "ST1000LM024 HN-M101MBB", NULL, ATA_QUIRK_BROKEN_FPDMA_AA | +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch b/queue-6.12/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch new file mode 100644 index 0000000000..dbf4e978ba --- /dev/null +++ b/queue-6.12/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch @@ -0,0 +1,220 @@ +From 397826153b4d3ecad0947be04da95b052ad0a996 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 20:50:32 -0700 +Subject: bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater + than 4K + +From: Yonghong Song + +[ Upstream commit 4fc012daf9c074772421c904357abf586336b1ca ] + +The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on +arm64 with 64KB page: + xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL + +In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on +when constructing frags, with 64K page size, the frag data_len could +be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail(). + +To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel +can test different page size properly. With the kernel change, the user +space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default +value is 17, so for 4K page, the maximum packet size will be less than 68K. +To test 64K page, a bigger maximum packet size than 68K is desired. So two +different functions are implemented for subtest xdp_adjust_frags_tail_grow. +Depending on different page size, different data input/output sizes are used +to adapt with different page size. + +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20250612035032.2207498-1-yonghong.song@linux.dev +Signed-off-by: Alexei Starovoitov +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 2 +- + .../bpf/prog_tests/xdp_adjust_tail.c | 96 +++++++++++++++++-- + .../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +- + 3 files changed, 97 insertions(+), 9 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 8612023bec60d..6418846d6bc65 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1248,7 +1248,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + headroom -= ctx->data; + } + +- max_data_sz = 4096 - headroom - tailroom; ++ max_data_sz = PAGE_SIZE - headroom - tailroom; + if (size > max_data_sz) { + /* disallow live data mode for jumbo frames */ + if (do_live) +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +index 53d6ad8c2257e..df90f5b4cee58 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +@@ -37,21 +37,26 @@ static void test_xdp_adjust_tail_shrink(void) + bpf_object__close(obj); + } + +-static void test_xdp_adjust_tail_grow(void) ++static void test_xdp_adjust_tail_grow(bool is_64k_pagesize) + { + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + struct bpf_object *obj; +- char buf[4096]; /* avoid segfault: large buf to hold grow results */ ++ char buf[8192]; /* avoid segfault: large buf to hold grow results */ + __u32 expect_sz; + int err, prog_fd; + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, +- .data_size_in = sizeof(pkt_v4), + .data_out = buf, + .data_size_out = sizeof(buf), + .repeat = 1, + ); + ++ /* topts.data_size_in as a special signal to bpf prog */ ++ if (is_64k_pagesize) ++ topts.data_size_in = sizeof(pkt_v4) - 1; ++ else ++ topts.data_size_in = sizeof(pkt_v4); ++ + err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); + if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow")) + return; +@@ -206,7 +211,7 @@ static void test_xdp_adjust_frags_tail_shrink(void) + bpf_object__close(obj); + } + +-static void test_xdp_adjust_frags_tail_grow(void) ++static void test_xdp_adjust_frags_tail_grow_4k(void) + { + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + __u32 exp_size; +@@ -271,16 +276,93 @@ static void test_xdp_adjust_frags_tail_grow(void) + bpf_object__close(obj); + } + ++static void test_xdp_adjust_frags_tail_grow_64k(void) ++{ ++ const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; ++ __u32 exp_size; ++ struct bpf_program *prog; ++ struct bpf_object *obj; ++ int err, i, prog_fd; ++ __u8 *buf; ++ LIBBPF_OPTS(bpf_test_run_opts, topts); ++ ++ obj = bpf_object__open(file); ++ if (libbpf_get_error(obj)) ++ return; ++ ++ prog = bpf_object__next_program(obj, NULL); ++ if (bpf_object__load(obj)) ++ goto out; ++ ++ prog_fd = bpf_program__fd(prog); ++ ++ buf = malloc(262144); ++ if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb")) ++ goto out; ++ ++ /* Test case add 10 bytes to last frag */ ++ memset(buf, 1, 262144); ++ exp_size = 90000 + 10; ++ ++ topts.data_in = buf; ++ topts.data_out = buf; ++ topts.data_size_in = 90000; ++ topts.data_size_out = 262144; ++ err = bpf_prog_test_run_opts(prog_fd, &topts); ++ ++ ASSERT_OK(err, "90Kb+10b"); ++ ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval"); ++ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); ++ ++ for (i = 0; i < 90000; i++) { ++ if (buf[i] != 1) ++ ASSERT_EQ(buf[i], 1, "90Kb+10b-old"); ++ } ++ ++ for (i = 90000; i < 90010; i++) { ++ if (buf[i] != 0) ++ ASSERT_EQ(buf[i], 0, "90Kb+10b-new"); ++ } ++ ++ for (i = 90010; i < 262144; i++) { ++ if (buf[i] != 1) ++ ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched"); ++ } ++ ++ /* Test a too large grow */ ++ memset(buf, 1, 262144); ++ exp_size = 90001; ++ ++ topts.data_in = topts.data_out = buf; ++ topts.data_size_in = 90001; ++ topts.data_size_out = 262144; ++ err = bpf_prog_test_run_opts(prog_fd, &topts); ++ ++ ASSERT_OK(err, "90Kb+10b"); ++ ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval"); ++ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); ++ ++ free(buf); ++out: ++ bpf_object__close(obj); ++} ++ + void test_xdp_adjust_tail(void) + { ++ int page_size = getpagesize(); ++ + if (test__start_subtest("xdp_adjust_tail_shrink")) + test_xdp_adjust_tail_shrink(); + if (test__start_subtest("xdp_adjust_tail_grow")) +- test_xdp_adjust_tail_grow(); ++ test_xdp_adjust_tail_grow(page_size == 65536); + if (test__start_subtest("xdp_adjust_tail_grow2")) + test_xdp_adjust_tail_grow2(); + if (test__start_subtest("xdp_adjust_frags_tail_shrink")) + test_xdp_adjust_frags_tail_shrink(); +- if (test__start_subtest("xdp_adjust_frags_tail_grow")) +- test_xdp_adjust_frags_tail_grow(); ++ if (test__start_subtest("xdp_adjust_frags_tail_grow")) { ++ if (page_size == 65536) ++ test_xdp_adjust_frags_tail_grow_64k(); ++ else ++ test_xdp_adjust_frags_tail_grow_4k(); ++ } + } +diff --git a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +index 81bb38d72cedd..e311e206be072 100644 +--- a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c ++++ b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +@@ -17,7 +17,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) + /* Data length determine test case */ + + if (data_len == 54) { /* sizeof(pkt_v4) */ +- offset = 4096; /* test too large offset */ ++ offset = 4096; /* test too large offset, 4k page size */ ++ } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */ ++ offset = 65536; /* test too large offset, 64k page size */ + } else if (data_len == 74) { /* sizeof(pkt_v6) */ + offset = 40; + } else if (data_len == 64) { +@@ -29,6 +31,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) + offset = 10; + } else if (data_len == 9001) { + offset = 4096; ++ } else if (data_len == 90000) { ++ offset = 10; /* test a small offset, 64k page size */ ++ } else if (data_len == 90001) { ++ offset = 65536; /* test too large offset, 64k page size */ + } else { + return XDP_ABORTED; /* No matching test */ + } +-- +2.51.0 + diff --git a/queue-6.12/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch b/queue-6.12/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch new file mode 100644 index 0000000000..bee774f604 --- /dev/null +++ b/queue-6.12/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch @@ -0,0 +1,79 @@ +From 7068de5747c5fbef86a669f541b4d5b23ef256bc Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Jan 2026 21:36:48 +0900 +Subject: bpf: Fix reference count leak in bpf_prog_test_run_xdp() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tetsuo Handa + +[ Upstream commit ec69daabe45256f98ac86c651b8ad1b2574489a7 ] + +syzbot is reporting + + unregister_netdevice: waiting for sit0 to become free. Usage count = 2 + +problem. A debug printk() patch found that a refcount is obtained at +xdp_convert_md_to_buff() from bpf_prog_test_run_xdp(). + +According to commit ec94670fcb3b ("bpf: Support specifying ingress via +xdp_md context in BPF_PROG_TEST_RUN"), the refcount obtained by +xdp_convert_md_to_buff() will be released by xdp_convert_buff_to_md(). + +Therefore, we can consider that the error handling path introduced by +commit 1c1949982524 ("bpf: introduce frags support to +bpf_prog_test_run_xdp()") forgot to call xdp_convert_buff_to_md(). + +Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Fixes: 1c1949982524 ("bpf: introduce frags support to bpf_prog_test_run_xdp()") +Signed-off-by: Tetsuo Handa +Reviewed-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/af090e53-9d9b-4412-8acb-957733b3975c@I-love.SAKURA.ne.jp +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 84ed67a15dee0..5b732c380c223 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1299,13 +1299,13 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (sinfo->nr_frags == MAX_SKB_FRAGS) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + frag = &sinfo->frags[sinfo->nr_frags++]; +@@ -1317,7 +1317,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (copy_from_user(page_address(page), data_in + size, + data_len)) { + ret = -EFAULT; +- goto out; ++ goto out_put_dev; + } + sinfo->xdp_frags_size += data_len; + size += data_len; +@@ -1332,6 +1332,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + ret = bpf_test_run_xdp_live(prog, &xdp, repeat, batch_size, &duration); + else + ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); ++out_put_dev: + /* We convert the xdp_buff back to an xdp_md before checking the return + * code so the reference count of any held netdevice will be decremented + * even if the test run failed. +-- +2.51.0 + diff --git a/queue-6.12/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch b/queue-6.12/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch new file mode 100644 index 0000000000..15c53f2c20 --- /dev/null +++ b/queue-6.12/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch @@ -0,0 +1,101 @@ +From d60fd97ed3aad57e0f37154c37ac49ebf9332ac6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:33:53 -0700 +Subject: bpf: Make variables in bpf_prog_test_run_xdp less confusing + +From: Amery Hung + +[ Upstream commit 7eb83bff02ad5e82e8c456c58717ef181c220870 ] + +Change the variable naming in bpf_prog_test_run_xdp() to make the +overall logic less confusing. As different modes were added to the +function over the time, some variables got overloaded, making +it hard to understand and changing the code becomes error-prone. + +Replace "size" with "linear_sz" where it refers to the size of metadata +and data. If "size" refers to input data size, use test.data_size_in +directly. + +Replace "max_data_sz" with "max_linear_sz" to better reflect the fact +that it is the maximum size of metadata and data (i.e., linear_sz). Also, +xdp_rxq.frags_size is always PAGE_SIZE, so just set it directly instead +of subtracting headroom and tailroom and adding them back. + +Signed-off-by: Amery Hung +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250922233356.3356453-6-ameryhung@gmail.com +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 6418846d6bc65..c8b8ac6ecbc20 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1200,9 +1200,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + { + bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); + u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ u32 retval = 0, duration, max_linear_sz, size; ++ u32 linear_sz = kattr->test.data_size_in; + u32 batch_size = kattr->test.batch_size; +- u32 retval = 0, duration, max_data_sz; +- u32 size = kattr->test.data_size_in; + u32 headroom = XDP_PACKET_HEADROOM; + u32 repeat = kattr->test.repeat; + struct netdev_rx_queue *rxqueue; +@@ -1239,7 +1239,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (ctx) { + /* There can't be user provided data before the meta data */ +- if (ctx->data_meta || ctx->data_end != size || ++ if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) +@@ -1248,30 +1248,30 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + headroom -= ctx->data; + } + +- max_data_sz = PAGE_SIZE - headroom - tailroom; +- if (size > max_data_sz) { +- /* disallow live data mode for jumbo frames */ +- if (do_live) +- goto free_ctx; +- size = max_data_sz; +- } ++ max_linear_sz = PAGE_SIZE - headroom - tailroom; ++ linear_sz = min_t(u32, linear_sz, max_linear_sz); ++ ++ /* disallow live data mode for jumbo frames */ ++ if (do_live && kattr->test.data_size_in > linear_sz) ++ goto free_ctx; + +- data = bpf_test_init(kattr, size, max_data_sz, headroom, tailroom); ++ data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); + if (IS_ERR(data)) { + ret = PTR_ERR(data); + goto free_ctx; + } + + rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0); +- rxqueue->xdp_rxq.frag_size = headroom + max_data_sz + tailroom; ++ rxqueue->xdp_rxq.frag_size = PAGE_SIZE; + xdp_init_buff(&xdp, rxqueue->xdp_rxq.frag_size, &rxqueue->xdp_rxq); +- xdp_prepare_buff(&xdp, data, headroom, size, true); ++ xdp_prepare_buff(&xdp, data, headroom, linear_sz, true); + sinfo = xdp_get_shared_info_from_buff(&xdp); + + ret = xdp_convert_md_to_buff(ctx, &xdp); + if (ret) + goto free_data; + ++ size = linear_sz; + if (unlikely(kattr->test.data_size_in > size)) { + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + +-- +2.51.0 + diff --git a/queue-6.12/bpf-support-specifying-linear-xdp-packet-data-size-f.patch b/queue-6.12/bpf-support-specifying-linear-xdp-packet-data-size-f.patch new file mode 100644 index 0000000000..596c8fa83a --- /dev/null +++ b/queue-6.12/bpf-support-specifying-linear-xdp-packet-data-size-f.patch @@ -0,0 +1,130 @@ +From 9a7d310ce01789d0237a8e8769c62418c3dd351d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:33:54 -0700 +Subject: bpf: Support specifying linear xdp packet data size for + BPF_PROG_TEST_RUN + +From: Amery Hung + +[ Upstream commit fe9544ed1a2e9217b2c5285c3a4ac0dc5a38bd7b ] + +To test bpf_xdp_pull_data(), an xdp packet containing fragments as well +as free linear data area after xdp->data_end needs to be created. +However, bpf_prog_test_run_xdp() always fills the linear area with +data_in before creating fragments, leaving no space to pull data. This +patch will allow users to specify the linear data size through +ctx->data_end. + +Currently, ctx_in->data_end must match data_size_in and will not be the +final ctx->data_end seen by xdp programs. This is because ctx->data_end +is populated according to the xdp_buff passed to test_run. The linear +data area available in an xdp_buff, max_linear_sz, is alawys filled up +before copying data_in into fragments. + +This patch will allow users to specify the size of data that goes into +the linear area. When ctx_in->data_end is different from data_size_in, +only ctx_in->data_end bytes of data will be put into the linear area when +creating the xdp_buff. + +While ctx_in->data_end will be allowed to be different from data_size_in, +it cannot be larger than the data_size_in as there will be no data to +copy from user space. If it is larger than the maximum linear data area +size, the layout suggested by the user will not be honored. Data beyond +max_linear_sz bytes will still be copied into fragments. + +Finally, since it is possible for a NIC to produce a xdp_buff with empty +linear data area, allow it when calling bpf_test_init() from +bpf_prog_test_run_xdp() so that we can test XDP kfuncs with such +xdp_buff. This is done by moving lower-bound check to callers as most of +them already do except bpf_prog_test_run_skb(). The change also fixes a +bug that allows passing an xdp_buff with data < ETH_HLEN. This can +happen when ctx is used and metadata is at least ETH_HLEN. + +Signed-off-by: Amery Hung +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250922233356.3356453-7-ameryhung@gmail.com +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 15 ++++++++++++--- + .../bpf/prog_tests/xdp_context_test_run.c | 4 +--- + 2 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index c8b8ac6ecbc20..318ffd55cf608 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -660,7 +660,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + void *data; + +- if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) ++ if (user_size > PAGE_SIZE - headroom - tailroom) + return ERR_PTR(-EINVAL); + + size = SKB_DATA_ALIGN(size); +@@ -995,6 +995,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, + kattr->test.cpu || kattr->test.batch_size) + return -EINVAL; + ++ if (size < ETH_HLEN) ++ return -EINVAL; ++ + data = bpf_test_init(kattr, kattr->test.data_size_in, + size, NET_SKB_PAD + NET_IP_ALIGN, + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); +@@ -1200,7 +1203,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + { + bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); + u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- u32 retval = 0, duration, max_linear_sz, size; ++ u32 retval = 0, meta_sz = 0, duration, max_linear_sz, size; + u32 linear_sz = kattr->test.data_size_in; + u32 batch_size = kattr->test.batch_size; + u32 headroom = XDP_PACKET_HEADROOM; +@@ -1239,13 +1242,16 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (ctx) { + /* There can't be user provided data before the meta data */ +- if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || ++ if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; + /* Meta data is allocated from the headroom */ + headroom -= ctx->data; ++ ++ meta_sz = ctx->data; ++ linear_sz = ctx->data_end; + } + + max_linear_sz = PAGE_SIZE - headroom - tailroom; +@@ -1255,6 +1261,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (do_live && kattr->test.data_size_in > linear_sz) + goto free_ctx; + ++ if (kattr->test.data_size_in - meta_sz < ETH_HLEN) ++ return -EINVAL; ++ + data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); + if (IS_ERR(data)) { + ret = PTR_ERR(data); +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +index e6a783c7f5db9..cd43d6616dd2d 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +@@ -80,9 +80,7 @@ void test_xdp_context_test_run(void) + /* Meta data must be 255 bytes or smaller */ + test_xdp_context_error(prog_fd, opts, 0, 256, sizeof(data), 0, 0, 0); + +- /* Total size of data must match data_end - data_meta */ +- test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), +- sizeof(data) - 1, 0, 0, 0); ++ /* Total size of data must be data_end - data_meta or larger */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), + sizeof(data) + 1, 0, 0, 0); + +-- +2.51.0 + diff --git a/queue-6.12/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch b/queue-6.12/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch new file mode 100644 index 0000000000..fb7746ae46 --- /dev/null +++ b/queue-6.12/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch @@ -0,0 +1,87 @@ +From eb11da103c4827b47e1d3d177627677270f2633b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jan 2026 12:47:45 +0100 +Subject: bpf, test_run: Subtract size of xdp_frame from allowed metadata size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit e558cca217790286e799a8baacd1610bda31b261 ] + +The xdp_frame structure takes up part of the XDP frame headroom, +limiting the size of the metadata. However, in bpf_test_run, we don't +take this into account, which makes it possible for userspace to supply +a metadata size that is too large (taking up the entire headroom). + +If userspace supplies such a large metadata size in live packet mode, +the xdp_update_frame_from_buff() call in xdp_test_run_init_page() call +will fail, after which packet transmission proceeds with an +uninitialised frame structure, leading to the usual Bad Stuff. + +The commit in the Fixes tag fixed a related bug where the second check +in xdp_update_frame_from_buff() could fail, but did not add any +additional constraints on the metadata size. Complete the fix by adding +an additional check on the metadata size. Reorder the checks slightly to +make the logic clearer and add a comment. + +Link: https://lore.kernel.org/r/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn +Fixes: b6f1f780b393 ("bpf, test_run: Fix packet size check for live packet mode") +Reported-by: Yinhao Hu +Reported-by: Kaiyan Mei +Signed-off-by: Toke Høiland-Jørgensen +Reviewed-by: Amery Hung +Link: https://lore.kernel.org/r/20260105114747.1358750-1-toke@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 318ffd55cf608..84ed67a15dee0 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1230,8 +1230,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + batch_size = NAPI_POLL_WEIGHT; + else if (batch_size > TEST_XDP_MAX_BATCH) + return -E2BIG; +- +- headroom += sizeof(struct xdp_page_head); + } else if (batch_size) { + return -EINVAL; + } +@@ -1244,16 +1242,26 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + /* There can't be user provided data before the meta data */ + if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || +- unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; +- /* Meta data is allocated from the headroom */ +- headroom -= ctx->data; + + meta_sz = ctx->data; ++ if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame)) ++ goto free_ctx; ++ ++ /* Meta data is allocated from the headroom */ ++ headroom -= meta_sz; + linear_sz = ctx->data_end; + } + ++ /* The xdp_page_head structure takes up space in each page, limiting the ++ * size of the packet data; add the extra size to headroom here to make ++ * sure it's accounted in the length checks below, but not in the ++ * metadata size check above. ++ */ ++ if (do_live) ++ headroom += sizeof(struct xdp_page_head); ++ + max_linear_sz = PAGE_SIZE - headroom - tailroom; + linear_sz = min_t(u32, linear_sz, max_linear_sz); + +-- +2.51.0 + diff --git a/queue-6.12/can-j1939-make-j1939_session_activate-fail-if-device.patch b/queue-6.12/can-j1939-make-j1939_session_activate-fail-if-device.patch new file mode 100644 index 0000000000..38128ddc75 --- /dev/null +++ b/queue-6.12/can-j1939-make-j1939_session_activate-fail-if-device.patch @@ -0,0 +1,51 @@ +From b373445628b957c19178ce45da2752391fc9227d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 22:39:59 +0900 +Subject: can: j1939: make j1939_session_activate() fail if device is no longer + registered + +From: Tetsuo Handa + +[ Upstream commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d ] + +syzbot is still reporting + + unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 + +even after commit 93a27b5891b8 ("can: j1939: add missing calls in +NETDEV_UNREGISTER notification handler") was added. A debug printk() patch +found that j1939_session_activate() can succeed even after +j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) +has completed. + +Since j1939_cancel_active_session() is processed with the session list lock +held, checking ndev->reg_state in j1939_session_activate() with the session +list lock held can reliably close the race window. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Signed-off-by: Tetsuo Handa +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index 9b72d118d756d..1186326b0f2e9 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1571,6 +1571,8 @@ int j1939_session_activate(struct j1939_session *session) + if (active) { + j1939_session_put(active); + ret = -EAGAIN; ++ } else if (priv->ndev->reg_state != NETREG_REGISTERED) { ++ ret = -ENODEV; + } else { + WARN_ON_ONCE(session->state != J1939_SESSION_NEW); + list_add_tail(&session->active_session_list_entry, +-- +2.51.0 + diff --git a/queue-6.12/drm-amd-display-fix-dp-no-audio-issue.patch b/queue-6.12/drm-amd-display-fix-dp-no-audio-issue.patch new file mode 100644 index 0000000000..0180d99c2a --- /dev/null +++ b/queue-6.12/drm-amd-display-fix-dp-no-audio-issue.patch @@ -0,0 +1,49 @@ +From 7160d652dee51f3b1f287e21e6f4b1572b7bf56b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:38:31 -0500 +Subject: drm/amd/display: Fix DP no audio issue + +From: Charlene Liu + +[ Upstream commit 3886b198bd6e49c801fe9552fcfbfc387a49fbbc ] + +[why] +need to enable APG_CLOCK_ENABLE enable first +also need to wake up az from D3 before access az block + +Reviewed-by: Swapnil Patel +Signed-off-by: Charlene Liu +Signed-off-by: Chenyu Chen +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit bf5e396957acafd46003318965500914d5f4edfa) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +index 13e7c253ad697..31c7dfff27cbb 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +@@ -1096,13 +1096,13 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) + if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) + num_audio++; + } ++ if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) { ++ /*wake AZ from D3 first before access az endpoint*/ ++ clk_mgr->funcs->enable_pme_wa(clk_mgr); ++ } + + pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); + +- if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) +- /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ +- clk_mgr->funcs->enable_pme_wa(clk_mgr); +- + link_hwss->enable_audio_packet(pipe_ctx); + + if (pipe_ctx->stream_res.audio) +-- +2.51.0 + diff --git a/queue-6.12/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch b/queue-6.12/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch new file mode 100644 index 0000000000..c0374c1d22 --- /dev/null +++ b/queue-6.12/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch @@ -0,0 +1,40 @@ +From 5551c392dd84728e85c218ec061f910d561864c4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 13:57:19 -0500 +Subject: drm/amdkfd: Fix improper NULL termination of queue restore SMI event + string + +From: Brian Kocoloski + +[ Upstream commit 969faea4e9d01787c58bab4d945f7ad82dad222d ] + +Pass character "0" rather than NULL terminator to properly format +queue restoration SMI events. Currently, the NULL terminator precedes +the newline character that is intended to delineate separate events +in the SMI event buffer, which can break userspace parsers. + +Signed-off-by: Brian Kocoloski +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +(cherry picked from commit 6e7143e5e6e21f9d5572e0390f7089e6d53edf3c) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c +index de8b9abf7afcf..592953fe9afc2 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c +@@ -312,7 +312,7 @@ void kfd_smi_event_queue_restore(struct kfd_node *node, pid_t pid) + { + kfd_smi_event_add(pid, node, KFD_SMI_EVENT_QUEUE_RESTORE, + KFD_EVENT_FMT_QUEUE_RESTORE(ktime_get_boottime_ns(), pid, +- node->id, 0)); ++ node->id, '0')); + } + + void kfd_smi_event_queue_restore_rescheduled(struct mm_struct *mm) +-- +2.51.0 + diff --git a/queue-6.12/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch b/queue-6.12/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch new file mode 100644 index 0000000000..f19514ad41 --- /dev/null +++ b/queue-6.12/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch @@ -0,0 +1,44 @@ +From 78b16d035c8ebe6658b622d3d635d66d51e2b6d6 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 21:03:55 +0000 +Subject: net: sfp: extend Potron XGSPON quirk to cover additional EEPROM + variant + +From: Marcus Hughes + +[ Upstream commit 71cfa7c893a05d09e7dc14713b27a8309fd4a2db ] + +Some Potron SFP+ XGSPON ONU sticks are shipped with different EEPROM +vendor ID and vendor name strings, but are otherwise functionally +identical to the existing "Potron SFP+ XGSPON ONU Stick" handled by +sfp_quirk_potron(). + +These modules, including units distributed under the "Better Internet" +branding, use the same UART pin assignment and require the same +TX_FAULT/LOS behaviour and boot delay. Re-use the existing Potron +quirk for this EEPROM variant. + +Signed-off-by: Marcus Hughes +Link: https://patch.msgid.link/20251207210355.333451-1-marcus.hughes@betterinternet.ltd +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/sfp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index f1827a1bd7a59..964aad00dc87c 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -491,6 +491,8 @@ static const struct sfp_quirk sfp_quirks[] = { + SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex, + sfp_fixup_nokia), + ++ SFP_QUIRK_F("BIDB", "X-ONU-SFPP", sfp_fixup_potron), ++ + // FLYPRO SFP-10GT-CS-30M uses Rollball protocol to talk to the PHY. + SFP_QUIRK_F("FLYPRO", "SFP-10GT-CS-30M", sfp_fixup_rollball), + +-- +2.51.0 + diff --git a/queue-6.12/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch b/queue-6.12/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch new file mode 100644 index 0000000000..825b5710d2 --- /dev/null +++ b/queue-6.12/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch @@ -0,0 +1,268 @@ +From 887c9b3aa0c3919e3bd2e76c6bc811746e1db335 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Jul 2024 01:18:25 +0200 +Subject: netfilter: nf_tables: avoid chain re-validation if possible + +From: Florian Westphal + +[ Upstream commit 8e1a1bc4f5a42747c08130b8242ebebd1210b32f ] + +Hamza Mahfooz reports cpu soft lock-ups in +nft_chain_validate(): + + watchdog: BUG: soft lockup - CPU#1 stuck for 27s! [iptables-nft-re:37547] +[..] + RIP: 0010:nft_chain_validate+0xcb/0x110 [nf_tables] +[..] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_table_validate+0x6b/0xb0 [nf_tables] + nf_tables_validate+0x8b/0xa0 [nf_tables] + nf_tables_commit+0x1df/0x1eb0 [nf_tables] +[..] + +Currently nf_tables will traverse the entire table (chain graph), starting +from the entry points (base chains), exploring all possible paths +(chain jumps). But there are cases where we could avoid revalidation. + +Consider: +1 input -> j2 -> j3 +2 input -> j2 -> j3 +3 input -> j1 -> j2 -> j3 + +Then the second rule does not need to revalidate j2, and, by extension j3, +because this was already checked during validation of the first rule. +We need to validate it only for rule 3. + +This is needed because chain loop detection also ensures we do not exceed +the jump stack: Just because we know that j2 is cycle free, its last jump +might now exceed the allowed stack size. We also need to update all +reachable chains with the new largest observed call depth. + +Care has to be taken to revalidate even if the chain depth won't be an +issue: chain validation also ensures that expressions are not called from +invalid base chains. For example, the masquerade expression can only be +called from NAT postrouting base chains. + +Therefore we also need to keep record of the base chain context (type, +hooknum) and revalidate if the chain becomes reachable from a different +hook location. + +Reported-by: Hamza Mahfooz +Closes: https://lore.kernel.org/netfilter-devel/20251118221735.GA5477@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net/ +Tested-by: Hamza Mahfooz +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 34 +++++++++++---- + net/netfilter/nf_tables_api.c | 69 +++++++++++++++++++++++++++++-- + 2 files changed, 91 insertions(+), 12 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index ee550229d4ffa..d440583aa4b24 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -1093,6 +1093,29 @@ struct nft_rule_blob { + __attribute__((aligned(__alignof__(struct nft_rule_dp)))); + }; + ++enum nft_chain_types { ++ NFT_CHAIN_T_DEFAULT = 0, ++ NFT_CHAIN_T_ROUTE, ++ NFT_CHAIN_T_NAT, ++ NFT_CHAIN_T_MAX ++}; ++ ++/** ++ * struct nft_chain_validate_state - validation state ++ * ++ * If a chain is encountered again during table validation it is ++ * possible to avoid revalidation provided the calling context is ++ * compatible. This structure stores relevant calling context of ++ * previous validations. ++ * ++ * @hook_mask: the hook numbers and locations the chain is linked to ++ * @depth: the deepest call chain level the chain is linked to ++ */ ++struct nft_chain_validate_state { ++ u8 hook_mask[NFT_CHAIN_T_MAX]; ++ u8 depth; ++}; ++ + /** + * struct nft_chain - nf_tables chain + * +@@ -1111,6 +1134,7 @@ struct nft_rule_blob { + * @udlen: user data length + * @udata: user data in the chain + * @blob_next: rule blob pointer to the next in the chain ++ * @vstate: validation state + */ + struct nft_chain { + struct nft_rule_blob __rcu *blob_gen_0; +@@ -1130,9 +1154,10 @@ struct nft_chain { + + /* Only used during control plane commit phase: */ + struct nft_rule_blob *blob_next; ++ struct nft_chain_validate_state vstate; + }; + +-int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain); ++int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain); + int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, + const struct nft_set_iter *iter, + struct nft_elem_priv *elem_priv); +@@ -1140,13 +1165,6 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set); + int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); + void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); + +-enum nft_chain_types { +- NFT_CHAIN_T_DEFAULT = 0, +- NFT_CHAIN_T_ROUTE, +- NFT_CHAIN_T_NAT, +- NFT_CHAIN_T_MAX +-}; +- + /** + * struct nft_chain_type - nf_tables chain type info + * +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 6a2b7ce67e7f3..c3613d8e7d725 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -120,6 +120,29 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s + + table->validate_state = new_validate_state; + } ++ ++static bool nft_chain_vstate_valid(const struct nft_ctx *ctx, ++ const struct nft_chain *chain) ++{ ++ const struct nft_base_chain *base_chain; ++ enum nft_chain_types type; ++ u8 hooknum; ++ ++ if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) ++ return false; ++ ++ base_chain = nft_base_chain(ctx->chain); ++ hooknum = base_chain->ops.hooknum; ++ type = base_chain->type->type; ++ ++ /* chain is already validated for this call depth */ ++ if (chain->vstate.depth >= ctx->level && ++ chain->vstate.hook_mask[type] & BIT(hooknum)) ++ return true; ++ ++ return false; ++} ++ + static void nf_tables_trans_destroy_work(struct work_struct *w); + + static void nft_trans_gc_work(struct work_struct *work); +@@ -3898,6 +3921,29 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + nf_tables_rule_destroy(ctx, rule); + } + ++static void nft_chain_vstate_update(const struct nft_ctx *ctx, struct nft_chain *chain) ++{ ++ const struct nft_base_chain *base_chain; ++ enum nft_chain_types type; ++ u8 hooknum; ++ ++ /* ctx->chain must hold the calling base chain. */ ++ if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) { ++ memset(&chain->vstate, 0, sizeof(chain->vstate)); ++ return; ++ } ++ ++ base_chain = nft_base_chain(ctx->chain); ++ hooknum = base_chain->ops.hooknum; ++ type = base_chain->type->type; ++ ++ BUILD_BUG_ON(BIT(NF_INET_NUMHOOKS) > U8_MAX); ++ ++ chain->vstate.hook_mask[type] |= BIT(hooknum); ++ if (chain->vstate.depth < ctx->level) ++ chain->vstate.depth = ctx->level; ++} ++ + /** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain +@@ -3907,15 +3953,25 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + * and set lookups until either the jump limit is hit or all reachable + * chains have been validated. + */ +-int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) ++int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain) + { + struct nft_expr *expr, *last; + struct nft_rule *rule; + int err; + ++ BUILD_BUG_ON(NFT_JUMP_STACK_SIZE > 255); + if (ctx->level == NFT_JUMP_STACK_SIZE) + return -EMLINK; + ++ if (ctx->level > 0) { ++ /* jumps to base chains are not allowed. */ ++ if (nft_is_base_chain(chain)) ++ return -ELOOP; ++ ++ if (nft_chain_vstate_valid(ctx, chain)) ++ return 0; ++ } ++ + list_for_each_entry(rule, &chain->rules, list) { + if (fatal_signal_pending(current)) + return -EINTR; +@@ -3936,6 +3992,7 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + } + } + ++ nft_chain_vstate_update(ctx, chain); + return 0; + } + EXPORT_SYMBOL_GPL(nft_chain_validate); +@@ -3947,7 +4004,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + .net = net, + .family = table->family, + }; +- int err; ++ int err = 0; + + list_for_each_entry(chain, &table->chains, list) { + if (!nft_is_base_chain(chain)) +@@ -3956,12 +4013,16 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + ctx.chain = chain; + err = nft_chain_validate(&ctx, chain); + if (err < 0) +- return err; ++ goto err; + + cond_resched(); + } + +- return 0; ++err: ++ list_for_each_entry(chain, &table->chains, list) ++ memset(&chain->vstate, 0, sizeof(chain->vstate)); ++ ++ return err; + } + + int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, +-- +2.51.0 + diff --git a/queue-6.12/powercap-fix-race-condition-in-register_control_type.patch b/queue-6.12/powercap-fix-race-condition-in-register_control_type.patch new file mode 100644 index 0000000000..29945ad75b --- /dev/null +++ b/queue-6.12/powercap-fix-race-condition-in-register_control_type.patch @@ -0,0 +1,65 @@ +From 087ce4a5e9decb9a917edd7babd5fe62b4c4996f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 00:32:16 +0530 +Subject: powercap: fix race condition in register_control_type() + +From: Sumeet Pawnikar + +[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] + +The device becomes visible to userspace via device_register() +even before it fully initialized by idr_init(). If userspace +or another thread tries to register a zone immediately after +device_register(), the control_type_valid() will fail because +the control_type is not yet in the list. The IDR is not yet +initialized, so this race condition causes zone registration +failure. + +Move idr_init() and list addition before device_register() +fix the race condition. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject adjustment, empty line added ] +Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index 4112a00973382..d14b36b75189d 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type( + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, "%s", name); +- result = device_register(&control_type->dev); +- if (result) { +- put_device(&control_type->dev); +- return ERR_PTR(result); +- } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + ++ result = device_register(&control_type->dev); ++ if (result) { ++ mutex_lock(&powercap_cntrl_list_lock); ++ list_del(&control_type->node); ++ mutex_unlock(&powercap_cntrl_list_lock); ++ ++ idr_destroy(&control_type->idr); ++ put_device(&control_type->dev); ++ return ERR_PTR(result); ++ } ++ + return control_type; + } + EXPORT_SYMBOL_GPL(powercap_register_control_type); +-- +2.51.0 + diff --git a/queue-6.12/powercap-fix-sscanf-error-return-value-handling.patch b/queue-6.12/powercap-fix-sscanf-error-return-value-handling.patch new file mode 100644 index 0000000000..3009014a5a --- /dev/null +++ b/queue-6.12/powercap-fix-sscanf-error-return-value-handling.patch @@ -0,0 +1,67 @@ +From 09e9e16d16a5373991030b1683e84c6d39d42b56 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 20:45:48 +0530 +Subject: powercap: fix sscanf() error return value handling + +From: Sumeet Pawnikar + +[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ] + +Fix inconsistent error handling for sscanf() return value check. + +Implicit boolean conversion is used instead of explicit return +value checks. The code checks if (!sscanf(...)) which is incorrect +because: + 1. sscanf returns the number of successfully parsed items + 2. On success, it returns 1 (one item passed) + 3. On failure, it returns 0 or EOF + 4. The check 'if (!sscanf(...))' is wrong because it treats + success (1) as failure + +All occurrences of sscanf() now uses explicit return value check. +With this behavior it returns '-EINVAL' when parsing fails (returns +0 or EOF), and continues when parsing succeeds (returns 1). + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject and changelog edits ] +Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index d14b36b75189d..1ff369880beb2 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -68,7 +68,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -93,7 +93,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -162,7 +162,7 @@ static ssize_t show_constraint_name(struct device *dev, + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-6.12/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch b/queue-6.12/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch new file mode 100644 index 0000000000..5520ef1c3f --- /dev/null +++ b/queue-6.12/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch @@ -0,0 +1,152 @@ +From ecb9a77cd645ca5e57cadddc6db4774dc5e93772 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:08:23 +0100 +Subject: scsi: sg: Fix occasional bogus elapsed time that exceeds timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Rábek + +[ Upstream commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 ] + +A race condition was found in sg_proc_debug_helper(). It was observed on +a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring +/proc/scsi/sg/debug every second. A very large elapsed time would +sometimes appear. This is caused by two race conditions. + +We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 +architecture. A patched kernel was built, and the race condition could +not be observed anymore after the application of this patch. A +reproducer C program utilising the scsi_debug module was also built by +Changhui Zhong and can be viewed here: + +https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c + +The first race happens between the reading of hp->duration in +sg_proc_debug_helper() and request completion in sg_rq_end_io(). The +hp->duration member variable may hold either of two types of +information: + + #1 - The start time of the request. This value is present while + the request is not yet finished. + + #2 - The total execution time of the request (end_time - start_time). + +If sg_proc_debug_helper() executes *after* the value of hp->duration was +changed from #1 to #2, but *before* srp->done is set to 1 in +sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the +elapsed time (value type #2) is subtracted from a timestamp, which +cannot yield a valid elapsed time (which is a type #2 value as well). + +To fix this issue, the value of hp->duration must change under the +protection of the sfp->rq_list_lock in sg_rq_end_io(). Since +sg_proc_debug_helper() takes this read lock, the change to srp->done and +srp->header.duration will happen atomically from the perspective of +sg_proc_debug_helper() and the race condition is thus eliminated. + +The second race condition happens between sg_proc_debug_helper() and +sg_new_write(). Even though hp->duration is set to the current time +stamp in sg_add_request() under the write lock's protection, it gets +overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() +to copy struct sg_io_hdr from userspace into kernel space. hp->duration +is set to the start time again in sg_common_write(). If +sg_proc_debug_helper() is called between these two calls, an arbitrary +value set by userspace (usually zero) is used to compute the elapsed +time. + +To fix this issue, hp->duration must be set to the current timestamp +again after get_sg_io_hdr() returns successfully. A small race window +still exists between get_sg_io_hdr() and setting hp->duration, but this +window is only a few instructions wide and does not result in observable +issues in practice, as confirmed by testing. + +Additionally, we fix the format specifier from %d to %u for printing +unsigned int values in sg_proc_debug_helper(). + +Signed-off-by: Michal Rábek +Suggested-by: Tomas Henzl +Tested-by: Changhui Zhong +Reviewed-by: Ewan D. Milne +Reviewed-by: John Meneghini +Reviewed-by: Tomas Henzl +Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sg.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 7260a1ebc03d3..53dd461508494 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -731,6 +731,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, + sg_remove_request(sfp, srp); + return -EFAULT; + } ++ hp->duration = jiffies_to_msecs(jiffies); ++ + if (hp->interface_id != 'S') { + sg_remove_request(sfp, srp); + return -ENOSYS; +@@ -815,7 +817,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, + return -ENODEV; + } + +- hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != '\0' && /* v3 (or later) interface */ + (SG_FLAG_Q_AT_TAIL & hp->flags)) + at_head = 0; +@@ -1339,9 +1340,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + "sg_cmd_done: pack_id=%d, res=0x%x\n", + srp->header.pack_id, result)); + srp->header.resid = resid; +- ms = jiffies_to_msecs(jiffies); +- srp->header.duration = (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; + if (0 != result) { + struct scsi_sense_hdr sshdr; + +@@ -1390,6 +1388,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + done = 0; + } + srp->done = done; ++ ms = jiffies_to_msecs(jiffies); ++ srp->header.duration = (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { +@@ -2535,6 +2536,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + const sg_io_hdr_t *hp; + const char * cp; + unsigned int ms; ++ unsigned int duration; + + k = 0; + list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { +@@ -2572,13 +2574,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " id=%d blen=%d", + srp->header.pack_id, blen); + if (srp->done) +- seq_printf(s, " dur=%d", hp->duration); ++ seq_printf(s, " dur=%u", hp->duration); + else { + ms = jiffies_to_msecs(jiffies); +- seq_printf(s, " t_o/elap=%d/%d", ++ duration = READ_ONCE(hp->duration); ++ if (duration) ++ duration = (ms > duration ? ++ ms - duration : 0); ++ seq_printf(s, " t_o/elap=%u/%u", + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), +- (ms > hp->duration ? ms - hp->duration : 0)); ++ duration); + } + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); +-- +2.51.0 + diff --git a/queue-6.12/series b/queue-6.12/series index 9039ae1804..20d18dc4f7 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -94,3 +94,23 @@ btrfs-remove-btrfs_fs_info-sectors_per_page.patch btrfs-truncate-ordered-extent-when-skipping-writeback-past-i_size.patch btrfs-use-variable-for-end-offset-in-extent_writepage_io.patch btrfs-fix-beyond-eof-write-handling.patch +bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch +bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch +bpf-support-specifying-linear-xdp-packet-data-size-f.patch +bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch +bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch +net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch +powercap-fix-race-condition-in-register_control_type.patch +powercap-fix-sscanf-error-return-value-handling.patch +netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch +ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch +drm-amd-display-fix-dp-no-audio-issue.patch +spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch +drm-amdkfd-fix-improper-null-termination-of-queue-re.patch +can-j1939-make-j1939_session_activate-fail-if-device.patch +alsa-usb-audio-update-for-native-dsd-support-quirks.patch +asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch +alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch +asoc-fsl_sai-add-missing-registers-to-cache-default.patch +scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch +spi-cadence-quadspi-prevent-lost-complete-call-durin.patch diff --git a/queue-6.12/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch b/queue-6.12/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch new file mode 100644 index 0000000000..9cebc683d8 --- /dev/null +++ b/queue-6.12/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch @@ -0,0 +1,63 @@ +From 4b0f8d2e44462bd2487e4c2ba1c35f3e1127bb91 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Dec 2025 22:33:04 +0100 +Subject: spi: cadence-quadspi: Prevent lost complete() call during indirect + read + +From: Mateusz Litwin + +[ Upstream commit d67396c9d697041b385d70ff2fd59cb07ae167e8 ] + +A race condition exists between the read loop and IRQ `complete()` call. +An interrupt could call the complete() between the inner loop and +reinit_completion(), potentially losing the completion event and causing +an unnecessary timeout. Moving reinit_completion() before the loop +prevents this. A premature signal will only result in a spurious wakeup +and another wait cycle, which is preferable to waiting for a timeout. + +Signed-off-by: Mateusz Litwin +Link: https://patch.msgid.link/20251218-cqspi_indirect_read_improve-v2-1-396079972f2a@nokia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-cadence-quadspi.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index aca3681d32ea1..e1d64a9a34462 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -758,6 +758,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */ + + while (remaining > 0) { ++ ret = 0; + if (use_irq && + !wait_for_completion_timeout(&cqspi->transfer_complete, + msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) +@@ -770,6 +771,14 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + if (cqspi->slow_sram) + writel(0x0, reg_base + CQSPI_REG_IRQMASK); + ++ /* ++ * Prevent lost interrupt and race condition by reinitializing early. ++ * A spurious wakeup and another wait cycle can occur here, ++ * which is preferable to waiting until timeout if interrupt is lost. ++ */ ++ if (use_irq) ++ reinit_completion(&cqspi->transfer_complete); ++ + bytes_to_read = cqspi_get_rd_sram_level(cqspi); + + if (ret && bytes_to_read == 0) { +@@ -802,7 +811,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + } + + if (use_irq && remaining > 0) { +- reinit_completion(&cqspi->transfer_complete); + if (cqspi->slow_sram) + writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK); + } +-- +2.51.0 + diff --git a/queue-6.12/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch b/queue-6.12/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch new file mode 100644 index 0000000000..1aa0721f41 --- /dev/null +++ b/queue-6.12/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch @@ -0,0 +1,43 @@ +From 539dc8a76a782716e336e47d042f988c4ffb8c07 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Dec 2025 18:10:47 +0800 +Subject: spi: mt65xx: Use IRQF_ONESHOT with threaded IRQ + +From: Fei Shao + +[ Upstream commit 8c04b77f87e6e321ae6acd28ce1de5553916153f ] + +This driver is migrated to use threaded IRQ since commit 5972eb05ca32 +("spi: spi-mt65xx: Use threaded interrupt for non-SPIMEM transfer"), and +we almost always want to disable the interrupt line to avoid excess +interrupts while the threaded handler is processing SPI transfer. +Use IRQF_ONESHOT for that purpose. + +In practice, we see MediaTek devices show SPI transfer timeout errors +when communicating with ChromeOS EC in certain scenarios, and with +IRQF_ONESHOT, the issue goes away. + +Signed-off-by: Fei Shao +Link: https://patch.msgid.link/20251217101131.1975131-1-fshao@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-mt65xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c +index dfee244fc3173..5532ace0b1334 100644 +--- a/drivers/spi/spi-mt65xx.c ++++ b/drivers/spi/spi-mt65xx.c +@@ -1266,7 +1266,7 @@ static int mtk_spi_probe(struct platform_device *pdev) + + ret = devm_request_threaded_irq(dev, irq, mtk_spi_interrupt, + mtk_spi_interrupt_thread, +- IRQF_TRIGGER_NONE, dev_name(dev), host); ++ IRQF_ONESHOT, dev_name(dev), host); + if (ret) + return dev_err_probe(dev, ret, "failed to register irq\n"); + +-- +2.51.0 + diff --git a/queue-6.18/accel-amdxdna-block-running-under-a-hypervisor.patch b/queue-6.18/accel-amdxdna-block-running-under-a-hypervisor.patch new file mode 100644 index 0000000000..98af4c0b1d --- /dev/null +++ b/queue-6.18/accel-amdxdna-block-running-under-a-hypervisor.patch @@ -0,0 +1,49 @@ +From 8de33cbda63a58ddfc0333a937436da26469c170 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 23:44:47 -0600 +Subject: accel/amdxdna: Block running under a hypervisor + +From: Mario Limonciello (AMD) + +[ Upstream commit 7bbf6d15e935abbb3d604c1fa157350e84a26f98 ] + +SVA support is required, which isn't configured by hypervisor +solutions. + +Closes: https://github.com/QubesOS/qubes-issues/issues/10275 +Closes: https://gitlab.freedesktop.org/drm/amd/-/issues/4656 +Reviewed-by: Lizhi Hou +Link: https://patch.msgid.link/20251213054513.87925-1-superm1@kernel.org +Signed-off-by: Mario Limonciello (AMD) +Signed-off-by: Sasha Levin +--- + drivers/accel/amdxdna/aie2_pci.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +diff --git a/drivers/accel/amdxdna/aie2_pci.c b/drivers/accel/amdxdna/aie2_pci.c +index 43f725e1a2d76..6e07793bbeacf 100644 +--- a/drivers/accel/amdxdna/aie2_pci.c ++++ b/drivers/accel/amdxdna/aie2_pci.c +@@ -17,6 +17,7 @@ + #include + #include + #include ++#include + + #include "aie2_msg_priv.h" + #include "aie2_pci.h" +@@ -486,6 +487,11 @@ static int aie2_init(struct amdxdna_dev *xdna) + unsigned long bars = 0; + int i, nvec, ret; + ++ if (!hypervisor_is_type(X86_HYPER_NATIVE)) { ++ XDNA_ERR(xdna, "Running under hypervisor not supported"); ++ return -EINVAL; ++ } ++ + ndev = drmm_kzalloc(&xdna->ddev, sizeof(*ndev), GFP_KERNEL); + if (!ndev) + return -ENOMEM; +-- +2.51.0 + diff --git a/queue-6.18/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch b/queue-6.18/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch new file mode 100644 index 0000000000..0d39b14251 --- /dev/null +++ b/queue-6.18/alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch @@ -0,0 +1,37 @@ +From fc1911ed60c58fd2f45f2e9b4309dc414cb5336d Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 19:46:58 +0200 +Subject: ALSA: hda/realtek: enable woofer speakers on Medion NM14LNL + +From: Kai Vehmanen + +[ Upstream commit e64826e5e367ad45539ab245b92f009ee165025c ] + +The ALC233 codec on these Medion NM14LNL (SPRCHRGD 14 S2) systems +requires a quirk to enable all speakers. + +Tested-by: davplsm +Link: https://github.com/thesofproject/linux/issues/5611 +Signed-off-by: Kai Vehmanen +Link: https://patch.msgid.link/20251212174658.752641-1-kai.vehmanen@linux.intel.com +Signed-off-by: Takashi Iwai +Signed-off-by: Sasha Levin +--- + sound/hda/codecs/realtek/alc269.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/sound/hda/codecs/realtek/alc269.c b/sound/hda/codecs/realtek/alc269.c +index eea8399e32588..eb6197d19078c 100644 +--- a/sound/hda/codecs/realtek/alc269.c ++++ b/sound/hda/codecs/realtek/alc269.c +@@ -7211,6 +7211,7 @@ static const struct hda_quirk alc269_fixup_tbl[] = { + SND_PCI_QUIRK(0x1d72, 0x1901, "RedmiBook 14", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1945, "Redmi G", ALC256_FIXUP_ASUS_HEADSET_MIC), + SND_PCI_QUIRK(0x1d72, 0x1947, "RedmiBook Air", ALC255_FIXUP_XIAOMI_HEADSET_MIC), ++ SND_PCI_QUIRK(0x1e39, 0xca14, "MEDION NM14LNL", ALC233_FIXUP_MEDION_MTL_SPK), + SND_PCI_QUIRK(0x1ee7, 0x2078, "HONOR BRB-X M1010", ALC2XX_FIXUP_HEADSET_MIC), + SND_PCI_QUIRK(0x1f66, 0x0105, "Ayaneo Portable Game Player", ALC287_FIXUP_CS35L41_I2C_2), + SND_PCI_QUIRK(0x2014, 0x800a, "Positivo ARN50", ALC269_FIXUP_LIMIT_INT_MIC_BOOST), +-- +2.51.0 + diff --git a/queue-6.18/alsa-usb-audio-update-for-native-dsd-support-quirks.patch b/queue-6.18/alsa-usb-audio-update-for-native-dsd-support-quirks.patch new file mode 100644 index 0000000000..6dc1141372 --- /dev/null +++ b/queue-6.18/alsa-usb-audio-update-for-native-dsd-support-quirks.patch @@ -0,0 +1,60 @@ +From ac4995d5e99e1dc2a23eda27df1273089c2dd41f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Dec 2025 17:22:21 +0200 +Subject: ALSA: usb-audio: Update for native DSD support quirks + +From: Jussi Laako + +[ Upstream commit da3a7efff64ec0d63af4499eea3a46a2e13b5797 ] + +Maintenance patch for native DSD support. + +Add set of missing device and vendor quirks; TEAC, Esoteric, Luxman and +Musical Fidelity. + +Signed-off-by: Jussi Laako +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20251211152224.1780782-1-jussi@sonarnerd.net +Signed-off-by: Sasha Levin +--- + sound/usb/quirks.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 61bd61ffb1b23..94a8fdc9c6d3c 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2230,6 +2230,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_IFACE_DELAY), ++ DEVICE_FLG(0x0644, 0x807d, /* TEAC UD-507 */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | ++ QUIRK_FLAG_IFACE_DELAY), ++ DEVICE_FLG(0x0644, 0x806c, /* Esoteric XD */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | ++ QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ +@@ -2388,6 +2394,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), ++ DEVICE_FLG(0x3255, 0x0000, /* Luxman D-10X */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), + DEVICE_FLG(0x339b, 0x3a07, /* Synaptics HONOR USB-C HEADSET */ + QUIRK_FLAG_MIXER_PLAYBACK_MIN_MUTE), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ +@@ -2431,6 +2439,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2622, /* IAG Limited devices */ + QUIRK_FLAG_DSD_RAW), ++ VENDOR_FLG(0x2772, /* Musical Fidelity devices */ ++ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x278b, /* Rotel? */ + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x292b, /* Gustard/Ess based devices */ +-- +2.51.0 + diff --git a/queue-6.18/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch b/queue-6.18/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch new file mode 100644 index 0000000000..47d4aa4833 --- /dev/null +++ b/queue-6.18/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch @@ -0,0 +1,42 @@ +From aeac3c459601bc032a460976fa9daed524c66b68 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 23:38:00 +0300 +Subject: ASoC: amd: yc: Add quirk for Honor MagicBook X16 2025 + +From: Andrew Elantsev + +[ Upstream commit e2cb8ef0372665854fca6fa7b30b20dd35acffeb ] + +Add a DMI quirk for the Honor MagicBook X16 2025 laptop +fixing the issue where the internal microphone was +not detected. + +Signed-off-by: Andrew Elantsev +Link: https://patch.msgid.link/20251210203800.142822-1-elantsew.andrew@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index f210a253da9f5..bf4d9d3365617 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -661,6 +661,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7UCX"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "HONOR"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"), ++ } ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.18/asoc-fsl_sai-add-missing-registers-to-cache-default.patch b/queue-6.18/asoc-fsl_sai-add-missing-registers-to-cache-default.patch new file mode 100644 index 0000000000..51c6c54042 --- /dev/null +++ b/queue-6.18/asoc-fsl_sai-add-missing-registers-to-cache-default.patch @@ -0,0 +1,55 @@ +From 318cfa4d7bd6fd611570a9a9eedd71849ccc3923 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 11:22:45 +0100 +Subject: ASoC: fsl_sai: Add missing registers to cache default + +From: Alexander Stein + +[ Upstream commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb ] + +Drivers does cache sync during runtime resume, setting all writable +registers. Not all writable registers are set in cache default, resulting +in the erorr message: + fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause + unexpected behavior + +Fix this by adding missing writable register defaults. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index 86730c2149146..2fa14fbdfe1a8 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -1081,6 +1081,7 @@ static const struct reg_default fsl_sai_reg_defaults_ofs0[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(0), 0}, + {FSL_SAI_RCR2(0), 0}, + {FSL_SAI_RCR3(0), 0}, +@@ -1104,12 +1105,14 @@ static const struct reg_default fsl_sai_reg_defaults_ofs8[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(8), 0}, + {FSL_SAI_RCR2(8), 0}, + {FSL_SAI_RCR3(8), 0}, + {FSL_SAI_RCR4(8), 0}, + {FSL_SAI_RCR5(8), 0}, + {FSL_SAI_RMR, 0}, ++ {FSL_SAI_RTCTL, 0}, + {FSL_SAI_MCTL, 0}, + {FSL_SAI_MDIV, 0}, + }; +-- +2.51.0 + diff --git a/queue-6.18/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch b/queue-6.18/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch new file mode 100644 index 0000000000..9440d882ce --- /dev/null +++ b/queue-6.18/ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch @@ -0,0 +1,37 @@ +From 9894394db81344f4bd10eb30b53824ea1c0e5270 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 9 Dec 2025 05:24:00 +0100 +Subject: ata: libata-core: Disable LPM on ST2000DM008-2FR102 + +From: Niklas Cassel + +[ Upstream commit ba624ba88d9f5c3e2ace9bb6697dbeb05b2dbc44 ] + +According to a user report, the ST2000DM008-2FR102 has problems with LPM. + +Reported-by: Emerson Pinter +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220693 +Signed-off-by: Niklas Cassel +Signed-off-by: Damien Le Moal +Signed-off-by: Sasha Levin +--- + drivers/ata/libata-core.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c +index f48fb63d7e854..1216b4f2eb904 100644 +--- a/drivers/ata/libata-core.c ++++ b/drivers/ata/libata-core.c +@@ -4132,6 +4132,9 @@ static const struct ata_dev_quirks_entry __ata_dev_quirks[] = { + { "ST3320[68]13AS", "SD1[5-9]", ATA_QUIRK_NONCQ | + ATA_QUIRK_FIRMWARE_WARN }, + ++ /* Seagate disks with LPM issues */ ++ { "ST2000DM008-2FR102", NULL, ATA_QUIRK_NOLPM }, ++ + /* drives which fail FPDMA_AA activation (some may freeze afterwards) + the ST disks also have LPM issues */ + { "ST1000LM024 HN-M101MBB", NULL, ATA_QUIRK_BROKEN_FPDMA_AA | +-- +2.51.0 + diff --git a/queue-6.18/block-validate-pi_offset-integrity-limit.patch b/queue-6.18/block-validate-pi_offset-integrity-limit.patch new file mode 100644 index 0000000000..28ef55fcf6 --- /dev/null +++ b/queue-6.18/block-validate-pi_offset-integrity-limit.patch @@ -0,0 +1,42 @@ +From 5fb233960a470fea737cda2cece885f13b2ea383 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 22:34:35 -0700 +Subject: block: validate pi_offset integrity limit + +From: Caleb Sander Mateos + +[ Upstream commit ccb8a3c08adf8121e2afb8e704f007ce99324d79 ] + +The PI tuple must be contained within the metadata value, so validate +that pi_offset + pi_tuple_size <= metadata_size. This guards against +block drivers that report invalid pi_offset values. + +Signed-off-by: Caleb Sander Mateos +Reviewed-by: Christoph Hellwig +Signed-off-by: Jens Axboe +Signed-off-by: Sasha Levin +--- + block/blk-settings.c | 7 +++---- + 1 file changed, 3 insertions(+), 4 deletions(-) + +diff --git a/block/blk-settings.c b/block/blk-settings.c +index d74b13ec8e548..f2c1940fe6f1a 100644 +--- a/block/blk-settings.c ++++ b/block/blk-settings.c +@@ -148,10 +148,9 @@ static int blk_validate_integrity_limits(struct queue_limits *lim) + return -EINVAL; + } + +- if (bi->pi_tuple_size > bi->metadata_size) { +- pr_warn("pi_tuple_size (%u) exceeds metadata_size (%u)\n", +- bi->pi_tuple_size, +- bi->metadata_size); ++ if (bi->pi_offset + bi->pi_tuple_size > bi->metadata_size) { ++ pr_warn("pi_offset (%u) + pi_tuple_size (%u) exceeds metadata_size (%u)\n", ++ bi->pi_offset, bi->pi_tuple_size, bi->metadata_size); + return -EINVAL; + } + +-- +2.51.0 + diff --git a/queue-6.18/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch b/queue-6.18/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch new file mode 100644 index 0000000000..6a8098fef3 --- /dev/null +++ b/queue-6.18/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch @@ -0,0 +1,79 @@ +From f0b4916c66b15c24afe5c236f54173b3501d99a1 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Jan 2026 21:36:48 +0900 +Subject: bpf: Fix reference count leak in bpf_prog_test_run_xdp() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tetsuo Handa + +[ Upstream commit ec69daabe45256f98ac86c651b8ad1b2574489a7 ] + +syzbot is reporting + + unregister_netdevice: waiting for sit0 to become free. Usage count = 2 + +problem. A debug printk() patch found that a refcount is obtained at +xdp_convert_md_to_buff() from bpf_prog_test_run_xdp(). + +According to commit ec94670fcb3b ("bpf: Support specifying ingress via +xdp_md context in BPF_PROG_TEST_RUN"), the refcount obtained by +xdp_convert_md_to_buff() will be released by xdp_convert_buff_to_md(). + +Therefore, we can consider that the error handling path introduced by +commit 1c1949982524 ("bpf: introduce frags support to +bpf_prog_test_run_xdp()") forgot to call xdp_convert_buff_to_md(). + +Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Fixes: 1c1949982524 ("bpf: introduce frags support to bpf_prog_test_run_xdp()") +Signed-off-by: Tetsuo Handa +Reviewed-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/af090e53-9d9b-4412-8acb-957733b3975c@I-love.SAKURA.ne.jp +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 59620fdd5cfda..6b04f47301c1e 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1300,13 +1300,13 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (sinfo->nr_frags == MAX_SKB_FRAGS) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + frag = &sinfo->frags[sinfo->nr_frags++]; +@@ -1318,7 +1318,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (copy_from_user(page_address(page), data_in + size, + data_len)) { + ret = -EFAULT; +- goto out; ++ goto out_put_dev; + } + sinfo->xdp_frags_size += data_len; + size += data_len; +@@ -1333,6 +1333,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + ret = bpf_test_run_xdp_live(prog, &xdp, repeat, batch_size, &duration); + else + ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); ++out_put_dev: + /* We convert the xdp_buff back to an xdp_md before checking the return + * code so the reference count of any held netdevice will be decremented + * even if the test run failed. +-- +2.51.0 + diff --git a/queue-6.18/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch b/queue-6.18/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch new file mode 100644 index 0000000000..fcea9dfbd0 --- /dev/null +++ b/queue-6.18/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch @@ -0,0 +1,87 @@ +From 7083c1dbe851cabae484eeab8832ac313de846c3 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jan 2026 12:47:45 +0100 +Subject: bpf, test_run: Subtract size of xdp_frame from allowed metadata size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit e558cca217790286e799a8baacd1610bda31b261 ] + +The xdp_frame structure takes up part of the XDP frame headroom, +limiting the size of the metadata. However, in bpf_test_run, we don't +take this into account, which makes it possible for userspace to supply +a metadata size that is too large (taking up the entire headroom). + +If userspace supplies such a large metadata size in live packet mode, +the xdp_update_frame_from_buff() call in xdp_test_run_init_page() call +will fail, after which packet transmission proceeds with an +uninitialised frame structure, leading to the usual Bad Stuff. + +The commit in the Fixes tag fixed a related bug where the second check +in xdp_update_frame_from_buff() could fail, but did not add any +additional constraints on the metadata size. Complete the fix by adding +an additional check on the metadata size. Reorder the checks slightly to +make the logic clearer and add a comment. + +Link: https://lore.kernel.org/r/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn +Fixes: b6f1f780b393 ("bpf, test_run: Fix packet size check for live packet mode") +Reported-by: Yinhao Hu +Reported-by: Kaiyan Mei +Signed-off-by: Toke Høiland-Jørgensen +Reviewed-by: Amery Hung +Link: https://lore.kernel.org/r/20260105114747.1358750-1-toke@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 55a79337ac51f..59620fdd5cfda 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1231,8 +1231,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + batch_size = NAPI_POLL_WEIGHT; + else if (batch_size > TEST_XDP_MAX_BATCH) + return -E2BIG; +- +- headroom += sizeof(struct xdp_page_head); + } else if (batch_size) { + return -EINVAL; + } +@@ -1245,16 +1243,26 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + /* There can't be user provided data before the meta data */ + if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || +- unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; +- /* Meta data is allocated from the headroom */ +- headroom -= ctx->data; + + meta_sz = ctx->data; ++ if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame)) ++ goto free_ctx; ++ ++ /* Meta data is allocated from the headroom */ ++ headroom -= meta_sz; + linear_sz = ctx->data_end; + } + ++ /* The xdp_page_head structure takes up space in each page, limiting the ++ * size of the packet data; add the extra size to headroom here to make ++ * sure it's accounted in the length checks below, but not in the ++ * metadata size check above. ++ */ ++ if (do_live) ++ headroom += sizeof(struct xdp_page_head); ++ + max_linear_sz = PAGE_SIZE - headroom - tailroom; + linear_sz = min_t(u32, linear_sz, max_linear_sz); + +-- +2.51.0 + diff --git a/queue-6.18/can-j1939-make-j1939_session_activate-fail-if-device.patch b/queue-6.18/can-j1939-make-j1939_session_activate-fail-if-device.patch new file mode 100644 index 0000000000..ad9ea99223 --- /dev/null +++ b/queue-6.18/can-j1939-make-j1939_session_activate-fail-if-device.patch @@ -0,0 +1,51 @@ +From 44ebcbd13db5e1168a848313d36b1c7907742ead Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 22:39:59 +0900 +Subject: can: j1939: make j1939_session_activate() fail if device is no longer + registered + +From: Tetsuo Handa + +[ Upstream commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d ] + +syzbot is still reporting + + unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 + +even after commit 93a27b5891b8 ("can: j1939: add missing calls in +NETDEV_UNREGISTER notification handler") was added. A debug printk() patch +found that j1939_session_activate() can succeed even after +j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) +has completed. + +Since j1939_cancel_active_session() is processed with the session list lock +held, checking ndev->reg_state in j1939_session_activate() with the session +list lock held can reliably close the race window. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Signed-off-by: Tetsuo Handa +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index fbf5c8001c9df..613a911dda100 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1567,6 +1567,8 @@ int j1939_session_activate(struct j1939_session *session) + if (active) { + j1939_session_put(active); + ret = -EAGAIN; ++ } else if (priv->ndev->reg_state != NETREG_REGISTERED) { ++ ret = -ENODEV; + } else { + WARN_ON_ONCE(session->state != J1939_SESSION_NEW); + list_add_tail(&session->active_session_list_entry, +-- +2.51.0 + diff --git a/queue-6.18/drm-amd-display-fix-dp-no-audio-issue.patch b/queue-6.18/drm-amd-display-fix-dp-no-audio-issue.patch new file mode 100644 index 0000000000..813c1129a4 --- /dev/null +++ b/queue-6.18/drm-amd-display-fix-dp-no-audio-issue.patch @@ -0,0 +1,49 @@ +From 1f5b4486935b3667f088c2a7bd10706ed4f5fa7b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:38:31 -0500 +Subject: drm/amd/display: Fix DP no audio issue + +From: Charlene Liu + +[ Upstream commit 3886b198bd6e49c801fe9552fcfbfc387a49fbbc ] + +[why] +need to enable APG_CLOCK_ENABLE enable first +also need to wake up az from D3 before access az block + +Reviewed-by: Swapnil Patel +Signed-off-by: Charlene Liu +Signed-off-by: Chenyu Chen +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit bf5e396957acafd46003318965500914d5f4edfa) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +index b94fec8347400..39be5a58f837a 100644 +--- a/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c ++++ b/drivers/gpu/drm/amd/display/dc/hwss/dce110/dce110_hwseq.c +@@ -1098,13 +1098,13 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) + if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) + num_audio++; + } ++ if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) { ++ /*wake AZ from D3 first before access az endpoint*/ ++ clk_mgr->funcs->enable_pme_wa(clk_mgr); ++ } + + pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); + +- if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) +- /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ +- clk_mgr->funcs->enable_pme_wa(clk_mgr); +- + link_hwss->enable_audio_packet(pipe_ctx); + + if (pipe_ctx->stream_res.audio) +-- +2.51.0 + diff --git a/queue-6.18/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch b/queue-6.18/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch new file mode 100644 index 0000000000..cdf005c3af --- /dev/null +++ b/queue-6.18/drm-amdkfd-fix-improper-null-termination-of-queue-re.patch @@ -0,0 +1,40 @@ +From 689e0b60c8f5287ed5cf7282613efea5fbec6313 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 20 Nov 2025 13:57:19 -0500 +Subject: drm/amdkfd: Fix improper NULL termination of queue restore SMI event + string + +From: Brian Kocoloski + +[ Upstream commit 969faea4e9d01787c58bab4d945f7ad82dad222d ] + +Pass character "0" rather than NULL terminator to properly format +queue restoration SMI events. Currently, the NULL terminator precedes +the newline character that is intended to delineate separate events +in the SMI event buffer, which can break userspace parsers. + +Signed-off-by: Brian Kocoloski +Reviewed-by: Philip Yang +Signed-off-by: Alex Deucher +(cherry picked from commit 6e7143e5e6e21f9d5572e0390f7089e6d53edf3c) +Signed-off-by: Sasha Levin +--- + drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c +index a499449fcb068..d2bc169e84b0b 100644 +--- a/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c ++++ b/drivers/gpu/drm/amd/amdkfd/kfd_smi_events.c +@@ -312,7 +312,7 @@ void kfd_smi_event_queue_restore(struct kfd_node *node, pid_t pid) + { + kfd_smi_event_add(pid, node, KFD_SMI_EVENT_QUEUE_RESTORE, + KFD_EVENT_FMT_QUEUE_RESTORE(ktime_get_boottime_ns(), pid, +- node->id, 0)); ++ node->id, '0')); + } + + void kfd_smi_event_queue_restore_rescheduled(struct mm_struct *mm) +-- +2.51.0 + diff --git a/queue-6.18/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch b/queue-6.18/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch new file mode 100644 index 0000000000..568e052746 --- /dev/null +++ b/queue-6.18/net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch @@ -0,0 +1,44 @@ +From db026f4d5fabc9e79ae82f2d799041559d324964 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 21:03:55 +0000 +Subject: net: sfp: extend Potron XGSPON quirk to cover additional EEPROM + variant + +From: Marcus Hughes + +[ Upstream commit 71cfa7c893a05d09e7dc14713b27a8309fd4a2db ] + +Some Potron SFP+ XGSPON ONU sticks are shipped with different EEPROM +vendor ID and vendor name strings, but are otherwise functionally +identical to the existing "Potron SFP+ XGSPON ONU Stick" handled by +sfp_quirk_potron(). + +These modules, including units distributed under the "Better Internet" +branding, use the same UART pin assignment and require the same +TX_FAULT/LOS behaviour and boot delay. Re-use the existing Potron +quirk for this EEPROM variant. + +Signed-off-by: Marcus Hughes +Link: https://patch.msgid.link/20251207210355.333451-1-marcus.hughes@betterinternet.ltd +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +--- + drivers/net/phy/sfp.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/drivers/net/phy/sfp.c b/drivers/net/phy/sfp.c +index 6b4dd906b804f..84bef5099dda6 100644 +--- a/drivers/net/phy/sfp.c ++++ b/drivers/net/phy/sfp.c +@@ -497,6 +497,8 @@ static const struct sfp_quirk sfp_quirks[] = { + SFP_QUIRK("ALCATELLUCENT", "3FE46541AA", sfp_quirk_2500basex, + sfp_fixup_nokia), + ++ SFP_QUIRK_F("BIDB", "X-ONU-SFPP", sfp_fixup_potron), ++ + // FLYPRO SFP-10GT-CS-30M uses Rollball protocol to talk to the PHY. + SFP_QUIRK_F("FLYPRO", "SFP-10GT-CS-30M", sfp_fixup_rollball), + +-- +2.51.0 + diff --git a/queue-6.18/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch b/queue-6.18/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch new file mode 100644 index 0000000000..b44c6d7bb4 --- /dev/null +++ b/queue-6.18/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch @@ -0,0 +1,268 @@ +From 93cc70b54e47ff647670e0c1e5c3517ce1948f5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Jul 2024 01:18:25 +0200 +Subject: netfilter: nf_tables: avoid chain re-validation if possible + +From: Florian Westphal + +[ Upstream commit 8e1a1bc4f5a42747c08130b8242ebebd1210b32f ] + +Hamza Mahfooz reports cpu soft lock-ups in +nft_chain_validate(): + + watchdog: BUG: soft lockup - CPU#1 stuck for 27s! [iptables-nft-re:37547] +[..] + RIP: 0010:nft_chain_validate+0xcb/0x110 [nf_tables] +[..] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_table_validate+0x6b/0xb0 [nf_tables] + nf_tables_validate+0x8b/0xa0 [nf_tables] + nf_tables_commit+0x1df/0x1eb0 [nf_tables] +[..] + +Currently nf_tables will traverse the entire table (chain graph), starting +from the entry points (base chains), exploring all possible paths +(chain jumps). But there are cases where we could avoid revalidation. + +Consider: +1 input -> j2 -> j3 +2 input -> j2 -> j3 +3 input -> j1 -> j2 -> j3 + +Then the second rule does not need to revalidate j2, and, by extension j3, +because this was already checked during validation of the first rule. +We need to validate it only for rule 3. + +This is needed because chain loop detection also ensures we do not exceed +the jump stack: Just because we know that j2 is cycle free, its last jump +might now exceed the allowed stack size. We also need to update all +reachable chains with the new largest observed call depth. + +Care has to be taken to revalidate even if the chain depth won't be an +issue: chain validation also ensures that expressions are not called from +invalid base chains. For example, the masquerade expression can only be +called from NAT postrouting base chains. + +Therefore we also need to keep record of the base chain context (type, +hooknum) and revalidate if the chain becomes reachable from a different +hook location. + +Reported-by: Hamza Mahfooz +Closes: https://lore.kernel.org/netfilter-devel/20251118221735.GA5477@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net/ +Tested-by: Hamza Mahfooz +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 34 +++++++++++---- + net/netfilter/nf_tables_api.c | 69 +++++++++++++++++++++++++++++-- + 2 files changed, 91 insertions(+), 12 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index fab7dc73f738c..0e266c2d0e7f0 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -1091,6 +1091,29 @@ struct nft_rule_blob { + __attribute__((aligned(__alignof__(struct nft_rule_dp)))); + }; + ++enum nft_chain_types { ++ NFT_CHAIN_T_DEFAULT = 0, ++ NFT_CHAIN_T_ROUTE, ++ NFT_CHAIN_T_NAT, ++ NFT_CHAIN_T_MAX ++}; ++ ++/** ++ * struct nft_chain_validate_state - validation state ++ * ++ * If a chain is encountered again during table validation it is ++ * possible to avoid revalidation provided the calling context is ++ * compatible. This structure stores relevant calling context of ++ * previous validations. ++ * ++ * @hook_mask: the hook numbers and locations the chain is linked to ++ * @depth: the deepest call chain level the chain is linked to ++ */ ++struct nft_chain_validate_state { ++ u8 hook_mask[NFT_CHAIN_T_MAX]; ++ u8 depth; ++}; ++ + /** + * struct nft_chain - nf_tables chain + * +@@ -1109,6 +1132,7 @@ struct nft_rule_blob { + * @udlen: user data length + * @udata: user data in the chain + * @blob_next: rule blob pointer to the next in the chain ++ * @vstate: validation state + */ + struct nft_chain { + struct nft_rule_blob __rcu *blob_gen_0; +@@ -1128,9 +1152,10 @@ struct nft_chain { + + /* Only used during control plane commit phase: */ + struct nft_rule_blob *blob_next; ++ struct nft_chain_validate_state vstate; + }; + +-int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain); ++int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain); + int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, + const struct nft_set_iter *iter, + struct nft_elem_priv *elem_priv); +@@ -1138,13 +1163,6 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set); + int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); + void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); + +-enum nft_chain_types { +- NFT_CHAIN_T_DEFAULT = 0, +- NFT_CHAIN_T_ROUTE, +- NFT_CHAIN_T_NAT, +- NFT_CHAIN_T_MAX +-}; +- + /** + * struct nft_chain_type - nf_tables chain type info + * +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index a3669acd68a32..3cbf2573b9e90 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -123,6 +123,29 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s + + table->validate_state = new_validate_state; + } ++ ++static bool nft_chain_vstate_valid(const struct nft_ctx *ctx, ++ const struct nft_chain *chain) ++{ ++ const struct nft_base_chain *base_chain; ++ enum nft_chain_types type; ++ u8 hooknum; ++ ++ if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) ++ return false; ++ ++ base_chain = nft_base_chain(ctx->chain); ++ hooknum = base_chain->ops.hooknum; ++ type = base_chain->type->type; ++ ++ /* chain is already validated for this call depth */ ++ if (chain->vstate.depth >= ctx->level && ++ chain->vstate.hook_mask[type] & BIT(hooknum)) ++ return true; ++ ++ return false; ++} ++ + static void nf_tables_trans_destroy_work(struct work_struct *w); + + static void nft_trans_gc_work(struct work_struct *work); +@@ -4079,6 +4102,29 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + nf_tables_rule_destroy(ctx, rule); + } + ++static void nft_chain_vstate_update(const struct nft_ctx *ctx, struct nft_chain *chain) ++{ ++ const struct nft_base_chain *base_chain; ++ enum nft_chain_types type; ++ u8 hooknum; ++ ++ /* ctx->chain must hold the calling base chain. */ ++ if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) { ++ memset(&chain->vstate, 0, sizeof(chain->vstate)); ++ return; ++ } ++ ++ base_chain = nft_base_chain(ctx->chain); ++ hooknum = base_chain->ops.hooknum; ++ type = base_chain->type->type; ++ ++ BUILD_BUG_ON(BIT(NF_INET_NUMHOOKS) > U8_MAX); ++ ++ chain->vstate.hook_mask[type] |= BIT(hooknum); ++ if (chain->vstate.depth < ctx->level) ++ chain->vstate.depth = ctx->level; ++} ++ + /** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain +@@ -4088,15 +4134,25 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + * and set lookups until either the jump limit is hit or all reachable + * chains have been validated. + */ +-int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) ++int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain) + { + struct nft_expr *expr, *last; + struct nft_rule *rule; + int err; + ++ BUILD_BUG_ON(NFT_JUMP_STACK_SIZE > 255); + if (ctx->level == NFT_JUMP_STACK_SIZE) + return -EMLINK; + ++ if (ctx->level > 0) { ++ /* jumps to base chains are not allowed. */ ++ if (nft_is_base_chain(chain)) ++ return -ELOOP; ++ ++ if (nft_chain_vstate_valid(ctx, chain)) ++ return 0; ++ } ++ + list_for_each_entry(rule, &chain->rules, list) { + if (fatal_signal_pending(current)) + return -EINTR; +@@ -4117,6 +4173,7 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + } + } + ++ nft_chain_vstate_update(ctx, chain); + return 0; + } + EXPORT_SYMBOL_GPL(nft_chain_validate); +@@ -4128,7 +4185,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + .net = net, + .family = table->family, + }; +- int err; ++ int err = 0; + + list_for_each_entry(chain, &table->chains, list) { + if (!nft_is_base_chain(chain)) +@@ -4137,12 +4194,16 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + ctx.chain = chain; + err = nft_chain_validate(&ctx, chain); + if (err < 0) +- return err; ++ goto err; + + cond_resched(); + } + +- return 0; ++err: ++ list_for_each_entry(chain, &table->chains, list) ++ memset(&chain->vstate, 0, sizeof(chain->vstate)); ++ ++ return err; + } + + int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, +-- +2.51.0 + diff --git a/queue-6.18/powercap-fix-race-condition-in-register_control_type.patch b/queue-6.18/powercap-fix-race-condition-in-register_control_type.patch new file mode 100644 index 0000000000..5ba54a97c9 --- /dev/null +++ b/queue-6.18/powercap-fix-race-condition-in-register_control_type.patch @@ -0,0 +1,65 @@ +From 17f02614618db4fff4a1c202b9528311c8e47c22 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 00:32:16 +0530 +Subject: powercap: fix race condition in register_control_type() + +From: Sumeet Pawnikar + +[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] + +The device becomes visible to userspace via device_register() +even before it fully initialized by idr_init(). If userspace +or another thread tries to register a zone immediately after +device_register(), the control_type_valid() will fail because +the control_type is not yet in the list. The IDR is not yet +initialized, so this race condition causes zone registration +failure. + +Move idr_init() and list addition before device_register() +fix the race condition. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject adjustment, empty line added ] +Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index 4112a00973382..d14b36b75189d 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type( + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, "%s", name); +- result = device_register(&control_type->dev); +- if (result) { +- put_device(&control_type->dev); +- return ERR_PTR(result); +- } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + ++ result = device_register(&control_type->dev); ++ if (result) { ++ mutex_lock(&powercap_cntrl_list_lock); ++ list_del(&control_type->node); ++ mutex_unlock(&powercap_cntrl_list_lock); ++ ++ idr_destroy(&control_type->idr); ++ put_device(&control_type->dev); ++ return ERR_PTR(result); ++ } ++ + return control_type; + } + EXPORT_SYMBOL_GPL(powercap_register_control_type); +-- +2.51.0 + diff --git a/queue-6.18/powercap-fix-sscanf-error-return-value-handling.patch b/queue-6.18/powercap-fix-sscanf-error-return-value-handling.patch new file mode 100644 index 0000000000..a47918a660 --- /dev/null +++ b/queue-6.18/powercap-fix-sscanf-error-return-value-handling.patch @@ -0,0 +1,67 @@ +From e104b182e36888684939af47ba8ea6c3afafec8b Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 20:45:48 +0530 +Subject: powercap: fix sscanf() error return value handling + +From: Sumeet Pawnikar + +[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ] + +Fix inconsistent error handling for sscanf() return value check. + +Implicit boolean conversion is used instead of explicit return +value checks. The code checks if (!sscanf(...)) which is incorrect +because: + 1. sscanf returns the number of successfully parsed items + 2. On success, it returns 1 (one item passed) + 3. On failure, it returns 0 or EOF + 4. The check 'if (!sscanf(...))' is wrong because it treats + success (1) as failure + +All occurrences of sscanf() now uses explicit return value check. +With this behavior it returns '-EINVAL' when parsing fails (returns +0 or EOF), and continues when parsing succeeds (returns 1). + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject and changelog edits ] +Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index d14b36b75189d..1ff369880beb2 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -68,7 +68,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -93,7 +93,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -162,7 +162,7 @@ static ssize_t show_constraint_name(struct device *dev, + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-6.18/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch b/queue-6.18/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch new file mode 100644 index 0000000000..3a36cfc4bd --- /dev/null +++ b/queue-6.18/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch @@ -0,0 +1,152 @@ +From 6d245054cc30a743a746689303cc2a752f9b6c5f Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:08:23 +0100 +Subject: scsi: sg: Fix occasional bogus elapsed time that exceeds timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Rábek + +[ Upstream commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 ] + +A race condition was found in sg_proc_debug_helper(). It was observed on +a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring +/proc/scsi/sg/debug every second. A very large elapsed time would +sometimes appear. This is caused by two race conditions. + +We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 +architecture. A patched kernel was built, and the race condition could +not be observed anymore after the application of this patch. A +reproducer C program utilising the scsi_debug module was also built by +Changhui Zhong and can be viewed here: + +https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c + +The first race happens between the reading of hp->duration in +sg_proc_debug_helper() and request completion in sg_rq_end_io(). The +hp->duration member variable may hold either of two types of +information: + + #1 - The start time of the request. This value is present while + the request is not yet finished. + + #2 - The total execution time of the request (end_time - start_time). + +If sg_proc_debug_helper() executes *after* the value of hp->duration was +changed from #1 to #2, but *before* srp->done is set to 1 in +sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the +elapsed time (value type #2) is subtracted from a timestamp, which +cannot yield a valid elapsed time (which is a type #2 value as well). + +To fix this issue, the value of hp->duration must change under the +protection of the sfp->rq_list_lock in sg_rq_end_io(). Since +sg_proc_debug_helper() takes this read lock, the change to srp->done and +srp->header.duration will happen atomically from the perspective of +sg_proc_debug_helper() and the race condition is thus eliminated. + +The second race condition happens between sg_proc_debug_helper() and +sg_new_write(). Even though hp->duration is set to the current time +stamp in sg_add_request() under the write lock's protection, it gets +overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() +to copy struct sg_io_hdr from userspace into kernel space. hp->duration +is set to the start time again in sg_common_write(). If +sg_proc_debug_helper() is called between these two calls, an arbitrary +value set by userspace (usually zero) is used to compute the elapsed +time. + +To fix this issue, hp->duration must be set to the current timestamp +again after get_sg_io_hdr() returns successfully. A small race window +still exists between get_sg_io_hdr() and setting hp->duration, but this +window is only a few instructions wide and does not result in observable +issues in practice, as confirmed by testing. + +Additionally, we fix the format specifier from %d to %u for printing +unsigned int values in sg_proc_debug_helper(). + +Signed-off-by: Michal Rábek +Suggested-by: Tomas Henzl +Tested-by: Changhui Zhong +Reviewed-by: Ewan D. Milne +Reviewed-by: John Meneghini +Reviewed-by: Tomas Henzl +Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sg.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index b3af9b78fa123..57fba34832ad1 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -731,6 +731,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, + sg_remove_request(sfp, srp); + return -EFAULT; + } ++ hp->duration = jiffies_to_msecs(jiffies); ++ + if (hp->interface_id != 'S') { + sg_remove_request(sfp, srp); + return -ENOSYS; +@@ -815,7 +817,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, + return -ENODEV; + } + +- hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != '\0' && /* v3 (or later) interface */ + (SG_FLAG_Q_AT_TAIL & hp->flags)) + at_head = 0; +@@ -1338,9 +1339,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + "sg_cmd_done: pack_id=%d, res=0x%x\n", + srp->header.pack_id, result)); + srp->header.resid = resid; +- ms = jiffies_to_msecs(jiffies); +- srp->header.duration = (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; + if (0 != result) { + struct scsi_sense_hdr sshdr; + +@@ -1389,6 +1387,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + done = 0; + } + srp->done = done; ++ ms = jiffies_to_msecs(jiffies); ++ srp->header.duration = (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { +@@ -2533,6 +2534,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + const sg_io_hdr_t *hp; + const char * cp; + unsigned int ms; ++ unsigned int duration; + + k = 0; + list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { +@@ -2570,13 +2572,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " id=%d blen=%d", + srp->header.pack_id, blen); + if (srp->done) +- seq_printf(s, " dur=%d", hp->duration); ++ seq_printf(s, " dur=%u", hp->duration); + else { + ms = jiffies_to_msecs(jiffies); +- seq_printf(s, " t_o/elap=%d/%d", ++ duration = READ_ONCE(hp->duration); ++ if (duration) ++ duration = (ms > duration ? ++ ms - duration : 0); ++ seq_printf(s, " t_o/elap=%u/%u", + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), +- (ms > hp->duration ? ms - hp->duration : 0)); ++ duration); + } + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); +-- +2.51.0 + diff --git a/queue-6.18/series b/queue-6.18/series index c2299e3fb6..57ee21bf50 100644 --- a/queue-6.18/series +++ b/queue-6.18/series @@ -160,3 +160,22 @@ btrfs-fix-beyond-eof-write-handling.patch gpio-mpsse-ensure-worker-is-torn-down.patch gpio-mpsse-add-quirk-support.patch gpio-mpsse-fix-reference-leak-in-gpio_mpsse_probe-error-paths.patch +bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch +bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch +net-sfp-extend-potron-xgspon-quirk-to-cover-addition.patch +powercap-fix-race-condition-in-register_control_type.patch +powercap-fix-sscanf-error-return-value-handling.patch +netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch +ata-libata-core-disable-lpm-on-st2000dm008-2fr102.patch +accel-amdxdna-block-running-under-a-hypervisor.patch +drm-amd-display-fix-dp-no-audio-issue.patch +spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch +drm-amdkfd-fix-improper-null-termination-of-queue-re.patch +can-j1939-make-j1939_session_activate-fail-if-device.patch +block-validate-pi_offset-integrity-limit.patch +alsa-usb-audio-update-for-native-dsd-support-quirks.patch +asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch +alsa-hda-realtek-enable-woofer-speakers-on-medion-nm.patch +asoc-fsl_sai-add-missing-registers-to-cache-default.patch +scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch +spi-cadence-quadspi-prevent-lost-complete-call-durin.patch diff --git a/queue-6.18/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch b/queue-6.18/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch new file mode 100644 index 0000000000..a112e4eb19 --- /dev/null +++ b/queue-6.18/spi-cadence-quadspi-prevent-lost-complete-call-durin.patch @@ -0,0 +1,63 @@ +From 09befc59c500916d6f8bb53814550c2f46d82572 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 18 Dec 2025 22:33:04 +0100 +Subject: spi: cadence-quadspi: Prevent lost complete() call during indirect + read + +From: Mateusz Litwin + +[ Upstream commit d67396c9d697041b385d70ff2fd59cb07ae167e8 ] + +A race condition exists between the read loop and IRQ `complete()` call. +An interrupt could call the complete() between the inner loop and +reinit_completion(), potentially losing the completion event and causing +an unnecessary timeout. Moving reinit_completion() before the loop +prevents this. A premature signal will only result in a spurious wakeup +and another wait cycle, which is preferable to waiting for a timeout. + +Signed-off-by: Mateusz Litwin +Link: https://patch.msgid.link/20251218-cqspi_indirect_read_improve-v2-1-396079972f2a@nokia.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-cadence-quadspi.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-cadence-quadspi.c b/drivers/spi/spi-cadence-quadspi.c +index 3231bdaf9bd06..1cca9d87fbde4 100644 +--- a/drivers/spi/spi-cadence-quadspi.c ++++ b/drivers/spi/spi-cadence-quadspi.c +@@ -769,6 +769,7 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + readl(reg_base + CQSPI_REG_INDIRECTRD); /* Flush posted write. */ + + while (remaining > 0) { ++ ret = 0; + if (use_irq && + !wait_for_completion_timeout(&cqspi->transfer_complete, + msecs_to_jiffies(CQSPI_READ_TIMEOUT_MS))) +@@ -781,6 +782,14 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + if (cqspi->slow_sram) + writel(0x0, reg_base + CQSPI_REG_IRQMASK); + ++ /* ++ * Prevent lost interrupt and race condition by reinitializing early. ++ * A spurious wakeup and another wait cycle can occur here, ++ * which is preferable to waiting until timeout if interrupt is lost. ++ */ ++ if (use_irq) ++ reinit_completion(&cqspi->transfer_complete); ++ + bytes_to_read = cqspi_get_rd_sram_level(cqspi); + + if (ret && bytes_to_read == 0) { +@@ -813,7 +822,6 @@ static int cqspi_indirect_read_execute(struct cqspi_flash_pdata *f_pdata, + } + + if (use_irq && remaining > 0) { +- reinit_completion(&cqspi->transfer_complete); + if (cqspi->slow_sram) + writel(CQSPI_REG_IRQ_WATERMARK, reg_base + CQSPI_REG_IRQMASK); + } +-- +2.51.0 + diff --git a/queue-6.18/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch b/queue-6.18/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch new file mode 100644 index 0000000000..34514e03ad --- /dev/null +++ b/queue-6.18/spi-mt65xx-use-irqf_oneshot-with-threaded-irq.patch @@ -0,0 +1,43 @@ +From cf02709a95ddf11c8ea2672b413096ad73c79225 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 17 Dec 2025 18:10:47 +0800 +Subject: spi: mt65xx: Use IRQF_ONESHOT with threaded IRQ + +From: Fei Shao + +[ Upstream commit 8c04b77f87e6e321ae6acd28ce1de5553916153f ] + +This driver is migrated to use threaded IRQ since commit 5972eb05ca32 +("spi: spi-mt65xx: Use threaded interrupt for non-SPIMEM transfer"), and +we almost always want to disable the interrupt line to avoid excess +interrupts while the threaded handler is processing SPI transfer. +Use IRQF_ONESHOT for that purpose. + +In practice, we see MediaTek devices show SPI transfer timeout errors +when communicating with ChromeOS EC in certain scenarios, and with +IRQF_ONESHOT, the issue goes away. + +Signed-off-by: Fei Shao +Link: https://patch.msgid.link/20251217101131.1975131-1-fshao@chromium.org +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + drivers/spi/spi-mt65xx.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/drivers/spi/spi-mt65xx.c b/drivers/spi/spi-mt65xx.c +index 4b40985af1eaf..90e5813cfdc33 100644 +--- a/drivers/spi/spi-mt65xx.c ++++ b/drivers/spi/spi-mt65xx.c +@@ -1320,7 +1320,7 @@ static int mtk_spi_probe(struct platform_device *pdev) + + ret = devm_request_threaded_irq(dev, irq, mtk_spi_interrupt, + mtk_spi_interrupt_thread, +- IRQF_TRIGGER_NONE, dev_name(dev), host); ++ IRQF_ONESHOT, dev_name(dev), host); + if (ret) + return dev_err_probe(dev, ret, "failed to register irq\n"); + +-- +2.51.0 + diff --git a/queue-6.6/alsa-usb-audio-update-for-native-dsd-support-quirks.patch b/queue-6.6/alsa-usb-audio-update-for-native-dsd-support-quirks.patch new file mode 100644 index 0000000000..7afa2880be --- /dev/null +++ b/queue-6.6/alsa-usb-audio-update-for-native-dsd-support-quirks.patch @@ -0,0 +1,60 @@ +From f46b662f6d6935379f59fbe683d039e25f6c40da Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 11 Dec 2025 17:22:21 +0200 +Subject: ALSA: usb-audio: Update for native DSD support quirks + +From: Jussi Laako + +[ Upstream commit da3a7efff64ec0d63af4499eea3a46a2e13b5797 ] + +Maintenance patch for native DSD support. + +Add set of missing device and vendor quirks; TEAC, Esoteric, Luxman and +Musical Fidelity. + +Signed-off-by: Jussi Laako +Signed-off-by: Takashi Iwai +Link: https://patch.msgid.link/20251211152224.1780782-1-jussi@sonarnerd.net +Signed-off-by: Sasha Levin +--- + sound/usb/quirks.c | 10 ++++++++++ + 1 file changed, 10 insertions(+) + +diff --git a/sound/usb/quirks.c b/sound/usb/quirks.c +index 44274f39d6937..cde5b5c165096 100644 +--- a/sound/usb/quirks.c ++++ b/sound/usb/quirks.c +@@ -2125,6 +2125,12 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + DEVICE_FLG(0x0644, 0x806b, /* TEAC UD-701 */ + QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | + QUIRK_FLAG_IFACE_DELAY), ++ DEVICE_FLG(0x0644, 0x807d, /* TEAC UD-507 */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | ++ QUIRK_FLAG_IFACE_DELAY), ++ DEVICE_FLG(0x0644, 0x806c, /* Esoteric XD */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY | ++ QUIRK_FLAG_IFACE_DELAY), + DEVICE_FLG(0x06f8, 0xb000, /* Hercules DJ Console (Windows Edition) */ + QUIRK_FLAG_IGNORE_CTL_ERROR), + DEVICE_FLG(0x06f8, 0xd002, /* Hercules DJ Console (Macintosh Edition) */ +@@ -2277,6 +2283,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_CTL_MSG_DELAY_1M), + DEVICE_FLG(0x30be, 0x0101, /* Schiit Hel */ + QUIRK_FLAG_IGNORE_CTL_ERROR), ++ DEVICE_FLG(0x3255, 0x0000, /* Luxman D-10X */ ++ QUIRK_FLAG_ITF_USB_DSD_DAC | QUIRK_FLAG_CTL_MSG_DELAY), + DEVICE_FLG(0x339b, 0x3a07, /* Synaptics HONOR USB-C HEADSET */ + QUIRK_FLAG_MIXER_MIN_MUTE), + DEVICE_FLG(0x413c, 0xa506, /* Dell AE515 sound bar */ +@@ -2320,6 +2328,8 @@ static const struct usb_audio_quirk_flags_table quirk_flags_table[] = { + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x2622, /* IAG Limited devices */ + QUIRK_FLAG_DSD_RAW), ++ VENDOR_FLG(0x2772, /* Musical Fidelity devices */ ++ QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x278b, /* Rotel? */ + QUIRK_FLAG_DSD_RAW), + VENDOR_FLG(0x292b, /* Gustard/Ess based devices */ +-- +2.51.0 + diff --git a/queue-6.6/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch b/queue-6.6/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch new file mode 100644 index 0000000000..26bc20eabf --- /dev/null +++ b/queue-6.6/asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch @@ -0,0 +1,42 @@ +From e97f2953a05377ea02611dee3a11bd3431a41b10 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 10 Dec 2025 23:38:00 +0300 +Subject: ASoC: amd: yc: Add quirk for Honor MagicBook X16 2025 + +From: Andrew Elantsev + +[ Upstream commit e2cb8ef0372665854fca6fa7b30b20dd35acffeb ] + +Add a DMI quirk for the Honor MagicBook X16 2025 laptop +fixing the issue where the internal microphone was +not detected. + +Signed-off-by: Andrew Elantsev +Link: https://patch.msgid.link/20251210203800.142822-1-elantsew.andrew@gmail.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/amd/yc/acp6x-mach.c | 7 +++++++ + 1 file changed, 7 insertions(+) + +diff --git a/sound/soc/amd/yc/acp6x-mach.c b/sound/soc/amd/yc/acp6x-mach.c +index 24919e68b3468..54dac6bfc9d18 100644 +--- a/sound/soc/amd/yc/acp6x-mach.c ++++ b/sound/soc/amd/yc/acp6x-mach.c +@@ -654,6 +654,13 @@ static const struct dmi_system_id yc_acp_quirk_table[] = { + DMI_MATCH(DMI_PRODUCT_NAME, "Bravo 15 C7UCX"), + } + }, ++ { ++ .driver_data = &acp6x_card, ++ .matches = { ++ DMI_MATCH(DMI_BOARD_VENDOR, "HONOR"), ++ DMI_MATCH(DMI_PRODUCT_NAME, "GOH-X"), ++ } ++ }, + {} + }; + +-- +2.51.0 + diff --git a/queue-6.6/asoc-fsl_sai-add-missing-registers-to-cache-default.patch b/queue-6.6/asoc-fsl_sai-add-missing-registers-to-cache-default.patch new file mode 100644 index 0000000000..b270de7c4d --- /dev/null +++ b/queue-6.6/asoc-fsl_sai-add-missing-registers-to-cache-default.patch @@ -0,0 +1,55 @@ +From 12b8b9ae98a61193fb60f406e39182a431975f43 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 16 Dec 2025 11:22:45 +0100 +Subject: ASoC: fsl_sai: Add missing registers to cache default + +From: Alexander Stein + +[ Upstream commit 90ed688792a6b7012b3e8a2f858bc3fe7454d0eb ] + +Drivers does cache sync during runtime resume, setting all writable +registers. Not all writable registers are set in cache default, resulting +in the erorr message: + fsl-sai 30c30000.sai: using zero-initialized flat cache, this may cause + unexpected behavior + +Fix this by adding missing writable register defaults. + +Signed-off-by: Alexander Stein +Link: https://patch.msgid.link/20251216102246.676181-1-alexander.stein@ew.tq-group.com +Signed-off-by: Mark Brown +Signed-off-by: Sasha Levin +--- + sound/soc/fsl/fsl_sai.c | 3 +++ + 1 file changed, 3 insertions(+) + +diff --git a/sound/soc/fsl/fsl_sai.c b/sound/soc/fsl/fsl_sai.c +index 0de878d64a3bd..95a502ec3a057 100644 +--- a/sound/soc/fsl/fsl_sai.c ++++ b/sound/soc/fsl/fsl_sai.c +@@ -979,6 +979,7 @@ static struct reg_default fsl_sai_reg_defaults_ofs0[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(0), 0}, + {FSL_SAI_RCR2(0), 0}, + {FSL_SAI_RCR3(0), 0}, +@@ -1002,12 +1003,14 @@ static struct reg_default fsl_sai_reg_defaults_ofs8[] = { + {FSL_SAI_TDR6, 0}, + {FSL_SAI_TDR7, 0}, + {FSL_SAI_TMR, 0}, ++ {FSL_SAI_TTCTL, 0}, + {FSL_SAI_RCR1(8), 0}, + {FSL_SAI_RCR2(8), 0}, + {FSL_SAI_RCR3(8), 0}, + {FSL_SAI_RCR4(8), 0}, + {FSL_SAI_RCR5(8), 0}, + {FSL_SAI_RMR, 0}, ++ {FSL_SAI_RTCTL, 0}, + {FSL_SAI_MCTL, 0}, + {FSL_SAI_MDIV, 0}, + }; +-- +2.51.0 + diff --git a/queue-6.6/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch b/queue-6.6/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch new file mode 100644 index 0000000000..9805fe23b0 --- /dev/null +++ b/queue-6.6/bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch @@ -0,0 +1,220 @@ +From 8370cf3db0d1361d73add5efb7a5adc9f26ae627 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Wed, 11 Jun 2025 20:50:32 -0700 +Subject: bpf: Fix an issue in bpf_prog_test_run_xdp when page size greater + than 4K + +From: Yonghong Song + +[ Upstream commit 4fc012daf9c074772421c904357abf586336b1ca ] + +The bpf selftest xdp_adjust_tail/xdp_adjust_frags_tail_grow failed on +arm64 with 64KB page: + xdp_adjust_tail/xdp_adjust_frags_tail_grow:FAIL + +In bpf_prog_test_run_xdp(), the xdp->frame_sz is set to 4K, but later on +when constructing frags, with 64K page size, the frag data_len could +be more than 4K. This will cause problems in bpf_xdp_frags_increase_tail(). + +To fix the failure, the xdp->frame_sz is set to be PAGE_SIZE so kernel +can test different page size properly. With the kernel change, the user +space and bpf prog needs adjustment. Currently, the MAX_SKB_FRAGS default +value is 17, so for 4K page, the maximum packet size will be less than 68K. +To test 64K page, a bigger maximum packet size than 68K is desired. So two +different functions are implemented for subtest xdp_adjust_frags_tail_grow. +Depending on different page size, different data input/output sizes are used +to adapt with different page size. + +Signed-off-by: Yonghong Song +Link: https://lore.kernel.org/r/20250612035032.2207498-1-yonghong.song@linux.dev +Signed-off-by: Alexei Starovoitov +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 2 +- + .../bpf/prog_tests/xdp_adjust_tail.c | 96 +++++++++++++++++-- + .../bpf/progs/test_xdp_adjust_tail_grow.c | 8 +- + 3 files changed, 97 insertions(+), 9 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 73fb9db55798c..373ccb243545f 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1192,7 +1192,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + headroom -= ctx->data; + } + +- max_data_sz = 4096 - headroom - tailroom; ++ max_data_sz = PAGE_SIZE - headroom - tailroom; + if (size > max_data_sz) { + /* disallow live data mode for jumbo frames */ + if (do_live) +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +index 53d6ad8c2257e..df90f5b4cee58 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_adjust_tail.c +@@ -37,21 +37,26 @@ static void test_xdp_adjust_tail_shrink(void) + bpf_object__close(obj); + } + +-static void test_xdp_adjust_tail_grow(void) ++static void test_xdp_adjust_tail_grow(bool is_64k_pagesize) + { + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + struct bpf_object *obj; +- char buf[4096]; /* avoid segfault: large buf to hold grow results */ ++ char buf[8192]; /* avoid segfault: large buf to hold grow results */ + __u32 expect_sz; + int err, prog_fd; + LIBBPF_OPTS(bpf_test_run_opts, topts, + .data_in = &pkt_v4, +- .data_size_in = sizeof(pkt_v4), + .data_out = buf, + .data_size_out = sizeof(buf), + .repeat = 1, + ); + ++ /* topts.data_size_in as a special signal to bpf prog */ ++ if (is_64k_pagesize) ++ topts.data_size_in = sizeof(pkt_v4) - 1; ++ else ++ topts.data_size_in = sizeof(pkt_v4); ++ + err = bpf_prog_test_load(file, BPF_PROG_TYPE_XDP, &obj, &prog_fd); + if (!ASSERT_OK(err, "test_xdp_adjust_tail_grow")) + return; +@@ -206,7 +211,7 @@ static void test_xdp_adjust_frags_tail_shrink(void) + bpf_object__close(obj); + } + +-static void test_xdp_adjust_frags_tail_grow(void) ++static void test_xdp_adjust_frags_tail_grow_4k(void) + { + const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; + __u32 exp_size; +@@ -271,16 +276,93 @@ static void test_xdp_adjust_frags_tail_grow(void) + bpf_object__close(obj); + } + ++static void test_xdp_adjust_frags_tail_grow_64k(void) ++{ ++ const char *file = "./test_xdp_adjust_tail_grow.bpf.o"; ++ __u32 exp_size; ++ struct bpf_program *prog; ++ struct bpf_object *obj; ++ int err, i, prog_fd; ++ __u8 *buf; ++ LIBBPF_OPTS(bpf_test_run_opts, topts); ++ ++ obj = bpf_object__open(file); ++ if (libbpf_get_error(obj)) ++ return; ++ ++ prog = bpf_object__next_program(obj, NULL); ++ if (bpf_object__load(obj)) ++ goto out; ++ ++ prog_fd = bpf_program__fd(prog); ++ ++ buf = malloc(262144); ++ if (!ASSERT_OK_PTR(buf, "alloc buf 256Kb")) ++ goto out; ++ ++ /* Test case add 10 bytes to last frag */ ++ memset(buf, 1, 262144); ++ exp_size = 90000 + 10; ++ ++ topts.data_in = buf; ++ topts.data_out = buf; ++ topts.data_size_in = 90000; ++ topts.data_size_out = 262144; ++ err = bpf_prog_test_run_opts(prog_fd, &topts); ++ ++ ASSERT_OK(err, "90Kb+10b"); ++ ASSERT_EQ(topts.retval, XDP_TX, "90Kb+10b retval"); ++ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); ++ ++ for (i = 0; i < 90000; i++) { ++ if (buf[i] != 1) ++ ASSERT_EQ(buf[i], 1, "90Kb+10b-old"); ++ } ++ ++ for (i = 90000; i < 90010; i++) { ++ if (buf[i] != 0) ++ ASSERT_EQ(buf[i], 0, "90Kb+10b-new"); ++ } ++ ++ for (i = 90010; i < 262144; i++) { ++ if (buf[i] != 1) ++ ASSERT_EQ(buf[i], 1, "90Kb+10b-untouched"); ++ } ++ ++ /* Test a too large grow */ ++ memset(buf, 1, 262144); ++ exp_size = 90001; ++ ++ topts.data_in = topts.data_out = buf; ++ topts.data_size_in = 90001; ++ topts.data_size_out = 262144; ++ err = bpf_prog_test_run_opts(prog_fd, &topts); ++ ++ ASSERT_OK(err, "90Kb+10b"); ++ ASSERT_EQ(topts.retval, XDP_DROP, "90Kb+10b retval"); ++ ASSERT_EQ(topts.data_size_out, exp_size, "90Kb+10b size"); ++ ++ free(buf); ++out: ++ bpf_object__close(obj); ++} ++ + void test_xdp_adjust_tail(void) + { ++ int page_size = getpagesize(); ++ + if (test__start_subtest("xdp_adjust_tail_shrink")) + test_xdp_adjust_tail_shrink(); + if (test__start_subtest("xdp_adjust_tail_grow")) +- test_xdp_adjust_tail_grow(); ++ test_xdp_adjust_tail_grow(page_size == 65536); + if (test__start_subtest("xdp_adjust_tail_grow2")) + test_xdp_adjust_tail_grow2(); + if (test__start_subtest("xdp_adjust_frags_tail_shrink")) + test_xdp_adjust_frags_tail_shrink(); +- if (test__start_subtest("xdp_adjust_frags_tail_grow")) +- test_xdp_adjust_frags_tail_grow(); ++ if (test__start_subtest("xdp_adjust_frags_tail_grow")) { ++ if (page_size == 65536) ++ test_xdp_adjust_frags_tail_grow_64k(); ++ else ++ test_xdp_adjust_frags_tail_grow_4k(); ++ } + } +diff --git a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +index 81bb38d72cedd..e311e206be072 100644 +--- a/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c ++++ b/tools/testing/selftests/bpf/progs/test_xdp_adjust_tail_grow.c +@@ -17,7 +17,9 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) + /* Data length determine test case */ + + if (data_len == 54) { /* sizeof(pkt_v4) */ +- offset = 4096; /* test too large offset */ ++ offset = 4096; /* test too large offset, 4k page size */ ++ } else if (data_len == 53) { /* sizeof(pkt_v4) - 1 */ ++ offset = 65536; /* test too large offset, 64k page size */ + } else if (data_len == 74) { /* sizeof(pkt_v6) */ + offset = 40; + } else if (data_len == 64) { +@@ -29,6 +31,10 @@ int _xdp_adjust_tail_grow(struct xdp_md *xdp) + offset = 10; + } else if (data_len == 9001) { + offset = 4096; ++ } else if (data_len == 90000) { ++ offset = 10; /* test a small offset, 64k page size */ ++ } else if (data_len == 90001) { ++ offset = 65536; /* test too large offset, 64k page size */ + } else { + return XDP_ABORTED; /* No matching test */ + } +-- +2.51.0 + diff --git a/queue-6.6/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch b/queue-6.6/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch new file mode 100644 index 0000000000..169ed3c7fe --- /dev/null +++ b/queue-6.6/bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch @@ -0,0 +1,79 @@ +From 0feb12963cf36f320f05a47bfc23e4c5fa61e2ca Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Thu, 8 Jan 2026 21:36:48 +0900 +Subject: bpf: Fix reference count leak in bpf_prog_test_run_xdp() +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Tetsuo Handa + +[ Upstream commit ec69daabe45256f98ac86c651b8ad1b2574489a7 ] + +syzbot is reporting + + unregister_netdevice: waiting for sit0 to become free. Usage count = 2 + +problem. A debug printk() patch found that a refcount is obtained at +xdp_convert_md_to_buff() from bpf_prog_test_run_xdp(). + +According to commit ec94670fcb3b ("bpf: Support specifying ingress via +xdp_md context in BPF_PROG_TEST_RUN"), the refcount obtained by +xdp_convert_md_to_buff() will be released by xdp_convert_buff_to_md(). + +Therefore, we can consider that the error handling path introduced by +commit 1c1949982524 ("bpf: introduce frags support to +bpf_prog_test_run_xdp()") forgot to call xdp_convert_buff_to_md(). + +Reported-by: syzbot+881d65229ca4f9ae8c84@syzkaller.appspotmail.com +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Fixes: 1c1949982524 ("bpf: introduce frags support to bpf_prog_test_run_xdp()") +Signed-off-by: Tetsuo Handa +Reviewed-by: Toke Høiland-Jørgensen +Link: https://lore.kernel.org/r/af090e53-9d9b-4412-8acb-957733b3975c@I-love.SAKURA.ne.jp +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 7 ++++--- + 1 file changed, 4 insertions(+), 3 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 1989d239939b1..7e11ec31d40e4 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1243,13 +1243,13 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (sinfo->nr_frags == MAX_SKB_FRAGS) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + page = alloc_page(GFP_KERNEL); + if (!page) { + ret = -ENOMEM; +- goto out; ++ goto out_put_dev; + } + + frag = &sinfo->frags[sinfo->nr_frags++]; +@@ -1261,7 +1261,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (copy_from_user(page_address(page), data_in + size, + data_len)) { + ret = -EFAULT; +- goto out; ++ goto out_put_dev; + } + sinfo->xdp_frags_size += data_len; + size += data_len; +@@ -1276,6 +1276,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + ret = bpf_test_run_xdp_live(prog, &xdp, repeat, batch_size, &duration); + else + ret = bpf_test_run(prog, &xdp, repeat, &retval, &duration, true); ++out_put_dev: + /* We convert the xdp_buff back to an xdp_md before checking the return + * code so the reference count of any held netdevice will be decremented + * even if the test run failed. +-- +2.51.0 + diff --git a/queue-6.6/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch b/queue-6.6/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch new file mode 100644 index 0000000000..242f6e992b --- /dev/null +++ b/queue-6.6/bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch @@ -0,0 +1,101 @@ +From 76c96e86abf7113969f35a1e35c8d2df8b945f5e Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:33:53 -0700 +Subject: bpf: Make variables in bpf_prog_test_run_xdp less confusing + +From: Amery Hung + +[ Upstream commit 7eb83bff02ad5e82e8c456c58717ef181c220870 ] + +Change the variable naming in bpf_prog_test_run_xdp() to make the +overall logic less confusing. As different modes were added to the +function over the time, some variables got overloaded, making +it hard to understand and changing the code becomes error-prone. + +Replace "size" with "linear_sz" where it refers to the size of metadata +and data. If "size" refers to input data size, use test.data_size_in +directly. + +Replace "max_data_sz" with "max_linear_sz" to better reflect the fact +that it is the maximum size of metadata and data (i.e., linear_sz). Also, +xdp_rxq.frags_size is always PAGE_SIZE, so just set it directly instead +of subtracting headroom and tailroom and adding them back. + +Signed-off-by: Amery Hung +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250922233356.3356453-6-ameryhung@gmail.com +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 26 +++++++++++++------------- + 1 file changed, 13 insertions(+), 13 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 373ccb243545f..1e598c858a145 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1144,9 +1144,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + { + bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); + u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); ++ u32 retval = 0, duration, max_linear_sz, size; ++ u32 linear_sz = kattr->test.data_size_in; + u32 batch_size = kattr->test.batch_size; +- u32 retval = 0, duration, max_data_sz; +- u32 size = kattr->test.data_size_in; + u32 headroom = XDP_PACKET_HEADROOM; + u32 repeat = kattr->test.repeat; + struct netdev_rx_queue *rxqueue; +@@ -1183,7 +1183,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (ctx) { + /* There can't be user provided data before the meta data */ +- if (ctx->data_meta || ctx->data_end != size || ++ if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) +@@ -1192,30 +1192,30 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + headroom -= ctx->data; + } + +- max_data_sz = PAGE_SIZE - headroom - tailroom; +- if (size > max_data_sz) { +- /* disallow live data mode for jumbo frames */ +- if (do_live) +- goto free_ctx; +- size = max_data_sz; +- } ++ max_linear_sz = PAGE_SIZE - headroom - tailroom; ++ linear_sz = min_t(u32, linear_sz, max_linear_sz); ++ ++ /* disallow live data mode for jumbo frames */ ++ if (do_live && kattr->test.data_size_in > linear_sz) ++ goto free_ctx; + +- data = bpf_test_init(kattr, size, max_data_sz, headroom, tailroom); ++ data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); + if (IS_ERR(data)) { + ret = PTR_ERR(data); + goto free_ctx; + } + + rxqueue = __netif_get_rx_queue(current->nsproxy->net_ns->loopback_dev, 0); +- rxqueue->xdp_rxq.frag_size = headroom + max_data_sz + tailroom; ++ rxqueue->xdp_rxq.frag_size = PAGE_SIZE; + xdp_init_buff(&xdp, rxqueue->xdp_rxq.frag_size, &rxqueue->xdp_rxq); +- xdp_prepare_buff(&xdp, data, headroom, size, true); ++ xdp_prepare_buff(&xdp, data, headroom, linear_sz, true); + sinfo = xdp_get_shared_info_from_buff(&xdp); + + ret = xdp_convert_md_to_buff(ctx, &xdp); + if (ret) + goto free_data; + ++ size = linear_sz; + if (unlikely(kattr->test.data_size_in > size)) { + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + +-- +2.51.0 + diff --git a/queue-6.6/bpf-support-specifying-linear-xdp-packet-data-size-f.patch b/queue-6.6/bpf-support-specifying-linear-xdp-packet-data-size-f.patch new file mode 100644 index 0000000000..4e9c074034 --- /dev/null +++ b/queue-6.6/bpf-support-specifying-linear-xdp-packet-data-size-f.patch @@ -0,0 +1,130 @@ +From 92d17bfbf41be8986954b3db3e1042e02adb8ea4 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 22 Sep 2025 16:33:54 -0700 +Subject: bpf: Support specifying linear xdp packet data size for + BPF_PROG_TEST_RUN + +From: Amery Hung + +[ Upstream commit fe9544ed1a2e9217b2c5285c3a4ac0dc5a38bd7b ] + +To test bpf_xdp_pull_data(), an xdp packet containing fragments as well +as free linear data area after xdp->data_end needs to be created. +However, bpf_prog_test_run_xdp() always fills the linear area with +data_in before creating fragments, leaving no space to pull data. This +patch will allow users to specify the linear data size through +ctx->data_end. + +Currently, ctx_in->data_end must match data_size_in and will not be the +final ctx->data_end seen by xdp programs. This is because ctx->data_end +is populated according to the xdp_buff passed to test_run. The linear +data area available in an xdp_buff, max_linear_sz, is alawys filled up +before copying data_in into fragments. + +This patch will allow users to specify the size of data that goes into +the linear area. When ctx_in->data_end is different from data_size_in, +only ctx_in->data_end bytes of data will be put into the linear area when +creating the xdp_buff. + +While ctx_in->data_end will be allowed to be different from data_size_in, +it cannot be larger than the data_size_in as there will be no data to +copy from user space. If it is larger than the maximum linear data area +size, the layout suggested by the user will not be honored. Data beyond +max_linear_sz bytes will still be copied into fragments. + +Finally, since it is possible for a NIC to produce a xdp_buff with empty +linear data area, allow it when calling bpf_test_init() from +bpf_prog_test_run_xdp() so that we can test XDP kfuncs with such +xdp_buff. This is done by moving lower-bound check to callers as most of +them already do except bpf_prog_test_run_skb(). The change also fixes a +bug that allows passing an xdp_buff with data < ETH_HLEN. This can +happen when ctx is used and metadata is at least ETH_HLEN. + +Signed-off-by: Amery Hung +Signed-off-by: Martin KaFai Lau +Link: https://patch.msgid.link/20250922233356.3356453-7-ameryhung@gmail.com +Stable-dep-of: e558cca21779 ("bpf, test_run: Subtract size of xdp_frame from allowed metadata size") +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 15 ++++++++++++--- + .../bpf/prog_tests/xdp_context_test_run.c | 4 +--- + 2 files changed, 13 insertions(+), 6 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index 1e598c858a145..b4a912ed8f2ec 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -630,7 +630,7 @@ static void *bpf_test_init(const union bpf_attr *kattr, u32 user_size, + void __user *data_in = u64_to_user_ptr(kattr->test.data_in); + void *data; + +- if (user_size < ETH_HLEN || user_size > PAGE_SIZE - headroom - tailroom) ++ if (user_size > PAGE_SIZE - headroom - tailroom) + return ERR_PTR(-EINVAL); + + size = SKB_DATA_ALIGN(size); +@@ -964,6 +964,9 @@ int bpf_prog_test_run_skb(struct bpf_prog *prog, const union bpf_attr *kattr, + if (kattr->test.flags || kattr->test.cpu || kattr->test.batch_size) + return -EINVAL; + ++ if (size < ETH_HLEN) ++ return -EINVAL; ++ + data = bpf_test_init(kattr, kattr->test.data_size_in, + size, NET_SKB_PAD + NET_IP_ALIGN, + SKB_DATA_ALIGN(sizeof(struct skb_shared_info))); +@@ -1144,7 +1147,7 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + { + bool do_live = (kattr->test.flags & BPF_F_TEST_XDP_LIVE_FRAMES); + u32 tailroom = SKB_DATA_ALIGN(sizeof(struct skb_shared_info)); +- u32 retval = 0, duration, max_linear_sz, size; ++ u32 retval = 0, meta_sz = 0, duration, max_linear_sz, size; + u32 linear_sz = kattr->test.data_size_in; + u32 batch_size = kattr->test.batch_size; + u32 headroom = XDP_PACKET_HEADROOM; +@@ -1183,13 +1186,16 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + + if (ctx) { + /* There can't be user provided data before the meta data */ +- if (ctx->data_meta || ctx->data_end != kattr->test.data_size_in || ++ if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || + unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; + /* Meta data is allocated from the headroom */ + headroom -= ctx->data; ++ ++ meta_sz = ctx->data; ++ linear_sz = ctx->data_end; + } + + max_linear_sz = PAGE_SIZE - headroom - tailroom; +@@ -1199,6 +1205,9 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + if (do_live && kattr->test.data_size_in > linear_sz) + goto free_ctx; + ++ if (kattr->test.data_size_in - meta_sz < ETH_HLEN) ++ return -EINVAL; ++ + data = bpf_test_init(kattr, linear_sz, max_linear_sz, headroom, tailroom); + if (IS_ERR(data)) { + ret = PTR_ERR(data); +diff --git a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +index ab4952b9fb1d4..eab8625aad3b6 100644 +--- a/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c ++++ b/tools/testing/selftests/bpf/prog_tests/xdp_context_test_run.c +@@ -80,9 +80,7 @@ void test_xdp_context_test_run(void) + /* Meta data must be 32 bytes or smaller */ + test_xdp_context_error(prog_fd, opts, 0, 36, sizeof(data), 0, 0, 0); + +- /* Total size of data must match data_end - data_meta */ +- test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), +- sizeof(data) - 1, 0, 0, 0); ++ /* Total size of data must be data_end - data_meta or larger */ + test_xdp_context_error(prog_fd, opts, 0, sizeof(__u32), + sizeof(data) + 1, 0, 0, 0); + +-- +2.51.0 + diff --git a/queue-6.6/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch b/queue-6.6/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch new file mode 100644 index 0000000000..36ffa0a55f --- /dev/null +++ b/queue-6.6/bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch @@ -0,0 +1,87 @@ +From 01fd2c37d7c86ac94587a00d47286bb9b1dba327 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Mon, 5 Jan 2026 12:47:45 +0100 +Subject: bpf, test_run: Subtract size of xdp_frame from allowed metadata size +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Toke Høiland-Jørgensen + +[ Upstream commit e558cca217790286e799a8baacd1610bda31b261 ] + +The xdp_frame structure takes up part of the XDP frame headroom, +limiting the size of the metadata. However, in bpf_test_run, we don't +take this into account, which makes it possible for userspace to supply +a metadata size that is too large (taking up the entire headroom). + +If userspace supplies such a large metadata size in live packet mode, +the xdp_update_frame_from_buff() call in xdp_test_run_init_page() call +will fail, after which packet transmission proceeds with an +uninitialised frame structure, leading to the usual Bad Stuff. + +The commit in the Fixes tag fixed a related bug where the second check +in xdp_update_frame_from_buff() could fail, but did not add any +additional constraints on the metadata size. Complete the fix by adding +an additional check on the metadata size. Reorder the checks slightly to +make the logic clearer and add a comment. + +Link: https://lore.kernel.org/r/fa2be179-bad7-4ee3-8668-4903d1853461@hust.edu.cn +Fixes: b6f1f780b393 ("bpf, test_run: Fix packet size check for live packet mode") +Reported-by: Yinhao Hu +Reported-by: Kaiyan Mei +Signed-off-by: Toke Høiland-Jørgensen +Reviewed-by: Amery Hung +Link: https://lore.kernel.org/r/20260105114747.1358750-1-toke@redhat.com +Signed-off-by: Alexei Starovoitov +Signed-off-by: Sasha Levin +--- + net/bpf/test_run.c | 18 +++++++++++++----- + 1 file changed, 13 insertions(+), 5 deletions(-) + +diff --git a/net/bpf/test_run.c b/net/bpf/test_run.c +index b4a912ed8f2ec..1989d239939b1 100644 +--- a/net/bpf/test_run.c ++++ b/net/bpf/test_run.c +@@ -1174,8 +1174,6 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + batch_size = NAPI_POLL_WEIGHT; + else if (batch_size > TEST_XDP_MAX_BATCH) + return -E2BIG; +- +- headroom += sizeof(struct xdp_page_head); + } else if (batch_size) { + return -EINVAL; + } +@@ -1188,16 +1186,26 @@ int bpf_prog_test_run_xdp(struct bpf_prog *prog, const union bpf_attr *kattr, + /* There can't be user provided data before the meta data */ + if (ctx->data_meta || ctx->data_end > kattr->test.data_size_in || + ctx->data > ctx->data_end || +- unlikely(xdp_metalen_invalid(ctx->data)) || + (do_live && (kattr->test.data_out || kattr->test.ctx_out))) + goto free_ctx; +- /* Meta data is allocated from the headroom */ +- headroom -= ctx->data; + + meta_sz = ctx->data; ++ if (xdp_metalen_invalid(meta_sz) || meta_sz > headroom - sizeof(struct xdp_frame)) ++ goto free_ctx; ++ ++ /* Meta data is allocated from the headroom */ ++ headroom -= meta_sz; + linear_sz = ctx->data_end; + } + ++ /* The xdp_page_head structure takes up space in each page, limiting the ++ * size of the packet data; add the extra size to headroom here to make ++ * sure it's accounted in the length checks below, but not in the ++ * metadata size check above. ++ */ ++ if (do_live) ++ headroom += sizeof(struct xdp_page_head); ++ + max_linear_sz = PAGE_SIZE - headroom - tailroom; + linear_sz = min_t(u32, linear_sz, max_linear_sz); + +-- +2.51.0 + diff --git a/queue-6.6/can-j1939-make-j1939_session_activate-fail-if-device.patch b/queue-6.6/can-j1939-make-j1939_session_activate-fail-if-device.patch new file mode 100644 index 0000000000..68d4944e83 --- /dev/null +++ b/queue-6.6/can-j1939-make-j1939_session_activate-fail-if-device.patch @@ -0,0 +1,51 @@ +From e177c104112dcd56127a4ec8b56e17ef3df8832c Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Tue, 25 Nov 2025 22:39:59 +0900 +Subject: can: j1939: make j1939_session_activate() fail if device is no longer + registered + +From: Tetsuo Handa + +[ Upstream commit 5d5602236f5db19e8b337a2cd87a90ace5ea776d ] + +syzbot is still reporting + + unregister_netdevice: waiting for vcan0 to become free. Usage count = 2 + +even after commit 93a27b5891b8 ("can: j1939: add missing calls in +NETDEV_UNREGISTER notification handler") was added. A debug printk() patch +found that j1939_session_activate() can succeed even after +j1939_cancel_active_session() from j1939_netdev_notify(NETDEV_UNREGISTER) +has completed. + +Since j1939_cancel_active_session() is processed with the session list lock +held, checking ndev->reg_state in j1939_session_activate() with the session +list lock held can reliably close the race window. + +Reported-by: syzbot +Closes: https://syzkaller.appspot.com/bug?extid=881d65229ca4f9ae8c84 +Signed-off-by: Tetsuo Handa +Acked-by: Oleksij Rempel +Link: https://patch.msgid.link/b9653191-d479-4c8b-8536-1326d028db5c@I-love.SAKURA.ne.jp +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Sasha Levin +--- + net/can/j1939/transport.c | 2 ++ + 1 file changed, 2 insertions(+) + +diff --git a/net/can/j1939/transport.c b/net/can/j1939/transport.c +index 9b72d118d756d..1186326b0f2e9 100644 +--- a/net/can/j1939/transport.c ++++ b/net/can/j1939/transport.c +@@ -1571,6 +1571,8 @@ int j1939_session_activate(struct j1939_session *session) + if (active) { + j1939_session_put(active); + ret = -EAGAIN; ++ } else if (priv->ndev->reg_state != NETREG_REGISTERED) { ++ ret = -ENODEV; + } else { + WARN_ON_ONCE(session->state != J1939_SESSION_NEW); + list_add_tail(&session->active_session_list_entry, +-- +2.51.0 + diff --git a/queue-6.6/drm-amd-display-fix-dp-no-audio-issue.patch b/queue-6.6/drm-amd-display-fix-dp-no-audio-issue.patch new file mode 100644 index 0000000000..34107f5637 --- /dev/null +++ b/queue-6.6/drm-amd-display-fix-dp-no-audio-issue.patch @@ -0,0 +1,49 @@ +From ac4a30d3770f6273bb3acefb3f37ca5cea3e85b2 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 28 Nov 2025 19:38:31 -0500 +Subject: drm/amd/display: Fix DP no audio issue + +From: Charlene Liu + +[ Upstream commit 3886b198bd6e49c801fe9552fcfbfc387a49fbbc ] + +[why] +need to enable APG_CLOCK_ENABLE enable first +also need to wake up az from D3 before access az block + +Reviewed-by: Swapnil Patel +Signed-off-by: Charlene Liu +Signed-off-by: Chenyu Chen +Tested-by: Daniel Wheeler +Signed-off-by: Alex Deucher +(cherry picked from commit bf5e396957acafd46003318965500914d5f4edfa) +Signed-off-by: Sasha Levin +--- + .../gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +diff --git a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +index d389eeb264a79..0172fede51b5b 100644 +--- a/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c ++++ b/drivers/gpu/drm/amd/display/dc/dce110/dce110_hw_sequencer.c +@@ -1097,13 +1097,13 @@ void dce110_enable_audio_stream(struct pipe_ctx *pipe_ctx) + if (dc->current_state->res_ctx.pipe_ctx[i].stream_res.audio != NULL) + num_audio++; + } ++ if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) { ++ /*wake AZ from D3 first before access az endpoint*/ ++ clk_mgr->funcs->enable_pme_wa(clk_mgr); ++ } + + pipe_ctx->stream_res.audio->funcs->az_enable(pipe_ctx->stream_res.audio); + +- if (num_audio >= 1 && clk_mgr->funcs->enable_pme_wa) +- /*this is the first audio. apply the PME w/a in order to wake AZ from D3*/ +- clk_mgr->funcs->enable_pme_wa(clk_mgr); +- + link_hwss->enable_audio_packet(pipe_ctx); + + if (pipe_ctx->stream_res.audio) +-- +2.51.0 + diff --git a/queue-6.6/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch b/queue-6.6/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch new file mode 100644 index 0000000000..64fa35b40d --- /dev/null +++ b/queue-6.6/netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch @@ -0,0 +1,268 @@ +From 88b61609bcc88b25fe037b4b6f0f5f425d5a4c78 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Jul 2024 01:18:25 +0200 +Subject: netfilter: nf_tables: avoid chain re-validation if possible + +From: Florian Westphal + +[ Upstream commit 8e1a1bc4f5a42747c08130b8242ebebd1210b32f ] + +Hamza Mahfooz reports cpu soft lock-ups in +nft_chain_validate(): + + watchdog: BUG: soft lockup - CPU#1 stuck for 27s! [iptables-nft-re:37547] +[..] + RIP: 0010:nft_chain_validate+0xcb/0x110 [nf_tables] +[..] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_immediate_validate+0x36/0x50 [nf_tables] + nft_chain_validate+0xc9/0x110 [nf_tables] + nft_table_validate+0x6b/0xb0 [nf_tables] + nf_tables_validate+0x8b/0xa0 [nf_tables] + nf_tables_commit+0x1df/0x1eb0 [nf_tables] +[..] + +Currently nf_tables will traverse the entire table (chain graph), starting +from the entry points (base chains), exploring all possible paths +(chain jumps). But there are cases where we could avoid revalidation. + +Consider: +1 input -> j2 -> j3 +2 input -> j2 -> j3 +3 input -> j1 -> j2 -> j3 + +Then the second rule does not need to revalidate j2, and, by extension j3, +because this was already checked during validation of the first rule. +We need to validate it only for rule 3. + +This is needed because chain loop detection also ensures we do not exceed +the jump stack: Just because we know that j2 is cycle free, its last jump +might now exceed the allowed stack size. We also need to update all +reachable chains with the new largest observed call depth. + +Care has to be taken to revalidate even if the chain depth won't be an +issue: chain validation also ensures that expressions are not called from +invalid base chains. For example, the masquerade expression can only be +called from NAT postrouting base chains. + +Therefore we also need to keep record of the base chain context (type, +hooknum) and revalidate if the chain becomes reachable from a different +hook location. + +Reported-by: Hamza Mahfooz +Closes: https://lore.kernel.org/netfilter-devel/20251118221735.GA5477@linuxonhyperv3.guj3yctzbm1etfxqx2vob5hsef.xx.internal.cloudapp.net/ +Tested-by: Hamza Mahfooz +Signed-off-by: Florian Westphal +Signed-off-by: Sasha Levin +--- + include/net/netfilter/nf_tables.h | 34 +++++++++++---- + net/netfilter/nf_tables_api.c | 69 +++++++++++++++++++++++++++++-- + 2 files changed, 91 insertions(+), 12 deletions(-) + +diff --git a/include/net/netfilter/nf_tables.h b/include/net/netfilter/nf_tables.h +index a8fcbdb37a7f9..02a73037fae01 100644 +--- a/include/net/netfilter/nf_tables.h ++++ b/include/net/netfilter/nf_tables.h +@@ -1079,6 +1079,29 @@ struct nft_rule_blob { + __attribute__((aligned(__alignof__(struct nft_rule_dp)))); + }; + ++enum nft_chain_types { ++ NFT_CHAIN_T_DEFAULT = 0, ++ NFT_CHAIN_T_ROUTE, ++ NFT_CHAIN_T_NAT, ++ NFT_CHAIN_T_MAX ++}; ++ ++/** ++ * struct nft_chain_validate_state - validation state ++ * ++ * If a chain is encountered again during table validation it is ++ * possible to avoid revalidation provided the calling context is ++ * compatible. This structure stores relevant calling context of ++ * previous validations. ++ * ++ * @hook_mask: the hook numbers and locations the chain is linked to ++ * @depth: the deepest call chain level the chain is linked to ++ */ ++struct nft_chain_validate_state { ++ u8 hook_mask[NFT_CHAIN_T_MAX]; ++ u8 depth; ++}; ++ + /** + * struct nft_chain - nf_tables chain + * +@@ -1097,6 +1120,7 @@ struct nft_rule_blob { + * @udlen: user data length + * @udata: user data in the chain + * @blob_next: rule blob pointer to the next in the chain ++ * @vstate: validation state + */ + struct nft_chain { + struct nft_rule_blob __rcu *blob_gen_0; +@@ -1116,9 +1140,10 @@ struct nft_chain { + + /* Only used during control plane commit phase: */ + struct nft_rule_blob *blob_next; ++ struct nft_chain_validate_state vstate; + }; + +-int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain); ++int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain); + int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, + const struct nft_set_iter *iter, + struct nft_set_elem *elem); +@@ -1126,13 +1151,6 @@ int nft_set_catchall_validate(const struct nft_ctx *ctx, struct nft_set *set); + int nf_tables_bind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); + void nf_tables_unbind_chain(const struct nft_ctx *ctx, struct nft_chain *chain); + +-enum nft_chain_types { +- NFT_CHAIN_T_DEFAULT = 0, +- NFT_CHAIN_T_ROUTE, +- NFT_CHAIN_T_NAT, +- NFT_CHAIN_T_MAX +-}; +- + /** + * struct nft_chain_type - nf_tables chain type info + * +diff --git a/net/netfilter/nf_tables_api.c b/net/netfilter/nf_tables_api.c +index 43ebe3b4f886a..c00dd7dae5cb9 100644 +--- a/net/netfilter/nf_tables_api.c ++++ b/net/netfilter/nf_tables_api.c +@@ -121,6 +121,29 @@ static void nft_validate_state_update(struct nft_table *table, u8 new_validate_s + + table->validate_state = new_validate_state; + } ++ ++static bool nft_chain_vstate_valid(const struct nft_ctx *ctx, ++ const struct nft_chain *chain) ++{ ++ const struct nft_base_chain *base_chain; ++ enum nft_chain_types type; ++ u8 hooknum; ++ ++ if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) ++ return false; ++ ++ base_chain = nft_base_chain(ctx->chain); ++ hooknum = base_chain->ops.hooknum; ++ type = base_chain->type->type; ++ ++ /* chain is already validated for this call depth */ ++ if (chain->vstate.depth >= ctx->level && ++ chain->vstate.hook_mask[type] & BIT(hooknum)) ++ return true; ++ ++ return false; ++} ++ + static void nf_tables_trans_destroy_work(struct work_struct *w); + static DECLARE_WORK(trans_destroy_work, nf_tables_trans_destroy_work); + +@@ -3798,6 +3821,29 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + nf_tables_rule_destroy(ctx, rule); + } + ++static void nft_chain_vstate_update(const struct nft_ctx *ctx, struct nft_chain *chain) ++{ ++ const struct nft_base_chain *base_chain; ++ enum nft_chain_types type; ++ u8 hooknum; ++ ++ /* ctx->chain must hold the calling base chain. */ ++ if (WARN_ON_ONCE(!nft_is_base_chain(ctx->chain))) { ++ memset(&chain->vstate, 0, sizeof(chain->vstate)); ++ return; ++ } ++ ++ base_chain = nft_base_chain(ctx->chain); ++ hooknum = base_chain->ops.hooknum; ++ type = base_chain->type->type; ++ ++ BUILD_BUG_ON(BIT(NF_INET_NUMHOOKS) > U8_MAX); ++ ++ chain->vstate.hook_mask[type] |= BIT(hooknum); ++ if (chain->vstate.depth < ctx->level) ++ chain->vstate.depth = ctx->level; ++} ++ + /** nft_chain_validate - loop detection and hook validation + * + * @ctx: context containing call depth and base chain +@@ -3807,15 +3853,25 @@ static void nf_tables_rule_release(const struct nft_ctx *ctx, struct nft_rule *r + * and set lookups until either the jump limit is hit or all reachable + * chains have been validated. + */ +-int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) ++int nft_chain_validate(const struct nft_ctx *ctx, struct nft_chain *chain) + { + struct nft_expr *expr, *last; + struct nft_rule *rule; + int err; + ++ BUILD_BUG_ON(NFT_JUMP_STACK_SIZE > 255); + if (ctx->level == NFT_JUMP_STACK_SIZE) + return -EMLINK; + ++ if (ctx->level > 0) { ++ /* jumps to base chains are not allowed. */ ++ if (nft_is_base_chain(chain)) ++ return -ELOOP; ++ ++ if (nft_chain_vstate_valid(ctx, chain)) ++ return 0; ++ } ++ + list_for_each_entry(rule, &chain->rules, list) { + if (fatal_signal_pending(current)) + return -EINTR; +@@ -3836,6 +3892,7 @@ int nft_chain_validate(const struct nft_ctx *ctx, const struct nft_chain *chain) + } + } + ++ nft_chain_vstate_update(ctx, chain); + return 0; + } + EXPORT_SYMBOL_GPL(nft_chain_validate); +@@ -3847,7 +3904,7 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + .net = net, + .family = table->family, + }; +- int err; ++ int err = 0; + + list_for_each_entry(chain, &table->chains, list) { + if (!nft_is_base_chain(chain)) +@@ -3856,12 +3913,16 @@ static int nft_table_validate(struct net *net, const struct nft_table *table) + ctx.chain = chain; + err = nft_chain_validate(&ctx, chain); + if (err < 0) +- return err; ++ goto err; + + cond_resched(); + } + +- return 0; ++err: ++ list_for_each_entry(chain, &table->chains, list) ++ memset(&chain->vstate, 0, sizeof(chain->vstate)); ++ ++ return err; + } + + int nft_setelem_validate(const struct nft_ctx *ctx, struct nft_set *set, +-- +2.51.0 + diff --git a/queue-6.6/powercap-fix-race-condition-in-register_control_type.patch b/queue-6.6/powercap-fix-race-condition-in-register_control_type.patch new file mode 100644 index 0000000000..857ea75d6e --- /dev/null +++ b/queue-6.6/powercap-fix-race-condition-in-register_control_type.patch @@ -0,0 +1,65 @@ +From 666bec5fec1cb2b5ca61216ffe3b18fe416d2999 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sat, 6 Dec 2025 00:32:16 +0530 +Subject: powercap: fix race condition in register_control_type() + +From: Sumeet Pawnikar + +[ Upstream commit 7bda1910c4bccd4b8d4726620bb3d6bbfb62286e ] + +The device becomes visible to userspace via device_register() +even before it fully initialized by idr_init(). If userspace +or another thread tries to register a zone immediately after +device_register(), the control_type_valid() will fail because +the control_type is not yet in the list. The IDR is not yet +initialized, so this race condition causes zone registration +failure. + +Move idr_init() and list addition before device_register() +fix the race condition. + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject adjustment, empty line added ] +Link: https://patch.msgid.link/20251205190216.5032-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 16 +++++++++++----- + 1 file changed, 11 insertions(+), 5 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index 4112a00973382..d14b36b75189d 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -625,17 +625,23 @@ struct powercap_control_type *powercap_register_control_type( + INIT_LIST_HEAD(&control_type->node); + control_type->dev.class = &powercap_class; + dev_set_name(&control_type->dev, "%s", name); +- result = device_register(&control_type->dev); +- if (result) { +- put_device(&control_type->dev); +- return ERR_PTR(result); +- } + idr_init(&control_type->idr); + + mutex_lock(&powercap_cntrl_list_lock); + list_add_tail(&control_type->node, &powercap_cntrl_list); + mutex_unlock(&powercap_cntrl_list_lock); + ++ result = device_register(&control_type->dev); ++ if (result) { ++ mutex_lock(&powercap_cntrl_list_lock); ++ list_del(&control_type->node); ++ mutex_unlock(&powercap_cntrl_list_lock); ++ ++ idr_destroy(&control_type->idr); ++ put_device(&control_type->dev); ++ return ERR_PTR(result); ++ } ++ + return control_type; + } + EXPORT_SYMBOL_GPL(powercap_register_control_type); +-- +2.51.0 + diff --git a/queue-6.6/powercap-fix-sscanf-error-return-value-handling.patch b/queue-6.6/powercap-fix-sscanf-error-return-value-handling.patch new file mode 100644 index 0000000000..c7e2689dc1 --- /dev/null +++ b/queue-6.6/powercap-fix-sscanf-error-return-value-handling.patch @@ -0,0 +1,67 @@ +From f714f7aa98b5aac54f9fa6af790c0fb6cbbf9319 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Sun, 7 Dec 2025 20:45:48 +0530 +Subject: powercap: fix sscanf() error return value handling + +From: Sumeet Pawnikar + +[ Upstream commit efc4c35b741af973de90f6826bf35d3b3ac36bf1 ] + +Fix inconsistent error handling for sscanf() return value check. + +Implicit boolean conversion is used instead of explicit return +value checks. The code checks if (!sscanf(...)) which is incorrect +because: + 1. sscanf returns the number of successfully parsed items + 2. On success, it returns 1 (one item passed) + 3. On failure, it returns 0 or EOF + 4. The check 'if (!sscanf(...))' is wrong because it treats + success (1) as failure + +All occurrences of sscanf() now uses explicit return value check. +With this behavior it returns '-EINVAL' when parsing fails (returns +0 or EOF), and continues when parsing succeeds (returns 1). + +Signed-off-by: Sumeet Pawnikar +[ rjw: Subject and changelog edits ] +Link: https://patch.msgid.link/20251207151549.202452-1-sumeet4linux@gmail.com +Signed-off-by: Rafael J. Wysocki +Signed-off-by: Sasha Levin +--- + drivers/powercap/powercap_sys.c | 6 +++--- + 1 file changed, 3 insertions(+), 3 deletions(-) + +diff --git a/drivers/powercap/powercap_sys.c b/drivers/powercap/powercap_sys.c +index d14b36b75189d..1ff369880beb2 100644 +--- a/drivers/powercap/powercap_sys.c ++++ b/drivers/powercap/powercap_sys.c +@@ -68,7 +68,7 @@ static ssize_t show_constraint_##_attr(struct device *dev, \ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -93,7 +93,7 @@ static ssize_t store_constraint_##_attr(struct device *dev,\ + int id; \ + struct powercap_zone_constraint *pconst;\ + \ +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) \ ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) \ + return -EINVAL; \ + if (id >= power_zone->const_id_cnt) \ + return -EINVAL; \ +@@ -162,7 +162,7 @@ static ssize_t show_constraint_name(struct device *dev, + ssize_t len = -ENODATA; + struct powercap_zone_constraint *pconst; + +- if (!sscanf(dev_attr->attr.name, "constraint_%d_", &id)) ++ if (sscanf(dev_attr->attr.name, "constraint_%d_", &id) != 1) + return -EINVAL; + if (id >= power_zone->const_id_cnt) + return -EINVAL; +-- +2.51.0 + diff --git a/queue-6.6/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch b/queue-6.6/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch new file mode 100644 index 0000000000..2494f02107 --- /dev/null +++ b/queue-6.6/scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch @@ -0,0 +1,152 @@ +From 76a7f4e8ea0423ef1b8bea689f7eff10d5cf1e11 Mon Sep 17 00:00:00 2001 +From: Sasha Levin +Date: Fri, 12 Dec 2025 17:08:23 +0100 +Subject: scsi: sg: Fix occasional bogus elapsed time that exceeds timeout +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Michal Rábek + +[ Upstream commit 0e1677654259a2f3ccf728de1edde922a3c4ba57 ] + +A race condition was found in sg_proc_debug_helper(). It was observed on +a system using an IBM LTO-9 SAS Tape Drive (ULTRIUM-TD9) and monitoring +/proc/scsi/sg/debug every second. A very large elapsed time would +sometimes appear. This is caused by two race conditions. + +We reproduced the issue with an IBM ULTRIUM-HH9 tape drive on an x86_64 +architecture. A patched kernel was built, and the race condition could +not be observed anymore after the application of this patch. A +reproducer C program utilising the scsi_debug module was also built by +Changhui Zhong and can be viewed here: + +https://github.com/MichaelRabek/linux-tests/blob/master/drivers/scsi/sg/sg_race_trigger.c + +The first race happens between the reading of hp->duration in +sg_proc_debug_helper() and request completion in sg_rq_end_io(). The +hp->duration member variable may hold either of two types of +information: + + #1 - The start time of the request. This value is present while + the request is not yet finished. + + #2 - The total execution time of the request (end_time - start_time). + +If sg_proc_debug_helper() executes *after* the value of hp->duration was +changed from #1 to #2, but *before* srp->done is set to 1 in +sg_rq_end_io(), a fresh timestamp is taken in the else branch, and the +elapsed time (value type #2) is subtracted from a timestamp, which +cannot yield a valid elapsed time (which is a type #2 value as well). + +To fix this issue, the value of hp->duration must change under the +protection of the sfp->rq_list_lock in sg_rq_end_io(). Since +sg_proc_debug_helper() takes this read lock, the change to srp->done and +srp->header.duration will happen atomically from the perspective of +sg_proc_debug_helper() and the race condition is thus eliminated. + +The second race condition happens between sg_proc_debug_helper() and +sg_new_write(). Even though hp->duration is set to the current time +stamp in sg_add_request() under the write lock's protection, it gets +overwritten by a call to get_sg_io_hdr(), which calls copy_from_user() +to copy struct sg_io_hdr from userspace into kernel space. hp->duration +is set to the start time again in sg_common_write(). If +sg_proc_debug_helper() is called between these two calls, an arbitrary +value set by userspace (usually zero) is used to compute the elapsed +time. + +To fix this issue, hp->duration must be set to the current timestamp +again after get_sg_io_hdr() returns successfully. A small race window +still exists between get_sg_io_hdr() and setting hp->duration, but this +window is only a few instructions wide and does not result in observable +issues in practice, as confirmed by testing. + +Additionally, we fix the format specifier from %d to %u for printing +unsigned int values in sg_proc_debug_helper(). + +Signed-off-by: Michal Rábek +Suggested-by: Tomas Henzl +Tested-by: Changhui Zhong +Reviewed-by: Ewan D. Milne +Reviewed-by: John Meneghini +Reviewed-by: Tomas Henzl +Link: https://patch.msgid.link/20251212160900.64924-1-mrabek@redhat.com +Signed-off-by: Martin K. Petersen +Signed-off-by: Sasha Levin +--- + drivers/scsi/sg.c | 20 +++++++++++++------- + 1 file changed, 13 insertions(+), 7 deletions(-) + +diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c +index 9258a1a8c23c1..0dd8b9f8d6717 100644 +--- a/drivers/scsi/sg.c ++++ b/drivers/scsi/sg.c +@@ -731,6 +731,8 @@ sg_new_write(Sg_fd *sfp, struct file *file, const char __user *buf, + sg_remove_request(sfp, srp); + return -EFAULT; + } ++ hp->duration = jiffies_to_msecs(jiffies); ++ + if (hp->interface_id != 'S') { + sg_remove_request(sfp, srp); + return -ENOSYS; +@@ -815,7 +817,6 @@ sg_common_write(Sg_fd * sfp, Sg_request * srp, + return -ENODEV; + } + +- hp->duration = jiffies_to_msecs(jiffies); + if (hp->interface_id != '\0' && /* v3 (or later) interface */ + (SG_FLAG_Q_AT_TAIL & hp->flags)) + at_head = 0; +@@ -1339,9 +1340,6 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + "sg_cmd_done: pack_id=%d, res=0x%x\n", + srp->header.pack_id, result)); + srp->header.resid = resid; +- ms = jiffies_to_msecs(jiffies); +- srp->header.duration = (ms > srp->header.duration) ? +- (ms - srp->header.duration) : 0; + if (0 != result) { + struct scsi_sense_hdr sshdr; + +@@ -1390,6 +1388,9 @@ sg_rq_end_io(struct request *rq, blk_status_t status) + done = 0; + } + srp->done = done; ++ ms = jiffies_to_msecs(jiffies); ++ srp->header.duration = (ms > srp->header.duration) ? ++ (ms - srp->header.duration) : 0; + write_unlock_irqrestore(&sfp->rq_list_lock, iflags); + + if (likely(done)) { +@@ -2537,6 +2538,7 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + const sg_io_hdr_t *hp; + const char * cp; + unsigned int ms; ++ unsigned int duration; + + k = 0; + list_for_each_entry(fp, &sdp->sfds, sfd_siblings) { +@@ -2574,13 +2576,17 @@ static void sg_proc_debug_helper(struct seq_file *s, Sg_device * sdp) + seq_printf(s, " id=%d blen=%d", + srp->header.pack_id, blen); + if (srp->done) +- seq_printf(s, " dur=%d", hp->duration); ++ seq_printf(s, " dur=%u", hp->duration); + else { + ms = jiffies_to_msecs(jiffies); +- seq_printf(s, " t_o/elap=%d/%d", ++ duration = READ_ONCE(hp->duration); ++ if (duration) ++ duration = (ms > duration ? ++ ms - duration : 0); ++ seq_printf(s, " t_o/elap=%u/%u", + (new_interface ? hp->timeout : + jiffies_to_msecs(fp->timeout)), +- (ms > hp->duration ? ms - hp->duration : 0)); ++ duration); + } + seq_printf(s, "ms sgat=%d op=0x%02x\n", usg, + (int) srp->data.cmd_opcode); +-- +2.51.0 + diff --git a/queue-6.6/series b/queue-6.6/series index e1ceac56a9..a9d1bec1d4 100644 --- a/queue-6.6/series +++ b/queue-6.6/series @@ -70,3 +70,17 @@ nfs_common-factor-out-nfs_errtbl-and-nfs_stat_to_errno.patch nfsd-remove-nfserr_eagain.patch x86-microcode-amd-select-which-microcode-patch-to-load.patch riscv-uprobes-add-missing-fence.i-after-building-the-xol-buffer.patch +bpf-fix-an-issue-in-bpf_prog_test_run_xdp-when-page-.patch +bpf-make-variables-in-bpf_prog_test_run_xdp-less-con.patch +bpf-support-specifying-linear-xdp-packet-data-size-f.patch +bpf-test_run-subtract-size-of-xdp_frame-from-allowed.patch +bpf-fix-reference-count-leak-in-bpf_prog_test_run_xd.patch +powercap-fix-race-condition-in-register_control_type.patch +powercap-fix-sscanf-error-return-value-handling.patch +netfilter-nf_tables-avoid-chain-re-validation-if-pos.patch +drm-amd-display-fix-dp-no-audio-issue.patch +can-j1939-make-j1939_session_activate-fail-if-device.patch +alsa-usb-audio-update-for-native-dsd-support-quirks.patch +asoc-amd-yc-add-quirk-for-honor-magicbook-x16-2025.patch +asoc-fsl_sai-add-missing-registers-to-cache-default.patch +scsi-sg-fix-occasional-bogus-elapsed-time-that-excee.patch -- 2.47.3