From: Greg Kroah-Hartman Date: Mon, 18 Aug 2025 11:52:43 +0000 (+0200) Subject: 6.12-stable patches X-Git-Tag: v6.12.43~12 X-Git-Url: http://git.ipfire.org/?a=commitdiff_plain;h=c0b5668a13c032642778b35d5c7b3876289d01ab;p=thirdparty%2Fkernel%2Fstable-queue.git 6.12-stable patches added patches: arm64-dts-ti-k3-j722s-evm-fix-usb-gpio-hog-level-for-type-c.patch arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-select-type-c.patch hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch mfd-cros_ec-separate-charge-control-probing-from-usb-pd.patch net-add-net_passive_inc-and-net_passive_dec.patch net-better-track-kernel-sockets-lifetime.patch pci-acpi-fix-runtime-pm-ref-imbalance-on-hot-plug-capable-ports.patch pci-allow-pci-bridges-to-go-to-d3hot-on-all-non-x86.patch pci-store-all-pcie-supported-link-speeds.patch rust-kbuild-clean-output-before-running-rustdoc.patch rust-workaround-rustdoc-target-modifiers-bug.patch smb-client-fix-netns-refcount-leak-after-net_passive-changes.patch tools-hv-fcopy-fix-irregularities-with-size-of-ring-buffer.patch wifi-mac80211-check-basic-rates-validity-in-sta_link_apply_parameters.patch --- diff --git a/queue-6.12/arm64-dts-ti-k3-j722s-evm-fix-usb-gpio-hog-level-for-type-c.patch b/queue-6.12/arm64-dts-ti-k3-j722s-evm-fix-usb-gpio-hog-level-for-type-c.patch new file mode 100644 index 0000000000..3641503d7a --- /dev/null +++ b/queue-6.12/arm64-dts-ti-k3-j722s-evm-fix-usb-gpio-hog-level-for-type-c.patch @@ -0,0 +1,44 @@ +From stable+bounces-169789-greg=kroah.com@vger.kernel.org Fri Aug 15 19:24:03 2025 +From: Sasha Levin +Date: Fri, 15 Aug 2025 13:23:52 -0400 +Subject: arm64: dts: ti: k3-j722s-evm: Fix USB gpio-hog level for Type-C +To: stable@vger.kernel.org +Cc: Siddharth Vadapalli , Vignesh Raghavendra , Sasha Levin +Message-ID: <20250815172352.165389-2-sashal@kernel.org> + +From: Siddharth Vadapalli + +[ Upstream commit 65ba2a6e77e9e5c843a591055789050e77b5c65e ] + +According to the "GPIO Expander Map / Table" section of the J722S EVM +Schematic within the Evaluation Module Design Files package [0], the +GPIO Pin P05 located on the GPIO Expander 1 (I2C0/0x23) has to be pulled +down to select the Type-C interface. Since commit under Fixes claims to +enable the Type-C interface, update the property within "p05-hog" from +"output-high" to "output-low", thereby switching from the Type-A +interface to the Type-C interface. + +[0]: https://www.ti.com/lit/zip/sprr495 + +Cc: stable@vger.kernel.org +Fixes: 485705df5d5f ("arm64: dts: ti: k3-j722s: Enable PCIe and USB support on J722S-EVM") +Signed-off-by: Siddharth Vadapalli +Link: https://lore.kernel.org/r/20250623100657.4082031-1-s-vadapalli@ti.com +Signed-off-by: Vignesh Raghavendra +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts ++++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts +@@ -496,7 +496,7 @@ + /* P05 - USB2.0_MUX_SEL */ + gpio-hog; + gpios = <5 GPIO_ACTIVE_LOW>; +- output-high; ++ output-low; + }; + + p01_hog: p01-hog { diff --git a/queue-6.12/arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-select-type-c.patch b/queue-6.12/arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-select-type-c.patch new file mode 100644 index 0000000000..f417415011 --- /dev/null +++ b/queue-6.12/arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-select-type-c.patch @@ -0,0 +1,48 @@ +From stable+bounces-169788-greg=kroah.com@vger.kernel.org Fri Aug 15 19:24:02 2025 +From: Sasha Levin +Date: Fri, 15 Aug 2025 13:23:51 -0400 +Subject: arm64: dts: ti: k3-j722s-evm: Fix USB2.0_MUX_SEL to select Type-C +To: stable@vger.kernel.org +Cc: Hrushikesh Salunke , Roger Quadros , Vignesh Raghavendra , Sasha Levin +Message-ID: <20250815172352.165389-1-sashal@kernel.org> + +From: Hrushikesh Salunke + +[ Upstream commit bc8d9e6b5821c40ab5dd3a81e096cb114939de50 ] + +J722S SOC has two usb controllers USB0 and USB1. USB0 is brought out on +the EVM as a stacked USB connector which has one Type-A and one Type-C +port. These Type-A and Type-C ports are connected to MUX so only +one of them can be enabled at a time. + +Commit under Fixes, tries to enable the USB0 instance of USB to +interface with the Type-C port via the USB hub, by configuring the +USB2.0_MUX_SEL to GPIO_ACTIVE_HIGH. But it is observed on J722S-EVM +that Type-A port is enabled instead of Type-C port. + +Fix this by setting USB2.0_MUX_SEL to GPIO_ACTIVE_LOW to enable Type-C +port. + +Fixes: 485705df5d5f ("arm64: dts: ti: k3-j722s: Enable PCIe and USB support on J722S-EVM") +Signed-off-by: Hrushikesh Salunke +Reviewed-by: Roger Quadros +Link: https://lore.kernel.org/r/20250116125726.2549489-1-h-salunke@ti.com +Signed-off-by: Vignesh Raghavendra +Stable-dep-of: 65ba2a6e77e9 ("arm64: dts: ti: k3-j722s-evm: Fix USB gpio-hog level for Type-C") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + arch/arm64/boot/dts/ti/k3-j722s-evm.dts | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +--- a/arch/arm64/boot/dts/ti/k3-j722s-evm.dts ++++ b/arch/arm64/boot/dts/ti/k3-j722s-evm.dts +@@ -495,7 +495,7 @@ + p05-hog { + /* P05 - USB2.0_MUX_SEL */ + gpio-hog; +- gpios = <5 GPIO_ACTIVE_HIGH>; ++ gpios = <5 GPIO_ACTIVE_LOW>; + output-high; + }; + diff --git a/queue-6.12/hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch b/queue-6.12/hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch new file mode 100644 index 0000000000..9f9b3624e0 --- /dev/null +++ b/queue-6.12/hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch @@ -0,0 +1,66 @@ +From c061046fe9ce3ff31fb9a807144a2630ad349c17 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Mon, 30 Jun 2025 12:37:13 +0000 +Subject: HID: apple: avoid setting up battery timer for devices without battery + +From: Aditya Garg + +commit c061046fe9ce3ff31fb9a807144a2630ad349c17 upstream. + +Currently, the battery timer is set up for all devices using hid-apple, +irrespective of whether they actually have a battery or not. + +APPLE_RDESC_BATTERY is a quirk that indicates the device has a battery +and needs the battery timer. This patch checks for this quirk before +setting up the timer, ensuring that only devices with a battery will +have the timer set up. + +Fixes: 6e143293e17a ("HID: apple: Report Magic Keyboard battery over USB") +Cc: stable@vger.kernel.org +Signed-off-by: Aditya Garg +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + drivers/hid/hid-apple.c | 17 +++++++++++------ + 1 file changed, 11 insertions(+), 6 deletions(-) + +--- a/drivers/hid/hid-apple.c ++++ b/drivers/hid/hid-apple.c +@@ -934,10 +934,12 @@ static int apple_probe(struct hid_device + return ret; + } + +- timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0); +- mod_timer(&asc->battery_timer, +- jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS)); +- apple_fetch_battery(hdev); ++ if (quirks & APPLE_RDESC_BATTERY) { ++ timer_setup(&asc->battery_timer, apple_battery_timer_tick, 0); ++ mod_timer(&asc->battery_timer, ++ jiffies + msecs_to_jiffies(APPLE_BATTERY_TIMEOUT_MS)); ++ apple_fetch_battery(hdev); ++ } + + if (quirks & APPLE_BACKLIGHT_CTL) + apple_backlight_init(hdev); +@@ -951,7 +953,9 @@ static int apple_probe(struct hid_device + return 0; + + out_err: +- del_timer_sync(&asc->battery_timer); ++ if (quirks & APPLE_RDESC_BATTERY) ++ del_timer_sync(&asc->battery_timer); ++ + hid_hw_stop(hdev); + return ret; + } +@@ -960,7 +964,8 @@ static void apple_remove(struct hid_devi + { + struct apple_sc *asc = hid_get_drvdata(hdev); + +- del_timer_sync(&asc->battery_timer); ++ if (asc->quirks & APPLE_RDESC_BATTERY) ++ del_timer_sync(&asc->battery_timer); + + hid_hw_stop(hdev); + } diff --git a/queue-6.12/hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch b/queue-6.12/hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch new file mode 100644 index 0000000000..c2f0b45788 --- /dev/null +++ b/queue-6.12/hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch @@ -0,0 +1,128 @@ +From 9bdc30e35cbc1aa78ccf01040354209f1e11ca22 Mon Sep 17 00:00:00 2001 +From: Aditya Garg +Date: Mon, 30 Jun 2025 12:37:13 +0000 +Subject: HID: magicmouse: avoid setting up battery timer when not needed + +From: Aditya Garg + +commit 9bdc30e35cbc1aa78ccf01040354209f1e11ca22 upstream. + +Currently, the battery timer is set up for all devices using +hid-magicmouse, irrespective of whether they actually need it or not. + +The current implementation requires the battery timer for Magic Mouse 2 +and Magic Trackpad 2 when connected via USB only. Add checks to ensure +that the battery timer is only set up when they are connected via USB. + +Fixes: 0b91b4e4dae6 ("HID: magicmouse: Report battery level over USB") +Cc: stable@vger.kernel.org +Signed-off-by: Aditya Garg +Signed-off-by: Jiri Kosina +Signed-off-by: Greg Kroah-Hartman +--- + +--- + drivers/hid/hid-magicmouse.c | 58 ++++++++++++++++++++++++++++--------------- + 1 file changed, 38 insertions(+), 20 deletions(-) + +--- a/drivers/hid/hid-magicmouse.c ++++ b/drivers/hid/hid-magicmouse.c +@@ -775,16 +775,30 @@ static void magicmouse_enable_mt_work(st + hid_err(msc->hdev, "unable to request touch data (%d)\n", ret); + } + ++static bool is_usb_magicmouse2(__u32 vendor, __u32 product) ++{ ++ if (vendor != USB_VENDOR_ID_APPLE) ++ return false; ++ return product == USB_DEVICE_ID_APPLE_MAGICMOUSE2; ++} ++ ++static bool is_usb_magictrackpad2(__u32 vendor, __u32 product) ++{ ++ if (vendor != USB_VENDOR_ID_APPLE) ++ return false; ++ return product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || ++ product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC; ++} ++ + static int magicmouse_fetch_battery(struct hid_device *hdev) + { + #ifdef CONFIG_HID_BATTERY_STRENGTH + struct hid_report_enum *report_enum; + struct hid_report *report; + +- if (!hdev->battery || hdev->vendor != USB_VENDOR_ID_APPLE || +- (hdev->product != USB_DEVICE_ID_APPLE_MAGICMOUSE2 && +- hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 && +- hdev->product != USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC)) ++ if (!hdev->battery || ++ (!is_usb_magicmouse2(hdev->vendor, hdev->product) && ++ !is_usb_magictrackpad2(hdev->vendor, hdev->product))) + return -1; + + report_enum = &hdev->report_enum[hdev->battery_report_type]; +@@ -846,16 +860,17 @@ static int magicmouse_probe(struct hid_d + return ret; + } + +- timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0); +- mod_timer(&msc->battery_timer, +- jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS)); +- magicmouse_fetch_battery(hdev); +- +- if (id->vendor == USB_VENDOR_ID_APPLE && +- (id->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || +- ((id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || +- id->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) && +- hdev->type != HID_TYPE_USBMOUSE))) ++ if (is_usb_magicmouse2(id->vendor, id->product) || ++ is_usb_magictrackpad2(id->vendor, id->product)) { ++ timer_setup(&msc->battery_timer, magicmouse_battery_timer_tick, 0); ++ mod_timer(&msc->battery_timer, ++ jiffies + msecs_to_jiffies(USB_BATTERY_TIMEOUT_MS)); ++ magicmouse_fetch_battery(hdev); ++ } ++ ++ if (is_usb_magicmouse2(id->vendor, id->product) || ++ (is_usb_magictrackpad2(id->vendor, id->product) && ++ hdev->type != HID_TYPE_USBMOUSE)) + return 0; + + if (!msc->input) { +@@ -911,7 +926,10 @@ static int magicmouse_probe(struct hid_d + + return 0; + err_stop_hw: +- del_timer_sync(&msc->battery_timer); ++ if (is_usb_magicmouse2(id->vendor, id->product) || ++ is_usb_magictrackpad2(id->vendor, id->product)) ++ del_timer_sync(&msc->battery_timer); ++ + hid_hw_stop(hdev); + return ret; + } +@@ -922,7 +940,9 @@ static void magicmouse_remove(struct hid + + if (msc) { + cancel_delayed_work_sync(&msc->work); +- del_timer_sync(&msc->battery_timer); ++ if (is_usb_magicmouse2(hdev->vendor, hdev->product) || ++ is_usb_magictrackpad2(hdev->vendor, hdev->product)) ++ del_timer_sync(&msc->battery_timer); + } + + hid_hw_stop(hdev); +@@ -939,10 +959,8 @@ static const __u8 *magicmouse_report_fix + * 0x05, 0x01, // Usage Page (Generic Desktop) 0 + * 0x09, 0x02, // Usage (Mouse) 2 + */ +- if (hdev->vendor == USB_VENDOR_ID_APPLE && +- (hdev->product == USB_DEVICE_ID_APPLE_MAGICMOUSE2 || +- hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2 || +- hdev->product == USB_DEVICE_ID_APPLE_MAGICTRACKPAD2_USBC) && ++ if ((is_usb_magicmouse2(hdev->vendor, hdev->product) || ++ is_usb_magictrackpad2(hdev->vendor, hdev->product)) && + *rsize == 83 && rdesc[46] == 0x84 && rdesc[58] == 0x85) { + hid_info(hdev, + "fixing up magicmouse battery report descriptor\n"); diff --git a/queue-6.12/mfd-cros_ec-separate-charge-control-probing-from-usb-pd.patch b/queue-6.12/mfd-cros_ec-separate-charge-control-probing-from-usb-pd.patch new file mode 100644 index 0000000000..010e97e58c --- /dev/null +++ b/queue-6.12/mfd-cros_ec-separate-charge-control-probing-from-usb-pd.patch @@ -0,0 +1,71 @@ +From e40fc1160d491c3bcaf8e940ae0dde0a7c5e8e14 Mon Sep 17 00:00:00 2001 +From: =?UTF-8?q?Thomas=20Wei=C3=9Fschuh?= +Date: Wed, 21 May 2025 16:42:51 +0200 +Subject: mfd: cros_ec: Separate charge-control probing from USB-PD +MIME-Version: 1.0 +Content-Type: text/plain; charset=UTF-8 +Content-Transfer-Encoding: 8bit + +From: Thomas Weißschuh + +commit e40fc1160d491c3bcaf8e940ae0dde0a7c5e8e14 upstream. + +The charge-control subsystem in the ChromeOS EC is not strictly tied to +its USB-PD subsystem. + +Since commit 7613bc0d116a ("mfd: cros_ec: Don't load charger with UCSI") +the presence of EC_FEATURE_UCSI_PPM would inhibit the probing of the +charge-control driver. + +Furthermore recent versions of the EC firmware in Framework laptops +hard-disable EC_FEATURE_USB_PD to avoid probing cros-usbpd-charger, +which then also breaks cros-charge-control. + +Instead use the dedicated EC_FEATURE_CHARGER. + +Cc: stable@vger.kernel.org +Link: https://github.com/FrameworkComputer/EmbeddedController/commit/1d7bcf1d50137c8c01969eb65880bc83e424597e +Fixes: 555b5fcdb844 ("mfd: cros_ec: Register charge control subdevice") +Signed-off-by: Thomas Weißschuh +Reviewed-by: Tzung-Bi Shih +Tested-by: Tom Vincent +Link: https://lore.kernel.org/r/20250521-cros-ec-mfd-chctl-probe-v1-1-6ebfe3a6efa7@weissschuh.net +Signed-off-by: Lee Jones +Signed-off-by: Greg Kroah-Hartman +--- + drivers/mfd/cros_ec_dev.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/drivers/mfd/cros_ec_dev.c ++++ b/drivers/mfd/cros_ec_dev.c +@@ -87,7 +87,6 @@ static const struct mfd_cell cros_ec_sen + }; + + static const struct mfd_cell cros_usbpd_charger_cells[] = { +- { .name = "cros-charge-control", }, + { .name = "cros-usbpd-charger", }, + { .name = "cros-usbpd-logger", }, + }; +@@ -108,6 +107,10 @@ static const struct mfd_cell cros_ec_key + { .name = "cros-keyboard-leds", }, + }; + ++static const struct mfd_cell cros_ec_charge_control_cells[] = { ++ { .name = "cros-charge-control", }, ++}; ++ + static const struct cros_feature_to_cells cros_subdevices[] = { + { + .id = EC_FEATURE_CEC, +@@ -144,6 +147,11 @@ static const struct cros_feature_to_cell + .mfd_cells = cros_ec_keyboard_leds_cells, + .num_cells = ARRAY_SIZE(cros_ec_keyboard_leds_cells), + }, ++ { ++ .id = EC_FEATURE_CHARGER, ++ .mfd_cells = cros_ec_charge_control_cells, ++ .num_cells = ARRAY_SIZE(cros_ec_charge_control_cells), ++ }, + }; + + static const struct mfd_cell cros_ec_platform_cells[] = { diff --git a/queue-6.12/net-add-net_passive_inc-and-net_passive_dec.patch b/queue-6.12/net-add-net_passive_inc-and-net_passive_dec.patch new file mode 100644 index 0000000000..630046cb3f --- /dev/null +++ b/queue-6.12/net-add-net_passive_inc-and-net_passive_dec.patch @@ -0,0 +1,106 @@ +From stable+bounces-168247-greg=kroah.com@vger.kernel.org Tue Aug 12 20:36:20 2025 +From: Sasha Levin +Date: Tue, 12 Aug 2025 14:32:05 -0400 +Subject: net: Add net_passive_inc() and net_passive_dec(). +To: stable@vger.kernel.org +Cc: Kuniyuki Iwashima , Eric Dumazet , Jakub Kicinski , Sasha Levin +Message-ID: <20250812183207.2024870-1-sashal@kernel.org> + +From: Kuniyuki Iwashima + +[ Upstream commit e57a6320215c3967f51ab0edeff87db2095440e4 ] + +net_drop_ns() is NULL when CONFIG_NET_NS is disabled. + +The next patch introduces a function that increments +and decrements net->passive. + +As a prep, let's rename and export net_free() to +net_passive_dec() and add net_passive_inc(). + +Suggested-by: Eric Dumazet +Link: https://lore.kernel.org/netdev/CANn89i+oUCt2VGvrbrweniTendZFEh+nwS=uonc004-aPkWy-Q@mail.gmail.com/ +Signed-off-by: Kuniyuki Iwashima +Reviewed-by: Eric Dumazet +Link: https://patch.msgid.link/20250217191129.19967-2-kuniyu@amazon.com +Signed-off-by: Jakub Kicinski +Stable-dep-of: 59b33fab4ca4 ("smb: client: fix netns refcount leak after net_passive changes") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/net/net_namespace.h | 16 ++++++++++++++++ + net/core/net_namespace.c | 8 ++++---- + 2 files changed, 20 insertions(+), 4 deletions(-) + +--- a/include/net/net_namespace.h ++++ b/include/net/net_namespace.h +@@ -291,6 +291,7 @@ static inline int check_net(const struct + } + + void net_drop_ns(void *); ++void net_passive_dec(struct net *net); + + #else + +@@ -320,8 +321,23 @@ static inline int check_net(const struct + } + + #define net_drop_ns NULL ++ ++static inline void net_passive_dec(struct net *net) ++{ ++ refcount_dec(&net->passive); ++} + #endif + ++static inline void net_passive_inc(struct net *net) ++{ ++ refcount_inc(&net->passive); ++} ++ ++/* Returns true if the netns initialization is completed successfully */ ++static inline bool net_initialized(const struct net *net) ++{ ++ return READ_ONCE(net->list.next); ++} + + static inline void __netns_tracker_alloc(struct net *net, + netns_tracker *tracker, +--- a/net/core/net_namespace.c ++++ b/net/core/net_namespace.c +@@ -458,7 +458,7 @@ static void net_complete_free(void) + + } + +-static void net_free(struct net *net) ++void net_passive_dec(struct net *net) + { + if (refcount_dec_and_test(&net->passive)) { + kfree(rcu_access_pointer(net->gen)); +@@ -476,7 +476,7 @@ void net_drop_ns(void *p) + struct net *net = (struct net *)p; + + if (net) +- net_free(net); ++ net_passive_dec(net); + } + + struct net *copy_net_ns(unsigned long flags, +@@ -517,7 +517,7 @@ put_userns: + key_remove_domain(net->key_domain); + #endif + put_user_ns(user_ns); +- net_free(net); ++ net_passive_dec(net); + dec_ucounts: + dec_net_namespaces(ucounts); + return ERR_PTR(rv); +@@ -662,7 +662,7 @@ static void cleanup_net(struct work_stru + key_remove_domain(net->key_domain); + #endif + put_user_ns(net->user_ns); +- net_free(net); ++ net_passive_dec(net); + } + } + diff --git a/queue-6.12/net-better-track-kernel-sockets-lifetime.patch b/queue-6.12/net-better-track-kernel-sockets-lifetime.patch new file mode 100644 index 0000000000..d537187dda --- /dev/null +++ b/queue-6.12/net-better-track-kernel-sockets-lifetime.patch @@ -0,0 +1,242 @@ +From stable+bounces-168248-greg=kroah.com@vger.kernel.org Tue Aug 12 20:36:36 2025 +From: Sasha Levin +Date: Tue, 12 Aug 2025 14:32:06 -0400 +Subject: net: better track kernel sockets lifetime +To: stable@vger.kernel.org +Cc: Eric Dumazet , syzbot+30a19e01a97420719891@syzkaller.appspotmail.com, Kuniyuki Iwashima , Jakub Kicinski , Sasha Levin +Message-ID: <20250812183207.2024870-2-sashal@kernel.org> + +From: Eric Dumazet + +[ Upstream commit 5c70eb5c593d64d93b178905da215a9fd288a4b5 ] + +While kernel sockets are dismantled during pernet_operations->exit(), +their freeing can be delayed by any tx packets still held in qdisc +or device queues, due to skb_set_owner_w() prior calls. + +This then trigger the following warning from ref_tracker_dir_exit() [1] + +To fix this, make sure that kernel sockets own a reference on net->passive. + +Add sk_net_refcnt_upgrade() helper, used whenever a kernel socket +is converted to a refcounted one. + +[1] + +[ 136.263918][ T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at +[ 136.263918][ T35] sk_alloc+0x2b3/0x370 +[ 136.263918][ T35] inet6_create+0x6ce/0x10f0 +[ 136.263918][ T35] __sock_create+0x4c0/0xa30 +[ 136.263918][ T35] inet_ctl_sock_create+0xc2/0x250 +[ 136.263918][ T35] igmp6_net_init+0x39/0x390 +[ 136.263918][ T35] ops_init+0x31e/0x590 +[ 136.263918][ T35] setup_net+0x287/0x9e0 +[ 136.263918][ T35] copy_net_ns+0x33f/0x570 +[ 136.263918][ T35] create_new_namespaces+0x425/0x7b0 +[ 136.263918][ T35] unshare_nsproxy_namespaces+0x124/0x180 +[ 136.263918][ T35] ksys_unshare+0x57d/0xa70 +[ 136.263918][ T35] __x64_sys_unshare+0x38/0x40 +[ 136.263918][ T35] do_syscall_64+0xf3/0x230 +[ 136.263918][ T35] entry_SYSCALL_64_after_hwframe+0x77/0x7f +[ 136.263918][ T35] +[ 136.343488][ T35] ref_tracker: net notrefcnt@ffff8880638f01e0 has 1/2 users at +[ 136.343488][ T35] sk_alloc+0x2b3/0x370 +[ 136.343488][ T35] inet6_create+0x6ce/0x10f0 +[ 136.343488][ T35] __sock_create+0x4c0/0xa30 +[ 136.343488][ T35] inet_ctl_sock_create+0xc2/0x250 +[ 136.343488][ T35] ndisc_net_init+0xa7/0x2b0 +[ 136.343488][ T35] ops_init+0x31e/0x590 +[ 136.343488][ T35] setup_net+0x287/0x9e0 +[ 136.343488][ T35] copy_net_ns+0x33f/0x570 +[ 136.343488][ T35] create_new_namespaces+0x425/0x7b0 +[ 136.343488][ T35] unshare_nsproxy_namespaces+0x124/0x180 +[ 136.343488][ T35] ksys_unshare+0x57d/0xa70 +[ 136.343488][ T35] __x64_sys_unshare+0x38/0x40 +[ 136.343488][ T35] do_syscall_64+0xf3/0x230 +[ 136.343488][ T35] entry_SYSCALL_64_after_hwframe+0x77/0x7f + +Fixes: 0cafd77dcd03 ("net: add a refcount tracker for kernel sockets") +Reported-by: syzbot+30a19e01a97420719891@syzkaller.appspotmail.com +Closes: https://lore.kernel.org/netdev/67b72aeb.050a0220.14d86d.0283.GAE@google.com/T/#u +Signed-off-by: Eric Dumazet +Reviewed-by: Kuniyuki Iwashima +Link: https://patch.msgid.link/20250220131854.4048077-1-edumazet@google.com +Signed-off-by: Jakub Kicinski +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + include/net/sock.h | 1 + + net/core/sock.c | 27 ++++++++++++++++++++++----- + net/mptcp/subflow.c | 5 +---- + net/netlink/af_netlink.c | 10 ---------- + net/rds/tcp.c | 8 ++------ + net/smc/af_smc.c | 5 +---- + net/sunrpc/svcsock.c | 5 +---- + net/sunrpc/xprtsock.c | 8 ++------ + 8 files changed, 30 insertions(+), 39 deletions(-) + +--- a/include/net/sock.h ++++ b/include/net/sock.h +@@ -1780,6 +1780,7 @@ static inline bool sock_allow_reclassifi + struct sock *sk_alloc(struct net *net, int family, gfp_t priority, + struct proto *prot, int kern); + void sk_free(struct sock *sk); ++void sk_net_refcnt_upgrade(struct sock *sk); + void sk_destruct(struct sock *sk); + struct sock *sk_clone_lock(const struct sock *sk, const gfp_t priority); + void sk_free_unlock_clone(struct sock *sk); +--- a/net/core/sock.c ++++ b/net/core/sock.c +@@ -2243,6 +2243,7 @@ struct sock *sk_alloc(struct net *net, i + get_net_track(net, &sk->ns_tracker, priority); + sock_inuse_add(net, 1); + } else { ++ net_passive_inc(net); + __netns_tracker_alloc(net, &sk->ns_tracker, + false, priority); + } +@@ -2267,6 +2268,7 @@ EXPORT_SYMBOL(sk_alloc); + static void __sk_destruct(struct rcu_head *head) + { + struct sock *sk = container_of(head, struct sock, sk_rcu); ++ struct net *net = sock_net(sk); + struct sk_filter *filter; + + if (sk->sk_destruct) +@@ -2298,14 +2300,28 @@ static void __sk_destruct(struct rcu_hea + put_cred(sk->sk_peer_cred); + put_pid(sk->sk_peer_pid); + +- if (likely(sk->sk_net_refcnt)) +- put_net_track(sock_net(sk), &sk->ns_tracker); +- else +- __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false); +- ++ if (likely(sk->sk_net_refcnt)) { ++ put_net_track(net, &sk->ns_tracker); ++ } else { ++ __netns_tracker_free(net, &sk->ns_tracker, false); ++ net_passive_dec(net); ++ } + sk_prot_free(sk->sk_prot_creator, sk); + } + ++void sk_net_refcnt_upgrade(struct sock *sk) ++{ ++ struct net *net = sock_net(sk); ++ ++ WARN_ON_ONCE(sk->sk_net_refcnt); ++ __netns_tracker_free(net, &sk->ns_tracker, false); ++ net_passive_dec(net); ++ sk->sk_net_refcnt = 1; ++ get_net_track(net, &sk->ns_tracker, GFP_KERNEL); ++ sock_inuse_add(net, 1); ++} ++EXPORT_SYMBOL_GPL(sk_net_refcnt_upgrade); ++ + void sk_destruct(struct sock *sk) + { + bool use_call_rcu = sock_flag(sk, SOCK_RCU_FREE); +@@ -2402,6 +2418,7 @@ struct sock *sk_clone_lock(const struct + * is not properly dismantling its kernel sockets at netns + * destroy time. + */ ++ net_passive_inc(sock_net(newsk)); + __netns_tracker_alloc(sock_net(newsk), &newsk->ns_tracker, + false, priority); + } +--- a/net/mptcp/subflow.c ++++ b/net/mptcp/subflow.c +@@ -1768,10 +1768,7 @@ int mptcp_subflow_create_socket(struct s + * needs it. + * Update ns_tracker to current stack trace and refcounted tracker. + */ +- __netns_tracker_free(net, &sf->sk->ns_tracker, false); +- sf->sk->sk_net_refcnt = 1; +- get_net_track(net, &sf->sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sf->sk); + err = tcp_set_ulp(sf->sk, "mptcp"); + if (err) + goto err_free; +--- a/net/netlink/af_netlink.c ++++ b/net/netlink/af_netlink.c +@@ -794,16 +794,6 @@ static int netlink_release(struct socket + + sock_prot_inuse_add(sock_net(sk), &netlink_proto, -1); + +- /* Because struct net might disappear soon, do not keep a pointer. */ +- if (!sk->sk_net_refcnt && sock_net(sk) != &init_net) { +- __netns_tracker_free(sock_net(sk), &sk->ns_tracker, false); +- /* Because of deferred_put_nlk_sk and use of work queue, +- * it is possible netns will be freed before this socket. +- */ +- sock_net_set(sk, &init_net); +- __netns_tracker_alloc(&init_net, &sk->ns_tracker, +- false, GFP_KERNEL); +- } + call_rcu(&nlk->rcu, deferred_put_nlk_sk); + return 0; + } +--- a/net/rds/tcp.c ++++ b/net/rds/tcp.c +@@ -504,12 +504,8 @@ bool rds_tcp_tune(struct socket *sock) + release_sock(sk); + return false; + } +- /* Update ns_tracker to current stack trace and refcounted tracker */ +- __netns_tracker_free(net, &sk->ns_tracker, false); +- +- sk->sk_net_refcnt = 1; +- netns_tracker_alloc(net, &sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sk); ++ put_net(net); + } + rtn = net_generic(net, rds_tcp_netid); + if (rtn->sndbuf_size > 0) { +--- a/net/smc/af_smc.c ++++ b/net/smc/af_smc.c +@@ -3353,10 +3353,7 @@ int smc_create_clcsk(struct net *net, st + * which need net ref. + */ + sk = smc->clcsock->sk; +- __netns_tracker_free(net, &sk->ns_tracker, false); +- sk->sk_net_refcnt = 1; +- get_net_track(net, &sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sk); + return 0; + } + +--- a/net/sunrpc/svcsock.c ++++ b/net/sunrpc/svcsock.c +@@ -1568,10 +1568,7 @@ static struct svc_xprt *svc_create_socke + newlen = error; + + if (protocol == IPPROTO_TCP) { +- __netns_tracker_free(net, &sock->sk->ns_tracker, false); +- sock->sk->sk_net_refcnt = 1; +- get_net_track(net, &sock->sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sock->sk); + if ((error = kernel_listen(sock, 64)) < 0) + goto bummer; + } +--- a/net/sunrpc/xprtsock.c ++++ b/net/sunrpc/xprtsock.c +@@ -1960,12 +1960,8 @@ static struct socket *xs_create_sock(str + goto out; + } + +- if (protocol == IPPROTO_TCP) { +- __netns_tracker_free(xprt->xprt_net, &sock->sk->ns_tracker, false); +- sock->sk->sk_net_refcnt = 1; +- get_net_track(xprt->xprt_net, &sock->sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(xprt->xprt_net, 1); +- } ++ if (protocol == IPPROTO_TCP) ++ sk_net_refcnt_upgrade(sock->sk); + + filp = sock_alloc_file(sock, O_NONBLOCK, NULL); + if (IS_ERR(filp)) diff --git a/queue-6.12/pci-acpi-fix-runtime-pm-ref-imbalance-on-hot-plug-capable-ports.patch b/queue-6.12/pci-acpi-fix-runtime-pm-ref-imbalance-on-hot-plug-capable-ports.patch new file mode 100644 index 0000000000..62e0169959 --- /dev/null +++ b/queue-6.12/pci-acpi-fix-runtime-pm-ref-imbalance-on-hot-plug-capable-ports.patch @@ -0,0 +1,135 @@ +From stable+bounces-169833-greg=kroah.com@vger.kernel.org Sat Aug 16 00:08:35 2025 +From: Sasha Levin +Date: Fri, 15 Aug 2025 18:08:24 -0400 +Subject: PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports +To: stable@vger.kernel.org +Cc: Lukas Wunner , Laurent Bigonville , Mario Limonciello , Bjorn Helgaas , "Rafael J. Wysocki" , Sasha Levin +Message-ID: <20250815220824.248963-3-sashal@kernel.org> + +From: Lukas Wunner + +[ Upstream commit 6cff20ce3b92ffbf2fc5eb9e5a030b3672aa414a ] + +pci_bridge_d3_possible() is called from both pcie_portdrv_probe() and +pcie_portdrv_remove() to determine whether runtime power management shall +be enabled (on probe) or disabled (on remove) on a PCIe port. + +The underlying assumption is that pci_bridge_d3_possible() always returns +the same value, else a runtime PM reference imbalance would occur. That +assumption is not given if the PCIe port is inaccessible on remove due to +hot-unplug: pci_bridge_d3_possible() calls pciehp_is_native(), which +accesses Config Space to determine whether the port is Hot-Plug Capable. +An inaccessible port returns "all ones", which is converted to "all +zeroes" by pcie_capability_read_dword(). Hence the port no longer seems +Hot-Plug Capable on remove even though it was on probe. + +The resulting runtime PM ref imbalance causes warning messages such as: + + pcieport 0000:02:04.0: Runtime PM usage count underflow! + +Avoid the Config Space access (and thus the runtime PM ref imbalance) by +caching the Hot-Plug Capable bit in struct pci_dev. + +The struct already contains an "is_hotplug_bridge" flag, which however is +not only set on Hot-Plug Capable PCIe ports, but also Conventional PCI +Hot-Plug bridges and ACPI slots. The flag identifies bridges which are +allocated additional MMIO and bus number resources to allow for hierarchy +expansion. + +The kernel is somewhat sloppily using "is_hotplug_bridge" in a number of +places to identify Hot-Plug Capable PCIe ports, even though the flag +encompasses other devices. Subsequent commits replace these occurrences +with the new flag to clearly delineate Hot-Plug Capable PCIe ports from +other kinds of hotplug bridges. + +Document the existing "is_hotplug_bridge" and the new "is_pciehp" flag +and document the (non-obvious) requirement that pci_bridge_d3_possible() +always returns the same value across the entire lifetime of a bridge, +including its hot-removal. + +Fixes: 5352a44a561d ("PCI: pciehp: Make pciehp_is_native() stricter") +Reported-by: Laurent Bigonville +Closes: https://bugzilla.kernel.org/show_bug.cgi?id=220216 +Reported-by: Mario Limonciello +Closes: https://lore.kernel.org/r/20250609020223.269407-3-superm1@kernel.org/ +Link: https://lore.kernel.org/all/20250620025535.3425049-3-superm1@kernel.org/T/#u +Signed-off-by: Lukas Wunner +Signed-off-by: Bjorn Helgaas +Acked-by: Rafael J. Wysocki +Cc: stable@vger.kernel.org # v4.18+ +Link: https://patch.msgid.link/fe5dcc3b2e62ee1df7905d746bde161eb1b3291c.1752390101.git.lukas@wunner.de +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci-acpi.c | 4 +--- + drivers/pci/pci.c | 6 +++++- + drivers/pci/probe.c | 2 +- + include/linux/pci.h | 6 ++++++ + 4 files changed, 13 insertions(+), 5 deletions(-) + +--- a/drivers/pci/pci-acpi.c ++++ b/drivers/pci/pci-acpi.c +@@ -816,13 +816,11 @@ int pci_acpi_program_hp_params(struct pc + bool pciehp_is_native(struct pci_dev *bridge) + { + const struct pci_host_bridge *host; +- u32 slot_cap; + + if (!IS_ENABLED(CONFIG_HOTPLUG_PCI_PCIE)) + return false; + +- pcie_capability_read_dword(bridge, PCI_EXP_SLTCAP, &slot_cap); +- if (!(slot_cap & PCI_EXP_SLTCAP_HPC)) ++ if (!bridge->is_pciehp) + return false; + + if (pcie_ports_native) +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -3023,8 +3023,12 @@ static const struct dmi_system_id bridge + * pci_bridge_d3_possible - Is it possible to put the bridge into D3 + * @bridge: Bridge to check + * +- * This function checks if it is possible to move the bridge to D3. + * Currently we only allow D3 for some PCIe ports and for Thunderbolt. ++ * ++ * Return: Whether it is possible to move the bridge to D3. ++ * ++ * The return value is guaranteed to be constant across the entire lifetime ++ * of the bridge, including its hot-removal. + */ + bool pci_bridge_d3_possible(struct pci_dev *bridge) + { +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -1627,7 +1627,7 @@ void set_pcie_hotplug_bridge(struct pci_ + + pcie_capability_read_dword(pdev, PCI_EXP_SLTCAP, ®32); + if (reg32 & PCI_EXP_SLTCAP_HPC) +- pdev->is_hotplug_bridge = 1; ++ pdev->is_hotplug_bridge = pdev->is_pciehp = 1; + } + + static void set_pcie_thunderbolt(struct pci_dev *dev) +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -327,6 +327,11 @@ struct rcec_ea; + * determined (e.g., for Root Complex Integrated + * Endpoints without the relevant Capability + * Registers). ++ * @is_hotplug_bridge: Hotplug bridge of any kind (e.g. PCIe Hot-Plug Capable, ++ * Conventional PCI Hot-Plug, ACPI slot). ++ * Such bridges are allocated additional MMIO and bus ++ * number resources to allow for hierarchy expansion. ++ * @is_pciehp: PCIe Hot-Plug Capable bridge. + */ + struct pci_dev { + struct list_head bus_list; /* Node in per-bus list */ +@@ -450,6 +455,7 @@ struct pci_dev { + unsigned int is_physfn:1; + unsigned int is_virtfn:1; + unsigned int is_hotplug_bridge:1; ++ unsigned int is_pciehp:1; + unsigned int shpc_managed:1; /* SHPC owned by shpchp */ + unsigned int is_thunderbolt:1; /* Thunderbolt controller */ + /* diff --git a/queue-6.12/pci-allow-pci-bridges-to-go-to-d3hot-on-all-non-x86.patch b/queue-6.12/pci-allow-pci-bridges-to-go-to-d3hot-on-all-non-x86.patch new file mode 100644 index 0000000000..60e0343ad7 --- /dev/null +++ b/queue-6.12/pci-allow-pci-bridges-to-go-to-d3hot-on-all-non-x86.patch @@ -0,0 +1,72 @@ +From stable+bounces-169832-greg=kroah.com@vger.kernel.org Sat Aug 16 00:08:38 2025 +From: Sasha Levin +Date: Fri, 15 Aug 2025 18:08:23 -0400 +Subject: PCI: Allow PCI bridges to go to D3Hot on all non-x86 +To: stable@vger.kernel.org +Cc: Manivannan Sadhasivam , Brian Norris , Bjorn Helgaas , Sasha Levin +Message-ID: <20250815220824.248963-2-sashal@kernel.org> + +From: Manivannan Sadhasivam + +[ Upstream commit a5fb3ff632876d63ee1fc5ed3af2464240145a00 ] + +Currently, pci_bridge_d3_possible() encodes a variety of decision factors +when deciding whether a given bridge can be put into D3. A particular one +of note is for "recent enough PCIe ports." Per Rafael [0]: + + "There were hardware issues related to PM on x86 platforms predating + the introduction of Connected Standby in Windows. For instance, + programming a port into D3hot by writing to its PMCSR might cause the + PCIe link behind it to go down and the only way to revive it was to + power cycle the Root Complex. And similar." + +Thus, this function contains a DMI-based check for post-2015 BIOS. + +The above factors (Windows, x86) don't really apply to non-x86 systems, and +also, many such systems don't have BIOS or DMI. However, we'd like to be +able to suspend bridges on non-x86 systems too. + +Restrict the "recent enough" check to x86. If we find further +incompatibilities, it probably makes sense to expand on the deny-list +approach (i.e., bridge_d3_blacklist or similar). + +Link: https://lore.kernel.org/r/20250320110604.v6.1.Id0a0e78ab0421b6bce51c4b0b87e6aebdfc69ec7@changeid +Link: https://lore.kernel.org/linux-pci/CAJZ5v0j_6jeMAQ7eFkZBe5Yi+USGzysxAgfemYh=-zq4h5W+Qg@mail.gmail.com/ [0] +Link: https://lore.kernel.org/linux-pci/20240227225442.GA249898@bhelgaas/ [1] +Link: https://lore.kernel.org/linux-pci/20240828210705.GA37859@bhelgaas/ [2] +[Brian: rewrite to !X86 based on Rafael's suggestions] +Signed-off-by: Manivannan Sadhasivam +Signed-off-by: Brian Norris +Signed-off-by: Bjorn Helgaas +Stable-dep-of: 6cff20ce3b92 ("PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci.c | 8 ++++---- + 1 file changed, 4 insertions(+), 4 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -3024,7 +3024,7 @@ static const struct dmi_system_id bridge + * @bridge: Bridge to check + * + * This function checks if it is possible to move the bridge to D3. +- * Currently we only allow D3 for recent enough PCIe ports and Thunderbolt. ++ * Currently we only allow D3 for some PCIe ports and for Thunderbolt. + */ + bool pci_bridge_d3_possible(struct pci_dev *bridge) + { +@@ -3068,10 +3068,10 @@ bool pci_bridge_d3_possible(struct pci_d + return false; + + /* +- * It should be safe to put PCIe ports from 2015 or newer +- * to D3. ++ * Out of caution, we only allow PCIe ports from 2015 or newer ++ * into D3 on x86. + */ +- if (dmi_get_bios_year() >= 2015) ++ if (!IS_ENABLED(CONFIG_X86) || dmi_get_bios_year() >= 2015) + return true; + break; + } diff --git a/queue-6.12/pci-store-all-pcie-supported-link-speeds.patch b/queue-6.12/pci-store-all-pcie-supported-link-speeds.patch new file mode 100644 index 0000000000..636cf62c4f --- /dev/null +++ b/queue-6.12/pci-store-all-pcie-supported-link-speeds.patch @@ -0,0 +1,220 @@ +From stable+bounces-169831-greg=kroah.com@vger.kernel.org Sat Aug 16 00:08:33 2025 +From: Sasha Levin +Date: Fri, 15 Aug 2025 18:08:22 -0400 +Subject: PCI: Store all PCIe Supported Link Speeds +To: stable@vger.kernel.org +Cc: "Ilpo Järvinen" , "Lukas Wunner" , "Bjorn Helgaas" , "Jonathan Cameron" , "Sasha Levin" +Message-ID: <20250815220824.248963-1-sashal@kernel.org> + +From: Ilpo Järvinen + +[ Upstream commit d2bd39c0456b75be9dfc7d774b8d021355c26ae3 ] + +The PCIe bandwidth controller added by a subsequent commit will require +selecting PCIe Link Speeds that are lower than the Maximum Link Speed. + +The struct pci_bus only stores max_bus_speed. Even if PCIe r6.1 sec 8.2.1 +currently disallows gaps in supported Link Speeds, the Implementation Note +in PCIe r6.1 sec 7.5.3.18, recommends determining supported Link Speeds +using the Supported Link Speeds Vector in the Link Capabilities 2 Register +(when available) to "avoid software being confused if a future +specification defines Links that do not require support for all slower +speeds." + +Reuse code in pcie_get_speed_cap() to add pcie_get_supported_speeds() to +query the Supported Link Speeds Vector of a PCIe device. The value is taken +directly from the Supported Link Speeds Vector or synthesized from the Max +Link Speed in the Link Capabilities Register when the Link Capabilities 2 +Register is not available. + +The Supported Link Speeds Vector in the Link Capabilities Register 2 +corresponds to the bus below on Root Ports and Downstream Ports, whereas it +corresponds to the bus above on Upstream Ports and Endpoints (PCIe r6.1 sec +7.5.3.18): + + Supported Link Speeds Vector - This field indicates the supported Link + speed(s) of the associated Port. + +Add supported_speeds into the struct pci_dev that caches the +Supported Link Speeds Vector. + +supported_speeds contains a set of Link Speeds only in the case where PCIe +Link Speed can be determined. Root Complex Integrated Endpoints do not have +a well-defined Link Speed because they do not implement either of the Link +Capabilities Registers, which is allowed by PCIe r6.1 sec 7.5.3 (the same +limitation applies to determining cur_bus_speed and max_bus_speed that are +PCI_SPEED_UNKNOWN in such case). This is of no concern from PCIe bandwidth +controller point of view because such devices are not attached into a PCIe +Root Port that could be controlled. + +The supported_speeds field keeps the extra reserved zero at the least +significant bit to match the Link Capabilities 2 Register layout. + +An attempt was made to store supported_speeds field into the struct pci_bus +as an intersection of both ends of the Link, however, the subordinate +struct pci_bus is not available early enough. The Target Speed quirk (in +pcie_failed_link_retrain()) can run either during initial scan or later, +requiring it to use the API provided by the PCIe bandwidth controller to +set the Target Link Speed in order to co-exist with the bandwidth +controller. When the Target Speed quirk is calling the bandwidth controller +during initial scan, the struct pci_bus is not yet initialized. As such, +storing supported_speeds into the struct pci_bus is not viable. + +Suggested-by: Lukas Wunner +Link: https://lore.kernel.org/r/20241018144755.7875-4-ilpo.jarvinen@linux.intel.com +Signed-off-by: Ilpo Järvinen +[bhelgaas: move pcie_get_supported_speeds() decl to drivers/pci/pci.h] +Signed-off-by: Bjorn Helgaas +Reviewed-by: Jonathan Cameron +Stable-dep-of: 6cff20ce3b92 ("PCI/ACPI: Fix runtime PM ref imbalance on Hot-Plug Capable ports") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/pci/pci.c | 58 ++++++++++++++++++++++++++++++------------ + drivers/pci/pci.h | 1 + drivers/pci/probe.c | 3 ++ + include/linux/pci.h | 10 ++++++- + include/uapi/linux/pci_regs.h | 1 + 5 files changed, 56 insertions(+), 17 deletions(-) + +--- a/drivers/pci/pci.c ++++ b/drivers/pci/pci.c +@@ -6199,38 +6199,64 @@ u32 pcie_bandwidth_available(struct pci_ + EXPORT_SYMBOL(pcie_bandwidth_available); + + /** +- * pcie_get_speed_cap - query for the PCI device's link speed capability ++ * pcie_get_supported_speeds - query Supported Link Speed Vector + * @dev: PCI device to query + * +- * Query the PCI device speed capability. Return the maximum link speed +- * supported by the device. ++ * Query @dev supported link speeds. ++ * ++ * Implementation Note in PCIe r6.0 sec 7.5.3.18 recommends determining ++ * supported link speeds using the Supported Link Speeds Vector in the Link ++ * Capabilities 2 Register (when available). ++ * ++ * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. ++ * ++ * Without Link Capabilities 2, i.e., prior to PCIe r3.0, Supported Link ++ * Speeds field in Link Capabilities is used and only 2.5 GT/s and 5.0 GT/s ++ * speeds were defined. ++ * ++ * For @dev without Supported Link Speed Vector, the field is synthesized ++ * from the Max Link Speed field in the Link Capabilities Register. ++ * ++ * Return: Supported Link Speeds Vector (+ reserved 0 at LSB). + */ +-enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) ++u8 pcie_get_supported_speeds(struct pci_dev *dev) + { + u32 lnkcap2, lnkcap; ++ u8 speeds; + + /* +- * Link Capabilities 2 was added in PCIe r3.0, sec 7.8.18. The +- * implementation note there recommends using the Supported Link +- * Speeds Vector in Link Capabilities 2 when supported. +- * +- * Without Link Capabilities 2, i.e., prior to PCIe r3.0, software +- * should use the Supported Link Speeds field in Link Capabilities, +- * where only 2.5 GT/s and 5.0 GT/s speeds were defined. ++ * Speeds retain the reserved 0 at LSB before PCIe Supported Link ++ * Speeds Vector to allow using SLS Vector bit defines directly. + */ + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP2, &lnkcap2); ++ speeds = lnkcap2 & PCI_EXP_LNKCAP2_SLS; + + /* PCIe r3.0-compliant */ +- if (lnkcap2) +- return PCIE_LNKCAP2_SLS2SPEED(lnkcap2); ++ if (speeds) ++ return speeds; + + pcie_capability_read_dword(dev, PCI_EXP_LNKCAP, &lnkcap); ++ ++ /* Synthesize from the Max Link Speed field */ + if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_5_0GB) +- return PCIE_SPEED_5_0GT; ++ speeds = PCI_EXP_LNKCAP2_SLS_5_0GB | PCI_EXP_LNKCAP2_SLS_2_5GB; + else if ((lnkcap & PCI_EXP_LNKCAP_SLS) == PCI_EXP_LNKCAP_SLS_2_5GB) +- return PCIE_SPEED_2_5GT; ++ speeds = PCI_EXP_LNKCAP2_SLS_2_5GB; ++ ++ return speeds; ++} + +- return PCI_SPEED_UNKNOWN; ++/** ++ * pcie_get_speed_cap - query for the PCI device's link speed capability ++ * @dev: PCI device to query ++ * ++ * Query the PCI device speed capability. ++ * ++ * Return: the maximum link speed supported by the device. ++ */ ++enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev) ++{ ++ return PCIE_LNKCAP2_SLS2SPEED(dev->supported_speeds); + } + EXPORT_SYMBOL(pcie_get_speed_cap); + +--- a/drivers/pci/pci.h ++++ b/drivers/pci/pci.h +@@ -390,6 +390,7 @@ static inline int pcie_dev_speed_mbps(en + return -EINVAL; + } + ++u8 pcie_get_supported_speeds(struct pci_dev *dev); + const char *pci_speed_string(enum pci_bus_speed speed); + enum pci_bus_speed pcie_get_speed_cap(struct pci_dev *dev); + enum pcie_link_width pcie_get_width_cap(struct pci_dev *dev); +--- a/drivers/pci/probe.c ++++ b/drivers/pci/probe.c +@@ -1972,6 +1972,9 @@ int pci_setup_device(struct pci_dev *dev + + set_pcie_untrusted(dev); + ++ if (pci_is_pcie(dev)) ++ dev->supported_speeds = pcie_get_supported_speeds(dev); ++ + /* "Unknown power state" */ + dev->current_state = PCI_UNKNOWN; + +--- a/include/linux/pci.h ++++ b/include/linux/pci.h +@@ -320,7 +320,14 @@ struct pci_sriov; + struct pci_p2pdma; + struct rcec_ea; + +-/* The pci_dev structure describes PCI devices */ ++/* struct pci_dev - describes a PCI device ++ * ++ * @supported_speeds: PCIe Supported Link Speeds Vector (+ reserved 0 at ++ * LSB). 0 when the supported speeds cannot be ++ * determined (e.g., for Root Complex Integrated ++ * Endpoints without the relevant Capability ++ * Registers). ++ */ + struct pci_dev { + struct list_head bus_list; /* Node in per-bus list */ + struct pci_bus *bus; /* Bus this device is on */ +@@ -524,6 +531,7 @@ struct pci_dev { + struct npem *npem; /* Native PCIe Enclosure Management */ + #endif + u16 acs_cap; /* ACS Capability offset */ ++ u8 supported_speeds; /* Supported Link Speeds Vector */ + phys_addr_t rom; /* Physical address if not from BAR */ + size_t romlen; /* Length if not from BAR */ + /* +--- a/include/uapi/linux/pci_regs.h ++++ b/include/uapi/linux/pci_regs.h +@@ -678,6 +678,7 @@ + #define PCI_EXP_DEVSTA2 0x2a /* Device Status 2 */ + #define PCI_CAP_EXP_RC_ENDPOINT_SIZEOF_V2 0x2c /* end of v2 EPs w/o link */ + #define PCI_EXP_LNKCAP2 0x2c /* Link Capabilities 2 */ ++#define PCI_EXP_LNKCAP2_SLS 0x000000fe /* Supported Link Speeds Vector */ + #define PCI_EXP_LNKCAP2_SLS_2_5GB 0x00000002 /* Supported Speed 2.5GT/s */ + #define PCI_EXP_LNKCAP2_SLS_5_0GB 0x00000004 /* Supported Speed 5GT/s */ + #define PCI_EXP_LNKCAP2_SLS_8_0GB 0x00000008 /* Supported Speed 8GT/s */ diff --git a/queue-6.12/rust-kbuild-clean-output-before-running-rustdoc.patch b/queue-6.12/rust-kbuild-clean-output-before-running-rustdoc.patch new file mode 100644 index 0000000000..cefd33b420 --- /dev/null +++ b/queue-6.12/rust-kbuild-clean-output-before-running-rustdoc.patch @@ -0,0 +1,69 @@ +From 252fea131e15aba2cd487119d1a8f546471199e2 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Sat, 26 Jul 2025 15:34:35 +0200 +Subject: rust: kbuild: clean output before running `rustdoc` + +From: Miguel Ojeda + +commit 252fea131e15aba2cd487119d1a8f546471199e2 upstream. + +`rustdoc` can get confused when generating documentation into a folder +that contains generated files from other `rustdoc` versions. + +For instance, running something like: + + rustup default 1.78.0 + make LLVM=1 rustdoc + rustup default 1.88.0 + make LLVM=1 rustdoc + +may generate errors like: + + error: couldn't generate documentation: invalid template: last line expected to start with a comment + | + = note: failed to create or modify "./Documentation/output/rust/rustdoc/src-files.js" + +Thus just always clean the output folder before generating the +documentation -- we are anyway regenerating it every time the `rustdoc` +target gets called, at least for the time being. + +Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). +Reported-by: Daniel Almeida +Closes: https://rust-for-linux.zulipchat.com/#narrow/channel/288089/topic/x/near/527201113 +Reviewed-by: Tamir Duberstein +Link: https://lore.kernel.org/r/20250726133435.2460085-1-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/Makefile | 7 +++++-- + 1 file changed, 5 insertions(+), 2 deletions(-) + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -92,14 +92,14 @@ rustdoc: rustdoc-core rustdoc-macros rus + rustdoc-macros: private rustdoc_host = yes + rustdoc-macros: private rustc_target_flags = --crate-type proc-macro \ + --extern proc_macro +-rustdoc-macros: $(src)/macros/lib.rs FORCE ++rustdoc-macros: $(src)/macros/lib.rs rustdoc-clean FORCE + +$(call if_changed,rustdoc) + + # Starting with Rust 1.82.0, skipping `-Wrustdoc::unescaped_backticks` should + # not be needed -- see https://github.com/rust-lang/rust/pull/128307. + rustdoc-core: private skip_flags = --edition=2021 -Wrustdoc::unescaped_backticks + rustdoc-core: private rustc_target_flags = --edition=$(core-edition) $(core-cfgs) +-rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs FORCE ++rustdoc-core: $(RUST_LIB_SRC)/core/src/lib.rs rustdoc-clean FORCE + +$(call if_changed,rustdoc) + + rustdoc-compiler_builtins: $(src)/compiler_builtins.rs rustdoc-core FORCE +@@ -116,6 +116,9 @@ rustdoc-kernel: $(src)/kernel/lib.rs rus + $(obj)/bindings.o FORCE + +$(call if_changed,rustdoc) + ++rustdoc-clean: FORCE ++ $(Q)rm -rf $(rustdoc_output) ++ + quiet_cmd_rustc_test_library = RUSTC TL $< + cmd_rustc_test_library = \ + OBJTREE=$(abspath $(objtree)) \ diff --git a/queue-6.12/rust-workaround-rustdoc-target-modifiers-bug.patch b/queue-6.12/rust-workaround-rustdoc-target-modifiers-bug.patch new file mode 100644 index 0000000000..5edf1a3028 --- /dev/null +++ b/queue-6.12/rust-workaround-rustdoc-target-modifiers-bug.patch @@ -0,0 +1,81 @@ +From abbf9a44944171ca99c150adad9361a2f517d3b6 Mon Sep 17 00:00:00 2001 +From: Miguel Ojeda +Date: Sun, 27 Jul 2025 11:23:17 +0200 +Subject: rust: workaround `rustdoc` target modifiers bug + +From: Miguel Ojeda + +commit abbf9a44944171ca99c150adad9361a2f517d3b6 upstream. + +Starting with Rust 1.88.0 (released 2025-06-26), `rustdoc` complains +about a target modifier mismatch in configurations where `-Zfixed-x18` +is passed: + + error: mixing `-Zfixed-x18` will cause an ABI mismatch in crate `rust_out` + | + = help: the `-Zfixed-x18` flag modifies the ABI so Rust crates compiled with different values of this flag cannot be used together safely + = note: unset `-Zfixed-x18` in this crate is incompatible with `-Zfixed-x18=` in dependency `core` + = help: set `-Zfixed-x18=` in this crate or unset `-Zfixed-x18` in `core` + = help: if you are sure this will not cause problems, you may use `-Cunsafe-allow-abi-mismatch=fixed-x18` to silence this error + +The reason is that `rustdoc` was not passing the target modifiers when +configuring the session options, and thus it would report a mismatch +that did not exist as soon as a target modifier is used in a dependency. + +We did not notice it in the kernel until now because `-Zfixed-x18` has +been a target modifier only since 1.88.0 (and it is the only one we use +so far). + +The issue has been reported upstream [1] and a fix has been submitted +[2], including a test similar to the kernel case. + + [ This is now fixed upstream (thanks Guillaume for the quick review), + so it will be fixed in Rust 1.90.0 (expected 2025-09-18). + + - Miguel ] + +Meanwhile, conditionally pass `-Cunsafe-allow-abi-mismatch=fixed-x18` +to workaround the issue on our side. + +Cc: stable@vger.kernel.org # Needed in 6.12.y and later (Rust is pinned in older LTSs). +Reported-by: Konrad Dybcio +Closes: https://lore.kernel.org/rust-for-linux/36cdc798-524f-4910-8b77-d7b9fac08d77@oss.qualcomm.com/ +Link: https://github.com/rust-lang/rust/issues/144521 [1] +Link: https://github.com/rust-lang/rust/pull/144523 [2] +Reviewed-by: Alice Ryhl +Link: https://lore.kernel.org/r/20250727092317.2930617-1-ojeda@kernel.org +Signed-off-by: Miguel Ojeda +Signed-off-by: Greg Kroah-Hartman +--- + rust/Makefile | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/rust/Makefile ++++ b/rust/Makefile +@@ -55,6 +55,10 @@ core-cfgs = \ + + core-edition := $(if $(call rustc-min-version,108700),2024,2021) + ++# `rustdoc` did not save the target modifiers, thus workaround for ++# the time being (https://github.com/rust-lang/rust/issues/144521). ++rustdoc_modifiers_workaround := $(if $(call rustc-min-version,108800),-Cunsafe-allow-abi-mismatch=fixed-x18) ++ + quiet_cmd_rustdoc = RUSTDOC $(if $(rustdoc_host),H, ) $< + cmd_rustdoc = \ + OBJTREE=$(abspath $(objtree)) \ +@@ -63,6 +67,7 @@ quiet_cmd_rustdoc = RUSTDOC $(if $(rustd + -Zunstable-options --generate-link-to-definition \ + --output $(rustdoc_output) \ + --crate-name $(subst rustdoc-,,$@) \ ++ $(rustdoc_modifiers_workaround) \ + $(if $(rustdoc_host),,--sysroot=/dev/null) \ + @$(objtree)/include/generated/rustc_cfg $< + +@@ -178,6 +183,7 @@ quiet_cmd_rustdoc_test_kernel = RUSTDOC + --extern bindings --extern uapi \ + --no-run --crate-name kernel -Zunstable-options \ + --sysroot=/dev/null \ ++ $(rustdoc_modifiers_workaround) \ + --test-builder $(objtree)/scripts/rustdoc_test_builder \ + $< $(rustdoc_test_kernel_quiet); \ + $(objtree)/scripts/rustdoc_test_gen diff --git a/queue-6.12/series b/queue-6.12/series index 76637ede13..4b7cf78d2c 100644 --- a/queue-6.12/series +++ b/queue-6.12/series @@ -419,3 +419,18 @@ media-uvcvideo-do-not-mark-valid-metadata-as-invalid.patch media-v4l2-add-support-for-nv12m-tiled-variants-to-v4l2_format_info.patch tools-nolibc-fix-spelling-of-fd_setbitmask-in-fd_-macros.patch rdma-siw-fix-the-sendmsg-byte-count-in-siw_tcp_sendpages.patch +hid-magicmouse-avoid-setting-up-battery-timer-when-not-needed.patch +wifi-mac80211-check-basic-rates-validity-in-sta_link_apply_parameters.patch +tools-hv-fcopy-fix-irregularities-with-size-of-ring-buffer.patch +hid-apple-avoid-setting-up-battery-timer-for-devices-without-battery.patch +mfd-cros_ec-separate-charge-control-probing-from-usb-pd.patch +net-add-net_passive_inc-and-net_passive_dec.patch +net-better-track-kernel-sockets-lifetime.patch +smb-client-fix-netns-refcount-leak-after-net_passive-changes.patch +pci-store-all-pcie-supported-link-speeds.patch +pci-allow-pci-bridges-to-go-to-d3hot-on-all-non-x86.patch +pci-acpi-fix-runtime-pm-ref-imbalance-on-hot-plug-capable-ports.patch +arm64-dts-ti-k3-j722s-evm-fix-usb2.0_mux_sel-to-select-type-c.patch +arm64-dts-ti-k3-j722s-evm-fix-usb-gpio-hog-level-for-type-c.patch +rust-kbuild-clean-output-before-running-rustdoc.patch +rust-workaround-rustdoc-target-modifiers-bug.patch diff --git a/queue-6.12/smb-client-fix-netns-refcount-leak-after-net_passive-changes.patch b/queue-6.12/smb-client-fix-netns-refcount-leak-after-net_passive-changes.patch new file mode 100644 index 0000000000..b34ad7dbdb --- /dev/null +++ b/queue-6.12/smb-client-fix-netns-refcount-leak-after-net_passive-changes.patch @@ -0,0 +1,128 @@ +From stable+bounces-168250-greg=kroah.com@vger.kernel.org Tue Aug 12 20:33:14 2025 +From: Sasha Levin +Date: Tue, 12 Aug 2025 14:32:07 -0400 +Subject: smb: client: fix netns refcount leak after net_passive changes +To: stable@vger.kernel.org +Cc: Wang Zhaolong , Kuniyuki Iwashima , Enzo Matsumiya , Steve French , Sasha Levin +Message-ID: <20250812183207.2024870-3-sashal@kernel.org> + +From: Wang Zhaolong + +[ Upstream commit 59b33fab4ca4d7dacc03367082777627e05d0323 ] + +After commit 5c70eb5c593d ("net: better track kernel sockets lifetime"), +kernel sockets now use net_passive reference counting. However, commit +95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock after rmmod"") +restored the manual socket refcount manipulation without adapting to this +new mechanism, causing a memory leak. + +The issue can be reproduced by[1]: +1. Creating a network namespace +2. Mounting and Unmounting CIFS within the namespace +3. Deleting the namespace + +Some memory leaks may appear after a period of time following step 3. + +unreferenced object 0xffff9951419f6b00 (size 256): + comm "ip", pid 447, jiffies 4294692389 (age 14.730s) + hex dump (first 32 bytes): + 1b 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 ................ + 00 00 00 00 00 00 00 00 80 77 c2 44 51 99 ff ff .........w.DQ... + backtrace: + __kmem_cache_alloc_node+0x30e/0x3d0 + __kmalloc+0x52/0x120 + net_alloc_generic+0x1d/0x30 + copy_net_ns+0x86/0x200 + create_new_namespaces+0x117/0x300 + unshare_nsproxy_namespaces+0x60/0xa0 + ksys_unshare+0x148/0x360 + __x64_sys_unshare+0x12/0x20 + do_syscall_64+0x59/0x110 + entry_SYSCALL_64_after_hwframe+0x78/0xe2 +... +unreferenced object 0xffff9951442e7500 (size 32): + comm "mount.cifs", pid 475, jiffies 4294693782 (age 13.343s) + hex dump (first 32 bytes): + 40 c5 38 46 51 99 ff ff 18 01 96 42 51 99 ff ff @.8FQ......BQ... + 01 00 00 00 6f 00 c5 07 6f 00 d8 07 00 00 00 00 ....o...o....... + backtrace: + __kmem_cache_alloc_node+0x30e/0x3d0 + kmalloc_trace+0x2a/0x90 + ref_tracker_alloc+0x8e/0x1d0 + sk_alloc+0x18c/0x1c0 + inet_create+0xf1/0x370 + __sock_create+0xd7/0x1e0 + generic_ip_connect+0x1d4/0x5a0 [cifs] + cifs_get_tcp_session+0x5d0/0x8a0 [cifs] + cifs_mount_get_session+0x47/0x1b0 [cifs] + dfs_mount_share+0xfa/0xa10 [cifs] + cifs_mount+0x68/0x2b0 [cifs] + cifs_smb3_do_mount+0x10b/0x760 [cifs] + smb3_get_tree+0x112/0x2e0 [cifs] + vfs_get_tree+0x29/0xf0 + path_mount+0x2d4/0xa00 + __se_sys_mount+0x165/0x1d0 + +Root cause: +When creating kernel sockets, sk_alloc() calls net_passive_inc() for +sockets with sk_net_refcnt=0. The CIFS code manually converts kernel +sockets to user sockets by setting sk_net_refcnt=1, but doesn't call +the corresponding net_passive_dec(). This creates an imbalance in the +net_passive counter, which prevents the network namespace from being +destroyed when its last user reference is dropped. As a result, the +entire namespace and all its associated resources remain allocated. + +Timeline of patches leading to this issue: +- commit ef7134c7fc48 ("smb: client: Fix use-after-free of network + namespace.") in v6.12 fixed the original netns UAF by manually + managing socket refcounts +- commit e9f2517a3e18 ("smb: client: fix TCP timers deadlock after + rmmod") in v6.13 attempted to use kernel sockets but introduced + TCP timer issues +- commit 5c70eb5c593d ("net: better track kernel sockets lifetime") + in v6.14-rc5 introduced the net_passive mechanism with + sk_net_refcnt_upgrade() for proper socket conversion +- commit 95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock + after rmmod"") in v6.15-rc3 reverted to manual refcount management + without adapting to the new net_passive changes + +Fix this by using sk_net_refcnt_upgrade() which properly handles the +net_passive counter when converting kernel sockets to user sockets. + +Link: https://bugzilla.kernel.org/show_bug.cgi?id=220343 [1] +Fixes: 95d2b9f693ff ("Revert "smb: client: fix TCP timers deadlock after rmmod"") +Cc: stable@vger.kernel.org +Reviewed-by: Kuniyuki Iwashima +Reviewed-by: Enzo Matsumiya +Signed-off-by: Wang Zhaolong +Signed-off-by: Steve French +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/smb/client/connect.c | 9 +++------ + 1 file changed, 3 insertions(+), 6 deletions(-) + +--- a/fs/smb/client/connect.c ++++ b/fs/smb/client/connect.c +@@ -3165,18 +3165,15 @@ generic_ip_connect(struct TCP_Server_Inf + struct net *net = cifs_net_ns(server); + struct sock *sk; + +- rc = __sock_create(net, sfamily, SOCK_STREAM, +- IPPROTO_TCP, &server->ssocket, 1); ++ rc = sock_create_kern(net, sfamily, SOCK_STREAM, ++ IPPROTO_TCP, &server->ssocket); + if (rc < 0) { + cifs_server_dbg(VFS, "Error %d creating socket\n", rc); + return rc; + } + + sk = server->ssocket->sk; +- __netns_tracker_free(net, &sk->ns_tracker, false); +- sk->sk_net_refcnt = 1; +- get_net_track(net, &sk->ns_tracker, GFP_KERNEL); +- sock_inuse_add(net, 1); ++ sk_net_refcnt_upgrade(sk); + + /* BB other socket options to set KEEPALIVE, NODELAY? */ + cifs_dbg(FYI, "Socket created\n"); diff --git a/queue-6.12/tools-hv-fcopy-fix-irregularities-with-size-of-ring-buffer.patch b/queue-6.12/tools-hv-fcopy-fix-irregularities-with-size-of-ring-buffer.patch new file mode 100644 index 0000000000..af1cdfa702 --- /dev/null +++ b/queue-6.12/tools-hv-fcopy-fix-irregularities-with-size-of-ring-buffer.patch @@ -0,0 +1,180 @@ +From a4131a50d072b369bfed0b41e741c41fd8048641 Mon Sep 17 00:00:00 2001 +From: Naman Jain +Date: Fri, 11 Jul 2025 11:38:46 +0530 +Subject: tools/hv: fcopy: Fix irregularities with size of ring buffer + +From: Naman Jain + +commit a4131a50d072b369bfed0b41e741c41fd8048641 upstream. + +Size of ring buffer, as defined in uio_hv_generic driver, is no longer +fixed to 16 KB. This creates a problem in fcopy, since this size was +hardcoded. With the change in place to make ring sysfs node actually +reflect the size of underlying ring buffer, it is safe to get the size +of ring sysfs file and use it for ring buffer size in fcopy daemon. +Fix the issue of disparity in ring buffer size, by making it dynamic +in fcopy uio daemon. + +Cc: stable@vger.kernel.org +Fixes: 0315fef2aff9 ("uio_hv_generic: Align ring size to system page") +Signed-off-by: Naman Jain +Reviewed-by: Saurabh Sengar +Reviewed-by: Long Li +Link: https://lore.kernel.org/r/20250711060846.9168-1-namjain@linux.microsoft.com +Signed-off-by: Wei Liu +Message-ID: <20250711060846.9168-1-namjain@linux.microsoft.com> +Signed-off-by: Greg Kroah-Hartman +--- + tools/hv/hv_fcopy_uio_daemon.c | 91 ++++++++++++++++++++++++++++++++++++----- + 1 file changed, 81 insertions(+), 10 deletions(-) + +--- a/tools/hv/hv_fcopy_uio_daemon.c ++++ b/tools/hv/hv_fcopy_uio_daemon.c +@@ -35,7 +35,10 @@ + #define WIN8_SRV_MINOR 1 + #define WIN8_SRV_VERSION (WIN8_SRV_MAJOR << 16 | WIN8_SRV_MINOR) + +-#define FCOPY_UIO "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/uio" ++#define FCOPY_DEVICE_PATH(subdir) \ ++ "/sys/bus/vmbus/devices/eb765408-105f-49b6-b4aa-c123b64d17d4/" #subdir ++#define FCOPY_UIO_PATH FCOPY_DEVICE_PATH(uio) ++#define FCOPY_CHANNELS_PATH FCOPY_DEVICE_PATH(channels) + + #define FCOPY_VER_COUNT 1 + static const int fcopy_versions[] = { +@@ -47,9 +50,62 @@ static const int fw_versions[] = { + UTIL_FW_VERSION + }; + +-#define HV_RING_SIZE 0x4000 /* 16KB ring buffer size */ ++static uint32_t get_ring_buffer_size(void) ++{ ++ char ring_path[PATH_MAX]; ++ DIR *dir; ++ struct dirent *entry; ++ struct stat st; ++ uint32_t ring_size = 0; ++ int retry_count = 0; + +-static unsigned char desc[HV_RING_SIZE]; ++ /* Find the channel directory */ ++ dir = opendir(FCOPY_CHANNELS_PATH); ++ if (!dir) { ++ usleep(100 * 1000); /* Avoid race with kernel, wait 100ms and retry once */ ++ dir = opendir(FCOPY_CHANNELS_PATH); ++ if (!dir) { ++ syslog(LOG_ERR, "Failed to open channels directory: %s", strerror(errno)); ++ return 0; ++ } ++ } ++ ++retry_once: ++ while ((entry = readdir(dir)) != NULL) { ++ if (entry->d_type == DT_DIR && strcmp(entry->d_name, ".") != 0 && ++ strcmp(entry->d_name, "..") != 0) { ++ snprintf(ring_path, sizeof(ring_path), "%s/%s/ring", ++ FCOPY_CHANNELS_PATH, entry->d_name); ++ ++ if (stat(ring_path, &st) == 0) { ++ /* ++ * stat returns size of Tx, Rx rings combined, ++ * so take half of it for individual ring size. ++ */ ++ ring_size = (uint32_t)st.st_size / 2; ++ syslog(LOG_INFO, "Ring buffer size from %s: %u bytes", ++ ring_path, ring_size); ++ break; ++ } ++ } ++ } ++ ++ if (!ring_size && retry_count == 0) { ++ retry_count = 1; ++ rewinddir(dir); ++ usleep(100 * 1000); /* Wait 100ms and retry once */ ++ goto retry_once; ++ } ++ ++ closedir(dir); ++ ++ if (!ring_size) ++ syslog(LOG_ERR, "Could not determine ring size"); ++ ++ return ring_size; ++} ++ ++static unsigned char *desc; + + static int target_fd; + static char target_fname[PATH_MAX]; +@@ -397,7 +453,7 @@ int main(int argc, char *argv[]) + int daemonize = 1, long_index = 0, opt, ret = -EINVAL; + struct vmbus_br txbr, rxbr; + void *ring; +- uint32_t len = HV_RING_SIZE; ++ uint32_t ring_size, len; + char uio_name[NAME_MAX] = {0}; + char uio_dev_path[PATH_MAX] = {0}; + +@@ -428,7 +484,20 @@ int main(int argc, char *argv[]) + openlog("HV_UIO_FCOPY", 0, LOG_USER); + syslog(LOG_INFO, "starting; pid is:%d", getpid()); + +- fcopy_get_first_folder(FCOPY_UIO, uio_name); ++ ring_size = get_ring_buffer_size(); ++ if (!ring_size) { ++ ret = -ENODEV; ++ goto exit; ++ } ++ ++ desc = malloc(ring_size * sizeof(unsigned char)); ++ if (!desc) { ++ syslog(LOG_ERR, "malloc failed for desc buffer"); ++ ret = -ENOMEM; ++ goto exit; ++ } ++ ++ fcopy_get_first_folder(FCOPY_UIO_PATH, uio_name); + snprintf(uio_dev_path, sizeof(uio_dev_path), "/dev/%s", uio_name); + fcopy_fd = open(uio_dev_path, O_RDWR); + +@@ -436,17 +505,17 @@ int main(int argc, char *argv[]) + syslog(LOG_ERR, "open %s failed; error: %d %s", + uio_dev_path, errno, strerror(errno)); + ret = fcopy_fd; +- goto exit; ++ goto free_desc; + } + +- ring = vmbus_uio_map(&fcopy_fd, HV_RING_SIZE); ++ ring = vmbus_uio_map(&fcopy_fd, ring_size); + if (!ring) { + ret = errno; + syslog(LOG_ERR, "mmap ringbuffer failed; error: %d %s", ret, strerror(ret)); + goto close; + } +- vmbus_br_setup(&txbr, ring, HV_RING_SIZE); +- vmbus_br_setup(&rxbr, (char *)ring + HV_RING_SIZE, HV_RING_SIZE); ++ vmbus_br_setup(&txbr, ring, ring_size); ++ vmbus_br_setup(&rxbr, (char *)ring + ring_size, ring_size); + + rxbr.vbr->imask = 0; + +@@ -461,7 +530,7 @@ int main(int argc, char *argv[]) + continue; + } + +- len = HV_RING_SIZE; ++ len = ring_size; + ret = rte_vmbus_chan_recv_raw(&rxbr, desc, &len); + if (unlikely(ret <= 0)) { + /* This indicates a failure to communicate (or worse) */ +@@ -481,6 +550,8 @@ int main(int argc, char *argv[]) + } + close: + close(fcopy_fd); ++free_desc: ++ free(desc); + exit: + return ret; + } diff --git a/queue-6.12/wifi-mac80211-check-basic-rates-validity-in-sta_link_apply_parameters.patch b/queue-6.12/wifi-mac80211-check-basic-rates-validity-in-sta_link_apply_parameters.patch new file mode 100644 index 0000000000..428afa341c --- /dev/null +++ b/queue-6.12/wifi-mac80211-check-basic-rates-validity-in-sta_link_apply_parameters.patch @@ -0,0 +1,54 @@ +From 16ee3ea8faef8ff042acc15867a6c458c573de61 Mon Sep 17 00:00:00 2001 +From: Mikhail Lobanov +Date: Mon, 17 Mar 2025 13:31:37 +0300 +Subject: wifi: mac80211: check basic rates validity in sta_link_apply_parameters + +From: Mikhail Lobanov + +commit 16ee3ea8faef8ff042acc15867a6c458c573de61 upstream. + +When userspace sets supported rates for a new station via +NL80211_CMD_NEW_STATION, it might send a list that's empty +or contains only invalid values. Currently, we process these +values in sta_link_apply_parameters() without checking the result of +ieee80211_parse_bitrates(), which can lead to an empty rates bitmap. + +A similar issue was addressed for NL80211_CMD_SET_BSS in commit +ce04abc3fcc6 ("wifi: mac80211: check basic rates validity"). +This patch applies the same approach in sta_link_apply_parameters() +for NL80211_CMD_NEW_STATION, ensuring there is at least one valid +rate by inspecting the result of ieee80211_parse_bitrates(). + +Found by Linux Verification Center (linuxtesting.org) with Syzkaller. + +Fixes: b95eb7f0eee4 ("wifi: cfg80211/mac80211: separate link params from station params") +Signed-off-by: Mikhail Lobanov +Link: https://patch.msgid.link/20250317103139.17625-1-m.lobanov@rosa.ru +Signed-off-by: Johannes Berg +Signed-off-by: Hanne-Lotta Mäenpää +Signed-off-by: Greg Kroah-Hartman +--- + net/mac80211/cfg.c | 12 ++++++------ + 1 file changed, 6 insertions(+), 6 deletions(-) + +--- a/net/mac80211/cfg.c ++++ b/net/mac80211/cfg.c +@@ -1879,12 +1879,12 @@ static int sta_link_apply_parameters(str + } + + if (params->supported_rates && +- params->supported_rates_len) { +- ieee80211_parse_bitrates(link->conf->chanreq.oper.width, +- sband, params->supported_rates, +- params->supported_rates_len, +- &link_sta->pub->supp_rates[sband->band]); +- } ++ params->supported_rates_len && ++ !ieee80211_parse_bitrates(link->conf->chanreq.oper.width, ++ sband, params->supported_rates, ++ params->supported_rates_len, ++ &link_sta->pub->supp_rates[sband->band])) ++ return -EINVAL; + + if (params->ht_capa) + ieee80211_ht_cap_ie_to_sta_ht_cap(sdata, sband,