From a827fb3760c20340bb06a88577b48d72648a22a2 Mon Sep 17 00:00:00 2001 From: Greg Kroah-Hartman Date: Mon, 3 Nov 2025 10:42:36 +0900 Subject: [PATCH] 5.10-stable patches added patches: can-gs_usb-increase-max-interface-to-u8_max.patch devcoredump-fix-circular-locking-dependency-with-devcd-mutex.patch net-phy-dp83867-disable-eee-support-as-not-implemented.patch net-ravb-enforce-descriptor-type-ordering.patch serial-8250_dw-handle-reset-control-deassert-error.patch serial-8250_dw-use-devm_add_action_or_reset.patch x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch xfs-always-warn-about-deprecated-mount-options.patch --- ...usb-increase-max-interface-to-u8_max.patch | 117 ++++++ ...-locking-dependency-with-devcd-mutex.patch | 389 ++++++++++++++++++ ...sable-eee-support-as-not-implemented.patch | 55 +++ ...avb-enforce-descriptor-type-ordering.patch | 75 ++++ ...-handle-reset-control-deassert-error.patch | 47 +++ ...8250_dw-use-devm_add_action_or_reset.patch | 143 +++++++ queue-5.10/series | 8 + ...tivating-previously-unavailable-rmid.patch | 139 +++++++ ...-warn-about-deprecated-mount-options.patch | 93 +++++ 9 files changed, 1066 insertions(+) create mode 100644 queue-5.10/can-gs_usb-increase-max-interface-to-u8_max.patch create mode 100644 queue-5.10/devcoredump-fix-circular-locking-dependency-with-devcd-mutex.patch create mode 100644 queue-5.10/net-phy-dp83867-disable-eee-support-as-not-implemented.patch create mode 100644 queue-5.10/net-ravb-enforce-descriptor-type-ordering.patch create mode 100644 queue-5.10/serial-8250_dw-handle-reset-control-deassert-error.patch create mode 100644 queue-5.10/serial-8250_dw-use-devm_add_action_or_reset.patch create mode 100644 queue-5.10/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch create mode 100644 queue-5.10/xfs-always-warn-about-deprecated-mount-options.patch diff --git a/queue-5.10/can-gs_usb-increase-max-interface-to-u8_max.patch b/queue-5.10/can-gs_usb-increase-max-interface-to-u8_max.patch new file mode 100644 index 0000000000..9cd194edd6 --- /dev/null +++ b/queue-5.10/can-gs_usb-increase-max-interface-to-u8_max.patch @@ -0,0 +1,117 @@ +From stable+bounces-189972-greg=kroah.com@vger.kernel.org Mon Oct 27 22:13:41 2025 +From: Celeste Liu +Date: Mon, 27 Oct 2025 20:55:39 +0800 +Subject: can: gs_usb: increase max interface to U8_MAX +To: stable@vger.kernel.org +Cc: Celeste Liu , Runcheng Lu , Vincent Mailhol , Marc Kleine-Budde +Message-ID: <20251027125538.798464-2-uwu@coelacanthus.name> + +From: Celeste Liu + +commit 2a27f6a8fb5722223d526843040f747e9b0e8060 upstream + +This issue was found by Runcheng Lu when develop HSCanT USB to CAN FD +converter[1]. The original developers may have only 3 interfaces +device to test so they write 3 here and wait for future change. + +During the HSCanT development, we actually used 4 interfaces, so the +limitation of 3 is not enough now. But just increase one is not +future-proofed. Since the channel index type in gs_host_frame is u8, +just make canch[] become a flexible array with a u8 index, so it +naturally constraint by U8_MAX and avoid statically allocate 256 +pointer for every gs_usb device. + +[1]: https://github.com/cherry-embedded/HSCanT-hardware + +Fixes: d08e973a77d1 ("can: gs_usb: Added support for the GS_USB CAN devices") +Reported-by: Runcheng Lu +Cc: stable@vger.kernel.org +Reviewed-by: Vincent Mailhol +Signed-off-by: Celeste Liu +Link: https://patch.msgid.link/20250930-gs-usb-max-if-v5-1-863330bf6666@coelacanthus.name +Signed-off-by: Marc Kleine-Budde +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/can/usb/gs_usb.c | 23 +++++++++++------------ + 1 file changed, 11 insertions(+), 12 deletions(-) + +--- a/drivers/net/can/usb/gs_usb.c ++++ b/drivers/net/can/usb/gs_usb.c +@@ -156,10 +156,6 @@ struct gs_host_frame { + #define GS_MAX_TX_URBS 10 + /* Only launch a max of GS_MAX_RX_URBS usb requests at a time. */ + #define GS_MAX_RX_URBS 30 +-/* Maximum number of interfaces the driver supports per device. +- * Current hardware only supports 2 interfaces. The future may vary. +- */ +-#define GS_MAX_INTF 2 + + struct gs_tx_context { + struct gs_can *dev; +@@ -190,10 +186,11 @@ struct gs_can { + + /* usb interface struct */ + struct gs_usb { +- struct gs_can *canch[GS_MAX_INTF]; + struct usb_anchor rx_submitted; + struct usb_device *udev; + u8 active_channels; ++ u8 channel_cnt; ++ struct gs_can *canch[] __counted_by(channel_cnt); + }; + + /* 'allocate' a tx context. +@@ -321,7 +318,7 @@ static void gs_usb_receive_bulk_callback + } + + /* device reports out of range channel id */ +- if (hf->channel >= GS_MAX_INTF) ++ if (hf->channel >= usbcan->channel_cnt) + goto device_detach; + + dev = usbcan->canch[hf->channel]; +@@ -409,7 +406,7 @@ static void gs_usb_receive_bulk_callback + /* USB failure take down all interfaces */ + if (rc == -ENODEV) { + device_detach: +- for (rc = 0; rc < GS_MAX_INTF; rc++) { ++ for (rc = 0; rc < usbcan->channel_cnt; rc++) { + if (usbcan->canch[rc]) + netif_device_detach(usbcan->canch[rc]->netdev); + } +@@ -991,20 +988,22 @@ static int gs_usb_probe(struct usb_inter + icount = dconf->icount + 1; + dev_info(&intf->dev, "Configuring for %d interfaces\n", icount); + +- if (icount > GS_MAX_INTF) { ++ if (icount > type_max(typeof(dev->channel_cnt))) { + dev_err(&intf->dev, +- "Driver cannot handle more that %d CAN interfaces\n", +- GS_MAX_INTF); ++ "Driver cannot handle more that %u CAN interfaces\n", ++ type_max(typeof(dev->channel_cnt))); + kfree(dconf); + return -EINVAL; + } + +- dev = kzalloc(sizeof(*dev), GFP_KERNEL); ++ dev = kzalloc(struct_size(dev, canch, icount), GFP_KERNEL); + if (!dev) { + kfree(dconf); + return -ENOMEM; + } + ++ dev->channel_cnt = icount; ++ + init_usb_anchor(&dev->rx_submitted); + + usb_set_intfdata(intf, dev); +@@ -1045,7 +1044,7 @@ static void gs_usb_disconnect(struct usb + return; + } + +- for (i = 0; i < GS_MAX_INTF; i++) ++ for (i = 0; i < dev->channel_cnt; i++) + if (dev->canch[i]) + gs_destroy_candev(dev->canch[i]); + diff --git a/queue-5.10/devcoredump-fix-circular-locking-dependency-with-devcd-mutex.patch b/queue-5.10/devcoredump-fix-circular-locking-dependency-with-devcd-mutex.patch new file mode 100644 index 0000000000..39db224e7d --- /dev/null +++ b/queue-5.10/devcoredump-fix-circular-locking-dependency-with-devcd-mutex.patch @@ -0,0 +1,389 @@ +From stable+bounces-189986-greg=kroah.com@vger.kernel.org Mon Oct 27 22:51:45 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 09:49:17 -0400 +Subject: devcoredump: Fix circular locking dependency with devcd->mutex. +To: stable@vger.kernel.org +Cc: Maarten Lankhorst , Mukesh Ojha , Greg Kroah-Hartman , Johannes Berg , "Rafael J. Wysocki" , Danilo Krummrich , linux-kernel@vger.kernel.org, Matthew Brost , Mukesh Ojha , Sasha Levin +Message-ID: <20251027134917.491617-1-sashal@kernel.org> + +From: Maarten Lankhorst + +[ Upstream commit a91c8096590bd7801a26454789f2992094fe36da ] + +The original code causes a circular locking dependency found by lockdep. + +====================================================== +WARNING: possible circular locking dependency detected +6.16.0-rc6-lgci-xe-xe-pw-151626v3+ #1 Tainted: G S U +------------------------------------------------------ +xe_fault_inject/5091 is trying to acquire lock: +ffff888156815688 ((work_completion)(&(&devcd->del_wk)->work)){+.+.}-{0:0}, at: __flush_work+0x25d/0x660 + +but task is already holding lock: + +ffff888156815620 (&devcd->mutex){+.+.}-{3:3}, at: dev_coredump_put+0x3f/0xa0 +which lock already depends on the new lock. +the existing dependency chain (in reverse order) is: +-> #2 (&devcd->mutex){+.+.}-{3:3}: + mutex_lock_nested+0x4e/0xc0 + devcd_data_write+0x27/0x90 + sysfs_kf_bin_write+0x80/0xf0 + kernfs_fop_write_iter+0x169/0x220 + vfs_write+0x293/0x560 + ksys_write+0x72/0xf0 + __x64_sys_write+0x19/0x30 + x64_sys_call+0x2bf/0x2660 + do_syscall_64+0x93/0xb60 + entry_SYSCALL_64_after_hwframe+0x76/0x7e +-> #1 (kn->active#236){++++}-{0:0}: + kernfs_drain+0x1e2/0x200 + __kernfs_remove+0xae/0x400 + kernfs_remove_by_name_ns+0x5d/0xc0 + remove_files+0x54/0x70 + sysfs_remove_group+0x3d/0xa0 + sysfs_remove_groups+0x2e/0x60 + device_remove_attrs+0xc7/0x100 + device_del+0x15d/0x3b0 + devcd_del+0x19/0x30 + process_one_work+0x22b/0x6f0 + worker_thread+0x1e8/0x3d0 + kthread+0x11c/0x250 + ret_from_fork+0x26c/0x2e0 + ret_from_fork_asm+0x1a/0x30 +-> #0 ((work_completion)(&(&devcd->del_wk)->work)){+.+.}-{0:0}: + __lock_acquire+0x1661/0x2860 + lock_acquire+0xc4/0x2f0 + __flush_work+0x27a/0x660 + flush_delayed_work+0x5d/0xa0 + dev_coredump_put+0x63/0xa0 + xe_driver_devcoredump_fini+0x12/0x20 [xe] + devm_action_release+0x12/0x30 + release_nodes+0x3a/0x120 + devres_release_all+0x8a/0xd0 + device_unbind_cleanup+0x12/0x80 + device_release_driver_internal+0x23a/0x280 + device_driver_detach+0x14/0x20 + unbind_store+0xaf/0xc0 + drv_attr_store+0x21/0x50 + sysfs_kf_write+0x4a/0x80 + kernfs_fop_write_iter+0x169/0x220 + vfs_write+0x293/0x560 + ksys_write+0x72/0xf0 + __x64_sys_write+0x19/0x30 + x64_sys_call+0x2bf/0x2660 + do_syscall_64+0x93/0xb60 + entry_SYSCALL_64_after_hwframe+0x76/0x7e +other info that might help us debug this: +Chain exists of: (work_completion)(&(&devcd->del_wk)->work) --> kn->active#236 --> &devcd->mutex + Possible unsafe locking scenario: + CPU0 CPU1 + ---- ---- + lock(&devcd->mutex); + lock(kn->active#236); + lock(&devcd->mutex); + lock((work_completion)(&(&devcd->del_wk)->work)); + *** DEADLOCK *** +5 locks held by xe_fault_inject/5091: + #0: ffff8881129f9488 (sb_writers#5){.+.+}-{0:0}, at: ksys_write+0x72/0xf0 + #1: ffff88810c755078 (&of->mutex#2){+.+.}-{3:3}, at: kernfs_fop_write_iter+0x123/0x220 + #2: ffff8881054811a0 (&dev->mutex){....}-{3:3}, at: device_release_driver_internal+0x55/0x280 + #3: ffff888156815620 (&devcd->mutex){+.+.}-{3:3}, at: dev_coredump_put+0x3f/0xa0 + #4: ffffffff8359e020 (rcu_read_lock){....}-{1:2}, at: __flush_work+0x72/0x660 +stack backtrace: +CPU: 14 UID: 0 PID: 5091 Comm: xe_fault_inject Tainted: G S U 6.16.0-rc6-lgci-xe-xe-pw-151626v3+ #1 PREEMPT_{RT,(lazy)} +Tainted: [S]=CPU_OUT_OF_SPEC, [U]=USER +Hardware name: Micro-Star International Co., Ltd. MS-7D25/PRO Z690-A DDR4(MS-7D25), BIOS 1.10 12/13/2021 +Call Trace: + + dump_stack_lvl+0x91/0xf0 + dump_stack+0x10/0x20 + print_circular_bug+0x285/0x360 + check_noncircular+0x135/0x150 + ? register_lock_class+0x48/0x4a0 + __lock_acquire+0x1661/0x2860 + lock_acquire+0xc4/0x2f0 + ? __flush_work+0x25d/0x660 + ? mark_held_locks+0x46/0x90 + ? __flush_work+0x25d/0x660 + __flush_work+0x27a/0x660 + ? __flush_work+0x25d/0x660 + ? trace_hardirqs_on+0x1e/0xd0 + ? __pfx_wq_barrier_func+0x10/0x10 + flush_delayed_work+0x5d/0xa0 + dev_coredump_put+0x63/0xa0 + xe_driver_devcoredump_fini+0x12/0x20 [xe] + devm_action_release+0x12/0x30 + release_nodes+0x3a/0x120 + devres_release_all+0x8a/0xd0 + device_unbind_cleanup+0x12/0x80 + device_release_driver_internal+0x23a/0x280 + ? bus_find_device+0xa8/0xe0 + device_driver_detach+0x14/0x20 + unbind_store+0xaf/0xc0 + drv_attr_store+0x21/0x50 + sysfs_kf_write+0x4a/0x80 + kernfs_fop_write_iter+0x169/0x220 + vfs_write+0x293/0x560 + ksys_write+0x72/0xf0 + __x64_sys_write+0x19/0x30 + x64_sys_call+0x2bf/0x2660 + do_syscall_64+0x93/0xb60 + ? __f_unlock_pos+0x15/0x20 + ? __x64_sys_getdents64+0x9b/0x130 + ? __pfx_filldir64+0x10/0x10 + ? do_syscall_64+0x1a2/0xb60 + ? clear_bhb_loop+0x30/0x80 + ? clear_bhb_loop+0x30/0x80 + entry_SYSCALL_64_after_hwframe+0x76/0x7e +RIP: 0033:0x76e292edd574 +Code: c7 00 16 00 00 00 b8 ff ff ff ff c3 66 2e 0f 1f 84 00 00 00 00 00 f3 0f 1e fa 80 3d d5 ea 0e 00 00 74 13 b8 01 00 00 00 0f 05 <48> 3d 00 f0 ff ff 77 54 c3 0f 1f 00 55 48 89 e5 48 83 ec 20 48 89 +RSP: 002b:00007fffe247a828 EFLAGS: 00000202 ORIG_RAX: 0000000000000001 +RAX: ffffffffffffffda RBX: 0000000000000000 RCX: 000076e292edd574 +RDX: 000000000000000c RSI: 00006267f6306063 RDI: 000000000000000b +RBP: 000000000000000c R08: 000076e292fc4b20 R09: 0000000000000000 +R10: 0000000000000000 R11: 0000000000000202 R12: 00006267f6306063 +R13: 000000000000000b R14: 00006267e6859c00 R15: 000076e29322a000 + +xe 0000:03:00.0: [drm] Xe device coredump has been deleted. + +Fixes: 01daccf74832 ("devcoredump : Serialize devcd_del work") +Cc: Mukesh Ojha +Cc: Greg Kroah-Hartman +Cc: Johannes Berg +Cc: Rafael J. Wysocki +Cc: Danilo Krummrich +Cc: linux-kernel@vger.kernel.org +Cc: stable@vger.kernel.org # v6.1+ +Signed-off-by: Maarten Lankhorst +Cc: Matthew Brost +Acked-by: Mukesh Ojha +Link: https://lore.kernel.org/r/20250723142416.1020423-1-dev@lankhorst.se +Signed-off-by: Greg Kroah-Hartman +[ replaced disable_delayed_work_sync() with cancel_delayed_work_sync() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/base/devcoredump.c | 138 +++++++++++++++++++++++++++------------------ + 1 file changed, 84 insertions(+), 54 deletions(-) + +--- a/drivers/base/devcoredump.c ++++ b/drivers/base/devcoredump.c +@@ -30,50 +30,46 @@ struct devcd_entry { + void *data; + size_t datalen; + /* +- * Here, mutex is required to serialize the calls to del_wk work between +- * user/kernel space which happens when devcd is added with device_add() +- * and that sends uevent to user space. User space reads the uevents, +- * and calls to devcd_data_write() which try to modify the work which is +- * not even initialized/queued from devcoredump. ++ * There are 2 races for which mutex is required. + * ++ * The first race is between device creation and userspace writing to ++ * schedule immediately destruction. + * ++ * This race is handled by arming the timer before device creation, but ++ * when device creation fails the timer still exists. + * +- * cpu0(X) cpu1(Y) ++ * To solve this, hold the mutex during device_add(), and set ++ * init_completed on success before releasing the mutex. + * +- * dev_coredump() uevent sent to user space +- * device_add() ======================> user space process Y reads the +- * uevents writes to devcd fd +- * which results into writes to ++ * That way the timer will never fire until device_add() is called, ++ * it will do nothing if init_completed is not set. The timer is also ++ * cancelled in that case. + * +- * devcd_data_write() +- * mod_delayed_work() +- * try_to_grab_pending() +- * del_timer() +- * debug_assert_init() +- * INIT_DELAYED_WORK() +- * schedule_delayed_work() +- * +- * +- * Also, mutex alone would not be enough to avoid scheduling of +- * del_wk work after it get flush from a call to devcd_free() +- * mentioned as below. +- * +- * disabled_store() +- * devcd_free() +- * mutex_lock() devcd_data_write() +- * flush_delayed_work() +- * mutex_unlock() +- * mutex_lock() +- * mod_delayed_work() +- * mutex_unlock() +- * So, delete_work flag is required. ++ * The second race involves multiple parallel invocations of devcd_free(), ++ * add a deleted flag so only 1 can call the destructor. + */ + struct mutex mutex; +- bool delete_work; ++ bool init_completed, deleted; + struct module *owner; + ssize_t (*read)(char *buffer, loff_t offset, size_t count, + void *data, size_t datalen); + void (*free)(void *data); ++ /* ++ * If nothing interferes and device_add() was returns success, ++ * del_wk will destroy the device after the timer fires. ++ * ++ * Multiple userspace processes can interfere in the working of the timer: ++ * - Writing to the coredump will reschedule the timer to run immediately, ++ * if still armed. ++ * ++ * This is handled by using "if (cancel_delayed_work()) { ++ * schedule_delayed_work() }", to prevent re-arming after having ++ * been previously fired. ++ * - Writing to /sys/class/devcoredump/disabled will destroy the ++ * coredump synchronously. ++ * This is handled by using disable_delayed_work_sync(), and then ++ * checking if deleted flag is set with &devcd->mutex held. ++ */ + struct delayed_work del_wk; + struct device *failing_dev; + }; +@@ -102,14 +98,27 @@ static void devcd_dev_release(struct dev + kfree(devcd); + } + ++static void __devcd_del(struct devcd_entry *devcd) ++{ ++ devcd->deleted = true; ++ device_del(&devcd->devcd_dev); ++ put_device(&devcd->devcd_dev); ++} ++ + static void devcd_del(struct work_struct *wk) + { + struct devcd_entry *devcd; ++ bool init_completed; + + devcd = container_of(wk, struct devcd_entry, del_wk.work); + +- device_del(&devcd->devcd_dev); +- put_device(&devcd->devcd_dev); ++ /* devcd->mutex serializes against dev_coredumpm_timeout */ ++ mutex_lock(&devcd->mutex); ++ init_completed = devcd->init_completed; ++ mutex_unlock(&devcd->mutex); ++ ++ if (init_completed) ++ __devcd_del(devcd); + } + + static ssize_t devcd_data_read(struct file *filp, struct kobject *kobj, +@@ -129,12 +138,12 @@ static ssize_t devcd_data_write(struct f + struct device *dev = kobj_to_dev(kobj); + struct devcd_entry *devcd = dev_to_devcd(dev); + +- mutex_lock(&devcd->mutex); +- if (!devcd->delete_work) { +- devcd->delete_work = true; +- mod_delayed_work(system_wq, &devcd->del_wk, 0); +- } +- mutex_unlock(&devcd->mutex); ++ /* ++ * Although it's tempting to use mod_delayed work here, ++ * that will cause a reschedule if the timer already fired. ++ */ ++ if (cancel_delayed_work(&devcd->del_wk)) ++ schedule_delayed_work(&devcd->del_wk, 0); + + return count; + } +@@ -162,11 +171,21 @@ static int devcd_free(struct device *dev + { + struct devcd_entry *devcd = dev_to_devcd(dev); + ++ /* ++ * To prevent a race with devcd_data_write(), cancel work and ++ * complete manually instead. ++ * ++ * We cannot rely on the return value of ++ * cancel_delayed_work_sync() here, because it might be in the ++ * middle of a cancel_delayed_work + schedule_delayed_work pair. ++ * ++ * devcd->mutex here guards against multiple parallel invocations ++ * of devcd_free(). ++ */ ++ cancel_delayed_work_sync(&devcd->del_wk); + mutex_lock(&devcd->mutex); +- if (!devcd->delete_work) +- devcd->delete_work = true; +- +- flush_delayed_work(&devcd->del_wk); ++ if (!devcd->deleted) ++ __devcd_del(devcd); + mutex_unlock(&devcd->mutex); + return 0; + } +@@ -190,12 +209,10 @@ static ssize_t disabled_show(struct clas + * put_device() <- last reference + * error = fn(dev, data) devcd_dev_release() + * devcd_free(dev, data) kfree(devcd) +- * mutex_lock(&devcd->mutex); + * + * +- * In the above diagram, It looks like disabled_store() would be racing with parallely +- * running devcd_del() and result in memory abort while acquiring devcd->mutex which +- * is called after kfree of devcd memory after dropping its last reference with ++ * In the above diagram, it looks like disabled_store() would be racing with parallelly ++ * running devcd_del() and result in memory abort after dropping its last reference with + * put_device(). However, this will not happens as fn(dev, data) runs + * with its own reference to device via klist_node so it is not its last reference. + * so, above situation would not occur. +@@ -357,7 +374,7 @@ void dev_coredumpm(struct device *dev, s + devcd->read = read; + devcd->free = free; + devcd->failing_dev = get_device(dev); +- devcd->delete_work = false; ++ devcd->deleted = false; + + mutex_init(&devcd->mutex); + device_initialize(&devcd->devcd_dev); +@@ -366,8 +383,14 @@ void dev_coredumpm(struct device *dev, s + atomic_inc_return(&devcd_count)); + devcd->devcd_dev.class = &devcd_class; + +- mutex_lock(&devcd->mutex); + dev_set_uevent_suppress(&devcd->devcd_dev, true); ++ ++ /* devcd->mutex prevents devcd_del() completing until init finishes */ ++ mutex_lock(&devcd->mutex); ++ devcd->init_completed = false; ++ INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); ++ schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); ++ + if (device_add(&devcd->devcd_dev)) + goto put_device; + +@@ -381,13 +404,20 @@ void dev_coredumpm(struct device *dev, s + + dev_set_uevent_suppress(&devcd->devcd_dev, false); + kobject_uevent(&devcd->devcd_dev.kobj, KOBJ_ADD); +- INIT_DELAYED_WORK(&devcd->del_wk, devcd_del); +- schedule_delayed_work(&devcd->del_wk, DEVCD_TIMEOUT); ++ ++ /* ++ * Safe to run devcd_del() now that we are done with devcd_dev. ++ * Alternatively we could have taken a ref on devcd_dev before ++ * dropping the lock. ++ */ ++ devcd->init_completed = true; + mutex_unlock(&devcd->mutex); + return; + put_device: +- put_device(&devcd->devcd_dev); + mutex_unlock(&devcd->mutex); ++ cancel_delayed_work_sync(&devcd->del_wk); ++ put_device(&devcd->devcd_dev); ++ + put_module: + module_put(owner); + free: diff --git a/queue-5.10/net-phy-dp83867-disable-eee-support-as-not-implemented.patch b/queue-5.10/net-phy-dp83867-disable-eee-support-as-not-implemented.patch new file mode 100644 index 0000000000..9bdf9189f4 --- /dev/null +++ b/queue-5.10/net-phy-dp83867-disable-eee-support-as-not-implemented.patch @@ -0,0 +1,55 @@ +From stable+bounces-192089-greg=kroah.com@vger.kernel.org Mon Nov 3 05:39:17 2025 +From: Sasha Levin +Date: Sun, 2 Nov 2025 15:39:09 -0500 +Subject: net: phy: dp83867: Disable EEE support as not implemented +To: stable@vger.kernel.org +Cc: Emanuele Ghidoli , Andrew Lunn , Jakub Kicinski , Sasha Levin +Message-ID: <20251102203909.3597447-1-sashal@kernel.org> + +From: Emanuele Ghidoli + +[ Upstream commit 84a905290cb4c3d9a71a9e3b2f2e02e031e7512f ] + +While the DP83867 PHYs report EEE capability through their feature +registers, the actual hardware does not support EEE (see Links). +When the connected MAC enables EEE, it causes link instability and +communication failures. + +The issue is reproducible with a iMX8MP and relevant stmmac ethernet port. +Since the introduction of phylink-managed EEE support in the stmmac driver, +EEE is now enabled by default, leading to issues on systems using the +DP83867 PHY. + +Call phy_disable_eee during phy initialization to prevent EEE from being +enabled on DP83867 PHYs. + +Link: https://e2e.ti.com/support/interface-group/interface/f/interface-forum/1445244/dp83867ir-dp83867-disable-eee-lpi +Link: https://e2e.ti.com/support/interface-group/interface/f/interface-forum/658638/dp83867ir-eee-energy-efficient-ethernet +Fixes: 2a10154abcb7 ("net: phy: dp83867: Add TI dp83867 phy") +Cc: stable@vger.kernel.org +Signed-off-by: Emanuele Ghidoli +Reviewed-by: Andrew Lunn +Link: https://patch.msgid.link/20251023144857.529566-1-ghidoliemanuele@gmail.com +Signed-off-by: Jakub Kicinski +[ replaced phy_disable_eee() call with direct eee_broken_modes assignment ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/phy/dp83867.c | 6 ++++++ + 1 file changed, 6 insertions(+) + +--- a/drivers/net/phy/dp83867.c ++++ b/drivers/net/phy/dp83867.c +@@ -664,6 +664,12 @@ static int dp83867_config_init(struct ph + return ret; + } + ++ /* Although the DP83867 reports EEE capability through the ++ * MDIO_PCS_EEE_ABLE and MDIO_AN_EEE_ADV registers, the feature ++ * is not actually implemented in hardware. ++ */ ++ phydev->eee_broken_modes = MDIO_EEE_100TX | MDIO_EEE_1000T; ++ + if (phy_interface_is_rgmii(phydev) || + phydev->interface == PHY_INTERFACE_MODE_SGMII) { + val = phy_read(phydev, MII_DP83867_PHYCTRL); diff --git a/queue-5.10/net-ravb-enforce-descriptor-type-ordering.patch b/queue-5.10/net-ravb-enforce-descriptor-type-ordering.patch new file mode 100644 index 0000000000..af360d294d --- /dev/null +++ b/queue-5.10/net-ravb-enforce-descriptor-type-ordering.patch @@ -0,0 +1,75 @@ +From stable+bounces-190005-greg=kroah.com@vger.kernel.org Mon Oct 27 23:55:34 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 10:40:08 -0400 +Subject: net: ravb: Enforce descriptor type ordering +To: stable@vger.kernel.org +Cc: "Lad Prabhakar" , "Fabrizio Castro" , "Niklas Söderlund" , "Jakub Kicinski" , "Sasha Levin" +Message-ID: <20251027144008.525379-1-sashal@kernel.org> + +From: Lad Prabhakar + +[ Upstream commit 5370c31e84b0e0999c7b5ff949f4e104def35584 ] + +Ensure the TX descriptor type fields are published in a safe order so the +DMA engine never begins processing a descriptor chain before all descriptor +fields are fully initialised. + +For multi-descriptor transmits the driver writes DT_FEND into the last +descriptor and DT_FSTART into the first. The DMA engine begins processing +when it observes DT_FSTART. Move the dma_wmb() barrier so it executes +immediately after DT_FEND and immediately before writing DT_FSTART +(and before DT_FSINGLE in the single-descriptor case). This guarantees +that all prior CPU writes to the descriptor memory are visible to the +device before DT_FSTART is seen. + +This avoids a situation where compiler/CPU reordering could publish +DT_FSTART ahead of DT_FEND or other descriptor fields, allowing the DMA to +start on a partially initialised chain and causing corrupted transmissions +or TX timeouts. Such a failure was observed on RZ/G2L with an RT kernel as +transmit queue timeouts and device resets. + +Fixes: 2f45d1902acf ("ravb: minimize TX data copying") +Cc: stable@vger.kernel.org +Co-developed-by: Fabrizio Castro +Signed-off-by: Fabrizio Castro +Signed-off-by: Lad Prabhakar +Reviewed-by: Niklas Söderlund +Link: https://patch.msgid.link/20251017151830.171062-4-prabhakar.mahadev-lad.rj@bp.renesas.com +Signed-off-by: Jakub Kicinski +[ kept unconditional skb_tx_timestamp() ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/net/ethernet/renesas/ravb_main.c | 16 ++++++++++++++-- + 1 file changed, 14 insertions(+), 2 deletions(-) + +--- a/drivers/net/ethernet/renesas/ravb_main.c ++++ b/drivers/net/ethernet/renesas/ravb_main.c +@@ -1596,13 +1596,25 @@ static netdev_tx_t ravb_start_xmit(struc + } + + skb_tx_timestamp(skb); +- /* Descriptor type must be set after all the above writes */ +- dma_wmb(); ++ + if (num_tx_desc > 1) { + desc->die_dt = DT_FEND; + desc--; ++ /* When using multi-descriptors, DT_FEND needs to get written ++ * before DT_FSTART, but the compiler may reorder the memory ++ * writes in an attempt to optimize the code. ++ * Use a dma_wmb() barrier to make sure DT_FEND and DT_FSTART ++ * are written exactly in the order shown in the code. ++ * This is particularly important for cases where the DMA engine ++ * is already running when we are running this code. If the DMA ++ * sees DT_FSTART without the corresponding DT_FEND it will enter ++ * an error condition. ++ */ ++ dma_wmb(); + desc->die_dt = DT_FSTART; + } else { ++ /* Descriptor type must be set after all the above writes */ ++ dma_wmb(); + desc->die_dt = DT_FSINGLE; + } + diff --git a/queue-5.10/serial-8250_dw-handle-reset-control-deassert-error.patch b/queue-5.10/serial-8250_dw-handle-reset-control-deassert-error.patch new file mode 100644 index 0000000000..a9a293f1f5 --- /dev/null +++ b/queue-5.10/serial-8250_dw-handle-reset-control-deassert-error.patch @@ -0,0 +1,47 @@ +From stable+bounces-190156-greg=kroah.com@vger.kernel.org Tue Oct 28 03:44:27 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:49 -0400 +Subject: serial: 8250_dw: handle reset control deassert error +To: stable@vger.kernel.org +Cc: Artem Shimko , stable , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027184249.638796-2-sashal@kernel.org> + +From: Artem Shimko + +[ Upstream commit daeb4037adf7d3349b4a1fb792f4bc9824686a4b ] + +Check the return value of reset_control_deassert() in the probe +function to prevent continuing probe when reset deassertion fails. + +Previously, reset_control_deassert() was called without checking its +return value, which could lead to probe continuing even when the +device reset wasn't properly deasserted. + +The fix checks the return value and returns an error with dev_err_probe() +if reset deassertion fails, providing better error handling and +diagnostics. + +Fixes: acbdad8dd1ab ("serial: 8250_dw: simplify optional reset handling") +Cc: stable +Signed-off-by: Artem Shimko +Link: https://patch.msgid.link/20251019095131.252848-1-a.shimko.dev@gmail.com +Signed-off-by: Greg Kroah-Hartman +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_dw.c | 4 +++- + 1 file changed, 3 insertions(+), 1 deletion(-) + +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -580,7 +580,9 @@ static int dw8250_probe(struct platform_ + if (IS_ERR(data->rst)) + return PTR_ERR(data->rst); + +- reset_control_deassert(data->rst); ++ err = reset_control_deassert(data->rst); ++ if (err) ++ return dev_err_probe(dev, err, "failed to deassert resets\n"); + + err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); + if (err) diff --git a/queue-5.10/serial-8250_dw-use-devm_add_action_or_reset.patch b/queue-5.10/serial-8250_dw-use-devm_add_action_or_reset.patch new file mode 100644 index 0000000000..ebbb6c62cb --- /dev/null +++ b/queue-5.10/serial-8250_dw-use-devm_add_action_or_reset.patch @@ -0,0 +1,143 @@ +From stable+bounces-190152-greg=kroah.com@vger.kernel.org Tue Oct 28 04:00:30 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 14:42:48 -0400 +Subject: serial: 8250_dw: Use devm_add_action_or_reset() +To: stable@vger.kernel.org +Cc: Andy Shevchenko , Greg Kroah-Hartman , Sasha Levin +Message-ID: <20251027184249.638796-1-sashal@kernel.org> + +From: Andy Shevchenko + +[ Upstream commit 295b09128d12fb1a7a67f771cc0ae0df869eafaf ] + +Slightly simplify ->probe() and drop a few goto labels by using +devm_add_action_or_reset() for clock and reset cleanup. + +Signed-off-by: Andy Shevchenko +Link: https://lore.kernel.org/r/20220509172129.37770-1-andriy.shevchenko@linux.intel.com +Signed-off-by: Greg Kroah-Hartman +Stable-dep-of: daeb4037adf7 ("serial: 8250_dw: handle reset control deassert error") +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + drivers/tty/serial/8250/8250_dw.c | 63 ++++++++++++++++++-------------------- + 1 file changed, 31 insertions(+), 32 deletions(-) + +--- a/drivers/tty/serial/8250/8250_dw.c ++++ b/drivers/tty/serial/8250/8250_dw.c +@@ -438,6 +438,16 @@ static void dw8250_quirks(struct uart_po + } + } + ++static void dw8250_clk_disable_unprepare(void *data) ++{ ++ clk_disable_unprepare(data); ++} ++ ++static void dw8250_reset_control_assert(void *data) ++{ ++ reset_control_assert(data); ++} ++ + static int dw8250_probe(struct platform_device *pdev) + { + struct uart_8250_port uart = {}, *up = &uart; +@@ -539,35 +549,43 @@ static int dw8250_probe(struct platform_ + if (err) + dev_warn(dev, "could not enable optional baudclk: %d\n", err); + ++ err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->clk); ++ if (err) ++ return err; ++ + if (data->clk) + p->uartclk = clk_get_rate(data->clk); + + /* If no clock rate is defined, fail. */ + if (!p->uartclk) { + dev_err(dev, "clock rate not defined\n"); +- err = -EINVAL; +- goto err_clk; ++ return -EINVAL; + } + + data->pclk = devm_clk_get_optional(dev, "apb_pclk"); +- if (IS_ERR(data->pclk)) { +- err = PTR_ERR(data->pclk); +- goto err_clk; +- } ++ if (IS_ERR(data->pclk)) ++ return PTR_ERR(data->pclk); + + err = clk_prepare_enable(data->pclk); + if (err) { + dev_err(dev, "could not enable apb_pclk\n"); +- goto err_clk; ++ return err; + } + ++ err = devm_add_action_or_reset(dev, dw8250_clk_disable_unprepare, data->pclk); ++ if (err) ++ return err; ++ + data->rst = devm_reset_control_get_optional_exclusive(dev, NULL); +- if (IS_ERR(data->rst)) { +- err = PTR_ERR(data->rst); +- goto err_pclk; +- } ++ if (IS_ERR(data->rst)) ++ return PTR_ERR(data->rst); ++ + reset_control_deassert(data->rst); + ++ err = devm_add_action_or_reset(dev, dw8250_reset_control_assert, data->rst); ++ if (err) ++ return err; ++ + dw8250_quirks(p, data); + + /* If the Busy Functionality is not implemented, don't handle it */ +@@ -585,10 +603,8 @@ static int dw8250_probe(struct platform_ + } + + data->data.line = serial8250_register_8250_port(up); +- if (data->data.line < 0) { +- err = data->data.line; +- goto err_reset; +- } ++ if (data->data.line < 0) ++ return data->data.line; + + /* + * Some platforms may provide a reference clock shared between several +@@ -609,17 +625,6 @@ static int dw8250_probe(struct platform_ + pm_runtime_enable(dev); + + return 0; +- +-err_reset: +- reset_control_assert(data->rst); +- +-err_pclk: +- clk_disable_unprepare(data->pclk); +- +-err_clk: +- clk_disable_unprepare(data->clk); +- +- return err; + } + + static int dw8250_remove(struct platform_device *pdev) +@@ -637,12 +642,6 @@ static int dw8250_remove(struct platform + + serial8250_unregister_port(data->data.line); + +- reset_control_assert(data->rst); +- +- clk_disable_unprepare(data->pclk); +- +- clk_disable_unprepare(data->clk); +- + pm_runtime_disable(dev); + pm_runtime_put_noidle(dev); + diff --git a/queue-5.10/series b/queue-5.10/series index ea6c209135..3505b1932c 100644 --- a/queue-5.10/series +++ b/queue-5.10/series @@ -22,3 +22,11 @@ drm-amd-pm-powerplay-smumgr-fix-pciebootlinklevel-va.patch drm-amd-pm-powerplay-smumgr-fix-pciebootlinklevel-va.patch-17561 block-fix-op_is_zone_mgmt-to-handle-req_op_zone_reset_all.patch regmap-slimbus-fix-bus_context-pointer-in-regmap-init-calls.patch +net-phy-dp83867-disable-eee-support-as-not-implemented.patch +net-ravb-enforce-descriptor-type-ordering.patch +xfs-always-warn-about-deprecated-mount-options.patch +devcoredump-fix-circular-locking-dependency-with-devcd-mutex.patch +can-gs_usb-increase-max-interface-to-u8_max.patch +serial-8250_dw-use-devm_add_action_or_reset.patch +serial-8250_dw-handle-reset-control-deassert-error.patch +x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch diff --git a/queue-5.10/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch b/queue-5.10/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch new file mode 100644 index 0000000000..5b9b0ca813 --- /dev/null +++ b/queue-5.10/x86-resctrl-fix-miscount-of-bandwidth-event-when-reactivating-previously-unavailable-rmid.patch @@ -0,0 +1,139 @@ +From stable+bounces-191534-greg=kroah.com@vger.kernel.org Wed Oct 29 03:28:16 2025 +From: Babu Moger +Date: Tue, 28 Oct 2025 13:25:14 -0500 +Subject: x86/resctrl: Fix miscount of bandwidth event when reactivating previously unavailable RMID +To: +Message-ID: <20251028182514.210574-1-babu.moger@amd.com> + +From: Babu Moger + +[ Upstream commit 15292f1b4c55a3a7c940dbcb6cb8793871ed3d92 ] + +Users can create as many monitoring groups as the number of RMIDs supported +by the hardware. However, on AMD systems, only a limited number of RMIDs +are guaranteed to be actively tracked by the hardware. RMIDs that exceed +this limit are placed in an "Unavailable" state. + +When a bandwidth counter is read for such an RMID, the hardware sets +MSR_IA32_QM_CTR.Unavailable (bit 62). When such an RMID starts being tracked +again the hardware counter is reset to zero. MSR_IA32_QM_CTR.Unavailable +remains set on first read after tracking re-starts and is clear on all +subsequent reads as long as the RMID is tracked. + +resctrl miscounts the bandwidth events after an RMID transitions from the +"Unavailable" state back to being tracked. This happens because when the +hardware starts counting again after resetting the counter to zero, resctrl +in turn compares the new count against the counter value stored from the +previous time the RMID was tracked. + +This results in resctrl computing an event value that is either undercounting +(when new counter is more than stored counter) or a mistaken overflow (when +new counter is less than stored counter). + +Reset the stored value (arch_mbm_state::prev_msr) of MSR_IA32_QM_CTR to +zero whenever the RMID is in the "Unavailable" state to ensure accurate +counting after the RMID resets to zero when it starts to be tracked again. + +Example scenario that results in mistaken overflow +================================================== +1. The resctrl filesystem is mounted, and a task is assigned to a + monitoring group. + + $mount -t resctrl resctrl /sys/fs/resctrl + $mkdir /sys/fs/resctrl/mon_groups/test1/ + $echo 1234 > /sys/fs/resctrl/mon_groups/test1/tasks + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + 21323 <- Total bytes on domain 0 + "Unavailable" <- Total bytes on domain 1 + + Task is running on domain 0. Counter on domain 1 is "Unavailable". + +2. The task runs on domain 0 for a while and then moves to domain 1. The + counter starts incrementing on domain 1. + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + 7345357 <- Total bytes on domain 0 + 4545 <- Total bytes on domain 1 + +3. At some point, the RMID in domain 0 transitions to the "Unavailable" + state because the task is no longer executing in that domain. + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + "Unavailable" <- Total bytes on domain 0 + 434341 <- Total bytes on domain 1 + +4. Since the task continues to migrate between domains, it may eventually + return to domain 0. + + $cat /sys/fs/resctrl/mon_groups/test1/mon_data/mon_L3_*/mbm_total_bytes + 17592178699059 <- Overflow on domain 0 + 3232332 <- Total bytes on domain 1 + +In this case, the RMID on domain 0 transitions from "Unavailable" state to +active state. The hardware sets MSR_IA32_QM_CTR.Unavailable (bit 62) when +the counter is read and begins tracking the RMID counting from 0. + +Subsequent reads succeed but return a value smaller than the previously +saved MSR value (7345357). Consequently, the resctrl's overflow logic is +triggered, it compares the previous value (7345357) with the new, smaller +value and incorrectly interprets this as a counter overflow, adding a large +delta. + +In reality, this is a false positive: the counter did not overflow but was +simply reset when the RMID transitioned from "Unavailable" back to active +state. + +Here is the text from APM [1] available from [2]. + +"In PQOS Version 2.0 or higher, the MBM hardware will set the U bit on the +first QM_CTR read when it begins tracking an RMID that it was not +previously tracking. The U bit will be zero for all subsequent reads from +that RMID while it is still tracked by the hardware. Therefore, a QM_CTR +read with the U bit set when that RMID is in use by a processor can be +considered 0 when calculating the difference with a subsequent read." + +[1] AMD64 Architecture Programmer's Manual Volume 2: System Programming + Publication # 24593 Revision 3.41 section 19.3.3 Monitoring L3 Memory + Bandwidth (MBM). + + [ bp: Split commit message into smaller paragraph chunks for better + consumption. ] + +Fixes: 4d05bf71f157d ("x86/resctrl: Introduce AMD QOS feature") +Signed-off-by: Babu Moger +Signed-off-by: Borislav Petkov (AMD) +Reviewed-by: Reinette Chatre +Tested-by: Reinette Chatre +Cc: stable@vger.kernel.org # needs adjustments for <= v6.17 +Link: https://bugzilla.kernel.org/show_bug.cgi?id=206537 # [2] +(cherry picked from commit 15292f1b4c55a3a7c940dbcb6cb8793871ed3d92) +[babu.moger@amd.com: Needed backport for v5.10 stable] +Signed-off-by: Greg Kroah-Hartman +--- + arch/x86/kernel/cpu/resctrl/monitor.c | 10 +++++++++- + 1 file changed, 9 insertions(+), 1 deletion(-) + +--- a/arch/x86/kernel/cpu/resctrl/monitor.c ++++ b/arch/x86/kernel/cpu/resctrl/monitor.c +@@ -224,11 +224,19 @@ static u64 mbm_overflow_count(u64 prev_m + + static u64 __mon_event_count(u32 rmid, struct rmid_read *rr) + { +- struct mbm_state *m; ++ struct mbm_state *m = NULL; + u64 chunks, tval; + + tval = __rmid_read(rmid, rr->evtid); + if (tval & (RMID_VAL_ERROR | RMID_VAL_UNAVAIL)) { ++ if (tval & RMID_VAL_UNAVAIL) { ++ if (rr->evtid == QOS_L3_MBM_TOTAL_EVENT_ID) ++ m = &rr->d->mbm_total[rmid]; ++ else if (rr->evtid == QOS_L3_MBM_LOCAL_EVENT_ID) ++ m = &rr->d->mbm_local[rmid]; ++ if (m) ++ m->prev_msr = 0; ++ } + return tval; + } + switch (rr->evtid) { diff --git a/queue-5.10/xfs-always-warn-about-deprecated-mount-options.patch b/queue-5.10/xfs-always-warn-about-deprecated-mount-options.patch new file mode 100644 index 0000000000..298958dbd9 --- /dev/null +++ b/queue-5.10/xfs-always-warn-about-deprecated-mount-options.patch @@ -0,0 +1,93 @@ +From stable+bounces-189989-greg=kroah.com@vger.kernel.org Mon Oct 27 22:56:48 2025 +From: Sasha Levin +Date: Mon, 27 Oct 2025 09:49:57 -0400 +Subject: xfs: always warn about deprecated mount options +To: stable@vger.kernel.org +Cc: "Darrick J. Wong" , Christoph Hellwig , Carlos Maiolino , Carlos Maiolino , Sasha Levin +Message-ID: <20251027134957.492843-1-sashal@kernel.org> + +From: "Darrick J. Wong" + +[ Upstream commit 630785bfbe12c3ee3ebccd8b530a98d632b7e39d ] + +The deprecation of the 'attr2' mount option in 6.18 wasn't entirely +successful because nobody noticed that the kernel never printed a +warning about attr2 being set in fstab if the only xfs filesystem is the +root fs; the initramfs mounts the root fs with no mount options; and the +init scripts only conveyed the fstab options by remounting the root fs. + +Fix this by making it complain all the time. + +Cc: stable@vger.kernel.org # v5.13 +Fixes: 92cf7d36384b99 ("xfs: Skip repetitive warnings about mount options") +Signed-off-by: Darrick J. Wong +Reviewed-by: Christoph Hellwig +Reviewed-by: Carlos Maiolino +Signed-off-by: Carlos Maiolino +[ adapted m_features field reference to m_flags ] +Signed-off-by: Sasha Levin +Signed-off-by: Greg Kroah-Hartman +--- + fs/xfs/xfs_super.c | 33 +++++++++++++++++++++------------ + 1 file changed, 21 insertions(+), 12 deletions(-) + +--- a/fs/xfs/xfs_super.c ++++ b/fs/xfs/xfs_super.c +@@ -1162,16 +1162,25 @@ suffix_kstrtoint( + static inline void + xfs_fs_warn_deprecated( + struct fs_context *fc, +- struct fs_parameter *param, +- uint64_t flag, +- bool value) ++ struct fs_parameter *param) + { +- /* Don't print the warning if reconfiguring and current mount point +- * already had the flag set ++ /* ++ * Always warn about someone passing in a deprecated mount option. ++ * Previously we wouldn't print the warning if we were reconfiguring ++ * and current mount point already had the flag set, but that was not ++ * the right thing to do. ++ * ++ * Many distributions mount the root filesystem with no options in the ++ * initramfs and rely on mount -a to remount the root fs with the ++ * options in fstab. However, the old behavior meant that there would ++ * never be a warning about deprecated mount options for the root fs in ++ * /etc/fstab. On a single-fs system, that means no warning at all. ++ * ++ * Compounding this problem are distribution scripts that copy ++ * /proc/mounts to fstab, which means that we can't remove mount ++ * options unless we're 100% sure they have only ever been advertised ++ * in /proc/mounts in response to explicitly provided mount options. + */ +- if ((fc->purpose & FS_CONTEXT_FOR_RECONFIGURE) && +- !!(XFS_M(fc->root->d_sb)->m_flags & flag) == value) +- return; + xfs_warn(fc->s_fs_info, "%s mount option is deprecated.", param->key); + } + +@@ -1314,19 +1323,19 @@ xfs_fc_parse_param( + #endif + /* Following mount options will be removed in September 2025 */ + case Opt_ikeep: +- xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_IKEEP, true); ++ xfs_fs_warn_deprecated(fc, param); + parsing_mp->m_flags |= XFS_MOUNT_IKEEP; + return 0; + case Opt_noikeep: +- xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_IKEEP, false); ++ xfs_fs_warn_deprecated(fc, param); + parsing_mp->m_flags &= ~XFS_MOUNT_IKEEP; + return 0; + case Opt_attr2: +- xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_ATTR2, true); ++ xfs_fs_warn_deprecated(fc, param); + parsing_mp->m_flags |= XFS_MOUNT_ATTR2; + return 0; + case Opt_noattr2: +- xfs_fs_warn_deprecated(fc, param, XFS_MOUNT_NOATTR2, true); ++ xfs_fs_warn_deprecated(fc, param); + parsing_mp->m_flags &= ~XFS_MOUNT_ATTR2; + parsing_mp->m_flags |= XFS_MOUNT_NOATTR2; + return 0; -- 2.47.3