6.6.122-rc1 review
Subsystems (3)
Greg Kroah-Hartman
maintainerPATCH 143/254 scsi: xen: scsiback: Fix potential memory leak in scsiback_remove()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Abdun Nihaal <[email protected]>
commit 901a5f309daba412e2a30364d7ec1492fa11c32c upstream.
Memory allocated for struct vscsiblk_info in scsiback_probe() is not freed in scsiback_remove() leading to potential memory leaks on remove, as well as in the scsiback_probe() error paths. Fix that by freeing it in scsiback_remove().
--- drivers/xen/xen-scsiback.c | 1 + 1 file changed, 1 insertion(+)
drivers/xen/xen-scsiback.c +1 -0
@@ -1262,6 +1262,7 @@ static void scsiback_remove(struct xenbugnttab_page_cache_shrink (&info->free_pages,0 );dev_set_drvdata (&dev->dev,NULL ); +kfree (info); } static int scsiback_probe(struct xenbus_device *dev,
Greg Kroah-Hartman
maintainerPATCH 144/254 arm64: dts: rockchip: remove dangerous max-link-speed from helios64
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
commit 0368e4afcf20f377c81fa77b1c7d0dee4a625a44 upstream.
Shawn Lin from Rockchip strongly discourages attempts to use their RK3399 PCIe core at 5.0 GT/s speed, citing concerns about catastrophic failures that may happen. Even if the odds are low, drop from last user of this non-default property for the RK3399 platform, helios64 board dts.
--- arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-kobol-helios64.dts +0 -1
@@ -427,7 +427,6 @@ &pcie0 { ep-gpios = <&gpio2 RK_PD4 GPIO_ACTIVE_HIGH>; - max-link-speed = <2>; num-lanes = <2>; pinctrl-names = "default"; status = "okay";
Greg Kroah-Hartman
maintainerPATCH 145/254 arm64: dts: rockchip: Fix voltage threshold for volume keys for Pinephone Pro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ondrej Jirman <[email protected]>
commit 5497ffe305b2ea31ae62d4a311d7cabfb671f54a upstream.
Previously sometimes pressing the volume-down button would register as a volume-up button. Match the thresholds as shown in the Pinephone Pro schematic.
Tests:
~ $ evtest
// Mashed the volume down ~100 times with varying intensity
Event: time xxx, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 1
Event: time xxx, type 1 (EV_KEY), code 114 (KEY_VOLUMEDOWN), value 0 // Mashed the volume up ~100 times with varying intensity
Event: time xxx, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 1
Event: time xxx, type 1 (EV_KEY), code 115 (KEY_VOLUMEUP), value 0
--- arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
arch/arm64/boot/dts/rockchip/rk3399-pinephone-pro.dts +2 -2
@@ -40,13 +40,13 @@ button-up { label = "Volume Up"; linux,code = <KEY_VOLUMEUP>; - press-threshold-microvolt = <100000>; + press-threshold-microvolt = <2000>; }; button-down { label = "Volume Down"; linux,code = <KEY_VOLUMEDOWN>; - press-threshold-microvolt = <600000>; + press-threshold-microvolt = <300000>; }; };
Greg Kroah-Hartman
maintainerPATCH 146/254 x86/kfence: avoid writing L1TF-vulnerable PTEs
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Cooper <[email protected]>
commit b505f1944535f83d369ae68813e7634d11b990d3 upstream.
For native, the choice of PTE is fine. There's real memory backing the non-present PTE. However, for XenPV, Xen complains:
(XEN) d1 L1TF-vulnerable L1e 8010000018200066 - Shadowing
To explain, some background on XenPV pagetables:
Xen PV guests are control their own pagetables; they choose the new PTE value, and use hypercalls to make changes so Xen can audit for safety.
In addition to a regular reference count, Xen also maintains a type reference count. e.g. SegDesc (referenced by vGDT/vLDT), Writable (referenced with _PAGE_RW) or L{1..4} (referenced by vCR3 or a lower pagetable level). This is in order to prevent e.g. a page being inserted into the pagetables for which the guest has a writable mapping.
For non-present mappings, all other bits become software accessible, and typically contain metadata rather a real frame address. There is nothing that a reference count could sensibly be tied to. As such, even if Xen could recognise the address as currently safe, nothing would prevent that frame from changing owner to another VM in the future.
When Xen detects a PV guest writing a L1TF-PTE, it responds by activating shadow paging. This is normally only used for the live phase of migration, and comes with a reasonable overhead.
KFENCE only cares about getting #PF to catch wild accesses; it doesn't care about the value for non-present mappings. Use a fully inverted PTE, to avoid hitting the slow path when running under Xen.
While adjusting the logic, take the opportunity to skip all actions if the PTE is already in the right state, half the number PVOps callouts, and skip TLB maintenance on a !P -> P transition which benefits non-Xen cases too.
--- arch/x86/include/asm/kfence.h | 29 ++++++++++++++++++++++++----- 1 file changed, 24 insertions(+), 5 deletions(-)
arch/x86/include/asm/kfence.h +24 -5
@@ -42,10 +42,34 @@ static inline bool kfence_protect_page(u {unsigned int level;pte_t *pte =lookup_address (addr, &level); +pteval_t val;if (WARN_ON (!pte || level !=PG_LEVEL_4K ))return false; + val =pte_val (*pte); + +/* +* protect requires making the page not-present. If the PTE is +* already in the right state, there's nothing to do. +*/ +if (protect != !!(val & _PAGE_PRESENT)) +return true; + +/* +* Otherwise, invert the entire PTE. This avoids writing out an +* L1TF-vulnerable PTE (not present, without the high address bits +* set). +*/ +set_pte (pte,__pte (~val)); + +/* +* If the page was protected (non-present) and we're making it +* present, there is no need to flush the TLB at all. +*/ +if (!protect) +return true; +/* * We need to avoid IPIs, as we may get KFENCE allocations or faults * with interrupts disabled. Therefore, the below is best-effort, and
@@ -53,11 +77,6 @@ static inline bool kfence_protect_page(u* lazy fault handling takes care of faults after the page is PRESENT. */ -if (protect) -set_pte (pte,__pte (pte_val (*pte) & ~_PAGE_PRESENT)); -else -set_pte (pte,__pte (pte_val (*pte) | _PAGE_PRESENT)); -/* * Flush this CPU's TLB, assuming whoever did the allocation/free is * likely to continue running on this CPU.
Greg Kroah-Hartman
maintainerPATCH 147/254 comedi: Fix getting range information for subdevices 16 to 255
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 10d28cffb3f6ec7ad67f0a4cd32c2afa92909452 upstream.
The COMEDI_RANGEINFO ioctl does not work properly for subdevice indices above 15. Currently, the only in-tree COMEDI drivers that support more than 16 subdevices are the "8255" driver and the "comedi_bond" driver. Making the ioctl work for subdevice indices up to 255 is achievable. It needs minor changes to the handling of the COMEDI_RANGEINFO and COMEDI_CHANINFO ioctls that should be mostly harmless to user-space, apart from making them less broken. Details follow...
The COMEDI_RANGEINFO ioctl command gets the list of supported ranges (usually with units of volts or milliamps) for a COMEDI subdevice or channel. (Only some subdevices have per-channel range tables, indicated by the SDF_RANGETYPE flag in the subdevice information.) It uses a range_type value and a user-space pointer, both supplied by user-space, but the range_type value should match what was obtained using the COMEDI_CHANINFO ioctl (if the subdevice has per-channel range tables) or COMEDI_SUBDINFO ioctl (if the subdevice uses a single range table for all channels). Bits 15 to 0 of the range_type value contain the length of the range table, which is the only part that user-space should care about (so it can use a suitably sized buffer to fetch the range table). Bits 23 to 16 store the channel index, which is assumed to be no more than 255 if the subdevice has per-channel range tables, and is set to 0 if the subdevice has a single range table. For range_type values produced by the COMEDI_SUBDINFO ioctl, bits 31 to 24 contain the subdevice index, which is assumed to be no more than 255. But for range_type values produced by the COMEDI_CHANINFO ioctl, bits 27 to 24 contain the subdevice index, which is assumed to be no more than 15, and bits 31 to 28 contain the COMEDI device's minor device number for some unknown reason lost in the mists of time. The COMEDI_RANGEINFO ioctl extract the length from bits 15 to 0 of the user-supplied range_type value, extracts the channel index from bits 23 to 16 (only used if the subdevice has per-channel range tables), extracts the subdevice index from bits 27 to 24, and ignores bits 31 to
28. So for subdevice indices 16 to 255, the COMEDI_SUBDINFO or COMEDI_CHANINFO ioctl will report a range_type value that doesn't work with the COMEDI_RANGEINFO ioctl. It will either get the range table for the subdevice index modulo 16, or will fail with -EINVAL.
To fix this, always use bits 31 to 24 of the range_type value to hold the subdevice index (assumed to be no more than 255). This affects the COMEDI_CHANINFO and COMEDI_RANGEINFO ioctls. There should not be anything in user-space that depends on the old, broken usage, although it may now see different values in bits 31 to 28 of the range_type values reported by the COMEDI_CHANINFO ioctl for subdevices that have per-channel subdevices. User-space should not be trying to decode bits 31 to 16 of the range_type values anyway.
--- drivers/comedi/comedi_fops.c | 2 +- drivers/comedi/range.c | 2 +- include/uapi/linux/comedi.h | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-)
drivers/comedi/comedi_fops.c +1 -1
@@ -1099,7 +1099,7 @@ static int do_chaninfo_ioctl(struct comefor (i =0 ; i < s->n_chan; i++) {int x; - x = (dev->minor <<28 ) | (it->subdev <<24 ) | (i <<16 ) | + x = (it->subdev <<24 ) | (i <<16 ) | (s->range_table_list[i]->length);if (put_user (x, it->rangelist + i))return -EFAULT ;
drivers/comedi/range.c +1 -1
@@ -52,7 +52,7 @@ int do_rangeinfo_ioctl(struct comedi_devconst struct comedi_lrange *lr;struct comedi_subdevice *s; - subd = (it->range_type >>24 ) &0xf ; + subd = (it->range_type >>24 ) &0xff ; chan = (it->range_type >>16 ) &0xff ;if (!dev->attached)
include/uapi/linux/comedi.h +1 -1
@@ -640,7 +640,7 @@ struct comedi_chaninfo {/** * struct comedi_rangeinfo - used to retrieve the range table for a channel -* @range_type: Encodes subdevice index (bits 27:24), channel index +* @range_type: Encodes subdevice index (bits 31:24), channel index * (bits 23:16) and range table length (bits 15:0). * @range_ptr: Pointer to array of @struct comedi_krange to be filled * in with the range table for the channel or subdevice.
Greg Kroah-Hartman
maintainerPATCH 148/254 platform/x86: hp-bioscfg: Fix kobject warnings for empty attribute names
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit fdee1b09721605f532352628d0a24623e7062efb upstream.
The hp-bioscfg driver attempts to register kobjects with empty names when the HP BIOS returns attributes with empty name strings. This causes multiple kernel warnings:
kobject: (00000000135fb5e6): attempted to be registered with empty name!
WARNING: CPU: 14 PID: 3336 at lib/kobject.c:219 kobject_add_internal+0x2eb/0x310
Add validation in hp_init_bios_buffer_attribute() to check if the attribute name is empty after parsing it from the WMI buffer. If empty, log a debug message and skip registration of that attribute, allowing the module to continue processing other valid attributes.
--- drivers/platform/x86/hp/hp-bioscfg/bioscfg.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/platform/x86/hp/hp-bioscfg/bioscfg.c +8 -0
@@ -10,6 +10,8 @@#include <linux/fs.h> #include <linux/module.h> #include <linux/kernel.h> +#include <linux/printk.h> +#include <linux/string.h> #include <linux/wmi.h> #include "bioscfg.h" #include "../../firmware_attributes_class.h"
@@ -786,6 +788,12 @@ static int hp_init_bios_buffer_attributeif (ret <0 ) goto buff_attr_exit; +if (strlen (str) ==0 ) { +pr_debug ("Ignoring attribute with empty name\n" ); + ret =0 ; + goto buff_attr_exit; + } +if (attr_type ==HPWMI_PASSWORD_TYPE || attr_type ==HPWMI_SECURE_PLATFORM_TYPE ) temp_kset = bioscfg_drv.authentication_dir_kset;
Greg Kroah-Hartman
maintainerPATCH 149/254 platform/x86: hp-bioscfg: Fix kernel panic in GET_INSTANCE_ID macro
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 25150715e0b049b99df664daf05dab12f41c3e13 upstream.
The GET_INSTANCE_ID macro that caused a kernel panic when accessing sysfs attributes:
1. Off-by-one error: The loop condition used '<=' instead of '<', causing access beyond array bounds. Since array indices are 0-based and go from 0 to instances_count-1, the loop should use '<'.
2. Missing NULL check: The code dereferenced attr_name_kobj->name without checking if attr_name_kobj was NULL, causing a null pointer dereference in min_length_show() and other attribute show functions.
The panic occurred when fwupd tried to read BIOS configuration attributes:
Oops: general protection fault [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:min_length_show+0xcf/0x1d0 [hp_bioscfg]
Add a NULL check for attr_name_kobj before dereferencing and corrects the loop boundary to match the pattern used elsewhere in the driver.
--- drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/platform/x86/hp/hp-bioscfg/bioscfg.h +4 -2
@@ -10,6 +10,7 @@#include <linux/wmi.h> #include <linux/types.h> +#include <linux/string.h> #include <linux/device.h> #include <linux/module.h> #include <linux/kernel.h>
@@ -285,8 +286,9 @@ enum hp_wmi_data_elements { { \int i; \ \ - for (i = 0; i <= bioscfg_drv.type##_instances_count; i++) { \ - if (!strcmp(kobj->name, bioscfg_drv.type##_data[i].attr_name_kobj->name)) \ + for (i = 0; i < bioscfg_drv.type##_instances_count; i++) { \ + if (bioscfg_drv.type##_data[i].attr_name_kobj && \ + !strcmp(kobj->name, bioscfg_drv.type##_data[i].attr_name_kobj->name)) \return i; \ } \return -EIO ; \
Signature · 1 line
2.52.0
Greg Kroah-Hartman
maintainerPATCH 150/254 io_uring/io-wq: check IO_WQ_BIT_EXIT inside work run loop
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
commit 10dc959398175736e495f71c771f8641e1ca1907 upstream.
Currently this is checked before running the pending work. Normally this is quite fine, as work items either end up blocking (which will create a new worker for other items), or they complete fairly quickly. But syzbot reports an issue where io-wq takes seemingly forever to exit, and with a bit of debugging, this turns out to be because it queues a bunch of big (2GB - 4096b) reads with a /dev/msr* file. Since this file type doesn't support ->read_iter(), loop_rw_iter() ends up handling them. Each read returns 16MB of data read, which takes 20 (!!) seconds. With a bunch of these pending, processing the whole chain can take a long time. Easily longer than the syzbot uninterruptible sleep timeout of 140 seconds. This then triggers a complaint off the io-wq exit path:
INFO: task syz.4.135:6326 blocked for more than 143 seconds.
Not tainted syzkaller #0
Blocked by coredump.
"echo 0 > /proc/sys/kernel/hung_task_timeout_secs" disables this message.
task:syz.4.135 state:D stack:26824 pid:6326 tgid:6324 ppid:5957 task_flags:0x400548 flags:0x00080000
Call Trace:
<TASK>
context_switch kernel/sched/core.c:5256 [inline]
__schedule+0x1139/0x6150 kernel/sched/core.c:6863
__schedule_loop kernel/sched/core.c:6945 [inline]
schedule+0xe7/0x3a0 kernel/sched/core.c:6960
schedule_timeout+0x257/0x290 kernel/time/sleep_timeout.c:75
do_wait_for_common kernel/sched/completion.c:100 [inline]
__wait_for_common+0x2fc/0x4e0 kernel/sched/completion.c:121
io_wq_exit_workers io_uring/io-wq.c:1328 [inline]
io_wq_put_and_exit+0x271/0x8a0 io_uring/io-wq.c:1356
io_uring_clean_tctx+0x10d/0x190 io_uring/tctx.c:203
io_uring_cancel_generic+0x69c/0x9a0 io_uring/cancel.c:651
io_uring_files_cancel include/linux/io_uring.h:19 [inline]
do_exit+0x2ce/0x2bd0 kernel/exit.c:911
do_group_exit+0xd3/0x2a0 kernel/exit.c:1112
get_signal+0x2671/0x26d0 kernel/signal.c:3034
arch_do_signal_or_restart+0x8f/0x7e0 arch/x86/kernel/signal.c:337
__exit_to_user_mode_loop kernel/entry/common.c:41 [inline]
exit_to_user_mode_loop+0x8c/0x540 kernel/entry/common.c:75
__exit_to_user_mode_prepare include/linux/irq-entry-common.h:226 [inline]
syscall_exit_to_user_mode_prepare include/linux/irq-entry-common.h:256 [inline]
syscall_exit_to_user_mode_work include/linux/entry-common.h:159 [inline]
syscall_exit_to_user_mode include/linux/entry-common.h:194 [inline]
do_syscall_64+0x4ee/0xf80 arch/x86/entry/syscall_64.c:100
entry_SYSCALL_64_after_hwframe+0x77/0x7f
RIP: 0033:0x7fa02738f749
RSP: 002b:00007fa0281ae0e8 EFLAGS: 00000246 ORIG_RAX: 00000000000000ca
RAX: fffffffffffffe00 RBX: 00007fa0275e6098 RCX: 00007fa02738f749
RDX: 0000000000000000 RSI: 0000000000000080 RDI: 00007fa0275e6098
RBP: 00007fa0275e6090 R08: 0000000000000000 R09: 0000000000000000
R10: 0000000000000000 R11: 0000000000000246 R12: 0000000000000000
R13: 00007fa0275e6128 R14: 00007fff14e4fcb0 R15: 00007fff14e4fd98There's really nothing wrong here, outside of processing these reads will take a LONG time. However, we can speed up the exit by checking the IO_WQ_BIT_EXIT inside the io_worker_handle_work() loop, as syzbot will exit the ring after queueing up all of these reads. Then once the first item is processed, io-wq will simply cancel the rest. That should avoid syzbot running into this complaint again.
--- io_uring/io-wq.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
io_uring/io-wq.c +1 -1
@@ -554,9 +554,9 @@ static void io_worker_handle_work(struct __releases(&acct->lock) {struct io_wq *wq = worker->wq; -bool do_kill =test_bit (IO_WQ_BIT_EXIT , &wq->state); do { + bool do_kill = test_bit(IO_WQ_BIT_EXIT, &wq->state); struct io_wq_work *work; /*
Greg Kroah-Hartman
maintainerPATCH 151/254 iio: imu: st_lsm6dsx: fix iio_chan_spec for sensors without event detection
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Lavra <[email protected]>
commit c34e2e2d67b3bb8d5a6d09b0d6dac845cdd13fb3 upstream.
The st_lsm6dsx_acc_channels array of struct iio_chan_spec has a non-NULL event_spec field, indicating support for IIO events. However, event detection is not supported for all sensors, and if userspace tries to configure accelerometer wakeup events on a sensor device that does not support them (e.g. LSM6DS0), st_lsm6dsx_write_event() dereferences a NULL pointer when trying to write to the wakeup register.
Define an additional struct iio_chan_spec array whose members have a NULL event_spec field, and use this array instead of st_lsm6dsx_acc_channels for sensors without event detection capability.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_core.c +11 -4
@@ -84,6 +84,13 @@ static const struct iio_chan_spec st_lsm IIO_CHAN_SOFT_TIMESTAMP(3), }; +static const struct iio_chan_spec st_lsm6ds0_acc_channels[] = { +ST_LSM6DSX_CHANNEL (IIO_ACCEL ,0x28 ,IIO_MOD_X ,0 ), +ST_LSM6DSX_CHANNEL (IIO_ACCEL ,0x2a ,IIO_MOD_Y ,1 ), +ST_LSM6DSX_CHANNEL (IIO_ACCEL ,0x2c ,IIO_MOD_Z ,2 ), +IIO_CHAN_SOFT_TIMESTAMP (3 ), +}; +static const struct iio_chan_spec st_lsm6dsx_gyro_channels[] = {ST_LSM6DSX_CHANNEL (IIO_ANGL_VEL ,0x22 ,IIO_MOD_X ,0 ),ST_LSM6DSX_CHANNEL (IIO_ANGL_VEL ,0x24 ,IIO_MOD_Y ,1 ),
@@ -125,8 +132,8 @@ static const struct st_lsm6dsx_settings }, .channels = { [ST_LSM6DSX_ID_ACC] = { - .chan = st_lsm6dsx_acc_channels, - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + .chan = st_lsm6ds0_acc_channels, + .len = ARRAY_SIZE(st_lsm6ds0_acc_channels), }, [ST_LSM6DSX_ID_GYRO] = { .chan = st_lsm6ds0_gyro_channels,
@@ -1428,8 +1435,8 @@ static const struct st_lsm6dsx_settings }, .channels = { [ST_LSM6DSX_ID_ACC] = { - .chan = st_lsm6dsx_acc_channels, - .len = ARRAY_SIZE(st_lsm6dsx_acc_channels), + .chan = st_lsm6ds0_acc_channels, + .len = ARRAY_SIZE(st_lsm6ds0_acc_channels), }, [ST_LSM6DSX_ID_GYRO] = { .chan = st_lsm6dsx_gyro_channels,
Greg Kroah-Hartman
maintainerPATCH 152/254 iio: adc: ad7280a: handle spi_setup() errors in probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pavel Zhigulin <[email protected]>
[ Upstream commit 6b39824ac4c15783787e6434449772bfb2e31214 ]
The probe() function ignored the return value of spi_setup(), leaving SPI configuration failures undetected. If spi_setup() fails, the driver should stop initialization and propagate the error to the caller.
Add proper error handling: check the return value of spi_setup() and return it on failure.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/iio/adc/ad7280a.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/iio/adc/ad7280a.c +3 -1
@@ -1028,7 +1028,9 @@ static int ad7280_probe(struct spi_device *spi) st->spi->max_speed_hz =AD7280A_MAX_SPI_CLK_HZ ; st->spi->mode =SPI_MODE_1 ; -spi_setup (st->spi); + ret =spi_setup (st->spi); +if (ret <0 ) +return ret; st->ctrl_lb =FIELD_PREP (AD7280A_CTRL_LB_ACQ_TIME_MSK , st->acquisition_time) |FIELD_PREP (AD7280A_CTRL_LB_THERMISTOR_MSK , st->thermistor_term_en);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 153/254 interconnect: debugfs: initialize src_node and dst_node to empty strings
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Georgi Djakov <[email protected]>
[ Upstream commit 8cc27f5c6dd17dd090f3a696683f04336c162ff5 ]
The debugfs_create_str() API assumes that the string pointer is either NULL or points to valid kmalloc() memory. Leaving the pointer uninitialized can cause problems.
Initialize src_node and dst_node to empty strings before creating the debugfs entries to guarantee that reads and writes are safe.
--- drivers/interconnect/debugfs-client.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/interconnect/debugfs-client.c +5 -0
@@ -150,6 +150,11 @@ int icc_debugfs_client_init(struct dentry *icc_dir)return ret; } + src_node =devm_kstrdup (&pdev->dev,"" ,GFP_KERNEL ); + dst_node =devm_kstrdup (&pdev->dev,"" ,GFP_KERNEL ); +if (!src_node || !dst_node) +return -ENOMEM ; + client_dir =debugfs_create_dir ("test_client" , icc_dir);debugfs_create_str ("src_node" ,0600 , client_dir, &src_node);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 154/254 spi: sprd: adi: Use devm_register_restart_handler()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrew Davis <[email protected]>
[ Upstream commit 8e6a43961f24cf841d3c0d199521d0b284d948b9 ]
Use device life-cycle managed register function to simplify probe error path and eliminate need for explicit remove function.
Stable-dep-of: 383d4f5cffcc ("spi: spi-sprd-adi: Fix double free in probe error path")
--- drivers/spi/spi-sprd-adi.c | 30 ++++++++---------------------- 1 file changed, 8 insertions(+), 22 deletions(-)
drivers/spi/spi-sprd-adi.c +8 -22
@@ -138,8 +138,7 @@ struct sprd_adi_data {u32 slave_offset;u32 slave_addr_size;int (*read_check)(u32 val,u32 reg); -int (*restart)(struct notifier_block *this, -unsigned long mode,void *cmd); +int (*restart)(struct sys_off_data *data);void (*wdg_rst)(void *p); };
@@ -150,7 +149,6 @@ struct sprd_adi {struct hwspinlock *hwlock;unsigned long slave_vbase;unsigned long slave_pbase; -struct notifier_block restart_handler;const struct sprd_adi_data *data; };
@@ -370,11 +368,9 @@ static void sprd_adi_set_wdt_rst_mode(void *p)#endif } -static int sprd_adi_restart (struct notifier_block *this,unsigned long mode, -void *cmd,struct sprd_adi_wdg *wdg) +static int sprd_adi_restart (struct sprd_adi *sadi,unsigned long mode, +const char *cmd,struct sprd_adi_wdg *wdg) { - struct sprd_adi *sadi = container_of(this, struct sprd_adi, - restart_handler);u32 val, reboot_mode =0 ;if (!cmd)
@@ -448,8 +444,7 @@ static int sprd_adi_restart(struct notifier_block *this, unsigned long mode,return NOTIFY_DONE ; } -static int sprd_adi_restart_sc9860 (struct notifier_block *this, -unsigned long mode,void *cmd) +static int sprd_adi_restart_sc9860 (struct sys_off_data *data) {struct sprd_adi_wdg wdg = { .base =PMIC_WDG_BASE ,
@@ -458,7 +453,7 @@ static int sprd_adi_restart_sc9860(struct notifier_block *this, .wdg_clk = PMIC_CLK_EN, }; -return sprd_adi_restart (this, mode, cmd, &wdg); +return sprd_adi_restart (data->cb_data, data->mode, data->cmd, &wdg); }static void sprd_adi_hw_init (struct sprd_adi *sadi)
@@ -590,9 +585,9 @@ static int sprd_adi_probe(struct platform_device *pdev) }if (sadi->data->restart) { - sadi->restart_handler.notifier_call = sadi->data->restart; - sadi->restart_handler.priority =128 ; - ret =register_restart_handler (&sadi->restart_handler); + ret =devm_register_restart_handler (&pdev->dev, + sadi->data->restart, + sadi);if (ret) {dev_err (&pdev->dev,"can not register restart handler\n" ); goto put_ctlr;
@@ -606,14 +601,6 @@ static int sprd_adi_probe(struct platform_device *pdev)return ret; } -static void sprd_adi_remove (struct platform_device *pdev) -{ -struct spi_controller *ctlr =dev_get_drvdata (&pdev->dev); -struct sprd_adi *sadi =spi_controller_get_devdata (ctlr); - -unregister_restart_handler (&sadi->restart_handler); -} -static struct sprd_adi_data sc9860_data = { .slave_offset =ADI_10BIT_SLAVE_OFFSET , .slave_addr_size =ADI_10BIT_SLAVE_ADDR_SIZE ,
@@ -657,7 +644,6 @@ static struct platform_driver sprd_adi_driver = { .of_match_table = sprd_adi_of_match, }, .probe = sprd_adi_probe, - .remove_new = sprd_adi_remove, };module_platform_driver (sprd_adi_driver);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 155/254 spi: sprd-adi: switch to use spi_alloc_host()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yingliang <[email protected]>
[ Upstream commit 0a3d087d09a8f52c02d0014bad63be99c53c4812 ]
Switch to use modern name function spi_alloc_host().
No functional changed.
Stable-dep-of: 383d4f5cffcc ("spi: spi-sprd-adi: Fix double free in probe error path")
--- drivers/spi/spi-sprd-adi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-sprd-adi.c +1 -1
@@ -528,7 +528,7 @@ static int sprd_adi_probe(struct platform_device *pdev) pdev->id =of_alias_get_id (np,"spi" ); num_chipselect =of_get_child_count (np); - ctlr =spi_alloc_master (&pdev->dev,sizeof (struct sprd_adi )); + ctlr =spi_alloc_host (&pdev->dev,sizeof (struct sprd_adi ));if (!ctlr)return -ENOMEM ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 156/254 spi: spi-sprd-adi: Fix double free in probe error path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 383d4f5cffcc8df930d95b06518a9d25a6d74aac ]
The driver currently uses spi_alloc_host() to allocate the controller but registers it using devm_spi_register_controller().
If devm_register_restart_handler() fails, the code jumps to the put_ctlr label and calls spi_controller_put(). However, since the controller was registered via a devm function, the device core will automatically call spi_controller_put() again when the probe fails. This results in a double-free of the spi_controller structure.
Fix this by switching to devm_spi_alloc_host() and removing the manual spi_controller_put() call.
--- drivers/spi/spi-sprd-adi.c | 33 ++++++++++----------------------- 1 file changed, 10 insertions(+), 23 deletions(-)
drivers/spi/spi-sprd-adi.c +10 -23
@@ -528,7 +528,7 @@ static int sprd_adi_probe(struct platform_device *pdev) pdev->id =of_alias_get_id (np,"spi" ); num_chipselect =of_get_child_count (np); - ctlr =spi_alloc_host (&pdev->dev,sizeof (struct sprd_adi )); + ctlr =devm_spi_alloc_host (&pdev->dev,sizeof (struct sprd_adi ));if (!ctlr)return -ENOMEM ;
@@ -536,10 +536,8 @@ static int sprd_adi_probe(struct platform_device *pdev) sadi =spi_controller_get_devdata (ctlr); sadi->base =devm_platform_get_and_ioremap_resource (pdev,0 , &res); -if (IS_ERR (sadi->base)) { - ret =PTR_ERR (sadi->base); - goto put_ctlr; - } +if (IS_ERR (sadi->base)) +return PTR_ERR (sadi->base); sadi->slave_vbase = (unsigned long )sadi->base + data->slave_offset;
@@ -551,18 +549,15 @@ static int sprd_adi_probe(struct platform_device *pdev)if (ret >0 || (IS_ENABLED (CONFIG_HWSPINLOCK ) && ret ==0 )) { sadi->hwlock =devm_hwspin_lock_request_specific (&pdev->dev, ret); -if (!sadi->hwlock) { - ret = -ENXIO ; - goto put_ctlr; - } +if (!sadi->hwlock) +return -ENXIO ; }else {switch (ret) {case -ENOENT :dev_info (&pdev->dev,"no hardware spinlock supplied\n" );break ;default : -dev_err_probe (&pdev->dev, ret,"failed to find hwlock id\n" ); - goto put_ctlr; +return dev_err_probe (&pdev->dev, ret,"failed to find hwlock id\n" ); } }
@@ -579,26 +574,18 @@ static int sprd_adi_probe(struct platform_device *pdev) ctlr->transfer_one = sprd_adi_transfer_one; ret =devm_spi_register_controller (&pdev->dev, ctlr); -if (ret) { -dev_err (&pdev->dev,"failed to register SPI controller\n" ); - goto put_ctlr; - } +if (ret) +return dev_err_probe (&pdev->dev, ret,"failed to register SPI controller\n" );if (sadi->data->restart) { ret =devm_register_restart_handler (&pdev->dev, sadi->data->restart, sadi); -if (ret) { -dev_err (&pdev->dev,"can not register restart handler\n" ); - goto put_ctlr; - } +if (ret) +return dev_err_probe (&pdev->dev, ret,"can not register restart handler\n" ); }return 0 ; - -put_ctlr: -spi_controller_put (ctlr); -return ret; }static struct sprd_adi_data sc9860_data = {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 157/254 regmap: Fix race condition in hwspinlock irqsave routine
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng-Yu Lee <[email protected]>
[ Upstream commit 4b58aac989c1e3fafb1c68a733811859df388250 ]
Previously, the address of the shared member '&map->spinlock_flags' was passed directly to 'hwspin_lock_timeout_irqsave'. This creates a race condition where multiple contexts contending for the lock could overwrite the shared flags variable, potentially corrupting the state for the current lock owner.
Fix this by using a local stack variable 'flags' to store the IRQ state temporarily.
--- drivers/base/regmap/regmap.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/base/regmap/regmap.c +3 -1
@@ -408,9 +408,11 @@ static void regmap_lock_hwlock_irq(void *__map)static void regmap_lock_hwlock_irqsave (void *__map) {struct regmap *map = __map; +unsigned long flags =0 ;hwspin_lock_timeout_irqsave (map->hwlock,UINT_MAX , - &map->spinlock_flags); + &flags); + map->spinlock_flags = flags; }static void regmap_unlock_hwlock (void *__map)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 158/254 kconfig: fix static linking of nconf
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arkadiusz Kozdra <[email protected]>
[ Upstream commit baaecfcac559bcac73206df447eb5c385fa22f2a ]
When running make nconfig with a static linking host toolchain, the libraries are linked in an incorrect order, resulting in errors similar to the following:
$ MAKEFLAGS='HOSTCC=cc\ -static' make nconfig /usr/bin/ld: /usr/lib64/gcc/x86_64-unknown-linux-gnu/14.2.1/../../../../lib64/libpanel.a(p_new.o): in function `new_panel': (.text+0x13): undefined reference to `_nc_panelhook_sp' /usr/bin/ld: (.text+0x6c): undefined reference to `_nc_panelhook_sp'
--- scripts/kconfig/nconf-cfg.sh | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
scripts/kconfig/nconf-cfg.sh +6 -5
@@ -4,8 +4,9 @@ cflags=$1 libs=$2 -PKG="ncursesw menuw panelw" -PKG2="ncurses menu panel" +# Keep library order for static linking (HOSTCC='cc -static') +PKG="menuw panelw ncursesw" +PKG2="menu panel ncurses" if [ -n "$(command -v ${HOSTPKG_CONFIG})" ]; then if ${HOSTPKG_CONFIG} --exists $PKG; then
@@ -26,19 +27,19 @@ fi # find ncurses by pkg-config.) if [ -f /usr/include/ncursesw/ncurses.h ]; then echo -D_GNU_SOURCE -I/usr/include/ncursesw > ${cflags} - echo -lncursesw -lmenuw -lpanelw > ${libs} + echo -lmenuw -lpanelw -lncursesw > ${libs} exit 0 fi if [ -f /usr/include/ncurses/ncurses.h ]; then echo -D_GNU_SOURCE -I/usr/include/ncurses > ${cflags} - echo -lncurses -lmenu -lpanel > ${libs} + echo -lmenu -lpanel -lncurses > ${libs} exit 0 fi if [ -f /usr/include/ncurses.h ]; then echo -D_GNU_SOURCE > ${cflags} - echo -lncurses -lmenu -lpanel > ${libs} + echo -lmenu -lpanel -lncurses > ${libs} exit 0 fi
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 159/254 riscv: clocksource: Fix stimecmp update hazard on RV32
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Naohiko Shimizu <[email protected]>
[ Upstream commit eaa9bb1d39d59e7c17b06cec12622b7c586ab629 ]
On RV32, updating the 64-bit stimecmp (or vstimecmp) CSR requires two separate 32-bit writes. A race condition exists if the timer triggers during these two writes.
The RISC-V Privileged Specification (e.g., Section 3.2.1 for mtimecmp) recommends a specific 3-step sequence to avoid spurious interrupts when updating 64-bit comparison registers on 32-bit systems:
1. Set the low-order bits (stimecmp) to all ones (ULONG_MAX).
2. Set the high-order bits (stimecmph) to the desired value.
3. Set the low-order bits (stimecmp) to the desired value.
Current implementation writes the LSB first without ensuring a future value, which may lead to a transient state where the 64-bit comparison is incorrectly evaluated as "expired" by the hardware. This results in spurious timer interrupts.
This patch adopts the spec-recommended 3-step sequence to ensure the intermediate 64-bit state is never smaller than the current time.
--- drivers/clocksource/timer-riscv.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/clocksource/timer-riscv.c +2 -1
@@ -39,8 +39,9 @@ static int riscv_clock_next_event(unsigned long delta,csr_set (CSR_IE ,IE_TIE );if (static_branch_likely (&riscv_sstc_available)) {#if defined(CONFIG_32BIT ) -csr_write (CSR_STIMECMP , next_tval &0xFFFFFFFF ); +csr_write (CSR_STIMECMP ,ULONG_MAX );csr_write (CSR_STIMECMPH , next_tval >>32 ); +csr_write (CSR_STIMECMP , next_tval &0xFFFFFFFF );#else csr_write (CSR_STIMECMP , next_tval);#endif
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 160/254 scsi: core: Wake up the error handler when final completions race against each other
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Jeffery <[email protected]>
[ Upstream commit fe2f8ad6f0999db3b318359a01ee0108c703a8c3 ]
The fragile ordering between marking commands completed or failed so that the error handler only wakes when the last running command completes or times out has race conditions. These race conditions can cause the SCSI layer to fail to wake the error handler, leaving I/O through the SCSI host stuck as the error state cannot advance.
First, there is an memory ordering issue within scsi_dec_host_busy(). The write which clears SCMD_STATE_INFLIGHT may be reordered with reads counting in scsi_host_busy(). While the local CPU will see its own write, reordering can allow other CPUs in scsi_dec_host_busy() or scsi_eh_inc_host_failed() to see a raised busy count, causing no CPU to see a host busy equal to the host_failed count.
This race condition can be prevented with a memory barrier on the error path to force the write to be visible before counting host busy commands.
Second, there is a general ordering issue with scsi_eh_inc_host_failed(). By counting busy commands before incrementing host_failed, it can race with a final command in scsi_dec_host_busy(), such that scsi_dec_host_busy() does not see host_failed incremented but scsi_eh_inc_host_failed() counts busy commands before SCMD_STATE_INFLIGHT is cleared by scsi_dec_host_busy(), resulting in neither waking the error handler task.
This needs the call to scsi_host_busy() to be moved after host_failed is incremented to close the race condition.
--- drivers/scsi/scsi_error.c | 11 ++++++++++- drivers/scsi/scsi_lib.c | 8 ++++++++ 2 files changed, 18 insertions(+), 1 deletion(-)
drivers/scsi/scsi_error.c +10 -1
@@ -282,11 +282,20 @@ static void scsi_eh_inc_host_failed(struct rcu_head *head) {struct scsi_cmnd *scmd =container_of (head,typeof (*scmd), rcu);struct Scsi_Host *shost = scmd->device->host; -unsigned int busy =scsi_host_busy (shost); +unsigned int busy;unsigned long flags;spin_lock_irqsave (shost->host_lock, flags); shost->host_failed++; +spin_unlock_irqrestore (shost->host_lock, flags); +/* +* The counting of busy requests needs to occur after adding to +* host_failed or after the lock acquire for adding to host_failed +* to prevent a race with host unbusy and missing an eh wakeup. +*/ + busy =scsi_host_busy (shost); + +spin_lock_irqsave (shost->host_lock, flags);scsi_eh_wakeup (shost, busy);spin_unlock_irqrestore (shost->host_lock, flags); }
drivers/scsi/scsi_lib.c +8 -0
@@ -278,6 +278,14 @@ static void scsi_dec_host_busy(struct Scsi_Host *shost, struct scsi_cmnd *cmd)rcu_read_lock ();__clear_bit (SCMD_STATE_INFLIGHT , &cmd->state);if (unlikely (scsi_host_in_recovery (shost))) { +/* +* Ensure the clear of SCMD_STATE_INFLIGHT is visible to +* other CPUs before counting busy requests. Otherwise, +* reordering can cause CPUs to race and miss an eh wakeup +* when no CPU sees all busy requests as done or timed out. +*/ +smp_mb (); +unsigned int busy =scsi_host_busy (shost);spin_lock_irqsave (shost->host_lock, flags);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 161/254 scsi: qla2xxx: Sanitize payload size to prevent member overflow
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiasheng Jiang <[email protected]>
[ Upstream commit 19bc5f2a6962dfaa0e32d0e0bc2271993d85d414 ]
In qla27xx_copy_fpin_pkt() and qla27xx_copy_multiple_pkt(), the frame_size reported by firmware is used to calculate the copy length into item->iocb. However, the iocb member is defined as a fixed-size 64-byte array within struct purex_item.
If the reported frame_size exceeds 64 bytes, subsequent memcpy calls will overflow the iocb member boundary. While extra memory might be allocated, this cross-member write is unsafe and triggers warnings under CONFIG_FORTIFY_SOURCE.
Fix this by capping total_bytes to the size of the iocb member (64 bytes) before allocation and copying. This ensures all copies remain within the bounds of the destination structure member.
--- drivers/scsi/qla2xxx/qla_isr.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/scsi/qla2xxx/qla_isr.c +7 -0
@@ -878,6 +878,9 @@ qla27xx_copy_multiple_pkt(struct scsi_qla_host *vha, void **pkt, payload_size =sizeof (purex->els_frame_payload); } +if (total_bytes >sizeof (item->iocb.iocb)) + total_bytes =sizeof (item->iocb.iocb); + pending_bytes = total_bytes; no_bytes = (pending_bytes > payload_size) ? payload_size : pending_bytes;
@@ -1163,6 +1166,10 @@ qla27xx_copy_fpin_pkt(struct scsi_qla_host *vha, void **pkt, total_bytes = (le16_to_cpu (purex->frame_size) &0x0FFF ) -PURX_ELS_HEADER_SIZE ; + +if (total_bytes >sizeof (item->iocb.iocb)) + total_bytes =sizeof (item->iocb.iocb); + pending_bytes = total_bytes; entry_count = entry_count_remaining = purex->entry_count; no_bytes = (pending_bytes > sizeof(purex->els_frame_payload)) ?
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 162/254 ALSA: usb: Increase volume range that triggers a warning
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arun Raghavan <[email protected]>
[ Upstream commit 6b971191fcfc9e3c2c0143eea22534f1f48dbb62 ]
On at least the HyperX Cloud III, the range is 18944 (-18944 -> 0 in steps of 1), so the original check for 255 steps is definitely obsolete. Let's give ourselves a little more headroom before we emit a warning.
--- sound/usb/mixer.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
sound/usb/mixer.c +3 -4
@@ -1807,11 +1807,10 @@ static void __build_feature_ctl(struct usb_mixer_interface *mixer, range = (cval->max - cval->min) / cval->res;/* -* Are there devices with volume range more than 255? I use a bit more -* to be sure. 384 is a resolution magic number found on Logitech -* devices. It will definitively catch all buggy Logitech devices. +* There are definitely devices with a range of ~20,000, so let's be +* conservative and allow for a bit more. */ -if (range >384 ) { +if (range >65535 ) {usb_audio_warn (mixer->chip,"Warning! Unlikely big volume range (=%u), cval->res is probably wrong." , range);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 163/254 netdevsim: fix a race issue related to the operation on bpf_bound_progs list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yun Lu <[email protected]>
[ Upstream commit b97d5eedf4976cc94321243be83b39efe81a0e15 ]
The netdevsim driver lacks a protection mechanism for operations on the bpf_bound_progs list. When the nsim_bpf_create_prog() performs list_add_tail, it is possible that nsim_bpf_destroy_prog() is simultaneously performs list_del. Concurrent operations on the list may lead to list corruption and trigger a kernel crash as follows:
[ 417.290971] kernel BUG at lib/list_debug.c:62! [ 417.290983] invalid opcode: 0000 [#1] PREEMPT SMP NOPTI [ 417.290992] CPU: 10 PID: 168 Comm: kworker/10:1 Kdump: loaded Not tainted 6.19.0-rc5 #1 [ 417.291003] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.16.3-debian-1.16.3-2 04/01/2014 [ 417.291007] Workqueue: events bpf_prog_free_deferred [ 417.291021] RIP: 0010:__list_del_entry_valid_or_report+0xa7/0xc0 [ 417.291034] Code: a8 ff 0f 0b 48 89 fe 48 89 ca 48 c7 c7 48 a1 eb ae e8 ed fb a8 ff 0f 0b 48 89 fe 48 89 c2 48 c7 c7 80 a1 eb ae e8 d9 fb a8 ff <0f> 0b 48 89 d1 48 c7 c7 d0 a1 eb ae 48 89 f2 48 89 c6 e8 c2 fb a8 [ 417.291040] RSP: 0018:ffffb16a40807df8 EFLAGS: 00010246 [ 417.291046] RAX: 000000000000006d RBX: ffff8e589866f500 RCX: 0000000000000000 [ 417.291051] RDX: 0000000000000000 RSI: ffff8e59f7b23180 RDI: ffff8e59f7b23180 [ 417.291055] RBP: ffffb16a412c9000 R08: 0000000000000000 R09: 0000000000000003 [ 417.291059] R10: ffffb16a40807c80 R11: ffffffffaf9edce8 R12: ffff8e594427ac20 [ 417.291063] R13: ffff8e59f7b44780 R14: ffff8e58800b7a05 R15: 0000000000000000 [ 417.291074] FS: 0000000000000000(0000) GS:ffff8e59f7b00000(0000) knlGS:0000000000000000 [ 417.291079] CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 [ 417.291083] CR2: 00007fc4083efe08 CR3: 00000001c3626006 CR4: 0000000000770ee0 [ 417.291088] PKRU: 55555554 [ 417.291091] Call Trace: [ 417.291096] <TASK> [ 417.291103] nsim_bpf_destroy_prog+0x31/0x80 [netdevsim] [ 417.291154] __bpf_prog_offload_destroy+0x2a/0x80 [ 417.291163] bpf_prog_dev_bound_destroy+0x6f/0xb0 [ 417.291171] bpf_prog_free_deferred+0x18e/0x1a0 [ 417.291178] process_one_work+0x18a/0x3a0 [ 417.291188] worker_thread+0x27b/0x3a0 [ 417.291197] ? __pfx_worker_thread+0x10/0x10 [ 417.291207] kthread+0xe5/0x120 [ 417.291214] ? __pfx_kthread+0x10/0x10 [ 417.291221] ret_from_fork+0x31/0x50 [ 417.291230] ? __pfx_kthread+0x10/0x10 [ 417.291236] ret_from_fork_asm+0x1a/0x30 [ 417.291246] </TASK>
Add a mutex lock, to prevent simultaneous addition and deletion operations on the list.
--- drivers/net/netdevsim/bpf.c | 6 ++++++ drivers/net/netdevsim/dev.c | 2 ++ drivers/net/netdevsim/netdevsim.h | 1 + 3 files changed, 9 insertions(+)
drivers/net/netdevsim/bpf.c +6 -0
@@ -244,7 +244,9 @@ static int nsim_bpf_create_prog(struct nsim_dev *nsim_dev, &state->state, &nsim_bpf_string_fops);debugfs_create_bool ("loaded" ,0400 , state->ddir, &state->is_loaded); +mutex_lock (&nsim_dev->progs_list_lock);list_add_tail (&state->l, &nsim_dev->bpf_bound_progs); +mutex_unlock (&nsim_dev->progs_list_lock); prog->aux->offload->dev_priv = state;
@@ -273,12 +275,16 @@ static int nsim_bpf_translate(struct bpf_prog *prog)static void nsim_bpf_destroy_prog (struct bpf_prog *prog) {struct nsim_bpf_bound_prog *state; +struct nsim_dev *nsim_dev; state = prog->aux->offload->dev_priv; + nsim_dev = state->nsim_dev;WARN (state->is_loaded,"offload state destroyed while program still bound" );debugfs_remove_recursive (state->ddir); +mutex_lock (&nsim_dev->progs_list_lock);list_del (&state->l); +mutex_unlock (&nsim_dev->progs_list_lock);kfree (state); }
drivers/net/netdevsim/dev.c +2 -0
@@ -1545,6 +1545,7 @@ int nsim_drv_probe(struct nsim_bus_dev *nsim_bus_dev) nsim_dev->max_macs =NSIM_DEV_MAX_MACS_DEFAULT ; nsim_dev->test1 =NSIM_DEV_TEST1_DEFAULT ;spin_lock_init (&nsim_dev->fa_cookie_lock); +mutex_init (&nsim_dev->progs_list_lock);dev_set_drvdata (&nsim_bus_dev->dev, nsim_dev);
@@ -1683,6 +1684,7 @@ void nsim_drv_remove(struct nsim_bus_dev *nsim_bus_dev)devl_unregister (devlink);kfree (nsim_dev->vfconfigs);kfree (nsim_dev->fa_cookie); +mutex_destroy (&nsim_dev->progs_list_lock);devl_unlock (devlink);devlink_free (devlink);dev_set_drvdata (&nsim_bus_dev->dev,NULL );
drivers/net/netdevsim/netdevsim.h +1 -0
@@ -295,6 +295,7 @@ struct nsim_dev {u32 prog_id_gen;struct list_head bpf_bound_progs;struct list_head bpf_bound_maps; +struct mutex progs_list_lock;struct netdev_phys_item_id switch_id;struct list_head port_list;bool fw_update_status;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 164/254 net: hns3: fix data race in hns3_fetch_stats
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Yang <[email protected]>
[ Upstream commit 748a81c8ceda1fdbdcd0af595947422e810442aa ]
In hns3_fetch_stats(), ring statistics, protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. These statistics are already accumulated by hns3_ring_stats_update(). Fix this by reading them into a temporary buffer first.
--- .../net/ethernet/hisilicon/hns3/hns3_enet.c | 69 ++++++++++--------- 1 file changed, 36 insertions(+), 33 deletions(-)
drivers/net/ethernet/hisilicon/hns3/hns3_enet.c +36 -33
@@ -2505,44 +2505,47 @@ static netdev_features_t hns3_features_check(struct sk_buff *skb,static void hns3_fetch_stats (struct rtnl_link_stats64 *stats,struct hns3_enet_ring *ring,bool is_tx) { +struct ring_stats ring_stats;unsigned int start;do { start =u64_stats_fetch_begin (&ring->syncp); -if (is_tx) { - stats->tx_bytes += ring->stats.tx_bytes; - stats->tx_packets += ring->stats.tx_pkts; - stats->tx_dropped += ring->stats.sw_err_cnt; - stats->tx_dropped += ring->stats.tx_vlan_err; - stats->tx_dropped += ring->stats.tx_l4_proto_err; - stats->tx_dropped += ring->stats.tx_l2l3l4_err; - stats->tx_dropped += ring->stats.tx_tso_err; - stats->tx_dropped += ring->stats.over_max_recursion; - stats->tx_dropped += ring->stats.hw_limitation; - stats->tx_dropped += ring->stats.copy_bits_err; - stats->tx_dropped += ring->stats.skb2sgl_err; - stats->tx_dropped += ring->stats.map_sg_err; - stats->tx_errors += ring->stats.sw_err_cnt; - stats->tx_errors += ring->stats.tx_vlan_err; - stats->tx_errors += ring->stats.tx_l4_proto_err; - stats->tx_errors += ring->stats.tx_l2l3l4_err; - stats->tx_errors += ring->stats.tx_tso_err; - stats->tx_errors += ring->stats.over_max_recursion; - stats->tx_errors += ring->stats.hw_limitation; - stats->tx_errors += ring->stats.copy_bits_err; - stats->tx_errors += ring->stats.skb2sgl_err; - stats->tx_errors += ring->stats.map_sg_err; - }else { - stats->rx_bytes += ring->stats.rx_bytes; - stats->rx_packets += ring->stats.rx_pkts; - stats->rx_dropped += ring->stats.l2_err; - stats->rx_errors += ring->stats.l2_err; - stats->rx_errors += ring->stats.l3l4_csum_err; - stats->rx_crc_errors += ring->stats.l2_err; - stats->multicast += ring->stats.rx_multicast; - stats->rx_length_errors += ring->stats.err_pkt_len; - } + ring_stats = ring->stats; }while (u64_stats_fetch_retry (&ring->syncp, start)); + +if (is_tx) { + stats->tx_bytes += ring_stats.tx_bytes; + stats->tx_packets += ring_stats.tx_pkts; + stats->tx_dropped += ring_stats.sw_err_cnt; + stats->tx_dropped += ring_stats.tx_vlan_err; + stats->tx_dropped += ring_stats.tx_l4_proto_err; + stats->tx_dropped += ring_stats.tx_l2l3l4_err; + stats->tx_dropped += ring_stats.tx_tso_err; + stats->tx_dropped += ring_stats.over_max_recursion; + stats->tx_dropped += ring_stats.hw_limitation; + stats->tx_dropped += ring_stats.copy_bits_err; + stats->tx_dropped += ring_stats.skb2sgl_err; + stats->tx_dropped += ring_stats.map_sg_err; + stats->tx_errors += ring_stats.sw_err_cnt; + stats->tx_errors += ring_stats.tx_vlan_err; + stats->tx_errors += ring_stats.tx_l4_proto_err; + stats->tx_errors += ring_stats.tx_l2l3l4_err; + stats->tx_errors += ring_stats.tx_tso_err; + stats->tx_errors += ring_stats.over_max_recursion; + stats->tx_errors += ring_stats.hw_limitation; + stats->tx_errors += ring_stats.copy_bits_err; + stats->tx_errors += ring_stats.skb2sgl_err; + stats->tx_errors += ring_stats.map_sg_err; + }else { + stats->rx_bytes += ring_stats.rx_bytes; + stats->rx_packets += ring_stats.rx_pkts; + stats->rx_dropped += ring_stats.l2_err; + stats->rx_errors += ring_stats.l2_err; + stats->rx_errors += ring_stats.l3l4_csum_err; + stats->rx_crc_errors += ring_stats.l2_err; + stats->multicast += ring_stats.rx_multicast; + stats->rx_length_errors += ring_stats.err_pkt_len; + } } static void hns3_nic_get_stats64(struct net_device *netdev,
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 165/254 be2net: fix data race in be_get_new_eqd
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Yang <[email protected]>
[ Upstream commit 302e5b481caa7b3d11ec0e058434c1fc95195e50 ]
In be_get_new_eqd(), statistics of pkts, protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. Before the commit in question, these statistics were retrieved one by one directly from queues. Fix this by reading them into temporary variables first.
--- drivers/net/ethernet/emulex/benet/be_main.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/net/ethernet/emulex/benet/be_main.c +5 -3
@@ -2141,7 +2141,7 @@ static int be_get_new_eqd(struct be_eq_obj *eqo)struct be_aic_obj *aic;struct be_rx_obj *rxo;struct be_tx_obj *txo; -u64 rx_pkts =0 , tx_pkts =0 ; +u64 rx_pkts =0 , tx_pkts =0 , pkts;ulong now;u32 pps, delta;int i;
@@ -2157,15 +2157,17 @@ static int be_get_new_eqd(struct be_eq_obj *eqo) for_all_rx_queues_on_eq(adapter, eqo, rxo, i) {do { start =u64_stats_fetch_begin (&rxo->stats.sync); - rx_pkts += rxo->stats.rx_pkts; + pkts = rxo->stats.rx_pkts; }while (u64_stats_fetch_retry (&rxo->stats.sync, start)); + rx_pkts += pkts; } for_all_tx_queues_on_eq(adapter, eqo, txo, i) {do { start =u64_stats_fetch_begin (&txo->stats.sync); - tx_pkts += txo->stats.tx_reqs; + pkts = txo->stats.tx_reqs; }while (u64_stats_fetch_retry (&txo->stats.sync, start)); + tx_pkts += pkts; }/* Skip, if wrapped around or first calculation */
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 166/254 net: hns3: fix wrong GENMASK() for HCLGE_FD_AD_COUNTER_NUM_M
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jijie Shao <[email protected]>
[ Upstream commit d57c67c956a1bad15115eba6e59d77a6dfeba01d ]
HCLGE_FD_AD_COUNTER_NUM_M should be at GENMASK(19, 13), rather than at GENMASK(20, 13), because bit 20 is HCLGE_FD_AD_NXT_STEP_B.
This patch corrects the wrong definition.
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_cmd.h +1 -1
@@ -731,7 +731,7 @@ struct hclge_fd_tcam_config_3_cmd {#define HCLGE_FD_AD_QID_M GENMASK(11, 2)#define HCLGE_FD_AD_USE_COUNTER_B 12#define HCLGE_FD_AD_COUNTER_NUM_S 13 -#define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(20, 13) +#define HCLGE_FD_AD_COUNTER_NUM_M GENMASK(19, 13)#define HCLGE_FD_AD_NXT_STEP_B 20#define HCLGE_FD_AD_NXT_KEY_S 21#define HCLGE_FD_AD_NXT_KEY_M GENMASK(25, 21)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 167/254 net: hns3: fix the HCLGE_FD_AD_NXT_KEY error setting issue
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jijie Shao <[email protected]>
[ Upstream commit f87e034d16e43af984380a95c32c25201b7759a7 ]
Use next_input_key instead of counter_id to set HCLGE_FD_AD_NXT_KEY.
--- drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/hisilicon/hns3/hns3pf/hclge_main.c +1 -1
@@ -5617,7 +5617,7 @@ static int hclge_fd_ad_config(struct hclge_dev *hdev, u8 stage, int loc, HCLGE_FD_AD_COUNTER_NUM_S, action->counter_id);hnae3_set_bit (ad_data,HCLGE_FD_AD_NXT_STEP_B , action->use_next_stage);hnae3_set_field (ad_data,HCLGE_FD_AD_NXT_KEY_M ,HCLGE_FD_AD_NXT_KEY_S , - action->counter_id); + action->next_input_key); req->ad_data =cpu_to_le64 (ad_data); ret =hclge_cmd_send (&hdev->hw, &desc,1 );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 168/254 mISDN: annotate data-race around dev->work
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 8175dbf174d487afab81e936a862a8d9b8a1ccb6 ]
dev->work can re read locklessly in mISDN_read() and mISDN_poll(). Add READ_ONCE()/WRITE_ONCE() annotations.
BUG: KCSAN: data-race in mISDN_ioctl / mISDN_read
write to 0xffff88812d848280 of 4 bytes by task 10864 on cpu 1:
misdn_add_timer drivers/isdn/mISDN/timerdev.c:175 [inline] mISDN_ioctl+0x2fb/0x550 drivers/isdn/mISDN/timerdev.c:233 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:597 [inline] __se_sys_ioctl+0xce/0x140 fs/ioctl.c:583 __x64_sys_ioctl+0x43/0x50 fs/ioctl.c:583 x64_sys_call+0x14b0/0x3000 arch/x86/include/generated/asm/syscalls_64.h:17 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd8/0x2c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
read to 0xffff88812d848280 of 4 bytes by task 10857 on cpu 0:
mISDN_read+0x1f2/0x470 drivers/isdn/mISDN/timerdev.c:112 do_loop_readv_writev fs/read_write.c:847 [inline] vfs_readv+0x3fb/0x690 fs/read_write.c:1020 do_readv+0xe7/0x210 fs/read_write.c:1080 __do_sys_readv fs/read_write.c:1165 [inline] __se_sys_readv fs/read_write.c:1162 [inline] __x64_sys_readv+0x45/0x50 fs/read_write.c:1162 x64_sys_call+0x2831/0x3000 arch/x86/include/generated/asm/syscalls_64.h:20 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xd8/0x2c0 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
value changed: 0x00000000 -> 0x00000001
--- drivers/isdn/mISDN/timerdev.c | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-)
drivers/isdn/mISDN/timerdev.c +8 -5
@@ -109,14 +109,14 @@ mISDN_read(struct file *filep, char __user *buf, size_t count, loff_t *off)spin_unlock_irq (&dev->lock);if (filep->f_flags &O_NONBLOCK )return -EAGAIN ; -wait_event_interruptible (dev->wait, (dev->work || +wait_event_interruptible (dev->wait, (READ_ONCE (dev->work) || !list_empty (list)));if (signal_pending (current))return -ERESTARTSYS ;spin_lock_irq (&dev->lock); }if (dev->work) - dev->work =0 ; +WRITE_ONCE (dev->work,0 );if (!list_empty (list)) { timer = list_first_entry(list, struct mISDNtimer, list);list_del (&timer->list);
@@ -141,13 +141,16 @@ mISDN_poll(struct file *filep, poll_table *wait)if (*debug &DEBUG_TIMER )printk (KERN_DEBUG "%s(%p, %p)\n" , __func__, filep, wait);if (dev) { +u32 work; +poll_wait (filep, &dev->wait, wait); mask =0 ; -if (dev->work || !list_empty (&dev->expired)) + work =READ_ONCE (dev->work); +if (work || !list_empty (&dev->expired)) mask |= (EPOLLIN |EPOLLRDNORM );if (*debug &DEBUG_TIMER )printk (KERN_DEBUG "%s work(%d) empty(%d)\n" , __func__, - dev->work,list_empty (&dev->expired)); + work,list_empty (&dev->expired)); }return mask; }
@@ -172,7 +175,7 @@ misdn_add_timer(struct mISDNtimerdev *dev, int timeout)struct mISDNtimer *timer;if (!timeout) { - dev->work =1 ; +WRITE_ONCE (dev->work,1 );wake_up_interruptible (&dev->wait); id =0 ; }else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 169/254 ipv6: annotate data-race in ndisc_router_discovery()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 9a063f96d87efc3a6cc667f8de096a3d38d74bb5 ]
syzbot found that ndisc_router_discovery() could read and write in6_dev->ra_mtu without holding a lock [1]
This looks fine, IFLA_INET6_RA_MTU is best effort.
Add READ_ONCE()/WRITE_ONCE() to document the race.
Note that we might also reject illegal MTU values (mtu < IPV6_MIN_MTU || mtu > skb->dev->mtu) in a future patch.
[1]
BUG: KCSAN: data-race in ndisc_router_discovery / ndisc_router_discovery
read to 0xffff888119809c20 of 4 bytes by task 25817 on cpu 1:
ndisc_router_discovery+0x151d/0x1c90 net/ipv6/ndisc.c:1558 ndisc_rcv+0x2ad/0x3d0 net/ipv6/ndisc.c:1841 icmpv6_rcv+0xe5a/0x12f0 net/ipv6/icmp.c:989 ip6_protocol_deliver_rcu+0xb2a/0x10d0 net/ipv6/ip6_input.c:438 ip6_input_finish+0xf0/0x1d0 net/ipv6/ip6_input.c:489 NF_HOOK include/linux/netfilter.h:318 [inline] ip6_input+0x5e/0x140 net/ipv6/ip6_input.c:500 ip6_mc_input+0x27c/0x470 net/ipv6/ip6_input.c:590 dst_input include/net/dst.h:474 [inline] ip6_rcv_finish+0x336/0x340 net/ipv6/ip6_input.c:79
...
write to 0xffff888119809c20 of 4 bytes by task 25816 on cpu 0:
ndisc_router_discovery+0x155a/0x1c90 net/ipv6/ndisc.c:1559 ndisc_rcv+0x2ad/0x3d0 net/ipv6/ndisc.c:1841 icmpv6_rcv+0xe5a/0x12f0 net/ipv6/icmp.c:989 ip6_protocol_deliver_rcu+0xb2a/0x10d0 net/ipv6/ip6_input.c:438 ip6_input_finish+0xf0/0x1d0 net/ipv6/ip6_input.c:489 NF_HOOK include/linux/netfilter.h:318 [inline] ip6_input+0x5e/0x140 net/ipv6/ip6_input.c:500 ip6_mc_input+0x27c/0x470 net/ipv6/ip6_input.c:590 dst_input include/net/dst.h:474 [inline] ip6_rcv_finish+0x336/0x340 net/ipv6/ip6_input.c:79
...
value changed: 0x00000000 -> 0xe5400659
--- net/ipv6/ndisc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
net/ipv6/ndisc.c +2 -2
@@ -1574,8 +1574,8 @@ static enum skb_drop_reason ndisc_router_discovery(struct sk_buff *skb)memcpy (&n, ((u8 *)(ndopts.nd_opts_mtu+1 ))+2 ,sizeof (mtu)); mtu =ntohl (n); -if (in6_dev->ra_mtu != mtu) { - in6_dev->ra_mtu = mtu; +if (READ_ONCE (in6_dev->ra_mtu) != mtu) { +WRITE_ONCE (in6_dev->ra_mtu, mtu); send_ifinfo_notify = true; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 170/254 usbnet: limit max_mtu based on devices hard_mtu
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Laurent Vivier <[email protected]>
[ Upstream commit c7159e960f1472a5493ac99aff0086ab1d683594 ]
The usbnet driver initializes net->max_mtu to ETH_MAX_MTU before calling the device's bind() callback. When the bind() callback sets dev->hard_mtu based the device's actual capability (from CDC Ethernet's wMaxSegmentSize descriptor), max_mtu is never updated to reflect this hardware limitation).
This allows userspace (DHCP or IPv6 RA) to configure MTU larger than the device can handle, leading to silent packet drops when the backend sends packet exceeding the device's buffer size.
Fix this by limiting net->max_mtu to the device's hard_mtu after the bind callback returns.
See https://gitlab.com/qemu-project/qemu/-/issues/3268 and
https://bugs.passt.top/attachment.cgi?bugid=189
--- drivers/net/usb/usbnet.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-)
drivers/net/usb/usbnet.c +6 -3
@@ -1799,9 +1799,12 @@ usbnet_probe (struct usb_interface *udev, const struct usb_device_id *prod)if ((dev->driver_info->flags &FLAG_NOARP ) !=0 ) net->flags |=IFF_NOARP ; -/* maybe the remote can't receive an Ethernet MTU */ -if (net->mtu > (dev->hard_mtu - net->hard_header_len)) - net->mtu = dev->hard_mtu - net->hard_header_len; +if (net->max_mtu > (dev->hard_mtu - net->hard_header_len)) + net->max_mtu = dev->hard_mtu - net->hard_header_len; + +if (net->mtu > net->max_mtu) + net->mtu = net->max_mtu; + }else if (!info->in || !info->out) status =usbnet_get_endpoints (dev, udev);else {
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 171/254 drm/amd/pm: Dont clear SI SMC table when setting power limit
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit d5077426e1a76d269e518e048bde2e9fc49b32ad ]
There is no reason to clear the SMC table.
We also don't need to recalculate the power limit then.
--- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 10 ---------- 1 file changed, 10 deletions(-)
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +0 -10
@@ -2257,8 +2257,6 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,if (scaling_factor ==0 )return -EINVAL ; -memset (smc_table,0 ,sizeof (SISLANDS_SMC_STATETABLE )); - ret = si_calculate_adjusted_tdp_limits(adev, false, /* ??? */ adev->pm.dpm.tdp_adjustment,
@@ -2312,16 +2310,8 @@ static int si_populate_smc_tdp_limits_2(struct amdgpu_device *adev,if (ni_pi->enable_power_containment) {SISLANDS_SMC_STATETABLE *smc_table = &si_pi->smc_statetable; -u32 scaling_factor =si_get_smc_power_scaling_factor (adev);int ret; -memset (smc_table,0 ,sizeof (SISLANDS_SMC_STATETABLE )); - - smc_table->dpm2Params.NearTDPLimit = -cpu_to_be32 (si_scale_power_for_smc (adev->pm.dpm.near_tdp_limit_adjusted, scaling_factor) *1000 ); - smc_table->dpm2Params.SafePowerLimit = -cpu_to_be32 (si_scale_power_for_smc ((adev->pm.dpm.near_tdp_limit_adjusted *SISLANDS_DPM2_TDP_SAFE_LIMIT_PERCENT ) /100 , scaling_factor) *1000 ); - ret = amdgpu_si_copy_bytes_to_smc(adev, (si_pi->state_table_start + offsetof(SISLANDS_SMC_STATETABLE, dpm2Params) +
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 172/254 drm/amd/pm: Workaround SI powertune issue on Radeon 430 (v2)
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 764a90eb02268a23b1bb98be5f4a13671346804a ]
Radeon 430 and 520 are OEM GPUs from 2016~2017 They have the same device id: 0x6611 and revision: 0x87
On the Radeon 430, powertune is buggy and throttles the GPU, never allowing it to reach its maximum SCLK. Work around this bug by raising the TDP limits we program to the SMC from 24W (specified by the VBIOS on Radeon 430) to 32W.
Disabling powertune entirely is not a viable workaround,
because it causes the Radeon 520 to heat up above 100 C,
which I prefer to avoid.
Additionally, revise the maximum SCLK limit. Considering the above issue, these GPUs never reached a high SCLK on Linux, and the workarounds were added before the GPUs were released, so the workaround likely didn't target these specifically. Use 780 MHz (the maximum SCLK according to the VBIOS on the Radeon 430). Note that the Radeon 520 VBIOS has a higher maximum SCLK: 905 MHz, but in practice it doesn't seem to perform better with the higher clock, only heats up more.
v2:
Move the workaround to si_populate_smc_tdp_limits.
--- drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/pm/legacy-dpm/si_dpm.c +12 -1
@@ -2265,6 +2265,12 @@ static int si_populate_smc_tdp_limits(struct amdgpu_device *adev,if (ret)return ret; +if (adev->pdev->device ==0x6611 && adev->pdev->revision ==0x87 ) { +/* Workaround buggy powertune on Radeon 430 and 520. */ + tdp_limit =32 ; + near_tdp_limit =28 ; + } + smc_table->dpm2Params.TDPLimit =cpu_to_be32 (si_scale_power_for_smc (tdp_limit, scaling_factor) *1000 ); smc_table->dpm2Params.NearTDPLimit =
@@ -3448,10 +3454,15 @@ static void si_apply_state_adjust_rules(struct amdgpu_device *adev, (adev->pdev->revision ==0x80 ) || (adev->pdev->revision ==0x81 ) || (adev->pdev->revision ==0x83 ) || - (adev->pdev->revision == 0x87) || + (adev->pdev->revision ==0x87 && + adev->pdev->device !=0x6611 ) || (adev->pdev->device ==0x6604 ) || (adev->pdev->device == 0x6605)) { max_sclk = 75000; + }else if (adev->pdev->revision ==0x87 && + adev->pdev->device ==0x6611 ) { +/* Radeon 430 and 520 */ + max_sclk =78000 ; } }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 173/254 be2net: Fix NULL pointer dereference in be_cmd_get_mac_from_list
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andrey Vatoropin <[email protected]>
[ Upstream commit 8215794403d264739cc676668087512950b2ff31 ]
When the parameter pmac_id_valid argument of be_cmd_get_mac_from_list() is set to false, the driver may request the PMAC_ID from the firmware of the network card, and this function will store that PMAC_ID at the provided address pmac_id. This is the contract of this function.
However, there is a location within the driver where both pmac_id_valid == false and pmac_id == NULL are being passed. This could result in dereferencing a NULL pointer.
To resolve this issue, it is necessary to pass the address of a stub variable to the function.
--- drivers/net/ethernet/emulex/benet/be_cmds.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/net/ethernet/emulex/benet/be_cmds.c +2 -1
@@ -3797,6 +3797,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac) {int status;bool pmac_valid = false; +u32 pmac_id;eth_zero_addr (mac);
@@ -3809,7 +3810,7 @@ int be_cmd_get_perm_mac(struct be_adapter *adapter, u8 *mac) adapter->if_handle, 0); }else { status =be_cmd_get_mac_from_list (adapter, mac, &pmac_valid, -NULL , adapter->if_handle,0 ); + &pmac_id, adapter->if_handle,0 ); }return status;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 174/254 selftests: net: amt: wait longer for connection before sending packets
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Taehee Yoo <[email protected]>
[ Upstream commit 04708606fd7bdc34b69089a4ff848ff36d7088f9 ]
Both send_mcast4() and send_mcast6() use sleep 2 to wait for the tunnel connection between the gateway and the relay, and for the listener socket to be created in the LISTENER namespace.
However, tests sometimes fail because packets are sent before the connection is fully established.
Increase the waiting time to make the tests more reliable, and use wait_local_port_listen() to explicitly wait for the listener socket.
--- tools/testing/selftests/net/amt.sh | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
tools/testing/selftests/net/amt.sh +5 -2
@@ -73,6 +73,8 @@ # +------------------------+ #============================================================================== +source lib.sh + readonly LISTENER=$(mktemp -u listener-XXXXXXXX) readonly GATEWAY=$(mktemp -u gateway-XXXXXXXX) readonly RELAY=$(mktemp -u relay-XXXXXXXX)
@@ -240,14 +242,15 @@ test_ipv6_forward() send_mcast4() { - sleep 2 + sleep 5 + wait_local_port_listen ${LISTENER} 4000 udp ip netns exec "${SOURCE}" bash -c \ 'printf "%s %128s" 172.17.0.2 | nc -w 1 -u 239.0.0.1 4000' & } send_mcast6() { - sleep 2 + wait_local_port_listen ${LISTENER} 6000 udp ip netns exec "${SOURCE}" bash -c \ 'printf "%s %128s" 2001:db8:3::2 | nc -w 1 -u ff0e::5:6 6000' & }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 175/254 bonding: provide a net pointer to __skb_flow_dissect()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 5f9b329096596b7e53e07d041d7fca4cbe1be752 ]
After 3cbf4ffba5ee ("net: plumb network namespace into __skb_flow_dissect") we have to provide a net pointer to __skb_flow_dissect(), either via skb->dev, skb->sk, or a user provided pointer.
In the following case, syzbot was able to cook a bare skb.
WARNING: net/core/flow_dissector.c:1131 at __skb_flow_dissect+0xb57/0x68b0 net/core/flow_dissector.c:1131, CPU#1: syz.2.1418/11053 Call Trace: <TASK> bond_flow_dissect drivers/net/bonding/bond_main.c:4093 [inline] __bond_xmit_hash+0x2d7/0xba0 drivers/net/bonding/bond_main.c:4157 bond_xmit_hash_xdp drivers/net/bonding/bond_main.c:4208 [inline] bond_xdp_xmit_3ad_xor_slave_get drivers/net/bonding/bond_main.c:5139 [inline] bond_xdp_get_xmit_slave+0x1fd/0x710 drivers/net/bonding/bond_main.c:5515 xdp_master_redirect+0x13f/0x2c0 net/core/filter.c:4388 bpf_prog_run_xdp include/net/xdp.h:700 [inline] bpf_test_run+0x6b2/0x7d0 net/bpf/test_run.c:421 bpf_prog_test_run_xdp+0x795/0x10e0 net/bpf/test_run.c:1390 bpf_prog_test_run+0x2c7/0x340 kernel/bpf/syscall.c:4703 __sys_bpf+0x562/0x860 kernel/bpf/syscall.c:6182 __do_sys_bpf kernel/bpf/syscall.c:6274 [inline] __se_sys_bpf kernel/bpf/syscall.c:6272 [inline] __x64_sys_bpf+0x7c/0x90 kernel/bpf/syscall.c:6272 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xec/0xf80 arch/x86/entry/syscall_64.c:94
--- drivers/net/bonding/bond_main.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/bonding/bond_main.c +3 -2
@@ -4186,8 +4186,9 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb, const vcase BOND_XMIT_POLICY_ENCAP23 :case BOND_XMIT_POLICY_ENCAP34 :memset (fk,0 ,sizeof (*fk)); -return __skb_flow_dissect (NULL , skb, &flow_keys_bonding, - fk, data, l2_proto, nhoff, hlen,0 ); +return __skb_flow_dissect (dev_net (bond->dev), skb, + &flow_keys_bonding, fk, data, + l2_proto, nhoff, hlen,0 );default :break ; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 176/254 net: dsa: fix off-by-one in maximum bridge ID determination
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit dfca045cd4d0ea07ff4198ba392be3e718acaddc ]
Prior to the blamed commit, the bridge_num range was from 0 to ds->max_num_bridges - 1. After the commit, it is from 1 to ds->max_num_bridges.
So this check:
if (bridge_num >= max) return 0; must be updated to: if (bridge_num > max) return 0;
in order to allow the last bridge_num value (==max) to be used.
This is easiest visible when a driver sets ds->max_num_bridges=1. The observed behaviour is that even the first created bridge triggers the netlink extack "Range of offloadable bridges exceeded" warning, and is handled in software rather than being offloaded.
--- net/dsa/dsa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/dsa/dsa.c +1 -1
@@ -158,7 +158,7 @@ unsigned int dsa_bridge_num_get(const struct net_device *bridge_dev, int max) bridge_num =find_next_zero_bit (&dsa_fwd_offloading_bridges,DSA_MAX_NUM_OFFLOADING_BRIDGES ,1 ); -if (bridge_num >= max) +if (bridge_num > max)return 0 ;set_bit (bridge_num, &dsa_fwd_offloading_bridges);
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 177/254 octeontx2-af: Fix error handling
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ratheesh Kannoth <[email protected]>
[ Upstream commit 19e4175e997a5b85eab97d522f00cc99abd1873c ]
This commit adds error handling and rollback logic to rvu_mbox_handler_attach_resources() to properly clean up partially attached resources when rvu_attach_block() fails.
--- .../net/ethernet/marvell/octeontx2/af/rvu.c | 86 ++++++++++++++----- 1 file changed, 64 insertions(+), 22 deletions(-)
drivers/net/ethernet/marvell/octeontx2/af/rvu.c +64 -22
@@ -1541,8 +1541,8 @@ static int rvu_get_attach_blkaddr(struct rvu *rvu, int blktype,return -ENODEV ; } -static void rvu_attach_block (struct rvu *rvu,int pcifunc,int blktype, -int num_lfs,struct rsrc_attach *attach) +static int rvu_attach_block (struct rvu *rvu,int pcifunc,int blktype, +int num_lfs,struct rsrc_attach *attach) {struct rvu_pfvf *pfvf =rvu_get_pfvf (rvu, pcifunc);struct rvu_hwinfo *hw = rvu->hw;
@@ -1552,21 +1552,21 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,u64 cfg;if (!num_lfs) -return ; +return -EINVAL ; blkaddr =rvu_get_attach_blkaddr (rvu, blktype, pcifunc, attach);if (blkaddr <0 ) -return ; +return -EFAULT ; block = &hw->block[blkaddr];if (!block->lf.bmap) -return ; +return -ESRCH ;for (slot =0 ; slot < num_lfs; slot++) {/* Allocate the resource */ lf =rvu_alloc_rsrc (&block->lf);if (lf <0 ) -return ; +return -EFAULT ; cfg = (1ULL <<63 ) | (pcifunc <<8 ) | slot; rvu_write64(rvu, blkaddr, block->lfcfg_reg |
@@ -1577,6 +1577,8 @@ static void rvu_attach_block(struct rvu *rvu, int pcifunc, int blktype,/* Set start MSIX vector for this LF within this PF/VF */ rvu_set_msix_offset (rvu, pfvf, block, lf); } + +return 0 ; } static int rvu_check_rsrc_availability(struct rvu *rvu,
@@ -1714,22 +1716,31 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,int err;/* If first request, detach all existing attached resources */ -if (!attach->modify) -rvu_detach_rsrcs (rvu,NULL , pcifunc); +if (!attach->modify) { + err =rvu_detach_rsrcs (rvu,NULL , pcifunc); +if (err) +return err; + }mutex_lock (&rvu->rsrc_lock);/* Check if the request can be accommodated */ err =rvu_check_rsrc_availability (rvu, attach, pcifunc);if (err) - goto exit; + goto fail1;/* Now attach the requested resources */ -if (attach->npalf) -rvu_attach_block (rvu, pcifunc,BLKTYPE_NPA ,1 , attach); +if (attach->npalf) { + err =rvu_attach_block (rvu, pcifunc,BLKTYPE_NPA ,1 , attach); +if (err) + goto fail1; + } -if (attach->nixlf) -rvu_attach_block (rvu, pcifunc,BLKTYPE_NIX ,1 , attach); +if (attach->nixlf) { + err =rvu_attach_block (rvu, pcifunc,BLKTYPE_NIX ,1 , attach); +if (err) + goto fail2; + }if (attach->sso) {/* RVU func doesn't know which exact LF or slot is attached
@@ -1739,33 +1750,64 @@ int rvu_mbox_handler_attach_resources(struct rvu *rvu,*/ if (attach->modify)rvu_detach_block (rvu, pcifunc,BLKTYPE_SSO ); -rvu_attach_block (rvu, pcifunc,BLKTYPE_SSO , - attach->sso, attach); + err =rvu_attach_block (rvu, pcifunc,BLKTYPE_SSO , + attach->sso, attach); +if (err) + goto fail3; }if (attach->ssow) {if (attach->modify)rvu_detach_block (rvu, pcifunc,BLKTYPE_SSOW ); -rvu_attach_block (rvu, pcifunc,BLKTYPE_SSOW , - attach->ssow, attach); + err =rvu_attach_block (rvu, pcifunc,BLKTYPE_SSOW , + attach->ssow, attach); +if (err) + goto fail4; }if (attach->timlfs) {if (attach->modify)rvu_detach_block (rvu, pcifunc,BLKTYPE_TIM ); -rvu_attach_block (rvu, pcifunc,BLKTYPE_TIM , - attach->timlfs, attach); + err =rvu_attach_block (rvu, pcifunc,BLKTYPE_TIM , + attach->timlfs, attach); +if (err) + goto fail5; }if (attach->cptlfs) {if (attach->modify &&rvu_attach_from_same_block (rvu,BLKTYPE_CPT , attach))rvu_detach_block (rvu, pcifunc,BLKTYPE_CPT ); -rvu_attach_block (rvu, pcifunc,BLKTYPE_CPT , - attach->cptlfs, attach); + err =rvu_attach_block (rvu, pcifunc,BLKTYPE_CPT , + attach->cptlfs, attach); +if (err) + goto fail6; } -exit: +mutex_unlock (&rvu->rsrc_lock); +return 0 ; + +fail6: +if (attach->timlfs) +rvu_detach_block (rvu, pcifunc,BLKTYPE_TIM ); + +fail5: +if (attach->ssow) +rvu_detach_block (rvu, pcifunc,BLKTYPE_SSOW ); + +fail4: +if (attach->sso) +rvu_detach_block (rvu, pcifunc,BLKTYPE_SSO ); + +fail3: +if (attach->nixlf) +rvu_detach_block (rvu, pcifunc,BLKTYPE_NIX ); + +fail2: +if (attach->npalf) +rvu_detach_block (rvu, pcifunc,BLKTYPE_NPA ); + +fail1:mutex_unlock (&rvu->rsrc_lock);return err; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 178/254 net: openvswitch: fix data race in ovs_vport_get_upcall_stats
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Yang <[email protected]>
[ Upstream commit cc4816bdb08639e5cd9acb295a02d6f0f09736b4 ]
In ovs_vport_get_upcall_stats(), some statistics protected by u64_stats_sync, are read and accumulated in ignorance of possible u64_stats_fetch_retry() events. These statistics are already accumulated by u64_stats_inc(). Fix this by reading them into temporary variables first.
--- net/openvswitch/vport.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-)
net/openvswitch/vport.c +6 -5
@@ -310,22 +310,23 @@ void ovs_vport_get_stats(struct vport *vport, struct ovs_vport_stats *stats)*/ int ovs_vport_get_upcall_stats (struct vport *vport,struct sk_buff *skb) { +u64 tx_success =0 , tx_fail =0 ;struct nlattr *nla;int i; -__u64 tx_success =0 ; -__u64 tx_fail =0 ; -for_each_possible_cpu (i) {const struct vport_upcall_stats_percpu *stats; +u64 n_success, n_fail;unsigned int start; stats =per_cpu_ptr (vport->upcall_stats, i);do { start =u64_stats_fetch_begin (&stats->syncp); - tx_success +=u64_stats_read (&stats->n_success); - tx_fail +=u64_stats_read (&stats->n_fail); + n_success =u64_stats_read (&stats->n_success); + n_fail =u64_stats_read (&stats->n_fail); }while (u64_stats_fetch_retry (&stats->syncp, start)); + tx_success += n_success; + tx_fail += n_fail; } nla =nla_nest_start_noflag (skb,OVS_VPORT_ATTR_UPCALL_STATS );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 179/254 vsock/virtio: fix potential underflow in virtio_transport_get_credit()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Melbin K Mathew <[email protected]>
[ Upstream commit 3ef3d52a1a9860d094395c7a3e593f3aa26ff012 ]
The credit calculation in virtio_transport_get_credit() uses unsigned arithmetic:
ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);
If the peer shrinks its advertised buffer (peer_buf_alloc) while bytes are in flight, the subtraction can underflow and produce a large positive value, potentially allowing more data to be queued than the peer can handle.
Reuse virtio_transport_has_space() which already handles this case and add a comment to make it clear why we are doing that.
--- net/vmw_vsock/virtio_transport_common.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
net/vmw_vsock/virtio_transport_common.c +9 -7
@@ -28,6 +28,7 @@static void virtio_transport_cancel_close_work (struct vsock_sock *vsk,bool cancel_timeout); +static s64 virtio_transport_has_space (struct virtio_vsock_sock *vvs);static const struct virtio_transport *virtio_transport_get_ops (struct vsock_sock *vsk)
@@ -316,9 +317,7 @@ u32 virtio_transport_get_credit(struct virtio_vsock_sock *vvs, u32 credit)return 0 ;spin_lock_bh (&vvs->tx_lock); - ret = vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); -if (ret > credit) - ret = credit; + ret =min_t (u32, credit,virtio_transport_has_space (vvs)); vvs->tx_cnt += ret;spin_unlock_bh (&vvs->tx_lock);
@@ -684,11 +683,14 @@ u32 virtio_transport_seqpacket_has_data(struct vsock_sock *vsk) }EXPORT_SYMBOL_GPL (virtio_transport_seqpacket_has_data); -static s64 virtio_transport_has_space (struct vsock_sock *vsk) +static s64 virtio_transport_has_space (struct virtio_vsock_sock *vvs) { -struct virtio_vsock_sock *vvs = vsk->trans;s64 bytes; +/* Use s64 arithmetic so if the peer shrinks peer_buf_alloc while +* we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction +* does not underflow. +*/ bytes = (s64 )vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt);if (bytes <0 ) bytes =0 ;
@@ -702,7 +704,7 @@ s64 virtio_transport_stream_has_space(struct vsock_sock *vsk)s64 bytes;spin_lock_bh (&vvs->tx_lock); - bytes =virtio_transport_has_space (vsk); + bytes =virtio_transport_has_space (vvs);spin_unlock_bh (&vvs->tx_lock);return bytes;
@@ -1301,7 +1303,7 @@ static bool virtio_transport_space_update(struct sock *sk,spin_lock_bh (&vvs->tx_lock); vvs->peer_buf_alloc =le32_to_cpu (hdr->buf_alloc); vvs->peer_fwd_cnt =le32_to_cpu (hdr->fwd_cnt); - space_available =virtio_transport_has_space (vsk); + space_available =virtio_transport_has_space (vvs);spin_unlock_bh (&vvs->tx_lock);return space_available; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 180/254 vsock/test: fix seqpacket message bounds test
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefano Garzarella <[email protected]>
[ Upstream commit 0a98de80136968bab7db37b16282b37f044694d3 ]
The test requires the sender (client) to send all messages before waking up the receiver (server).
Since virtio-vsock had a bug and did not respect the size of the TX buffer, this test worked, but now that we are going to fix the bug, the test hangs because the sender would fill the TX buffer before waking up the receiver.
Set the buffer size in the sender (client) as well, as we already do for the receiver (server).
--- tools/testing/vsock/vsock_test.c | 11 +++++++++++ 1 file changed, 11 insertions(+)
tools/testing/vsock/vsock_test.c +11 -0
@@ -396,6 +396,7 @@ static void test_stream_msg_peek_server(const struct test_opts *opts)static void test_seqpacket_msg_bounds_client (const struct test_opts *opts) { +unsigned long long sock_buf_size;unsigned long curr_hash;size_t max_msg_size;int page_size;
@@ -408,6 +409,16 @@ static void test_seqpacket_msg_bounds_client(const struct test_opts *opts)exit (EXIT_FAILURE ); } + sock_buf_size =SOCK_BUF_SIZE ; + +setsockopt_ull_check (fd,AF_VSOCK ,SO_VM_SOCKETS_BUFFER_MAX_SIZE , + sock_buf_size, +"setsockopt(SO_VM_SOCKETS_BUFFER_MAX_SIZE)" ); + +setsockopt_ull_check (fd,AF_VSOCK ,SO_VM_SOCKETS_BUFFER_SIZE , + sock_buf_size, +"setsockopt(SO_VM_SOCKETS_BUFFER_SIZE)" ); +/* Wait, until receiver sets buffer size. */ control_expectln ("SRVREADY" );
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 181/254 vsock/virtio: cap TX credit to local buffer size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Melbin K Mathew <[email protected]>
[ Upstream commit 8ee784fdf006cbe8739cfa093f54d326cbf54037 ]
The virtio transports derives its TX credit directly from peer_buf_alloc, which is set from the remote endpoint's SO_VM_SOCKETS_BUFFER_SIZE value.
On the host side this means that the amount of data we are willing to queue for a connection is scaled by a guest-chosen buffer size, rather than the host's own vsock configuration. A malicious guest can advertise a large buffer and read slowly, causing the host to allocate a correspondingly large amount of sk_buff memory.
The same thing would happen in the guest with a malicious host, since virtio transports share the same code base.
Introduce a small helper, virtio_transport_tx_buf_size(), that returns min(peer_buf_alloc, buf_alloc), and use it wherever we consume peer_buf_alloc.
This ensures the effective TX window is bounded by both the peer's advertised buffer and our own buf_alloc (already clamped to buffer_max_size via SO_VM_SOCKETS_BUFFER_MAX_SIZE), so a remote peer cannot force the other to queue more data than allowed by its own vsock settings.
On an unpatched Ubuntu 22.04 host (~64 GiB RAM), running a PoC with 32 guest vsock connections advertising 2 GiB each and reading slowly drove Slab/SUnreclaim from ~0.5 GiB to ~57 GiB; the system only recovered after killing the QEMU process. That said, if QEMU memory is limited with cgroups, the maximum memory used will be limited.
With this patch applied:
Before:
MemFree: ~61.6 GiB
Slab: ~142 MiB
SUnreclaim: ~117 MiBAfter 32 high-credit connections:
MemFree: ~61.5 GiB
Slab: ~178 MiB
SUnreclaim: ~152 MiBOnly ~35 MiB increase in Slab/SUnreclaim, no host OOM, and the guest remains responsive.
Compatibility with non-virtio transports:
- VMCI uses the AF_VSOCK buffer knobs to size its queue pairs per socket based on the local vsk->buffer_* values; the remote side cannot enlarge those queues beyond what the local endpoint configured.
- Hyper-V's vsock transport uses fixed-size VMBus ring buffers and an MTU bound; there is no peer-controlled credit field comparable to peer_buf_alloc, and the remote endpoint cannot drive in-flight kernel memory above those ring sizes.
- The loopback path reuses virtio_transport_common.c, so it naturally follows the same semantics as the virtio transport.
This change is limited to virtio_transport_common.c and thus affects virtio-vsock, vhost-vsock, and loopback, bringing them in line with the "remote window intersected with local policy" behaviour that VMCI and Hyper-V already effectively have.
--- net/vmw_vsock/virtio_transport_common.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
net/vmw_vsock/virtio_transport_common.c +12 -2
@@ -628,6 +628,15 @@ virtio_transport_seqpacket_dequeue(struct vsock_sock *vsk, }EXPORT_SYMBOL_GPL (virtio_transport_seqpacket_dequeue); +static u32 virtio_transport_tx_buf_size (struct virtio_vsock_sock *vvs) +{ +/* The peer advertises its receive buffer via peer_buf_alloc, but we +* cap it to our local buf_alloc so a remote peer cannot force us to +* queue more data than our own buffer configuration allows. +*/ +return min (vvs->peer_buf_alloc, vvs->buf_alloc); +} + int virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
@@ -637,7 +646,7 @@ virtio_transport_seqpacket_enqueue(struct vsock_sock *vsk,spin_lock_bh (&vvs->tx_lock); -if (len > vvs->peer_buf_alloc) { +if (len >virtio_transport_tx_buf_size (vvs)) {spin_unlock_bh (&vvs->tx_lock);return -EMSGSIZE ; }
@@ -691,7 +700,8 @@ static s64 virtio_transport_has_space(struct virtio_vsock_sock *vvs)* we have bytes in flight (tx_cnt - peer_fwd_cnt), the subtraction * does not underflow. */ - bytes = (s64 )vvs->peer_buf_alloc - (vvs->tx_cnt - vvs->peer_fwd_cnt); + bytes = (s64 )virtio_transport_tx_buf_size (vvs) - + (vvs->tx_cnt - vvs->peer_fwd_cnt);if (bytes <0 ) bytes =0 ;
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 182/254 net/sched: act_ife: avoid possible NULL deref
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Dumazet <[email protected]>
[ Upstream commit 27880b0b0d35ad1c98863d09788254e36f874968 ]
tcf_ife_encode() must make sure ife_encode() does not return NULL.
syzbot reported:
Oops: general protection fault, probably for non-canonical address 0xdffffc0000000000: 0000 [#1] SMP KASAN NOPTI KASAN: null-ptr-deref in range [0x0000000000000000-0x0000000000000007] RIP: 0010:ife_tlv_meta_encode+0x41/0xa0 net/ife/ife.c:166 CPU: 3 UID: 0 PID: 8990 Comm: syz.0.696 Not tainted syzkaller #0 PREEMPT(full) Call Trace: <TASK> ife_encode_meta_u32+0x153/0x180 net/sched/act_ife.c:101 tcf_ife_encode net/sched/act_ife.c:841 [inline] tcf_ife_act+0x1022/0x1de0 net/sched/act_ife.c:877 tc_act include/net/tc_wrapper.h:130 [inline] tcf_action_exec+0x1c0/0xa20 net/sched/act_api.c:1152 tcf_exts_exec include/net/pkt_cls.h:349 [inline] mall_classify+0x1a0/0x2a0 net/sched/cls_matchall.c:42 tc_classify include/net/tc_wrapper.h:197 [inline] __tcf_classify net/sched/cls_api.c:1764 [inline] tcf_classify+0x7f2/0x1380 net/sched/cls_api.c:1860 multiq_classify net/sched/sch_multiq.c:39 [inline] multiq_enqueue+0xe0/0x510 net/sched/sch_multiq.c:66 dev_qdisc_enqueue+0x45/0x250 net/core/dev.c:4147 __dev_xmit_skb net/core/dev.c:4262 [inline] __dev_queue_xmit+0x2998/0x46c0 net/core/dev.c:4798
--- net/sched/act_ife.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/sched/act_ife.c +4 -2
@@ -821,6 +821,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,/* could be stupid policy setup or mtu config * so lets be conservative.. */ if ((action ==TC_ACT_SHOT ) || exceed_mtu) { +drop:qstats_drop_inc (this_cpu_ptr (ife->common.cpu_qstats));return TC_ACT_SHOT ; }
@@ -829,6 +830,8 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,skb_push (skb, skb->dev->hard_header_len); ife_meta =ife_encode (skb, metalen); +if (!ife_meta) + goto drop;spin_lock (&ife->tcf_lock);
@@ -844,8 +847,7 @@ static int tcf_ife_encode(struct sk_buff *skb, const struct tc_action *a,if (err <0 ) {/* too corrupt to keep around if overwritten */ spin_unlock (&ife->tcf_lock); -qstats_drop_inc (this_cpu_ptr (ife->common.cpu_qstats)); -return TC_ACT_SHOT ; + goto drop; } skboff += err; }
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 183/254 x86: make page fault handling disable interrupts properly
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cedric Xing <[email protected]>
[ Upstream commit 614da1d3d4cdbd6e41aea06bc97ec15aacff6daf ]
There's a big comment in the x86 do_page_fault() about our interrupt disabling code:
* User address page fault handling might have reenabled
* interrupts. Fixing up all potential exit points of
* do_user_addr_fault() and its leaf functions is just not
* doable w/o creating an unholy mess or turning the code
* upside down.
but it turns out that comment is subtly wrong, and the code as a result is also wrong.
Because it's certainly true that we may have re-enabled interrupts when handling user page faults. And it's most certainly true that we don't want to bother fixing up all the cases.
But what isn't true is that it's limited to user address page faults.
The confusion stems from the fact that we have logic here that depends on the address range of the access, but other code then depends on the _context_ the access was done in. The two are not related, even though both of them are about user-vs-kernel.
In other words, both user and kernel addresses can cause interrupts to have been enabled (eg when __bad_area_nosemaphore() gets called for user accesses to kernel addresses). As a result we should make sure to disable interrupts again regardless of the address range before returning to the low-level fault handling code.
The __bad_area_nosemaphore() code actually did disable interrupts again after enabling them, just not consistently. Ironically, as noted in the original comment, fixing up all the cases is just not worth it, when the simple solution is to just do it unconditionally in one single place.
So remove the incomplete case that unsuccessfully tried to do what the comment said was "not doable" in commit ca4c6a9858c2 ("x86/traps: Make interrupt enable/disable symmetric in C code"), and just make it do the simple and straightforward thing.
--- arch/x86/mm/fault.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
arch/x86/mm/fault.c +5 -10
@@ -815,8 +815,6 @@ __bad_area_nosemaphore(struct pt_regs *regs, unsigned long error_code,force_sig_pkuerr ((void __user *)address, pkey); else force_sig_fault(SIGSEGV, si_code, (void __user *)address); - -local_irq_disable (); }static noinline void
@@ -1463,15 +1461,12 @@ handle_page_fault(struct pt_regs *regs, unsigned long error_code,do_kern_addr_fault (regs, error_code, address); }else {do_user_addr_fault (regs, error_code, address); -/* -* User address page fault handling might have reenabled -* interrupts. Fixing up all potential exit points of -* do_user_addr_fault() and its leaf functions is just not -* doable w/o creating an unholy mess or turning the code -* upside down. -*/ -local_irq_disable (); } +/* +* page fault handling might have reenabled interrupts, +* make sure to disable them again. +*/ +local_irq_disable (); }DEFINE_IDTENTRY_RAW_ERRORCODE (exc_page_fault)
Signature · 1 line
2.51.0
Greg Kroah-Hartman
maintainerPATCH 184/254 leds: led-class: Only Add LED to leds_list when it is fully ready
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Hans de Goede <[email protected]>
commit d1883cefd31752f0504b94c3bcfa1f6d511d6e87 upstream.
Before this change the LED was added to leds_list before led_init_core() gets called adding it the list before led_classdev.set_brightness_work gets initialized.
This leaves a window where led_trigger_register() of a LED's default trigger will call led_trigger_set() which calls led_set_brightness() which in turn will end up queueing the *uninitialized* led_classdev.set_brightness_work.
This race gets hit by the lenovo-thinkpad-t14s EC driver which registers 2 LEDs with a default trigger provided by snd_ctl_led.ko in quick succession. The first led_classdev_register() causes an async modprobe of snd_ctl_led to run and that async modprobe manages to exactly hit the window where the second LED is on the leds_list without led_init_core() being called for it, resulting in:
------------[ cut here ]------------ WARNING: CPU: 11 PID: 5608 at kernel/workqueue.c:4234 __flush_work+0x344/0x390 Hardware name: LENOVO 21N2S01F0B/21N2S01F0B, BIOS N42ET93W (2.23 ) 09/01/2025 ... Call trace: __flush_work+0x344/0x390 (P) flush_work+0x2c/0x50 led_trigger_set+0x1c8/0x340 led_trigger_register+0x17c/0x1c0 led_trigger_register_simple+0x84/0xe8 snd_ctl_led_init+0x40/0xf88 [snd_ctl_led] do_one_initcall+0x5c/0x318 do_init_module+0x9c/0x2b8 load_module+0x7e0/0x998
Close the race window by moving the adding of the LED to leds_list to after the led_init_core() call.
--- drivers/leds/led-class.c | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-)
drivers/leds/led-class.c +5 -5
@@ -546,11 +546,6 @@ int led_classdev_register_ext(struct dev#ifdef CONFIG_LEDS_BRIGHTNESS_HW_CHANGED led_cdev->brightness_hw_changed =-1 ;#endif -/* add to the list of leds */ -down_write (&leds_list_lock); -list_add_tail (&led_cdev->node, &leds_list); -up_write (&leds_list_lock); -if (!led_cdev->max_brightness) led_cdev->max_brightness =LED_FULL ;
@@ -558,6 +553,11 @@ int led_classdev_register_ext(struct devled_init_core (led_cdev); +/* add to the list of leds */ +down_write (&leds_list_lock); +list_add_tail (&led_cdev->node, &leds_list); +up_write (&leds_list_lock); +#ifdef CONFIG_LEDS_TRIGGERS led_trigger_set_default (led_cdev);#endif
Greg Kroah-Hartman
maintainerPATCH 185/254 of: fix reference count leak in of_alias_scan()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weigang He <[email protected]>
commit 81122fba08fa3ccafab6ed272a5c6f2203923a7e upstream.
of_find_node_by_path() returns a device_node with its refcount incremented. When kstrtoint() fails or dt_alloc() fails, the function continues to the next iteration without calling of_node_put(), causing a reference count leak.
Add of_node_put(np) before continue on both error paths to properly release the device_node reference.
--- drivers/of/base.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/of/base.c +6 -2
@@ -1788,13 +1788,17 @@ void of_alias_scan(void * (*dt_alloc)(u6 end--; len = end - start; -if (kstrtoint (end,10 , &id) <0 ) +if (kstrtoint (end,10 , &id) <0 ) { +of_node_put (np);continue ; + }/* Allocate an alias_prop with enough space for the stem */ ap = dt_alloc(sizeof(*ap) + len + 1, __alignof__(*ap)); -if (!ap) +if (!ap) { +of_node_put (np);continue ; + }memset (ap,0 ,sizeof (*ap) + len +1 ); ap->alias = start;of_alias_add (ap, np, id, start, len);
Greg Kroah-Hartman
maintainerPATCH 186/254 of: platform: Use default match table for /firmware
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rob Herring (Arm) <[email protected]>
commit 48e6a9c4a20870e09f85ff1a3628275d6bce31c0 upstream.
Calling of_platform_populate() without a match table will only populate the immediate child nodes under /firmware. This is usually fine, but in the case of something like a "simple-mfd" node such as "raspberrypi,bcm2835-firmware", those child nodes will not be populated. And subsequent calls won't work either because the /firmware node is marked as processed already.
Switch the call to of_platform_default_populate() to solve this problem. It should be a nop for existing cases.
--- drivers/of/platform.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/of/platform.c +1 -1
@@ -616,7 +616,7 @@ static int __init of_platform_default_po node =of_find_node_by_path ("/firmware" );if (node) { -of_platform_populate (node,NULL ,NULL ,NULL ); +of_platform_default_populate (node,NULL ,NULL );of_node_put (node); }
Greg Kroah-Hartman
maintainerPATCH 187/254 iio: accel: iis328dq: fix gain values
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Markus Koeniger <[email protected]>
commit b8f15d1df2e73322e2112de21a4a7f3553c7fb60 upstream.
The sensors IIS328DQ and H3LIS331DL share one configuration but H3LIS331DL has different gain parameters, configs therefore need to be split up.
The gain parameters for the IIS328DQ are 0.98, 1.95 and 3.91, depending on the selected measurement range.
See sensor manuals, chapter 2.1 "mechanical characteristics", parameter "Sensitivity".
Datasheet: https://www.st.com/resource/en/datasheet/iis328dq.pdf
Datasheet: https://www.st.com/resource/en/datasheet/h3lis331dl.pdf
--- drivers/iio/accel/st_accel_core.c | 72 +++++++++++++++++++++++++++++++++++++- 1 file changed, 71 insertions(+), 1 deletion(-)
drivers/iio/accel/st_accel_core.c +71 -1
@@ -517,7 +517,6 @@ static const struct st_sensor_settings s .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, .sensors_supported = { [0] = H3LIS331DL_ACCEL_DEV_NAME, - [1] = IIS328DQ_ACCEL_DEV_NAME, }, .ch = (struct iio_chan_spec *)st_accel_12bit_channels, .odr = {
@@ -561,6 +560,77 @@ static const struct st_sensor_settings s }, }, }, + .bdu = { + .addr = 0x23, + .mask = 0x80, + }, + .drdy_irq = { + .int1 = { + .addr = 0x22, + .mask = 0x02, + }, + .int2 = { + .addr = 0x22, + .mask = 0x10, + }, + .addr_ihl = 0x22, + .mask_ihl = 0x80, + }, + .sim = { + .addr = 0x23, + .value = BIT(0), + }, + .multi_read_bit = true, + .bootime = 2, + }, + { + .wai = 0x32, + .wai_addr = ST_SENSORS_DEFAULT_WAI_ADDRESS, + .sensors_supported = { + [0] = IIS328DQ_ACCEL_DEV_NAME, + }, + .ch = (struct iio_chan_spec *)st_accel_12bit_channels, + .odr = { + .addr = 0x20, + .mask = 0x18, + .odr_avl = { + { .hz = 50, .value = 0x00, }, + { .hz = 100, .value = 0x01, }, + { .hz = 400, .value = 0x02, }, + { .hz = 1000, .value = 0x03, }, + }, + }, + .pw = { + .addr = 0x20, + .mask = 0x20, + .value_on = ST_SENSORS_DEFAULT_POWER_ON_VALUE, + .value_off = ST_SENSORS_DEFAULT_POWER_OFF_VALUE, + }, + .enable_axis = { + .addr = ST_SENSORS_DEFAULT_AXIS_ADDR, + .mask = ST_SENSORS_DEFAULT_AXIS_MASK, + }, + .fs = { + .addr = 0x23, + .mask = 0x30, + .fs_avl = { + [0] = { + .num = ST_ACCEL_FS_AVL_100G, + .value = 0x00, + .gain = IIO_G_TO_M_S_2(980), + }, + [1] = { + .num = ST_ACCEL_FS_AVL_200G, + .value = 0x01, + .gain = IIO_G_TO_M_S_2(1950), + }, + [2] = { + .num = ST_ACCEL_FS_AVL_400G, + .value = 0x03, + .gain = IIO_G_TO_M_S_2(3910), + }, + }, + }, .bdu = { .addr = 0x23, .mask = 0x80,
Greg Kroah-Hartman
maintainerPATCH 188/254 iio: adc: ad9467: fix ad9434 vref mask
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tomas Melin <[email protected]>
commit 92452b1760ff2d1d411414965d4d06f75e1bda9a upstream.
The mask setting is 5 bits wide for the ad9434
(ref. data sheet register 0x18 FLEX_VREF). Apparently the settings from ad9265 were copied by mistake when support for the device was added to the driver.
--- drivers/iio/adc/ad9467.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ad9467.c +1 -1
@@ -90,7 +90,7 @@#define CHIPID_AD9434 0x6A#define AD9434_DEF_OUTPUT_MODE 0x00 -#define AD9434_REG_VREF_MASK 0xC0 +#define AD9434_REG_VREF_MASK GENMASK(4, 0)/* * Analog Devices AD9467 16-Bit, 200/250 MSPS ADC
Greg Kroah-Hartman
maintainerPATCH 189/254 iio: adc: at91-sama5d2_adc: Fix potential use-after-free in sama5d2_adc driver
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pei Xiao <[email protected]>
commit dbdb442218cd9d613adeab31a88ac973f22c4873 upstream.
at91_adc_interrupt can call at91_adc_touch_data_handler function to start the work by schedule_work(&st->touch_st.workq).
If we remove the module which will call at91_adc_remove to make cleanup, it will free indio_dev through iio_device_unregister but quite a bit later. While the work mentioned above will be used. The sequence of operations that may lead to a UAF bug is as follows:
CPU0 CPU1
| at91_adc_workq_handler
at91_adc_remove |
iio_device_unregister(indio_dev) |
//free indio_dev a bit later |
| iio_push_to_buffers(indio_dev)
| //use indio_devFix it by ensuring that the work is canceled before proceeding with the cleanup in at91_adc_remove.
--- drivers/iio/adc/at91-sama5d2_adc.c | 1 + 1 file changed, 1 insertion(+)
drivers/iio/adc/at91-sama5d2_adc.c +1 -0
@@ -2504,6 +2504,7 @@ static int at91_adc_remove(struct platfostruct at91_adc_state *st =iio_priv (indio_dev);iio_device_unregister (indio_dev); +cancel_work_sync (&st->touch_st.workq);at91_adc_dma_disable (st);
Greg Kroah-Hartman
maintainerPATCH 190/254 iio: chemical: scd4x: fix reported channel endianness
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fiona Klute <[email protected]>
commit 81d5a5366d3c20203fb9d7345e1aa46d668445a2 upstream.
The driver converts values read from the sensor from BE to CPU endianness in scd4x_read_meas(). The result is then pushed into the buffer in scd4x_trigger_handler(), so on LE architectures parsing the buffer using the reported BE type gave wrong results.
scd4x_read_raw() which provides sysfs *_raw values is not affected, it used the values returned by scd4x_read_meas() without further conversion.
--- drivers/iio/chemical/scd4x.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/iio/chemical/scd4x.c +3 -3
@@ -585,7 +585,7 @@ static const struct iio_chan_spec scd4x_ .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_BE, + .endianness = IIO_CPU, }, }, {
@@ -600,7 +600,7 @@ static const struct iio_chan_spec scd4x_ .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_BE, + .endianness = IIO_CPU, }, }, {
@@ -613,7 +613,7 @@ static const struct iio_chan_spec scd4x_ .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_BE, + .endianness = IIO_CPU, }, }, };
Greg Kroah-Hartman
maintainerPATCH 191/254 iio: dac: ad5686: add AD5695R to ad5686_chip_info_tbl
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kübrich, Andreas <[email protected]>
commit 441ac29923c9172bc5e4b2c4f52ae756192f5715 upstream.
The chip info for this variant (I2C, four channels, 14 bit, internal reference) seems to have been left out due to oversight, so ad5686_chip_info_tbl[ID_AD5695R] is all zeroes. Initialisation of an AD5695R still succeeds, but the resulting IIO device has no channels and no /dev/iio:device* node.
Add the missing chip info to the table.
--- drivers/iio/dac/ad5686.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/iio/dac/ad5686.c +6 -0
@@ -434,6 +434,12 @@ static const struct ad5686_chip_info ad5 .num_channels = 4, .regmap_type = AD5686_REGMAP, }, + [ID_AD5695R] = { + .channels = ad5685r_channels, + .int_vref_mv = 2500, + .num_channels = 4, + .regmap_type = AD5686_REGMAP, + }, [ID_AD5696] = { .channels = ad5686_channels, .num_channels = 4,
Greg Kroah-Hartman
maintainerPATCH 192/254 ALSA: ctxfi: Fix potential OOB access in audio mixer handling
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 61006c540cbdedea83b05577dc7fb7fa18fe1276 upstream.
In the audio mixer handling code of ctxfi driver, the conf field is used as a kind of loop index, and it's referred in the index callbacks (amixer_index() and sum_index()).
As spotted recently by fuzzers, the current code causes OOB access at
those functions.
| UBSAN: array-index-out-of-bounds in /build/reproducible-path/linux-6.17.8/sound/pci/ctxfi/ctamixer.c:347:48 | index 8 is out of range for type 'unsigned char [8]'
After the analysis, the cause was found to be the lack of the proper (re-)initialization of conj field.
This patch addresses those OOB accesses by adding the proper initializations of the loop indices.
--- sound/pci/ctxfi/ctamixer.c | 2 ++ 1 file changed, 2 insertions(+)
sound/pci/ctxfi/ctamixer.c +2 -0
@@ -205,6 +205,7 @@ static int amixer_rsc_init(struct amixer/* Set amixer specific operations */ amixer->rsc.ops = &amixer_basic_rsc_ops; + amixer->rsc.conj =0 ; amixer->ops = &amixer_ops; amixer->input =NULL ; amixer->sum =NULL ;
@@ -369,6 +370,7 @@ static int sum_rsc_init(struct sum *sum,return err; sum->rsc.ops = &sum_basic_rsc_ops; + sum->rsc.conj =0 ;return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 193/254 ALSA: usb-audio: Fix use-after-free in snd_usb_mixer_free()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Berk Cem Goksel <[email protected]>
commit 930e69757b74c3ae083b0c3c7419bfe7f0edc7b2 upstream.
When snd_usb_create_mixer() fails, snd_usb_mixer_free() frees mixer->id_elems but the controls already added to the card still reference the freed memory. Later when snd_card_register() runs, the OSS mixer layer calls their callbacks and hits a use-after-free read.
Call trace: get_ctl_value+0x63f/0x820 sound/usb/mixer.c:411 get_min_max_with_quirks.isra.0+0x240/0x1f40 sound/usb/mixer.c:1241 mixer_ctl_feature_info+0x26b/0x490 sound/usb/mixer.c:1381 snd_mixer_oss_build_test+0x174/0x3a0 sound/core/oss/mixer_oss.c:887 ... snd_card_register+0x4ed/0x6d0 sound/core/init.c:923 usb_audio_probe+0x5ef/0x2a90 sound/usb/card.c:1025
Fix by calling snd_ctl_remove() for all mixer controls before freeing id_elems. We save the next pointer first because snd_ctl_remove() frees the current element.
--- sound/usb/mixer.c | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-)
sound/usb/mixer.c +14 -1
@@ -2938,10 +2938,23 @@ static int parse_audio_unit(struct mixerstatic void snd_usb_mixer_free (struct usb_mixer_interface *mixer) { +struct usb_mixer_elem_list *list, *next; +int id; +/* kill pending URBs */ snd_usb_mixer_disconnect (mixer); -kfree (mixer->id_elems); +/* Unregister controls first, snd_ctl_remove() frees the element */ +if (mixer->id_elems) { +for (id =0 ; id <MAX_ID_ELEMS ; id++) { +for (list = mixer->id_elems[id]; list; list = next) { + next = list->next_id_elem; +if (list->kctl) +snd_ctl_remove (mixer->chip->card, list->kctl); + } + } +kfree (mixer->id_elems); + }if (mixer->urb) {kfree (mixer->urb->transfer_buffer);usb_free_urb (mixer->urb);
Greg Kroah-Hartman
maintainerPATCH 194/254 mmc: rtsx_pci_sdmmc: implement sdmmc_card_busy function
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Schwartz <[email protected]>
commit 122610220134b32c742cc056eaf64f7017ac8cd9 upstream.
rtsx_pci_sdmmc does not have an sdmmc_card_busy function, so any voltage switches cause a kernel warning, "mmc0: cannot verify signal voltage switch."
Copy the sdmmc_card_busy function from rtsx_pci_usb to rtsx_pci_sdmmc to fix this.
--- drivers/mmc/host/rtsx_pci_sdmmc.c | 41 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 41 insertions(+)
drivers/mmc/host/rtsx_pci_sdmmc.c +41 -0
@@ -1307,6 +1307,46 @@ out:return err; } +static int sdmmc_card_busy (struct mmc_host *mmc) +{ +struct realtek_pci_sdmmc *host =mmc_priv (mmc); +struct rtsx_pcr *pcr = host->pcr; +int err; +u8 stat; +u8 mask =SD_DAT3_STATUS |SD_DAT2_STATUS |SD_DAT1_STATUS + |SD_DAT0_STATUS ; + +mutex_lock (&pcr->pcr_mutex); + +rtsx_pci_start_run (pcr); + + err =rtsx_pci_write_register (pcr,SD_BUS_STAT , +SD_CLK_TOGGLE_EN |SD_CLK_FORCE_STOP , +SD_CLK_TOGGLE_EN ); +if (err) + goto out; + +mdelay (1 ); + + err =rtsx_pci_read_register (pcr,SD_BUS_STAT , &stat); +if (err) + goto out; + + err =rtsx_pci_write_register (pcr,SD_BUS_STAT , +SD_CLK_TOGGLE_EN |SD_CLK_FORCE_STOP ,0 ); +out: +mutex_unlock (&pcr->pcr_mutex); + +if (err) +return err; + +/* check if any pin between dat[0:3] is low */ +if ((stat & mask) != mask) +return 1 ; +else +return 0 ; +} +static int sdmmc_execute_tuning (struct mmc_host *mmc,u32 opcode) {struct realtek_pci_sdmmc *host =mmc_priv (mmc);
@@ -1405,6 +1445,7 @@ static const struct mmc_host_ops realtek .get_ro = sdmmc_get_ro, .get_cd = sdmmc_get_cd, .start_signal_voltage_switch = sdmmc_switch_voltage, + .card_busy = sdmmc_card_busy, .execute_tuning = sdmmc_execute_tuning, .init_sd_express = sdmmc_init_sd_express, };
Greg Kroah-Hartman
maintainerPATCH 195/254 mmc: sdhci-of-dwcmshc: Prevent illegal clock reduction in HS200/HS400 mode
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shawn Lin <[email protected]>
commit 3009738a855cf938bbfc9078bec725031ae623a4 upstream.
When operating in HS200 or HS400 timing modes, reducing the clock frequency below 52MHz will lead to link broken as the Rockchip DWC MSHC controller requires maintaining a minimum clock of 52MHz in these modes.
Add a check to prevent illegal clock reduction through debugfs:
root@debian:/# echo 50000000 > /sys/kernel/debug/mmc0/clock root@debian:/# [ 30.090146] mmc0: running CQE recovery mmc0: cqhci: Failed to halt mmc0: cqhci: spurious TCN for tag 0 WARNING: drivers/mmc/host/cqhci-core.c:797 at cqhci_irq+0x254/0x818, CPU#1: kworker/1:0H/24 Modules linked in: CPU: 1 UID: 0 PID: 24 Comm: kworker/1:0H Not tainted 6.19.0-rc1-00001-g09db0998649d-dirty #204 PREEMPT Hardware name: Rockchip RK3588 EVB1 V10 Board (DT) Workqueue: kblockd blk_mq_run_work_fn pstate: 604000c9 (nZCv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) pc : cqhci_irq+0x254/0x818 lr : cqhci_irq+0x254/0x818 ...
--- drivers/mmc/host/sdhci-of-dwcmshc.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/mmc/host/sdhci-of-dwcmshc.c +7 -0
@@ -244,6 +244,13 @@ static void dwcmshc_rk3568_set_clock(strsdhci_writel (host, extra, reg);if (clock <=52000000 ) { +if (host->mmc->ios.timing ==MMC_TIMING_MMC_HS200 || + host->mmc->ios.timing ==MMC_TIMING_MMC_HS400 ) { +dev_err (mmc_dev (host->mmc), +"Can't reduce the clock below 52MHz in HS200/HS400 mode" ); +return ; + } +/* * Disable DLL and reset both of sample and drive clock. * The bypass bit and start bit need to be set if DLL is not locked.
Greg Kroah-Hartman
maintainerPATCH 196/254 wifi: ath10k: fix dma_free_coherent() pointer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
commit 9282a1e171ad8d2205067e8ec3bbe4e3cef4f29f upstream.
dma_alloc_coherent() allocates a DMA mapped buffer and stores the addresses in XXX_unaligned fields. Those should be reused when freeing the buffer rather than the aligned addresses.
--- drivers/net/wireless/ath/ath10k/ce.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-)
drivers/net/wireless/ath/ath10k/ce.c +8 -8
@@ -1725,8 +1725,8 @@ static void _ath10k_ce_free_pipe(struct (ce_state->src_ring->nentries *sizeof (struct ce_desc ) +CE_DESC_RING_ALIGN ), - ce_state->src_ring->base_addr_owner_space, - ce_state->src_ring->base_addr_ce_space); + ce_state->src_ring->base_addr_owner_space_unaligned, + ce_state->src_ring->base_addr_ce_space_unaligned);kfree (ce_state->src_ring); }
@@ -1735,8 +1735,8 @@ static void _ath10k_ce_free_pipe(struct (ce_state->dest_ring->nentries *sizeof (struct ce_desc ) +CE_DESC_RING_ALIGN ), - ce_state->dest_ring->base_addr_owner_space, - ce_state->dest_ring->base_addr_ce_space); + ce_state->dest_ring->base_addr_owner_space_unaligned, + ce_state->dest_ring->base_addr_ce_space_unaligned);kfree (ce_state->dest_ring); }
@@ -1756,8 +1756,8 @@ static void _ath10k_ce_free_pipe_64(stru (ce_state->src_ring->nentries *sizeof (struct ce_desc_64 ) +CE_DESC_RING_ALIGN ), - ce_state->src_ring->base_addr_owner_space, - ce_state->src_ring->base_addr_ce_space); + ce_state->src_ring->base_addr_owner_space_unaligned, + ce_state->src_ring->base_addr_ce_space_unaligned);kfree (ce_state->src_ring); }
@@ -1766,8 +1766,8 @@ static void _ath10k_ce_free_pipe_64(stru (ce_state->dest_ring->nentries *sizeof (struct ce_desc_64 ) +CE_DESC_RING_ALIGN ), - ce_state->dest_ring->base_addr_owner_space, - ce_state->dest_ring->base_addr_ce_space); + ce_state->dest_ring->base_addr_owner_space_unaligned, + ce_state->dest_ring->base_addr_ce_space_unaligned);kfree (ce_state->dest_ring); }
Greg Kroah-Hartman
maintainerPATCH 197/254 wifi: ath12k: fix dma_free_coherent() pointer
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
commit bb97131fbf9b708dd9616ac2bdc793ad102b5c48 upstream.
dma_alloc_coherent() allocates a DMA mapped buffer and stores the addresses in XXX_unaligned fields. Those should be reused when freeing the buffer rather than the aligned addresses.
--- drivers/net/wireless/ath/ath12k/ce.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/net/wireless/ath/ath12k/ce.c +6 -6
@@ -893,8 +893,8 @@ void ath12k_ce_free_pipes(struct ath12k_dma_free_coherent (ab->dev, pipe->src_ring->nentries * desc_sz +CE_DESC_RING_ALIGN , - pipe->src_ring->base_addr_owner_space, - pipe->src_ring->base_addr_ce_space); + pipe->src_ring->base_addr_owner_space_unaligned, + pipe->src_ring->base_addr_ce_space_unaligned);kfree (pipe->src_ring); pipe->src_ring =NULL ; }
@@ -904,8 +904,8 @@ void ath12k_ce_free_pipes(struct ath12k_dma_free_coherent (ab->dev, pipe->dest_ring->nentries * desc_sz +CE_DESC_RING_ALIGN , - pipe->dest_ring->base_addr_owner_space, - pipe->dest_ring->base_addr_ce_space); + pipe->dest_ring->base_addr_owner_space_unaligned, + pipe->dest_ring->base_addr_ce_space_unaligned);kfree (pipe->dest_ring); pipe->dest_ring =NULL ; }
@@ -916,8 +916,8 @@ void ath12k_ce_free_pipes(struct ath12k_dma_free_coherent (ab->dev, pipe->status_ring->nentries * desc_sz +CE_DESC_RING_ALIGN , - pipe->status_ring->base_addr_owner_space, - pipe->status_ring->base_addr_ce_space); + pipe->status_ring->base_addr_owner_space_unaligned, + pipe->status_ring->base_addr_ce_space_unaligned);kfree (pipe->status_ring); pipe->status_ring =NULL ; }
Greg Kroah-Hartman
maintainerPATCH 198/254 wifi: mwifiex: Fix a loop in mwifiex_update_ampdu_rxwinsize()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
commit 2120f3a3738a65730c81bf10447b1ff776078915 upstream.
The "i" iterator variable is used to count two different things but unfortunately we can't store two different numbers in the same variable. Use "i" for the outside loop and "j" for the inside loop.
--- drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/net/wireless/marvell/mwifiex/11n_rxreorder.c +3 -3
@@ -827,7 +827,7 @@ void mwifiex_update_rxreor_flags(structstatic void mwifiex_update_ampdu_rxwinsize (struct mwifiex_adapter *adapter,bool coex_flag) { -u8 i; +u8 i, j;u32 rx_win_size;struct mwifiex_private *priv;
@@ -867,8 +867,8 @@ static void mwifiex_update_ampdu_rxwinsiif (rx_win_size != priv->add_ba_param.rx_win_size) {if (!priv->media_connected)continue ; -for (i =0 ; i <MAX_NUM_TID ; i++) -mwifiex_11n_delba (priv, i); +for (j =0 ; j <MAX_NUM_TID ; j++) +mwifiex_11n_delba (priv, j); } } }
Greg Kroah-Hartman
maintainerPATCH 199/254 wifi: rsi: Fix memory corruption due to not set vif driver data size
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit 4f431d88ea8093afc7ba55edf4652978c5a68f33 upstream.
The struct ieee80211_vif contains trailing space for vif driver data, when struct ieee80211_vif is allocated, the total memory size that is allocated is sizeof(struct ieee80211_vif) + size of vif driver data. The size of vif driver data is set by each WiFi driver as needed.
The RSI911x driver does not set vif driver data size, no trailing space for vif driver data is therefore allocated past struct ieee80211_vif . The RSI911x driver does however use the vif driver data to store its vif driver data structure "struct vif_priv". An access to vif->drv_priv leads to access out of struct ieee80211_vif bounds and corruption of some memory.
In case of the failure observed locally, rsi_mac80211_add_interface() would write struct vif_priv *vif_info = (struct vif_priv *)vif->drv_priv; vif_info->vap_id = vap_idx. This write corrupts struct fq_tin member struct list_head new_flows . The flow = list_first_entry(head, struct fq_flow, flowchain); in fq_tin_reset() then reports non-NULL bogus address, which when accessed causes a crash.
The trigger is very simple, boot the machine with init=/bin/sh , mount devtmpfs, sysfs, procfs, and then do "ip link set wlan0 up", "sleep 1", "ip link set wlan0 down" and the crash occurs.
Fix this by setting the correct size of vif driver data, which is the size of "struct vif_priv", so that memory is allocated and the driver can store its driver data in it, instead of corrupting memory around it.
--- drivers/net/wireless/rsi/rsi_91x_mac80211.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/wireless/rsi/rsi_91x_mac80211.c +1 -0
@@ -2023,6 +2023,7 @@ int rsi_mac80211_attach(struct rsi_commo hw->queues =MAX_HW_QUEUES ; hw->extra_tx_headroom =RSI_NEEDED_HEADROOM ; + hw->vif_data_size =sizeof (struct vif_priv ); hw->max_rates =1 ; hw->max_rate_tries =MAX_RETRIES ;
Greg Kroah-Hartman
maintainerPATCH 200/254 arm64/fpsimd: signal: Allocate SSVE storage when restoring ZA
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mark Rutland <[email protected]>
commit ea8ccfddbce0bee6310da4f3fc560ad520f5e6b4 upstream.
The code to restore a ZA context doesn't attempt to allocate the task's sve_state before setting TIF_SME. Consequently, restoring a ZA context can place a task into an invalid state where TIF_SME is set but the task's sve_state is NULL.
In legitimate but uncommon cases where the ZA signal context was NOT created by the kernel in the context of the same task (e.g. if the task is saved/restored with something like CRIU), we have no guarantee that sve_state had been allocated previously. In these cases, userspace can enter streaming mode without trapping while sve_state is NULL, causing a later NULL pointer dereference when the kernel attempts to store the register state:
| # ./sigreturn-za | Unable to handle kernel NULL pointer dereference at virtual address 0000000000000000 | Mem abort info: | ESR = 0x0000000096000046 | EC = 0x25: DABT (current EL), IL = 32 bits | SET = 0, FnV = 0 | EA = 0, S1PTW = 0 | FSC = 0x06: level 2 translation fault | Data abort info: | ISV = 0, ISS = 0x00000046, ISS2 = 0x00000000 | CM = 0, WnR = 1, TnD = 0, TagAccess = 0 | GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 | user pgtable: 4k pages, 52-bit VAs, pgdp=0000000101f47c00 | [0000000000000000] pgd=08000001021d8403, p4d=0800000102274403, pud=0800000102275403, pmd=0000000000000000 | Internal error: Oops: 0000000096000046 [#1] SMP | Modules linked in: | CPU: 0 UID: 0 PID: 153 Comm: sigreturn-za Not tainted 6.19.0-rc1 #1 PREEMPT | Hardware name: linux,dummy-virt (DT) | pstate: 214000c9 (nzCv daIF +PAN -UAO -TCO +DIT -SSBS BTYPE=--) | pc : sve_save_state+0x4/0xf0 | lr : fpsimd_save_user_state+0xb0/0x1c0 | sp : ffff80008070bcc0 | x29: ffff80008070bcc0 x28: fff00000c1ca4c40 x27: 63cfa172fb5cf658 | x26: fff00000c1ca5228 x25: 0000000000000000 x24: 0000000000000000 | x23: 0000000000000000 x22: fff00000c1ca4c40 x21: fff00000c1ca4c40 | x20: 0000000000000020 x19: fff00000ff6900f0 x18: 0000000000000000 | x17: fff05e8e0311f000 x16: 0000000000000000 x15: 028fca8f3bdaf21c | x14: 0000000000000212 x13: fff00000c0209f10 x12: 0000000000000020 | x11: 0000000000200b20 x10: 0000000000000000 x9 : fff00000ff69dcc0 | x8 : 00000000000003f2 x7 : 0000000000000001 x6 : fff00000c1ca5b48 | x5 : fff05e8e0311f000 x4 : 0000000008000000 x3 : 0000000000000000 | x2 : 0000000000000001 x1 : fff00000c1ca5970 x0 : 0000000000000440 | Call trace: | sve_save_state+0x4/0xf0 (P) | fpsimd_thread_switch+0x48/0x198 | __switch_to+0x20/0x1c0 | __schedule+0x36c/0xce0 | schedule+0x34/0x11c | exit_to_user_mode_loop+0x124/0x188 | el0_interrupt+0xc8/0xd8 | __el0_irq_handler_common+0x18/0x24 | el0t_64_irq_handler+0x10/0x1c | el0t_64_irq+0x198/0x19c | Code: 54000040 d51b4408 d65f03c0 d503245f (e5bb5800) | ---[ end trace 0000000000000000 ]---
Fix this by having restore_za_context() ensure that the task's sve_state is allocated, matching what we do when taking an SME trap. Any live SVE/SSVE state (which is restored earlier from a separate signal context) must be preserved, and hence this is not zeroed.
--- arch/arm64/kernel/signal.c | 4 ++++ 1 file changed, 4 insertions(+)
arch/arm64/kernel/signal.c +4 -0
@@ -475,6 +475,10 @@ static int restore_za_context(struct usefpsimd_flush_task_state (current);/* From now, fpsimd_thread_switch() won't touch thread.sve_state */ +sve_alloc (current, false); +if (!current->thread.sve_state) +return -ENOMEM ; +sme_alloc (current, true);if (!current->thread.sme_state) { current->thread.svcr &= ~SVCR_ZA_MASK ;
Greg Kroah-Hartman
maintainerPATCH 201/254 arm64: Set __nocfi on swsusp_arch_resume()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhaoyang Huang <[email protected]>
commit e2f8216ca2d8e61a23cb6ec355616339667e0ba6 upstream.
A DABT is reported[1] on an android based system when resume from hiberate. This happens because swsusp_arch_suspend_exit() is marked with SYM_CODE_*() and does not have a CFI hash, but swsusp_arch_resume() will attempt to verify the CFI hash when calling a copy of swsusp_arch_suspend_exit().
Given that there's an existing requirement that the entrypoint to swsusp_arch_suspend_exit() is the first byte of the .hibernate_exit.text section, we cannot fix this by marking swsusp_arch_suspend_exit() with SYM_FUNC_*(). The simplest fix for now is to disable the CFI check in swsusp_arch_resume().
Mark swsusp_arch_resume() as __nocfi to disable the CFI check.
[1]
[ 22.991934][ T1] Unable to handle kernel paging request at virtual address 0000000109170ffc [ 22.991934][ T1] Mem abort info: [ 22.991934][ T1] ESR = 0x0000000096000007 [ 22.991934][ T1] EC = 0x25: DABT (current EL), IL = 32 bits [ 22.991934][ T1] SET = 0, FnV = 0 [ 22.991934][ T1] EA = 0, S1PTW = 0 [ 22.991934][ T1] FSC = 0x07: level 3 translation fault [ 22.991934][ T1] Data abort info: [ 22.991934][ T1] ISV = 0, ISS = 0x00000007, ISS2 = 0x00000000 [ 22.991934][ T1] CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [ 22.991934][ T1] GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [ 22.991934][ T1] [0000000109170ffc] user address but active_mm is swapper [ 22.991934][ T1] Internal error: Oops: 0000000096000007 [#1] PREEMPT SMP [ 22.991934][ T1] Dumping ftrace buffer: [ 22.991934][ T1] (ftrace buffer empty) [ 22.991934][ T1] Modules linked in: [ 22.991934][ T1] CPU: 0 PID: 1 Comm: swapper/0 Not tainted 6.6.98-android15-8-g0b1d2aee7fc3-dirty-4k #1 688c7060a825a3ac418fe53881730b355915a419 [ 22.991934][ T1] Hardware name: Unisoc UMS9360-base Board (DT) [ 22.991934][ T1] pstate: 804000c5 (Nzcv daIF +PAN -UAO -TCO -DIT -SSBS BTYPE=--) [ 22.991934][ T1] pc : swsusp_arch_resume+0x2ac/0x344 [ 22.991934][ T1] lr : swsusp_arch_resume+0x294/0x344 [ 22.991934][ T1] sp : ffffffc08006b960 [ 22.991934][ T1] x29: ffffffc08006b9c0 x28: 0000000000000000 x27: 0000000000000000 [ 22.991934][ T1] x26: 0000000000000000 x25: 0000000000000000 x24: 0000000000000820 [ 22.991934][ T1] x23: ffffffd0817e3000 x22: ffffffd0817e3000 x21: 0000000000000000 [ 22.991934][ T1] x20: ffffff8089171000 x19: ffffffd08252c8c8 x18: ffffffc080061058 [ 22.991934][ T1] x17: 00000000529c6ef0 x16: 00000000529c6ef0 x15: 0000000000000004 [ 22.991934][ T1] x14: ffffff8178c88000 x13: 0000000000000006 x12: 0000000000000000 [ 22.991934][ T1] x11: 0000000000000015 x10: 0000000000000001 x9 : ffffffd082533000 [ 22.991934][ T1] x8 : 0000000109171000 x7 : 205b5d3433393139 x6 : 392e32322020205b [ 22.991934][ T1] x5 : 000000010916f000 x4 : 000000008164b000 x3 : ffffff808a4e0530 [ 22.991934][ T1] x2 : ffffffd08058e784 x1 : 0000000082326000 x0 : 000000010a283000 [ 22.991934][ T1] Call trace: [ 22.991934][ T1] swsusp_arch_resume+0x2ac/0x344 [ 22.991934][ T1] hibernation_restore+0x158/0x18c [ 22.991934][ T1] load_image_and_restore+0xb0/0xec [ 22.991934][ T1] software_resume+0xf4/0x19c [ 22.991934][ T1] software_resume_initcall+0x34/0x78 [ 22.991934][ T1] do_one_initcall+0xe8/0x370 [ 22.991934][ T1] do_initcall_level+0xc8/0x19c [ 22.991934][ T1] do_initcalls+0x70/0xc0 [ 22.991934][ T1] do_basic_setup+0x1c/0x28 [ 22.991934][ T1] kernel_init_freeable+0xe0/0x148 [ 22.991934][ T1] kernel_init+0x20/0x1a8 [ 22.991934][ T1] ret_from_fork+0x10/0x20 [ 22.991934][ T1] Code: a9400a61 f94013e0 f9438923 f9400a64 (b85fc110)
--- arch/arm64/kernel/hibernate.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/arm64/kernel/hibernate.c +1 -1
@@ -396,7 +396,7 @@ int swsusp_arch_suspend(void)* Memory allocated by get_safe_page() will be dealt with by the hibernate code, * we don't need to free it here. */ -int swsusp_arch_resume (void ) +int __nocfi swsusp_arch_resume(void) {int rc;void *zero_page;
Greg Kroah-Hartman
maintainerPATCH 202/254 octeontx2: Fix otx2_dma_map_page() error return code
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Fourier <[email protected]>
commit d998b0e5afffa90d0f03770bad31083767079858 upstream.
0 is a valid DMA address [1] so using it as the error value can lead to errors. The error value of dma_map_XXX() functions is DMA_MAPPING_ERROR which is ~0. The callers of otx2_dma_map_page() use dma_mapping_error() to test the return value of otx2_dma_map_page(). This means that they would not detect an error in otx2_dma_map_page().
Make otx2_dma_map_page() return the raw value of dma_map_page_attrs().
[1] https://lore.kernel.org/all/[email protected]
--- drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/net/ethernet/marvell/octeontx2/nic/otx2_common.h +1 -6
@@ -893,13 +893,8 @@ static inline dma_addr_t otx2_dma_map_pa size_t offset, size_t size, enum dma_data_direction dir) { - dma_addr_t iova; - - iova =dma_map_page_attrs (pfvf->dev, page, + return dma_map_page_attrs(pfvf->dev, page,offset ,size ,dir ,DMA_ATTR_SKIP_CPU_SYNC ); -if (unlikely (dma_mapping_error (pfvf->dev, iova))) -return (dma_addr_t )NULL ; -return iova; } static inline void otx2_dma_unmap_page(struct otx2_nic *pfvf,
Greg Kroah-Hartman
maintainerPATCH 203/254 slimbus: core: fix runtime PM imbalance on report present
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 0eb4ff6596114aabba1070a66afa2c2f5593739f upstream.
Make sure to balance the runtime PM usage count in case slimbus device or address allocation fails on report present, which would otherwise prevent the controller from suspending.
--- drivers/slimbus/core.c | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-)
drivers/slimbus/core.c +9 -7
@@ -496,21 +496,23 @@ int slim_device_report_present(struct slif (ctrl->sched.clk_state !=SLIM_CLK_ACTIVE ) {dev_err (ctrl->dev,"slim ctrl not active,state:%d, ret:%d\n" , ctrl->sched.clk_state, ret); - goto slimbus_not_active; + goto out_put_rpm; } sbdev =slim_get_device (ctrl, e_addr); -if (IS_ERR (sbdev)) -return -ENODEV ; +if (IS_ERR (sbdev)) { + ret = -ENODEV ; + goto out_put_rpm; + }if (sbdev->is_laddr_valid) { *laddr = sbdev->laddr; -return 0 ; + ret =0 ; + }else { + ret =slim_device_alloc_laddr (sbdev, true); } - ret =slim_device_alloc_laddr (sbdev, true); - -slimbus_not_active: +out_put_rpm:pm_runtime_mark_last_busy (ctrl->dev);pm_runtime_put_autosuspend (ctrl->dev);return ret;
Greg Kroah-Hartman
maintainerPATCH 204/254 slimbus: core: fix device reference leak on report present
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 9391380eb91ea5ac792aae9273535c8da5b9aa01 upstream.
Slimbus devices can be allocated dynamically upon reception of report-present messages.
Make sure to drop the reference taken when looking up already registered devices.
Note that this requires taking an extra reference in case the device has not yet been registered and has to be allocated.
--- drivers/slimbus/core.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/slimbus/core.c +3 -0
@@ -378,6 +378,8 @@ struct slim_device *slim_get_device(stru sbdev =slim_alloc_device (ctrl, e_addr,NULL );if (!sbdev)return ERR_PTR (-ENOMEM ); + +get_device (&sbdev->dev); }return sbdev;
@@ -512,6 +514,7 @@ int slim_device_report_present(struct sl ret =slim_device_alloc_laddr (sbdev, true); } +put_device (&sbdev->dev); out_put_rpm:pm_runtime_mark_last_busy (ctrl->dev);pm_runtime_put_autosuspend (ctrl->dev);
Greg Kroah-Hartman
maintainerPATCH 205/254 tracing: Fix crash on synthetic stacktrace field usage
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit 90f9f5d64cae4e72defd96a2a22760173cb3c9ec upstream.
When creating a synthetic event based on an existing synthetic event that had a stacktrace field and the new synthetic event used that field a kernel crash occurred:
~# cd /sys/kernel/tracing
~# echo 's:stack unsigned long stack[];' > dynamic_events
~# echo 'hist:keys=prev_pid:s0=common_stacktrace if prev_state & 3' >> events/sched/sched_switch/trigger ~# echo 'hist:keys=next_pid:s1=$s0:onmatch(sched.sched_switch).trace(stack,$s1)' >> events/sched/sched_switch/trigger
The above creates a synthetic event that takes a stacktrace when a task schedules out in a non-running state and passes that stacktrace to the sched_switch event when that task schedules back in. It triggers the "stack" synthetic event that has a stacktrace as its field (called "stack").
~# echo 's:syscall_stack s64 id; unsigned long stack[];' >> dynamic_events
~# echo 'hist:keys=common_pid:s2=stack' >> events/synthetic/stack/trigger
~# echo 'hist:keys=common_pid:s3=$s2,i0=id:onmatch(synthetic.stack).trace(syscall_stack,$i0,$s3)' >> events/raw_syscalls/sys_exit/trigger
The above makes another synthetic event called "syscall_stack" that attaches the first synthetic event (stack) to the sys_exit trace event and records the stacktrace from the stack event with the id of the system call that is exiting.
When enabling this event (or using it in a historgram):
~# echo 1 > events/synthetic/syscall_stack/enable
Produces a kernel crash!
BUG: unable to handle page fault for address: 0000000000400010 #PF: supervisor read access in kernel mode #PF: error_code(0x0000) - not-present page PGD 0 P4D 0 Oops: Oops: 0000 [#1] SMP PTI CPU: 6 UID: 0 PID: 1257 Comm: bash Not tainted 6.16.3+deb14-amd64 #1 PREEMPT(lazy) Debian 6.16.3-1 Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-debian-1.17.0-1 04/01/2014 RIP: 0010:trace_event_raw_event_synth+0x90/0x380 Code: c5 00 00 00 00 85 d2 0f 84 e1 00 00 00 31 db eb 34 0f 1f 00 66 66 2e 0f 1f 84 00 00 00 00 00 66 66 2e 0f 1f 84 00 00 00 00 00 <49> 8b 04 24 48 83 c3 01 8d 0c c5 08 00 00 00 01 cd 41 3b 5d 40 0f RSP: 0018:ffffd2670388f958 EFLAGS: 00010202 RAX: ffff8ba1065cc100 RBX: 0000000000000000 RCX: 0000000000000000 RDX: 0000000000000001 RSI: fffff266ffda7b90 RDI: ffffd2670388f9b0 RBP: 0000000000000010 R08: ffff8ba104e76000 R09: ffffd2670388fa50 R10: ffff8ba102dd42e0 R11: ffffffff9a908970 R12: 0000000000400010 R13: ffff8ba10a246400 R14: ffff8ba10a710220 R15: fffff266ffda7b90 FS: 00007fa3bc63f740(0000) GS:ffff8ba2e0f48000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 0000000000400010 CR3: 0000000107f9e003 CR4: 0000000000172ef0 Call Trace: <TASK> ? __tracing_map_insert+0x208/0x3a0 action_trace+0x67/0x70 event_hist_trigger+0x633/0x6d0 event_triggers_call+0x82/0x130 trace_event_buffer_commit+0x19d/0x250 trace_event_raw_event_sys_exit+0x62/0xb0 syscall_exit_work+0x9d/0x140 do_syscall_64+0x20a/0x2f0 ? trace_event_raw_event_sched_switch+0x12b/0x170 ? save_fpregs_to_fpstate+0x3e/0x90 ? _raw_spin_unlock+0xe/0x30 ? finish_task_switch.isra.0+0x97/0x2c0 ? __rseq_handle_notify_resume+0xad/0x4c0 ? __schedule+0x4b8/0xd00 ? restore_fpregs_from_fpstate+0x3c/0x90 ? switch_fpu_return+0x5b/0xe0 ? do_syscall_64+0x1ef/0x2f0 ? do_fault+0x2e9/0x540 ? __handle_mm_fault+0x7d1/0xf70 ? count_memcg_events+0x167/0x1d0 ? handle_mm_fault+0x1d7/0x2e0 ? do_user_addr_fault+0x2c3/0x7f0 entry_SYSCALL_64_after_hwframe+0x76/0x7e
The reason is that the stacktrace field is not labeled as such, and is treated as a normal field and not as a dynamic event that it is.
In trace_event_raw_event_synth() the event is field is still treated as a dynamic array, but the retrieval of the data is considered a normal field, and the reference is just the meta data:
// Meta data is retrieved instead of a dynamic array
str_val = (char *)(long)var_ref_vals[val_idx];
// Then when it tries to process it:
len = *((unsigned long *)str_val) + 1;
It triggers a kernel page fault.
To fix this, first when defining the fields of the first synthetic event, set the filter type to FILTER_STACKTRACE. This is used later by the second synthetic event to know that this field is a stacktrace. When creating the field of the new synthetic event, have it use this FILTER_STACKTRACE to know to create a stacktrace field to copy the stacktrace into.
--- kernel/trace/trace_events_hist.c | 9 +++++++++ kernel/trace/trace_events_synth.c | 8 +++++++- 2 files changed, 16 insertions(+), 1 deletion(-)
kernel/trace/trace_events_hist.c +9 -0
@@ -2047,6 +2047,15 @@ static struct hist_field *create_hist_fi hist_field->fn_num =HIST_FIELD_FN_RELDYNSTRING ; else hist_field->fn_num = HIST_FIELD_FN_PSTRING; + }else if (field->filter_type ==FILTER_STACKTRACE ) { + flags |=HIST_FIELD_FL_STACKTRACE ; + + hist_field->size =MAX_FILTER_STR_VAL ; + hist_field->type =kstrdup_const (field->type,GFP_KERNEL ); +if (!hist_field->type) + goto free; + + hist_field->fn_num =HIST_FIELD_FN_STACK ; }else { hist_field->size = field->size; hist_field->is_signed = field->is_signed;
kernel/trace/trace_events_synth.c +7 -1
@@ -137,7 +137,9 @@ static int synth_event_define_fields(strstruct synth_event *event = call->data;unsigned int i, size, n_u64;char *name, *type; +int filter_type;bool is_signed; +bool is_stack;int ret =0 ;for (i =0 , n_u64 =0 ; i < event->n_fields; i++) {
@@ -145,8 +147,12 @@ static int synth_event_define_fields(str is_signed = event->fields[i]->is_signed; type = event->fields[i]->type; name = event->fields[i]->name; + is_stack = event->fields[i]->is_stack; + + filter_type = is_stack ?FILTER_STACKTRACE :FILTER_OTHER ; + ret =trace_define_field (call, type, name, offset, size, - is_signed,FILTER_OTHER ); + is_signed, filter_type);if (ret)break ;
Greg Kroah-Hartman
maintainerPATCH 206/254 intel_th: fix device leak on output open()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 95fc36a234da24bbc5f476f8104a5a15f99ed3e3 upstream.
Make sure to drop the reference taken when looking up the th device during output device open() on errors and on close().
Note that a recent commit fixed the leak in a couple of open() error paths but not all of them, and the reference is still leaking on successful open().
--- drivers/hwtracing/intel_th/core.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-)
drivers/hwtracing/intel_th/core.c +16 -3
@@ -810,9 +810,12 @@ static int intel_th_output_open(struct iint err; dev =bus_find_device_by_devt (&intel_th_bus, inode->i_rdev); -if (!dev || !dev->driver) { +if (!dev) +return -ENODEV ; + +if (!dev->driver) { err = -ENODEV ; - goto out_no_device; + goto out_put_device; } thdrv =to_intel_th_driver (dev->driver);
@@ -836,12 +839,22 @@ static int intel_th_output_open(struct i out_put_device:put_device (dev); -out_no_device: +return err; } +static int intel_th_output_release (struct inode *inode,struct file *file) +{ +struct intel_th_device *thdev = file->private_data; + +put_device (&thdev->dev); + +return 0 ; +} +static const struct file_operations intel_th_output_fops = { .open = intel_th_output_open, + .release = intel_th_output_release, .llseek = noop_llseek, };
Greg Kroah-Hartman
maintainerPATCH 207/254 uacce: fix cdev handling in the cleanup path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wenkai Lin <[email protected]>
commit a3bece3678f6c88db1f44c602b2a63e84b4040ac upstream.
When cdev_device_add fails, it internally releases the cdev memory, and if cdev_device_del is then executed, it will cause a hang error. To fix it, we check the return value of cdev_device_add() and clear uacce->cdev to avoid calling cdev_device_del in the uacce_remove.
--- drivers/misc/uacce/uacce.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/misc/uacce/uacce.c +7 -1
@@ -553,6 +553,8 @@ EXPORT_SYMBOL_GPL(uacce_alloc);*/ int uacce_register (struct uacce_device *uacce) { +int ret; +if (!uacce)return -ENODEV ;
@@ -563,7 +565,11 @@ int uacce_register(struct uacce_device * uacce->cdev->ops = &uacce_fops; uacce->cdev->owner =THIS_MODULE ; -return cdev_device_add (uacce->cdev, &uacce->dev); + ret =cdev_device_add (uacce->cdev, &uacce->dev); +if (ret) + uacce->cdev =NULL ; + +return ret; }EXPORT_SYMBOL_GPL (uacce_register);
Greg Kroah-Hartman
maintainerPATCH 208/254 uacce: fix isolate sysfs check condition
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
commit 98eec349259b1fd876f350b1c600403bcef8f85d upstream.
uacce supports the device isolation feature. If the driver implements the isolate_err_threshold_read and isolate_err_threshold_write callback functions, uacce will create sysfs files now. Users can read and configure the isolation policy through sysfs. Currently, sysfs files are created as long as either isolate_err_threshold_read or isolate_err_threshold_write callback functions are present.
However, accessing a non-existent callback function may cause the system to crash. Therefore, intercept the creation of sysfs if neither read nor write exists; create sysfs if either is supported, but intercept unsupported operations at the call site.
--- drivers/misc/uacce/uacce.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/misc/uacce/uacce.c +6 -0
@@ -379,6 +379,9 @@ static ssize_t isolate_strategy_show(strstruct uacce_device *uacce =to_uacce_device (dev);u32 val; +if (!uacce->ops->isolate_err_threshold_read) +return -ENOENT ; + val = uacce->ops->isolate_err_threshold_read (uacce);return sysfs_emit (buf,"%u\n" , val);
@@ -391,6 +394,9 @@ static ssize_t isolate_strategy_store(stunsigned long val;int ret; +if (!uacce->ops->isolate_err_threshold_write) +return -ENOENT ; +if (kstrtoul (buf,0 , &val) <0 )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 209/254 uacce: implement mremap in uacce_vm_ops to return -EPERM
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Shen <[email protected]>
commit 02695347be532b628f22488300d40c4eba48b9b7 upstream.
The current uacce_vm_ops does not support the mremap operation of vm_operations_struct. Implement .mremap to return -EPERM to remind users.
The reason we need to explicitly disable mremap is that when the driver does not implement .mremap, it uses the default mremap method. This could lead to a risk scenario:
An application might first mmap address p1, then mremap to p2, followed by munmap(p1), and finally munmap(p2). Since the default mremap copies the original vma's vm_private_data (i.e., q) to the new vma, both munmap operations would trigger vma_close, causing q->qfr to be freed twice(qfr will be set to null here, so repeated release is ok).
--- drivers/misc/uacce/uacce.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/misc/uacce/uacce.c +6 -0
@@ -211,8 +211,14 @@ static void uacce_vma_close(struct vm_ar } } +static int uacce_vma_mremap (struct vm_area_struct *area) +{ +return -EPERM ; +} +static const struct vm_operations_struct uacce_vm_ops = { .close = uacce_vma_close, + .mremap = uacce_vma_mremap, };static int uacce_fops_mmap (struct file *filep,struct vm_area_struct *vma)
Greg Kroah-Hartman
maintainerPATCH 210/254 uacce: ensure safe queue release with state management
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenghai Huang <[email protected]>
commit 26c08dabe5475d99a13f353d8dd70e518de45663 upstream.
Directly calling put_queue carries risks since it cannot guarantee that resources of uacce_queue have been fully released beforehand. So adding a stop_queue operation for the UACCE_CMD_PUT_Q command and leaving the put_queue operation to the final resource release ensures safety.
Queue states are defined as follows:
- UACCE_Q_ZOMBIE: Initial state
- UACCE_Q_INIT: After opening uacce
- UACCE_Q_STARTED: After start is issued via ioctl
When executing poweroff -f in virt while accelerator are still working, uacce_fops_release and uacce_remove may execute concurrently. This can cause uacce_put_queue within uacce_fops_release to access a NULL ops pointer. Therefore, add state checks to prevent accessing freed pointers.
--- drivers/misc/uacce/uacce.c | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-)
drivers/misc/uacce/uacce.c +21 -7
@@ -37,20 +37,34 @@ static int uacce_start_queue(struct uaccreturn 0 ; } -static int uacce_put_queue (struct uacce_queue *q) +static int uacce_stop_queue (struct uacce_queue *q) {struct uacce_device *uacce = q->uacce; -if ((q->state ==UACCE_Q_STARTED ) && uacce->ops->stop_queue) +if (q->state !=UACCE_Q_STARTED ) +return 0 ; + +if (uacce->ops->stop_queue) uacce->ops->stop_queue (q); -if ((q->state ==UACCE_Q_INIT || q->state ==UACCE_Q_STARTED ) && - uacce->ops->put_queue) + q->state =UACCE_Q_INIT ; + +return 0 ; +} + +static void uacce_put_queue (struct uacce_queue *q) +{ +struct uacce_device *uacce = q->uacce; + +uacce_stop_queue (q); + +if (q->state !=UACCE_Q_INIT ) +return ; + +if (uacce->ops->put_queue) uacce->ops->put_queue (q); q->state =UACCE_Q_ZOMBIE ; - -return 0 ; } static long uacce_fops_unl_ioctl(struct file *filep,
@@ -77,7 +91,7 @@ static long uacce_fops_unl_ioctl(struct ret =uacce_start_queue (q);break ;case UACCE_CMD_PUT_Q : - ret =uacce_put_queue (q); + ret =uacce_stop_queue (q);break ;default :if (uacce->ops->ioctl)
Greg Kroah-Hartman
maintainerPATCH 211/254 netrom: fix double-free in nr_route_frame()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jeongjun Park <[email protected]>
commit ba1096c315283ee3292765f6aea4cca15816c4f7 upstream.
In nr_route_frame(), old_skb is immediately freed without checking if nr_neigh->ax25 pointer is NULL. Therefore, if nr_neigh->ax25 is NULL, the caller function will free old_skb again, causing a double-free bug.
Therefore, to prevent this, we need to modify it to check whether nr_neigh->ax25 is NULL before freeing old_skb.
--- net/netrom/nr_route.c | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-)
net/netrom/nr_route.c +9 -4
@@ -752,7 +752,7 @@ int nr_route_frame(struct sk_buff *skb,unsigned char *dptr;ax25_cb *ax25s;int ret; -struct sk_buff *skbn; +struct sk_buff *nskb, *oskb;/* * Reject malformed packets early. Check that it contains at least 2
@@ -811,14 +811,16 @@ int nr_route_frame(struct sk_buff *skb,/* We are going to change the netrom headers so we should get our own skb, we also did not know until now how much header space we had to reserve... - RXQ */ -if ((skbn=skb_copy_expand (skb, dev->hard_header_len,0 ,GFP_ATOMIC )) ==NULL ) { + nskb =skb_copy_expand (skb, dev->hard_header_len,0 ,GFP_ATOMIC ); + +if (!nskb) {nr_node_unlock (nr_node);nr_node_put (nr_node);dev_put (dev);return 0 ; } -kfree_skb (skb); - skb=skbn; + oskb = skb; + skb = nskb; skb->data[14 ]--; dptr =skb_push (skb,1 );
@@ -837,6 +839,9 @@ int nr_route_frame(struct sk_buff *skb,nr_node_unlock (nr_node);nr_node_put (nr_node); +if (ret) +kfree_skb (oskb); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 212/254 platform/x86: hp-bioscfg: Fix automatic module loading
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
commit 467d4afc6caa64b84a6db1634f8091e931f4a7cb upstream.
hp-bioscfg has a MODULE_DEVICE_TABLE with a GUID in it that looks plausible, but the module doesn't automatically load on applicable systems.
This is because the GUID has some lower case characters and so it doesn't match the modalias during boot. Update the GUIDs to be all uppercase.
--- drivers/platform/x86/hp/hp-bioscfg/bioscfg.h | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/platform/x86/hp/hp-bioscfg/bioscfg.h +3 -3
@@ -57,14 +57,14 @@ enum mechanism_values {#define PASSWD_MECHANISM_TYPES "password" -#define HP_WMI_BIOS_GUID "5FB7F034-2C63-45e9-BE91-3D44E2C707E4" +#define HP_WMI_BIOS_GUID "5FB7F034-2C63-45E9-BE91-3D44E2C707E4" -#define HP_WMI_BIOS_STRING_GUID "988D08E3-68F4-4c35-AF3E-6A1B8106F83C" +#define HP_WMI_BIOS_STRING_GUID "988D08E3-68F4-4C35-AF3E-6A1B8106F83C"#define HP_WMI_BIOS_INTEGER_GUID "8232DE3D-663D-4327-A8F4-E293ADB9BF05"#define HP_WMI_BIOS_ENUMERATION_GUID "2D114B49-2DFB-4130-B8FE-4A3C09E75133"#define HP_WMI_BIOS_ORDERED_LIST_GUID "14EA9746-CE1F-4098-A0E0-7045CB4DA745"#define HP_WMI_BIOS_PASSWORD_GUID "322F2028-0F84-4901-988E-015176049E2D" -#define HP_WMI_SET_BIOS_SETTING_GUID "1F4C91EB-DC5C-460b-951D-C7CB9B4B8D5E" +#define HP_WMI_SET_BIOS_SETTING_GUID "1F4C91EB-DC5C-460B-951D-C7CB9B4B8D5E"enum hp_wmi_spm_commandtype {HPWMI_SECUREPLATFORM_GET_STATE =0x10 ,
Greg Kroah-Hartman
maintainerPATCH 213/254 pmdomain: imx8m-blk-ctrl: Remove separate rst and clk mask for 8mq vpu
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ming Qian <[email protected]>
commit 3de49966499634454fd59e0e6fecd50baab7febd upstream.
For i.MX8MQ platform, the ADB in the VPUMIX domain has no separate reset and clock enable bits, but is ungated and reset together with the VPUs. So we can't reset G1 or G2 separately, it may led to the system hang. Remove rst_mask and clk_mask of imx8mq_vpu_blk_ctl_domain_data. Let imx8mq_vpu_power_notifier() do really vpu reset.
--- drivers/pmdomain/imx/imx8m-blk-ctrl.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-)
drivers/pmdomain/imx/imx8m-blk-ctrl.c +7 -4
@@ -845,22 +845,25 @@ static int imx8mq_vpu_power_notifier(strreturn NOTIFY_OK ; } +/* +* For i.MX8MQ, the ADB in the VPUMIX domain has no separate reset and clock +* enable bits, but is ungated and reset together with the VPUs. +* Resetting G1 or G2 separately may led to system hang. +* Remove the rst_mask and clk_mask from the domain data of G1 and G2, +* Let imx8mq_vpu_power_notifier() do really vpu reset. +*/ static const struct imx8m_blk_ctrl_domain_data imx8mq_vpu_blk_ctl_domain_data[] = { [IMX8MQ_VPUBLK_PD_G1 ] = { .name ="vpublk-g1" , .clk_names = (const char *[]){"g1" , }, .num_clks =1 , .gpc_name ="g1" , - .rst_mask =BIT (1 ), - .clk_mask =BIT (1 ), }, [IMX8MQ_VPUBLK_PD_G2 ] = { .name ="vpublk-g2" , .clk_names = (const char *[]){"g2" , }, .num_clks =1 , .gpc_name ="g2" , - .rst_mask =BIT (0 ), - .clk_mask =BIT (0 ), }, };
Greg Kroah-Hartman
maintainerPATCH 214/254 perf/x86/intel: Do not enable BTS for guests
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fernand Sieber <[email protected]>
commit 91dcfae0ff2b9b9ab03c1ec95babaceefbffb9f4 upstream.
By default when users program perf to sample branch instructions (PERF_COUNT_HW_BRANCH_INSTRUCTIONS) with a sample period of 1, perf interprets this as a special case and enables BTS (Branch Trace Store) as an optimization to avoid taking an interrupt on every branch.
Since BTS doesn't virtualize, this optimization doesn't make sense when the request originates from a guest. Add an additional check that prevents this optimization for virtualized events (exclude_host).
--- arch/x86/events/perf_event.h | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-)
arch/x86/events/perf_event.h +11 -2
@@ -1423,13 +1423,22 @@ static inline bool intel_pmu_has_bts_perstruct hw_perf_event *hwc = &event->hw;unsigned int hw_event, bts_event; -if (event->attr.freq) +/* +* Only use BTS for fixed rate period==1 events. +*/ +if (event->attr.freq || period !=1 ) +return false; + +/* +* BTS doesn't virtualize. +*/ +if (event->attr.exclude_host)return false; hw_event = hwc->config &INTEL_ARCH_EVENT_MASK ; bts_event = x86_pmu.event_map (PERF_COUNT_HW_BRANCH_INSTRUCTIONS ); -return hw_event == bts_event && period ==1 ; +return hw_event == bts_event; }static inline bool intel_pmu_has_bts (struct perf_event *event)
Greg Kroah-Hartman
maintainerPATCH 215/254 irqchip/gic-v3-its: Avoid truncating memory addresses
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Arnd Bergmann <[email protected]>
commit 8d76a7d89c12d08382b66e2f21f20d0627d14859 upstream.
On 32-bit machines with CONFIG_ARM_LPAE, it is possible for lowmem allocations to be backed by addresses physical memory above the 32-bit address limit, as found while experimenting with larger VMSPLIT configurations.
This caused the qemu virt model to crash in the GICv3 driver, which allocates the 'itt' object using GFP_KERNEL. Since all memory below the 4GB physical address limit is in ZONE_DMA in this configuration, kmalloc() defaults to higher addresses for ZONE_NORMAL, and the ITS driver stores the physical address in a 32-bit 'unsigned long' variable.
Change the itt_addr variable to the correct phys_addr_t type instead, along with all other variables in this driver that hold a physical address.
The gicv5 driver correctly uses u64 variables, while all other irqchip drivers don't call virt_to_phys or similar interfaces. It's expected that other device drivers have similar issues, but fixing this one is sufficient for booting a virtio based guest.
--- drivers/irqchip/irq-gic-v3-its.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/irqchip/irq-gic-v3-its.c +4 -4
@@ -616,7 +616,7 @@ static struct its_collection *its_build_struct its_cmd_block *cmd, struct its_cmd_desc *desc) { - unsigned long itt_addr; + phys_addr_t itt_addr;u8 size =ilog2 (desc->its_mapd_cmd.dev->nr_ites); itt_addr =virt_to_phys (desc->its_mapd_cmd.dev->itt);
@@ -787,7 +787,7 @@ static struct its_vpe *its_build_vmapp_c struct its_cmd_desc *desc) {struct its_vpe *vpe =valid_vpe (its, desc->its_vmapp_cmd.vpe); -unsigned long vpt_addr, vconf_addr; +phys_addr_t vpt_addr, vconf_addr;u64 target;bool alloc;
@@ -2404,10 +2404,10 @@ retry_baser: baser->psz = psz; tmp = indirect ?GITS_LVL1_ENTRY_SIZE : esz; -pr_info ("ITS@%pa: allocated %d %s @%lx (%s, esz %d, psz %dK, shr %d)\n" , +pr_info ("ITS@%pa: allocated %d %s @%llx (%s, esz %d, psz %dK, shr %d)\n" , &its->phys_base, (int )(PAGE_ORDER_TO_SIZE (order) / (int )tmp), its_base_type_string[type], - (unsigned long )virt_to_phys (base), + (u64 )virt_to_phys (base), indirect ?"indirect" :"flat" , (int )esz, psz /SZ_1K , (int )shr >>GITS_BASER_SHAREABILITY_SHIFT );
Greg Kroah-Hartman
maintainerPATCH 216/254 can: ems_usb: ems_usb_read_bulk_callback(): fix URB memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 0ce73a0eb5a27070957b67fd74059b6da89cc516 upstream.
Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:gs_usb_receive_bulk_callback(): fix URB memory leak").
In ems_usb_open(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback ems_usb_read_bulk_callback(), the URBs are processed and resubmitted. In ems_usb_close() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted).
However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in ems_usb_close().
Fix the memory leak by anchoring the URB in the ems_usb_read_bulk_callback() to the dev->rx_submitted anchor.
--- drivers/net/can/usb/ems_usb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/can/usb/ems_usb.c +7 -1
@@ -486,11 +486,17 @@ resubmit_urb: urb->transfer_buffer,RX_BUFFER_SIZE , ems_usb_read_bulk_callback, dev); +usb_anchor_urb (urb, &dev->rx_submitted); + retval =usb_submit_urb (urb,GFP_ATOMIC ); +if (!retval) +return ; + +usb_unanchor_urb (urb);if (retval == -ENODEV )netif_device_detach (netdev); -else if (retval) +else netdev_err (netdev,"failed resubmitting read bulk urb: %d\n" , retval); }
Greg Kroah-Hartman
maintainerPATCH 217/254 can: kvaser_usb: kvaser_usb_read_bulk_callback(): fix URB memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 248e8e1a125fa875158df521b30f2cc7e27eeeaa upstream.
Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:gs_usb_receive_bulk_callback(): fix URB memory leak").
In kvaser_usb_set_{,data_}bittiming() -> kvaser_usb_setup_rx_urbs(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback kvaser_usb_read_bulk_callback(), the URBs are processed and resubmitted. In kvaser_usb_remove_interfaces() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted).
However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs().
Fix the memory leak by anchoring the URB in the kvaser_usb_read_bulk_callback() to the dev->rx_submitted anchor.
--- drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/can/usb/kvaser_usb/kvaser_usb_core.c +8 -1
@@ -349,7 +349,14 @@ resubmit_urb: urb->transfer_buffer,KVASER_USB_RX_BUFFER_SIZE , kvaser_usb_read_bulk_callback, dev); +usb_anchor_urb (urb, &dev->rx_submitted); + err =usb_submit_urb (urb,GFP_ATOMIC ); +if (!err) +return ; + +usb_unanchor_urb (urb); +if (err == -ENODEV ) {for (i =0 ; i < dev->nchannels; i++) {if (!dev->nets[i])
@@ -357,7 +364,7 @@ resubmit_urb:netif_device_detach (dev->nets[i]->netdev); } - }else if (err) { + }else {dev_err (&dev->intf->dev,"Failed resubmitting read bulk urb: %d\n" , err); }
Greg Kroah-Hartman
maintainerPATCH 218/254 can: mcba_usb: mcba_usb_read_bulk_callback(): fix URB memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 710a7529fb13c5a470258ff5508ed3c498d54729 upstream.
Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:gs_usb_receive_bulk_callback(): fix URB memory leak").
In mcba_usb_probe() -> mcba_usb_start(), the URBs for USB-in transfers are allocated, added to the priv->rx_submitted anchor and submitted. In the complete callback mcba_usb_read_bulk_callback(), the URBs are processed and resubmitted. In mcba_usb_close() -> mcba_urb_unlink() the URBs are freed by calling usb_kill_anchored_urbs(&priv->rx_submitted).
However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs().
Fix the memory leak by anchoring the URB in the mcba_usb_read_bulk_callback()to the priv->rx_submitted anchor.
--- drivers/net/can/usb/mcba_usb.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/can/usb/mcba_usb.c +7 -1
@@ -608,11 +608,17 @@ resubmit_urb: urb->transfer_buffer,MCBA_USB_RX_BUFF_SIZE , mcba_usb_read_bulk_callback, priv); +usb_anchor_urb (urb, &priv->rx_submitted); + retval =usb_submit_urb (urb,GFP_ATOMIC ); +if (!retval) +return ; + +usb_unanchor_urb (urb);if (retval == -ENODEV )netif_device_detach (netdev); -else if (retval) +else netdev_err (netdev,"failed resubmitting read bulk urb: %d\n" , retval); }
Greg Kroah-Hartman
maintainerPATCH 219/254 can: usb_8dev: usb_8dev_read_bulk_callback(): fix URB memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit f7a980b3b8f80fe367f679da376cf76e800f9480 upstream.
Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:gs_usb_receive_bulk_callback(): fix URB memory leak").
In usb_8dev_open() -> usb_8dev_start(), the URBs for USB-in transfers are allocated, added to the priv->rx_submitted anchor and submitted. In the complete callback usb_8dev_read_bulk_callback(), the URBs are processed and resubmitted. In usb_8dev_close() -> unlink_all_urbs() the URBs are freed by calling usb_kill_anchored_urbs(&priv->rx_submitted).
However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in usb_kill_anchored_urbs().
Fix the memory leak by anchoring the URB in the usb_8dev_read_bulk_callback() to the priv->rx_submitted anchor.
--- drivers/net/can/usb/usb_8dev.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/net/can/usb/usb_8dev.c +7 -1
@@ -541,11 +541,17 @@ resubmit_urb: urb->transfer_buffer,RX_BUFFER_SIZE , usb_8dev_read_bulk_callback, priv); +usb_anchor_urb (urb, &priv->rx_submitted); + retval =usb_submit_urb (urb,GFP_ATOMIC ); +if (!retval) +return ; + +usb_unanchor_urb (urb);if (retval == -ENODEV )netif_device_detach (netdev); -else if (retval) +else netdev_err (netdev,"failed resubmitting read bulk urb: %d\n" , retval); }
Greg Kroah-Hartman
maintainerPATCH 220/254 migrate: correct lock ordering for hugetlb file folios
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matthew Wilcox (Oracle) <[email protected]>
commit b7880cb166ab62c2409046b2347261abf701530e upstream.
Syzbot has found a deadlock (analyzed by Lance Yang):
1) Task (5749): Holds folio_lock, then tries to acquire i_mmap_rwsem(read lock).
2) Task (5754): Holds i_mmap_rwsem(write lock), then tries to acquire folio_lock.
migrate_pages()
-> migrate_hugetlbs()
-> unmap_and_move_huge_page() <- Takes folio_lock!
-> remove_migration_ptes()
-> __rmap_walk_file()
-> i_mmap_lock_read() <- Waits for i_mmap_rwsem(read lock)!hugetlbfs_fallocate()
-> hugetlbfs_punch_hole() <- Takes i_mmap_rwsem(write lock)!
-> hugetlbfs_zero_partial_page()
-> filemap_lock_hugetlb_folio()
-> filemap_lock_folio()
-> __filemap_get_folio <- Waits for folio_lock!The migration path is the one taking locks in the wrong order according to the documentation at the top of mm/rmap.c. So expand the scope of the existing i_mmap_lock to cover the calls to remove_migration_ptes() too.
This is (mostly) how it used to be after commit c0d0381ade79. That was removed by 336bf30eb765 for both file & anon hugetlb pages when it should only have been removed for anon hugetlb pages.
--- mm/migrate.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
mm/migrate.c +6 -6
@@ -1369,6 +1369,7 @@ static int unmap_and_move_huge_page(new_int page_was_mapped =0 ;struct anon_vma *anon_vma =NULL ;struct address_space *mapping =NULL ; +enum ttu_flags ttu =0 ;if (folio_ref_count (src) ==1 ) {/* page was freed from under us. So we are done. */
@@ -1410,8 +1411,6 @@ static int unmap_and_move_huge_page(new_ goto put_anon;if (folio_mapped (src)) { -enum ttu_flags ttu =0 ; -if (!folio_test_anon (src)) {/* * In shared mappings, try_to_unmap could potentially
@@ -1428,9 +1427,6 @@ static int unmap_and_move_huge_page(new_try_to_migrate (src, ttu); page_was_mapped =1 ; - -if (ttu &TTU_RMAP_LOCKED ) -i_mmap_unlock_write (mapping); }if (!folio_mapped (src))
@@ -1438,7 +1434,11 @@ static int unmap_and_move_huge_page(new_if (page_was_mapped)remove_migration_ptes (src, - rc ==MIGRATEPAGE_SUCCESS ? dst : src, false); + rc ==MIGRATEPAGE_SUCCESS ? dst : src, + ttu ? true : false); + +if (ttu &TTU_RMAP_LOCKED ) +i_mmap_unlock_write (mapping); unlock_put_anon:folio_unlock (dst);
Greg Kroah-Hartman
maintainerPATCH 221/254 selftests/bpf: Check for timeout in perf_link test
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ihor Solodrai <[email protected]>
commit e6c209da7e0e9aaf955a7b59e91ed78c2b6c96fb upstream.
Recently perf_link test started unreliably failing on libbpf CI:
* https://github.com/libbpf/libbpf/actions/runs/11260672407/job/31312405473
* https://github.com/libbpf/libbpf/actions/runs/11260992334/job/31315514626
* https://github.com/libbpf/libbpf/actions/runs/11263162459/job/31320458251
Part of the test is running a dummy loop for a while and then checking for a counter incremented by the test program.
Instead of waiting for an arbitrary number of loop iterations once, check for the test counter in a loop and use get_time_ns() helper to enforce a 100ms timeout.
--- tools/testing/selftests/bpf/prog_tests/perf_link.c | 15 +++++++++++++-- 1 file changed, 13 insertions(+), 2 deletions(-)
tools/testing/selftests/bpf/prog_tests/perf_link.c +13 -2
@@ -4,8 +4,12 @@#include <pthread.h> #include <sched.h> #include <test_progs.h> +#include "testing_helpers.h" #include "test_perf_link.skel.h" +#define BURN_TIMEOUT_MS 100 +#define BURN_TIMEOUT_NS BURN_TIMEOUT_MS * 1000000 +static void burn_cpu (void ) {volatile int j =0 ;
@@ -32,6 +36,7 @@ void serial_test_perf_link(void)int run_cnt_before, run_cnt_after;struct bpf_link_info info;__u32 info_len =sizeof (info); +__u64 timeout_time_ns;/* create perf event */ memset (&attr,0 ,sizeof (attr));
@@ -63,8 +68,14 @@ void serial_test_perf_link(void)ASSERT_GT (info.prog_id,0 ,"link_prog_id" );/* ensure we get at least one perf_event prog execution */ -burn_cpu (); -ASSERT_GT (skel->bss->run_cnt,0 ,"run_cnt" ); + timeout_time_ns =get_time_ns () +BURN_TIMEOUT_NS ; +while (true) { +burn_cpu (); +if (skel->bss->run_cnt >0 ) +break ; +if (!ASSERT_LT (get_time_ns (), timeout_time_ns,"run_cnt_timeout" )) +break ; + }/* perf_event is still active, but we close link and BPF program * shouldn't be executed anymore
Greg Kroah-Hartman
maintainerPATCH 222/254 bpf: Do not let BPF test infra emit invalid GSO types to stack
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
commit 04a899573fb87273a656f178b5f920c505f68875 upstream.
Yinhao et al. reported that their fuzzer tool was able to trigger a skb_warn_bad_offload() from netif_skb_features() -> gso_features_check(). When a BPF program - triggered via BPF test infra - pushes the packet to the loopback device via bpf_clone_redirect() then mentioned offload warning can be seen. GSO-related features are then rightfully disabled.
We get into this situation due to convert___skb_to_skb() setting gso_segs and gso_size but not gso_type. Technically, it makes sense that this warning triggers since the GSO properties are malformed due to the gso_type. Potentially, the gso_type could be marked non-trustworthy through setting it at least to SKB_GSO_DODGY without any other specific assumptions, but that also feels wrong given we should not go further into the GSO engine in the first place.
The checks were added in 121d57af308d ("gso: validate gso_type in GSO handlers") because there were malicious (syzbot) senders that combine a protocol with a non-matching gso_type. If we would want to drop such packets, gso_features_check() currently only returns feature flags via netif_skb_features(), so one location for potentially dropping such skbs could be validate_xmit_unreadable_skb(), but then otoh it would be an additional check in the fast-path for a very corner case. Given bpf_clone_redirect() is the only place where BPF test infra could emit such packets, lets reject them right there.
--- net/bpf/test_run.c | 5 +++++ net/core/filter.c | 7 +++++++ 2 files changed, 12 insertions(+)
net/bpf/test_run.c +5 -0
@@ -914,6 +914,11 @@ static int convert___skb_to_skb(struct sif (__skb->gso_segs >GSO_MAX_SEGS )return -EINVAL ; + +/* Currently GSO type is zero/unset. If this gets extended with +* a small list of accepted GSO types in future, the filter for +* an unset GSO type in bpf_clone_redirect() can be lifted. +*/ skb_shinfo (skb)->gso_segs = __skb->gso_segs;skb_shinfo (skb)->gso_size = __skb->gso_size;skb_shinfo (skb)->hwtstamps.hwtstamp = __skb->hwtstamp;
net/core/filter.c +7 -0
@@ -2451,6 +2451,13 @@ BPF_CALL_3(bpf_clone_redirect, struct skif (unlikely (flags & (~(BPF_F_INGRESS ) |BPF_F_REDIRECT_INTERNAL )))return -EINVAL ; +/* BPF test infra's convert___skb_to_skb() can create type-less +* GSO packets. gso_features_check() will detect this as a bad +* offload. However, lets not leak them out in the first place. +*/ +if (unlikely (skb_is_gso (skb) && !skb_shinfo (skb)->gso_type)) +return -EBADMSG ; + dev =dev_get_by_index_rcu (dev_net (skb->dev), ifindex);if (unlikely (!dev))return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 223/254 bridge: mcast: Fix use-after-free during router port configuration
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
commit 7544f3f5b0b58c396f374d060898b5939da31709 upstream.
The bridge maintains a global list of ports behind which a multicast router resides. The list is consulted during forwarding to ensure multicast packets are forwarded to these ports even if the ports are not member in the matching MDB entry.
When per-VLAN multicast snooping is enabled, the per-port multicast context is disabled on each port and the port is removed from the global router port list:
# ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 # ip link add name dummy1 up master br1 type dummy # ip link set dev dummy1 type bridge_slave mcast_router 2 $ bridge -d mdb show | grep router router ports on br1: dummy1 # ip link set dev br1 type bridge mcast_vlan_snooping 1 $ bridge -d mdb show | grep router
However, the port can be re-added to the global list even when per-VLAN multicast snooping is enabled:
# ip link set dev dummy1 type bridge_slave mcast_router 0 # ip link set dev dummy1 type bridge_slave mcast_router 2 $ bridge -d mdb show | grep router router ports on br1: dummy1
Since commit 4b30ae9adb04 ("net: bridge: mcast: re-implement br_multicast_{enable, disable}_port functions"), when per-VLAN multicast snooping is enabled, multicast disablement on a port will disable the per-{port, VLAN} multicast contexts and not the per-port one. As a result, a port will remain in the global router port list even after it is deleted. This will lead to a use-after-free [1] when the list is traversed (when adding a new port to the list, for example):
# ip link del dev dummy1 # ip link add name dummy2 up master br1 type dummy # ip link set dev dummy2 type bridge_slave mcast_router 2
Similarly, stale entries can also be found in the per-VLAN router port list. When per-VLAN multicast snooping is disabled, the per-{port, VLAN} contexts are disabled on each port and the port is removed from the per-VLAN router port list:
# ip link add name br1 up type bridge vlan_filtering 1 mcast_snooping 1 mcast_vlan_snooping 1
# ip link add name dummy1 up master br1 type dummy
# bridge vlan add vid 2 dev dummy1
# bridge vlan global set vid 2 dev br1 mcast_snooping 1
# bridge vlan set vid 2 dev dummy1 mcast_router 2
$ bridge vlan global show dev br1 vid 2 | grep router
router ports: dummy1
# ip link set dev br1 type bridge mcast_vlan_snooping 0
$ bridge vlan global show dev br1 vid 2 | grep routerHowever, the port can be re-added to the per-VLAN list even when per-VLAN multicast snooping is disabled:
# bridge vlan set vid 2 dev dummy1 mcast_router 0
# bridge vlan set vid 2 dev dummy1 mcast_router 2
$ bridge vlan global show dev br1 vid 2 | grep router
router ports: dummy1When the VLAN is deleted from the port, the per-{port, VLAN} multicast context will not be disabled since multicast snooping is not enabled on the VLAN. As a result, the port will remain in the per-VLAN router port list even after it is no longer member in the VLAN. This will lead to a use-after-free [2] when the list is traversed (when adding a new port to the list, for example):
# ip link add name dummy2 up master br1 type dummy # bridge vlan add vid 2 dev dummy2 # bridge vlan del vid 2 dev dummy1 # bridge vlan set vid 2 dev dummy2 mcast_router 2
Fix these issues by removing the port from the relevant (global or per-VLAN) router port list in br_multicast_port_ctx_deinit(). The function is invoked during port deletion with the per-port multicast context and during VLAN deletion with the per-{port, VLAN} multicast context.
Note that deleting the multicast router timer is not enough as it only takes care of the temporary multicast router states (1 or 3) and not the permanent one (2).
[1]
BUG: KASAN: slab-out-of-bounds in br_multicast_add_router.part.0+0x3f1/0x560 Write of size 8 at addr ffff888004a67328 by task ip/384 [...] Call Trace: <TASK> dump_stack_lvl+0x6f/0xa0 print_address_description.constprop.0+0x6f/0x350 print_report+0x108/0x205 kasan_report+0xdf/0x110 br_multicast_add_router.part.0+0x3f1/0x560 br_multicast_set_port_router+0x74e/0xac0 br_setport+0xa55/0x1870 br_port_slave_changelink+0x95/0x120 __rtnl_newlink+0x5e8/0xa40 rtnl_newlink+0x627/0xb00 rtnetlink_rcv_msg+0x6fb/0xb70 netlink_rcv_skb+0x11f/0x350 netlink_unicast+0x426/0x710 netlink_sendmsg+0x75a/0xc20 __sock_sendmsg+0xc1/0x150 ____sys_sendmsg+0x5aa/0x7b0 ___sys_sendmsg+0xfc/0x180 __sys_sendmsg+0x124/0x1c0 do_syscall_64+0xbb/0x360 entry_SYSCALL_64_after_hwframe+0x4b/0x53
[2]
BUG: KASAN: slab-use-after-free in br_multicast_add_router.part.0+0x378/0x560 Read of size 8 at addr ffff888009f00840 by task bridge/391 [...] Call Trace: <TASK> dump_stack_lvl+0x6f/0xa0 print_address_description.constprop.0+0x6f/0x350 print_report+0x108/0x205 kasan_report+0xdf/0x110 br_multicast_add_router.part.0+0x378/0x560 br_multicast_set_port_router+0x6f9/0xac0 br_vlan_process_options+0x8b6/0x1430 br_vlan_rtm_process_one+0x605/0xa30 br_vlan_rtm_process+0x396/0x4c0 rtnetlink_rcv_msg+0x2f7/0xb70 netlink_rcv_skb+0x11f/0x350 netlink_unicast+0x426/0x710 netlink_sendmsg+0x75a/0xc20 __sock_sendmsg+0xc1/0x150 ____sys_sendmsg+0x5aa/0x7b0 ___sys_sendmsg+0xfc/0x180 __sys_sendmsg+0x124/0x1c0 do_syscall_64+0xbb/0x360 entry_SYSCALL_64_after_hwframe+0x4b/0x53
--- net/bridge/br_multicast.c | 9 +++++++++ 1 file changed, 9 insertions(+)
net/bridge/br_multicast.c +9 -0
@@ -2013,10 +2013,19 @@ void br_multicast_port_ctx_init(struct nvoid br_multicast_port_ctx_deinit (struct net_bridge_mcast_port *pmctx) { +struct net_bridge *br = pmctx->port->br; +bool del = false; +#if IS_ENABLED (CONFIG_IPV6 )del_timer_sync (&pmctx->ip6_mc_router_timer);#endif del_timer_sync (&pmctx->ip4_mc_router_timer); + +spin_lock_bh (&br->multicast_lock); + del |=br_ip6_multicast_rport_del (pmctx); + del |=br_ip4_multicast_rport_del (pmctx); +br_multicast_rport_del_notify (pmctx, del); +spin_unlock_bh (&br->multicast_lock); }int br_multicast_add_port (struct net_bridge_port *port)
Greg Kroah-Hartman
maintainerPATCH 224/254 can: esd_usb: esd_usb_read_bulk_callback(): fix URB memory leak
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marc Kleine-Budde <[email protected]>
commit 5a4391bdc6c8357242f62f22069c865b792406b3 upstream.
Fix similar memory leak as in commit 7352e1d5932a ("can: gs_usb:gs_usb_receive_bulk_callback(): fix URB memory leak").
In esd_usb_open(), the URBs for USB-in transfers are allocated, added to the dev->rx_submitted anchor and submitted. In the complete callback esd_usb_read_bulk_callback(), the URBs are processed and resubmitted. In esd_usb_close() the URBs are freed by calling usb_kill_anchored_urbs(&dev->rx_submitted).
However, this does not take into account that the USB framework unanchors the URB before the complete function is called. This means that once an in-URB has been completed, it is no longer anchored and is ultimately not released in esd_usb_close().
Fix the memory leak by anchoring the URB in the esd_usb_read_bulk_callback() to the dev->rx_submitted anchor.
--- drivers/net/can/usb/esd_usb.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/can/usb/esd_usb.c +8 -1
@@ -539,13 +539,20 @@ resubmit_urb: urb->transfer_buffer,ESD_USB_RX_BUFFER_SIZE , esd_usb_read_bulk_callback, dev); +usb_anchor_urb (urb, &dev->rx_submitted); + retval =usb_submit_urb (urb,GFP_ATOMIC ); +if (!retval) +return ; + +usb_unanchor_urb (urb); +if (retval == -ENODEV ) {for (i =0 ; i < dev->net_count; i++) {if (dev->nets[i])netif_device_detach (dev->nets[i]->netdev); } - }else if (retval) { + }else {dev_err (dev->udev->dev.parent,"failed resubmitting read bulk urb: %d\n" , retval); }
Greg Kroah-Hartman
maintainerPATCH 225/254 mm/damon/sysfs-scheme: cleanup access_pattern subdirs on scheme dir setup failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit 392b3d9d595f34877dd745b470c711e8ebcd225c upstream.
When a DAMOS-scheme DAMON sysfs directory setup fails after setup of access_pattern/ directory, subdirectories of access_pattern/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked.
Cleanup the directories under such failures.
--- mm/damon/sysfs-schemes.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
mm/damon/sysfs-schemes.c +4 -2
@@ -1282,9 +1282,10 @@ static int damon_sysfs_scheme_add_dirs(s err =damon_sysfs_scheme_set_access_pattern (scheme);if (err)return err; + err =damon_sysfs_scheme_set_quotas (scheme);if (err) - goto put_access_pattern_out; + goto rmdir_put_access_pattern_out; err =damon_sysfs_scheme_set_watermarks (scheme);if (err) goto put_quotas_access_pattern_out;
@@ -1311,7 +1312,8 @@ put_watermarks_quotas_access_pattern_out put_quotas_access_pattern_out:kobject_put (&scheme->quotas->kobj); scheme->quotas =NULL ; -put_access_pattern_out: +rmdir_put_access_pattern_out: +damon_sysfs_access_pattern_rm_dirs (scheme->access_pattern);kobject_put (&scheme->access_pattern->kobj); scheme->access_pattern =NULL ;return err;
Greg Kroah-Hartman
maintainerPATCH 226/254 mm/damon/sysfs-scheme: cleanup quotas subdirs on scheme dir setup failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: SeongJae Park <[email protected]>
commit dc7e1d75fd8c505096d0cddeca9e2efb2b55aaf9 upstream.
When a DAMOS-scheme DAMON sysfs directory setup fails after setup of quotas/ directory, subdirectories of quotas/ directory are not cleaned up. As a result, DAMON sysfs interface is nearly broken until the system reboots, and the memory for the unremoved directory is leaked.
Cleanup the directories under such failures.
--- mm/damon/sysfs-schemes.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
mm/damon/sysfs-schemes.c +3 -2
@@ -1288,7 +1288,7 @@ static int damon_sysfs_scheme_add_dirs(s goto rmdir_put_access_pattern_out; err =damon_sysfs_scheme_set_watermarks (scheme);if (err) - goto put_quotas_access_pattern_out; + goto rmdir_put_quotas_access_pattern_out; err =damon_sysfs_scheme_set_filters (scheme);if (err) goto put_watermarks_quotas_access_pattern_out;
@@ -1309,7 +1309,8 @@ put_filters_watermarks_quotas_access_pat put_watermarks_quotas_access_pattern_out:kobject_put (&scheme->watermarks->kobj); scheme->watermarks =NULL ; -put_quotas_access_pattern_out: +rmdir_put_quotas_access_pattern_out: +damon_sysfs_quotas_rm_dirs (scheme->quotas);kobject_put (&scheme->quotas->kobj); scheme->quotas =NULL ; rmdir_put_access_pattern_out:
Greg Kroah-Hartman
maintainerPATCH 227/254 iio: core: add missing mutex_destroy in iio_dev_release()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit f5d203467a31798191365efeb16cd619d2c8f23a ]
Add missing mutex_destroy() call in iio_dev_release() to properly clean up the mutex initialized in iio_device_alloc(). Ensure proper resource cleanup and follows kernel practices.
Found by code review.
While at it, create a lockdep key before mutex initialisation. This will help with converting it to the better API in the future.
Stable-dep-of: 9910159f0659 ("iio: core: add separate lockdep class for info_exist_lock")
--- drivers/iio/industrialio-core.c | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
drivers/iio/industrialio-core.c +7 -2
@@ -1618,6 +1618,9 @@ static void iio_dev_release(struct deviciio_device_detach_buffers (indio_dev); +mutex_destroy (&iio_dev_opaque->info_exist_lock); +mutex_destroy (&iio_dev_opaque->mlock); +lockdep_unregister_key (&iio_dev_opaque->mlock_key);ida_free (&iio_ida, iio_dev_opaque->id);
@@ -1663,8 +1666,7 @@ struct iio_dev *iio_device_alloc(struct indio_dev->dev.type = &iio_device_type; indio_dev->dev.bus = &iio_bus_type;device_initialize (&indio_dev->dev); -mutex_init (&iio_dev_opaque->mlock); -mutex_init (&iio_dev_opaque->info_exist_lock); +INIT_LIST_HEAD (&iio_dev_opaque->channel_attr_list); iio_dev_opaque->id =ida_alloc (&iio_ida,GFP_KERNEL );
@@ -1687,6 +1689,9 @@ struct iio_dev *iio_device_alloc(structlockdep_register_key (&iio_dev_opaque->mlock_key);lockdep_set_class (&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); +mutex_init (&iio_dev_opaque->mlock); +mutex_init (&iio_dev_opaque->info_exist_lock); +return indio_dev; }EXPORT_SYMBOL (iio_device_alloc);
Greg Kroah-Hartman
maintainerPATCH 228/254 iio: core: add separate lockdep class for info_exist_lock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Rasmus Villemoes <[email protected]>
[ Upstream commit 9910159f06590c17df4fbddedaabb4c0201cc4cb ]
When one iio device is a consumer of another, it is possible that the ->info_exist_lock of both ends up being taken when reading the value of the consumer device.
Since they currently belong to the same lockdep class (being initialized in a single location with mutex_init()), that results in a lockdep warning
CPU0
----
lock(&iio_dev_opaque->info_exist_lock);
lock(&iio_dev_opaque->info_exist_lock);*** DEADLOCK ***
May be due to missing lock nesting notation
4 locks held by sensors/414:
#0: c31fd6dc (&p->lock){+.+.}-{3:3}, at: seq_read_iter+0x44/0x4e4
#1: c4f5a1c4 (&of->mutex){+.+.}-{3:3}, at: kernfs_seq_start+0x1c/0xac
#2: c2827548 (kn->active#34){.+.+}-{0:0}, at: kernfs_seq_start+0x30/0xac
#3: c1dd2b68 (&iio_dev_opaque->info_exist_lock){+.+.}-{3:3}, at: iio_read_channel_processed_scale+0x24/0xd8
stack backtrace: CPU: 0 UID: 0 PID: 414 Comm: sensors Not tainted 6.17.11 #5 NONE Hardware name: Generic AM33XX (Flattened Device Tree) Call trace: unwind_backtrace from show_stack+0x10/0x14 show_stack from dump_stack_lvl+0x44/0x60 dump_stack_lvl from print_deadlock_bug+0x2b8/0x334 print_deadlock_bug from __lock_acquire+0x13a4/0x2ab0 __lock_acquire from lock_acquire+0xd0/0x2c0 lock_acquire from __mutex_lock+0xa0/0xe8c __mutex_lock from mutex_lock_nested+0x1c/0x24 mutex_lock_nested from iio_read_channel_raw+0x20/0x6c iio_read_channel_raw from rescale_read_raw+0x128/0x1c4 rescale_read_raw from iio_channel_read+0xe4/0xf4 iio_channel_read from iio_read_channel_processed_scale+0x6c/0xd8 iio_read_channel_processed_scale from iio_hwmon_read_val+0x68/0xbc iio_hwmon_read_val from dev_attr_show+0x18/0x48 dev_attr_show from sysfs_kf_seq_show+0x80/0x110 sysfs_kf_seq_show from seq_read_iter+0xdc/0x4e4 seq_read_iter from vfs_read+0x238/0x2e4 vfs_read from ksys_read+0x6c/0xec ksys_read from ret_fast_syscall+0x0/0x1c
Just as the mlock_key already has its own lockdep class, add a lock_class_key for the info_exist mutex.
Note that this has in theory been a problem since before IIO first left staging, but it only occurs when a chain of consumers is in use and that is not often done.
--- drivers/iio/industrialio-core.c | 3 ++- include/linux/iio/iio-opaque.h | 2 ++ 2 files changed, 4 insertions(+), 1 deletion(-)
drivers/iio/industrialio-core.c +2 -1
@@ -1621,6 +1621,7 @@ static void iio_dev_release(struct devicmutex_destroy (&iio_dev_opaque->info_exist_lock);mutex_destroy (&iio_dev_opaque->mlock); +lockdep_unregister_key (&iio_dev_opaque->info_exist_key);lockdep_unregister_key (&iio_dev_opaque->mlock_key);ida_free (&iio_ida, iio_dev_opaque->id);
@@ -1687,7 +1688,7 @@ struct iio_dev *iio_device_alloc(structINIT_LIST_HEAD (&iio_dev_opaque->ioctl_handlers);lockdep_register_key (&iio_dev_opaque->mlock_key); -lockdep_set_class (&iio_dev_opaque->mlock, &iio_dev_opaque->mlock_key); +lockdep_register_key (&iio_dev_opaque->info_exist_key);mutex_init (&iio_dev_opaque->mlock);mutex_init (&iio_dev_opaque->info_exist_lock);
include/linux/iio/iio-opaque.h +2 -0
@@ -14,6 +14,7 @@* @mlock: lock used to prevent simultaneous device state changes * @mlock_key: lockdep class for iio_dev lock * @info_exist_lock: lock to prevent use during removal +* @info_exist_key: lockdep class for info_exist lock * @trig_readonly: mark the current trigger immutable * @event_interface: event chrdevs associated with interrupt lines * @attached_buffers: array of buffers statically attached by the driver
@@ -47,6 +48,7 @@ struct iio_dev_opaque {struct mutex mlock;struct lock_class_key mlock_key;struct mutex info_exist_lock; +struct lock_class_key info_exist_key;bool trig_readonly;struct iio_event_interface *event_interface;struct iio_buffer **attached_buffers;
Greg Kroah-Hartman
maintainerPATCH 229/254 mm/rmap: fix two comments related to huge_pmd_unshare()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "David Hildenbrand (Red Hat)" <[email protected]>
[ Upstream commit a8682d500f691b6dfaa16ae1502d990aeb86e8be ]
PMD page table unsharing no longer touches the refcount of a PMD page table. Also, it is not about dropping the refcount of a "PMD page" but the "PMD page table".
Let's just simplify by saying that the PMD page table was unmapped, consequently also unmapping the folio that was mapped into this page.
This code should be deduplicated in the future.
--- mm/rmap.c | 20 ++++---------------- 1 file changed, 4 insertions(+), 16 deletions(-)
mm/rmap.c +4 -16
@@ -1579,14 +1579,8 @@ static bool try_to_unmap_one(struct foliflush_tlb_range (vma, range.start, range.end);/* -* The ref count of the PMD page was -* dropped which is part of the way map -* counting is done for shared PMDs. -* Return 'true' here. When there is -* no other sharing, huge_pmd_unshare -* returns false and we will unmap the -* actual page and drop map count -* to zero. +* The PMD table was unmapped, +* consequently unmapping the folio. */ page_vma_mapped_walk_done (&pvmw);break ;
@@ -1945,14 +1939,8 @@ static bool try_to_migrate_one(struct fo range.start, range.end);/* -* The ref count of the PMD page was -* dropped which is part of the way map -* counting is done for shared PMDs. -* Return 'true' here. When there is -* no other sharing, huge_pmd_unshare -* returns false and we will unmap the -* actual page and drop map count -* to zero. +* The PMD table was unmapped, +* consequently unmapping the folio. */ page_vma_mapped_walk_done (&pvmw);break ;
Greg Kroah-Hartman
maintainerPATCH 230/254 arm64: dts: rockchip: remove redundant max-link-speed from nanopi-r4s
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Geraldo Nascimento <[email protected]>
[ Upstream commit ce652c98a7bfa0b7c675ef5cd85c44c186db96af ]
This is already the default in rk3399-base.dtsi, remove redundant declaration from rk3399-nanopi-r4s.dtsi.
--- arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts | 1 - 1 file changed, 1 deletion(-)
arch/arm64/boot/dts/rockchip/rk3399-nanopi-r4s.dts +0 -1
@@ -73,7 +73,6 @@ }; &pcie0 { - max-link-speed = <1>; num-lanes = <1>; vpcie3v3-supply = <&vcc3v3_sys>; };
Greg Kroah-Hartman
maintainerPATCH 231/254 ALSA: scarlett2: Fix buffer overflow in config retrieval
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Samasth Norway Ananda <[email protected]>
[ Upstream commit 6f5c69f72e50d51be3a8c028ae7eda42c82902cb ]
The scarlett2_usb_get_config() function has a logic error in the endianness conversion code that can cause buffer overflows when count > 1.
The code checks if (size == 2) where size is the total buffer size in bytes, then loops count times treating each element as u16 (2 bytes). This causes the loop to access count * 2 bytes when the buffer only has size bytes allocated.
Fix by checking the element size (config_item->size) instead of the total buffer size. This ensures the endianness conversion matches the actual element type.
--- sound/usb/mixer_scarlett2.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
sound/usb/mixer_scarlett2.c +6 -1
@@ -1408,11 +1408,16 @@ static int scarlett2_usb_get_config( err =scarlett2_usb_get (mixer, config_item->offset, buf, size);if (err <0 )return err; -if (size ==2 ) { +if (config_item->size ==16 ) {u16 *buf_16 = buf;for (i =0 ; i < count; i++, buf_16++) *buf_16 =le16_to_cpu (*(__le16 *)buf_16); + }else if (config_item->size ==32 ) { +u32 *buf_32 = (u32 *)buf; + +for (i =0 ; i < count; i++, buf_32++) + *buf_32 =le32_to_cpu (*(__le32 *)buf_32); }return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 232/254 iio: adc: exynos_adc: fix OF populate on driver rebind
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit ea6b4feba85e996e840e0b661bc42793df6eb701 ]
Since commit c6e126de43e7 ("of: Keep track of populated platform devices") child devices will not be created by of_platform_populate() if the devices had previously been deregistered individually so that the OF_POPULATED flag is still set in the corresponding OF nodes.
Switch to using of_platform_depopulate() instead of open coding so that the child devices are created if the driver is rebound.
--- drivers/iio/adc/exynos_adc.c | 13 ++----------- 1 file changed, 2 insertions(+), 11 deletions(-)
drivers/iio/adc/exynos_adc.c +2 -11
@@ -721,14 +721,7 @@ static const struct iio_chan_spec exynos ADC_CHANNEL(9, "adc9"), }; -static int exynos_adc_remove_devices (struct device *dev,void *c) -{ -struct platform_device *pdev =to_platform_device (dev); - -platform_device_unregister (pdev); -return 0 ; -}static int exynos_adc_ts_open (struct input_dev *dev) {
@@ -929,8 +922,7 @@ static int exynos_adc_probe(struct platfreturn 0 ; err_of_populate: -device_for_each_child (&indio_dev->dev,NULL , - exynos_adc_remove_devices); +of_platform_depopulate (&indio_dev->dev);if (has_ts) {input_unregister_device (info->input);free_irq (info->tsirq, info);
@@ -959,8 +951,7 @@ static int exynos_adc_remove(struct platfree_irq (info->tsirq, info);input_unregister_device (info->input); } -device_for_each_child (&indio_dev->dev,NULL , - exynos_adc_remove_devices); +of_platform_depopulate (&indio_dev->dev);iio_device_unregister (indio_dev);free_irq (info->irq, info);if (info->data->exit_hw)
Greg Kroah-Hartman
maintainerPATCH 233/254 dmaengine: stm32: dmamux: fix device leak on route allocation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit dd6e4943889fb354efa3f700e42739da9bddb6ef ]
Make sure to drop the reference taken when looking up the DMA mux platform device during route allocation.
Note that holding a reference to a device does not prevent its driver data from going away so there is no point in keeping the reference.
--- drivers/dma/stm32-dmamux.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/dma/stm32-dmamux.c +12 -6
@@ -90,23 +90,25 @@ static void *stm32_dmamux_route_allocatestruct stm32_dmamux_data *dmamux =platform_get_drvdata (pdev);struct stm32_dmamux *mux;u32 i, min, max; -int ret; +int ret = -EINVAL ;unsigned long flags;if (dma_spec->args_count !=3 ) {dev_err (&pdev->dev,"invalid number of dma mux args\n" ); -return ERR_PTR (-EINVAL ); + goto err_put_pdev; }if (dma_spec->args[0 ] > dmamux->dmamux_requests) {dev_err (&pdev->dev,"invalid mux request number: %d\n" , dma_spec->args[0 ]); -return ERR_PTR (-EINVAL ); + goto err_put_pdev; } mux =kzalloc (sizeof (*mux),GFP_KERNEL ); -if (!mux) -return ERR_PTR (-ENOMEM ); +if (!mux) { + ret = -ENOMEM ; + goto err_put_pdev; + }spin_lock_irqsave (&dmamux->lock, flags); mux->chan_id = find_first_zero_bit(dmamux->dma_inuse,
@@ -133,7 +135,6 @@ static void *stm32_dmamux_route_allocate dma_spec->np =of_parse_phandle (ofdma->of_node,"dma-masters" , i -1 );if (!dma_spec->np) {dev_err (&pdev->dev,"can't get dma master\n" ); - ret = -EINVAL ; goto error; }
@@ -160,6 +161,8 @@ static void *stm32_dmamux_route_allocatedev_dbg (&pdev->dev,"Mapping DMAMUX(%u) to DMA%u(%u)\n" , mux->request, mux->master, mux->chan_id); +put_device (&pdev->dev); +return mux; error:
@@ -167,6 +170,9 @@ error: error_chan_id:kfree (mux); +err_put_pdev: +put_device (&pdev->dev); +return ERR_PTR (ret); }
Greg Kroah-Hartman
maintainerPATCH 234/254 dmaengine: stm32: dmamux: fix OF node leak on route allocation failure
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit b1b590a590af13ded598e70f0b72bc1e515787a1 ]
Make sure to drop the reference taken to the DMA master OF node also on late route allocation failures.
--- drivers/dma/stm32-dmamux.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/dma/stm32-dmamux.c +3 -1
@@ -143,7 +143,7 @@ static void *stm32_dmamux_route_allocate ret =pm_runtime_resume_and_get (&pdev->dev);if (ret <0 ) {spin_unlock_irqrestore (&dmamux->lock, flags); - goto error; + goto err_put_dma_spec_np; }spin_unlock_irqrestore (&dmamux->lock, flags);
@@ -165,6 +165,8 @@ static void *stm32_dmamux_route_allocatereturn mux; +err_put_dma_spec_np: +of_node_put (dma_spec->np); error:clear_bit (mux->chan_id, dmamux->dma_inuse);
Greg Kroah-Hartman
maintainerPATCH 235/254 mm/page_alloc: prevent pcp corruption with SMP=n
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vlastimil Babka <[email protected]>
[ Upstream commit 038a102535eb49e10e93eafac54352fcc5d78847 ]
The kernel test robot has reported:
BUG: spinlock trylock failure on UP on CPU#0, kcompactd0/28 lock: 0xffff888807e35ef0, .magic: dead4ead, .owner: kcompactd0/28, .owner_cpu: 0 CPU: 0 UID: 0 PID: 28 Comm: kcompactd0 Not tainted 6.18.0-rc5-00127-ga06157804399 #1 PREEMPT 8cc09ef94dcec767faa911515ce9e609c45db470 Call Trace: <IRQ> __dump_stack (lib/dump_stack.c:95) dump_stack_lvl (lib/dump_stack.c:123) dump_stack (lib/dump_stack.c:130) spin_dump (kernel/locking/spinlock_debug.c:71) do_raw_spin_trylock (kernel/locking/spinlock_debug.c:?) _raw_spin_trylock (include/linux/spinlock_api_smp.h:89 kernel/locking/spinlock.c:138) __free_frozen_pages (mm/page_alloc.c:2973) ___free_pages (mm/page_alloc.c:5295) __free_pages (mm/page_alloc.c:5334) tlb_remove_table_rcu (include/linux/mm.h:? include/linux/mm.h:3122 include/asm-generic/tlb.h:220 mm/mmu_gather.c:227 mm/mmu_gather.c:290) ? __cfi_tlb_remove_table_rcu (mm/mmu_gather.c:289) ? rcu_core (kernel/rcu/tree.c:?) rcu_core (include/linux/rcupdate.h:341 kernel/rcu/tree.c:2607 kernel/rcu/tree.c:2861) rcu_core_si (kernel/rcu/tree.c:2879) handle_softirqs (arch/x86/include/asm/jump_label.h:36 include/trace/events/irq.h:142 kernel/softirq.c:623) __irq_exit_rcu (arch/x86/include/asm/jump_label.h:36 kernel/softirq.c:725) irq_exit_rcu (kernel/softirq.c:741) sysvec_apic_timer_interrupt (arch/x86/kernel/apic/apic.c:1052) </IRQ> <TASK> RIP: 0010:_raw_spin_unlock_irqrestore (arch/x86/include/asm/preempt.h:95 include/linux/spinlock_api_smp.h:152 kernel/locking/spinlock.c:194) free_pcppages_bulk (mm/page_alloc.c:1494) drain_pages_zone (include/linux/spinlock.h:391 mm/page_alloc.c:2632) __drain_all_pages (mm/page_alloc.c:2731) drain_all_pages (mm/page_alloc.c:2747) kcompactd (mm/compaction.c:3115) kthread (kernel/kthread.c:465) ? __cfi_kcompactd (mm/compaction.c:3166) ? __cfi_kthread (kernel/kthread.c:412) ret_from_fork (arch/x86/kernel/process.c:164) ? __cfi_kthread (kernel/kthread.c:412) ret_from_fork_asm (arch/x86/entry/entry_64.S:255) </TASK>
Matthew has analyzed the report and identified that in drain_page_zone() we are in a section protected by spin_lock(&pcp->lock) and then get an interrupt that attempts spin_trylock() on the same lock. The code is designed to work this way without disabling IRQs and occasionally fail the trylock with a fallback. However, the SMP=n spinlock implementation assumes spin_trylock() will always succeed, and thus it's normally a no-op. Here the enabled lock debugging catches the problem, but otherwise it could cause a corruption of the pcp structure.
The problem has been introduced by commit 574907741599 ("mm/page_alloc:
leave IRQs enabled for per-cpu page allocations"). The pcp locking scheme recognizes the need for disabling IRQs to prevent nesting spin_trylock() sections on SMP=n, but the need to prevent the nesting in spin_lock() has not been recognized. Fix it by introducing local wrappers that change the spin_lock() to spin_lock_iqsave() with SMP=n and use them in all places that do spin_lock(&pcp->lock).
--- mm/page_alloc.c | 37 +++++++++++++++++++++++++++++++++---- 1 file changed, 33 insertions(+), 4 deletions(-)
mm/page_alloc.c +33 -4
@@ -160,6 +160,33 @@ static DEFINE_MUTEX(pcp_batch_high_lock)#define pcp_spin_unlock (ptr) \ pcpu_spin_unlock(lock, ptr) +/* +* With the UP spinlock implementation, when we spin_lock(&pcp->lock) (for i.e. +* a potentially remote cpu drain) and get interrupted by an operation that +* attempts pcp_spin_trylock(), we can't rely on the trylock failure due to UP +* spinlock assumptions making the trylock a no-op. So we have to turn that +* spin_lock() to a spin_lock_irqsave(). This works because on UP there are no +* remote cpu's so we can only be locking the only existing local one. +*/ +#if defined(CONFIG_SMP ) || defined(CONFIG_PREEMPT_RT ) +static inline void __flags_noop (unsigned long *flags) { } +#define pcp_spin_lock_maybe_irqsave (ptr, flags) \ +({ \ + __flags_noop(&(flags)); \ + spin_lock(&(ptr)->lock); \ +}) +#define pcp_spin_unlock_maybe_irqrestore (ptr, flags) \ +({ \ + spin_unlock(&(ptr)->lock); \ + __flags_noop(&(flags)); \ +}) +#else +#define pcp_spin_lock_maybe_irqsave (ptr, flags) \ + spin_lock_irqsave(&(ptr)->lock, flags) +#define pcp_spin_unlock_maybe_irqrestore (ptr, flags) \ + spin_unlock_irqrestore(&(ptr)->lock, flags) +#endif +#ifdef CONFIG_USE_PERCPU_NUMA_NODE_ID DEFINE_PER_CPU (int, numa_node);EXPORT_PER_CPU_SYMBOL (numa_node);
@@ -2181,14 +2208,15 @@ static int rmqueue_bulk(struct zone *zon*/ void drain_zone_pages (struct zone *zone,struct per_cpu_pages *pcp) { +unsigned long UP_flags;int to_drain, batch; batch =READ_ONCE (pcp->batch); to_drain =min (pcp->count, batch);if (to_drain >0 ) { -spin_lock (&pcp->lock); +pcp_spin_lock_maybe_irqsave (pcp, UP_flags);free_pcppages_bulk (zone, to_drain, pcp,0 ); -spin_unlock (&pcp->lock); +pcp_spin_unlock_maybe_irqrestore (pcp, UP_flags); } }#endif
@@ -2199,10 +2227,11 @@ void drain_zone_pages(struct zone *zone,static void drain_pages_zone (unsigned int cpu,struct zone *zone) {struct per_cpu_pages *pcp =per_cpu_ptr (zone->per_cpu_pageset, cpu); +unsigned long UP_flags;int count; do { - spin_lock(&pcp->lock); + pcp_spin_lock_maybe_irqsave(pcp, UP_flags); count = pcp->count; if (count) { int to_drain = min(count,
@@ -2211,7 +2240,7 @@ static void drain_pages_zone(unsigned infree_pcppages_bulk (zone, to_drain, pcp,0 ); count -= to_drain; } -spin_unlock (&pcp->lock); +pcp_spin_unlock_maybe_irqrestore (pcp, UP_flags); }while (count); }
Greg Kroah-Hartman
maintainerPATCH 236/254 mm: kmsan: fix poisoning of high-order non-compound pages
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ryan Roberts <[email protected]>
[ Upstream commit 4795d205d78690a46b60164f44b8bb7b3e800865 ]
kmsan_free_page() is called by the page allocator's free_pages_prepare() during page freeing. Its job is to poison all the memory covered by the page. It can be called with an order-0 page, a compound high-order page or a non-compound high-order page. But page_size() only works for order-0 and compound pages. For a non-compound high-order page it will incorrectly return PAGE_SIZE.
The implication is that the tail pages of a high-order non-compound page do not get poisoned at free, so any invalid access while they are free could go unnoticed. It looks like the pages will be poisoned again at allocation time, so that would bookend the window.
Fix this by using the order parameter to calculate the size.
--- mm/kmsan/shadow.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
mm/kmsan/shadow.c +1 -1
@@ -210,7 +210,7 @@ void kmsan_free_page(struct page *page,return ;kmsan_enter_runtime ();kmsan_internal_poison_memory (page_address (page), -page_size (page), +PAGE_SIZE << order,GFP_KERNEL ,KMSAN_POISON_CHECK |KMSAN_POISON_FREE );kmsan_leave_runtime ();
Greg Kroah-Hartman
maintainerPATCH 237/254 phy: phy-rockchip-inno-usb2: Use dev_err_probe() in the probe path
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dragan Simic <[email protected]>
[ Upstream commit 40452520850683f6771094ca218ff206d1fcb022 ]
Improve error handling in the probe path by using function dev_err_probe() instead of function dev_err(), where appropriate.
Stable-dep-of: e07dea3de508 ("phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()")
--- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 27 +++++++++----------------- 1 file changed, 10 insertions(+), 17 deletions(-)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c +10 -17
@@ -420,11 +420,9 @@ static int rockchip_usb2phy_extcon_regisif (of_property_read_bool (node,"extcon" )) { edev =extcon_get_edev_by_phandle (rphy->dev,0 ); -if (IS_ERR (edev)) { -if (PTR_ERR (edev) != -EPROBE_DEFER ) -dev_err (rphy->dev,"Invalid or missing extcon\n" ); -return PTR_ERR (edev); - } +if (IS_ERR (edev)) +return dev_err_probe (rphy->dev,PTR_ERR (edev), +"invalid or missing extcon\n" ); }else {/* Initialize extcon device */ edev = devm_extcon_dev_allocate(rphy->dev,
@@ -434,10 +432,9 @@ static int rockchip_usb2phy_extcon_regisreturn -ENOMEM ; ret =devm_extcon_dev_register (rphy->dev, edev); -if (ret) { -dev_err (rphy->dev,"failed to register extcon device\n" ); -return ret; - } +if (ret) +return dev_err_probe (rphy->dev, ret, +"failed to register extcon device\n" ); } rphy->edev = edev;
@@ -1396,10 +1393,8 @@ static int rockchip_usb2phy_probe(struct } ret =rockchip_usb2phy_clk480m_register (rphy); -if (ret) { -dev_err (dev,"failed to register 480m output clock\n" ); -return ret; - } +if (ret) +return dev_err_probe (dev, ret,"failed to register 480m output clock\n" );if (rphy->phy_cfg->phy_tuning) { ret = rphy->phy_cfg->phy_tuning (rphy);
@@ -1419,8 +1414,7 @@ static int rockchip_usb2phy_probe(struct phy =devm_phy_create (dev, child_np, &rockchip_usb2phy_ops);if (IS_ERR (phy)) { -dev_err_probe (dev,PTR_ERR (phy),"failed to create phy\n" ); - ret =PTR_ERR (phy); + ret =dev_err_probe (dev,PTR_ERR (phy),"failed to create phy\n" ); goto put_child; }
@@ -1457,8 +1451,7 @@ next_child:"rockchip_usb2phy" , rphy);if (ret) { -dev_err (rphy->dev, -"failed to request usb2phy irq handle\n" ); +dev_err_probe (rphy->dev, ret,"failed to request usb2phy irq handle\n" ); goto put_child; } }
Greg Kroah-Hartman
maintainerPATCH 238/254 phy: rockchip: inno-usb2: Fix a double free bug in rockchip_usb2phy_probe()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wentao Liang <[email protected]>
[ Upstream commit e07dea3de508cd6950c937cec42de7603190e1ca ]
The for_each_available_child_of_node() calls of_node_put() to release child_np in each success loop. After breaking from the loop with the child_np has been released, the code will jump to the put_child label and will call the of_node_put() again if the devm_request_threaded_irq() fails. These cause a double free bug.
Fix by returning directly to avoid the duplicate of_node_put().
--- drivers/phy/rockchip/phy-rockchip-inno-usb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/phy/rockchip/phy-rockchip-inno-usb2.c +1 -1
@@ -1452,7 +1452,7 @@ next_child: rphy);if (ret) {dev_err_probe (rphy->dev, ret,"failed to request usb2phy irq handle\n" ); - goto put_child; +return ret; } }
Greg Kroah-Hartman
maintainerPATCH 239/254 ASoC: codecs: wsa881x: Drop unused version readout
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Krzysztof Kozlowski <[email protected]>
[ Upstream commit 3d2a69eb503d15171a7ba51cf0b562728ac396b7 ]
Driver does not use the device version after reading it from the registers, so simplify by dropping unneeded code.
Stable-dep-of: 29d71b8a5a40 ("ASoC: codecs: wsa881x: fix unnecessary initialisation")
--- sound/soc/codecs/wsa881x.c | 2 -- 1 file changed, 2 deletions(-)
sound/soc/codecs/wsa881x.c +0 -2
@@ -680,7 +680,6 @@ struct wsa881x_priv {* For backwards compatibility. */ unsigned int sd_n_val; -int version;int active_ports;bool port_prepared[WSA881X_MAX_SWR_PORTS ];bool port_enable[WSA881X_MAX_SWR_PORTS ];
@@ -691,7 +690,6 @@ static void wsa881x_init(struct wsa881x_struct regmap *rm = wsa881x->regmap;unsigned int val =0 ; -regmap_read (rm,WSA881X_CHIP_ID1 , &wsa881x->version);regmap_register_patch (wsa881x->regmap, wsa881x_rev_2_0,ARRAY_SIZE (wsa881x_rev_2_0));
Greg Kroah-Hartman
maintainerPATCH 240/254 ASoC: codecs: wsa881x: fix unnecessary initialisation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 29d71b8a5a40708b3eed9ba4953bfc2312c9c776 ]
The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED.
--- sound/soc/codecs/wsa881x.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/soc/codecs/wsa881x.c +9 -0
@@ -681,6 +681,7 @@ struct wsa881x_priv {*/ unsigned int sd_n_val;int active_ports; +bool hw_init;bool port_prepared[WSA881X_MAX_SWR_PORTS ];bool port_enable[WSA881X_MAX_SWR_PORTS ]; };
@@ -690,6 +691,9 @@ static void wsa881x_init(struct wsa881x_struct regmap *rm = wsa881x->regmap;unsigned int val =0 ; +if (wsa881x->hw_init) +return ; +regmap_register_patch (wsa881x->regmap, wsa881x_rev_2_0,ARRAY_SIZE (wsa881x_rev_2_0));
@@ -727,6 +731,8 @@ static void wsa881x_init(struct wsa881x_regmap_update_bits (rm,WSA881X_OTP_REG_28 ,0x3F ,0x3A );regmap_update_bits (rm,WSA881X_BONGO_RESRV_REG1 ,0xFF ,0xB2 );regmap_update_bits (rm,WSA881X_BONGO_RESRV_REG2 ,0xFF ,0x05 ); + + wsa881x->hw_init = true; }static int wsa881x_component_probe (struct snd_soc_component *comp)
@@ -1071,6 +1077,9 @@ static int wsa881x_update_status(struct {struct wsa881x_priv *wsa881x =dev_get_drvdata (&slave->dev); +if (status ==SDW_SLAVE_UNATTACHED ) + wsa881x->hw_init = false; +if (status ==SDW_SLAVE_ATTACHED && slave->dev_num >0 )wsa881x_init (wsa881x);
Greg Kroah-Hartman
maintainerPATCH 241/254 ASoC: codecs: wsa883x: fix unnecessary initialisation
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
[ Upstream commit 49aadf830eb048134d33ad7329d92ecff45d8dbb ]
The soundwire update_status() callback may be called multiple times with the same ATTACHED status but initialisation should only be done when transitioning from UNATTACHED to ATTACHED.
This avoids repeated initialisation of the codecs during boot of machines like the Lenovo ThinkPad X13s:
[ 11.614523] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.618022] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.621377] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.624065] wsa883x-codec sdw:1:0:0217:0202:00:1: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.631382] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2 [ 11.634424] wsa883x-codec sdw:1:0:0217:0202:00:2: WSA883X Version 1_1, Variant: WSA8835_V2
--- sound/soc/codecs/wsa883x.c | 9 +++++++++ 1 file changed, 9 insertions(+)
sound/soc/codecs/wsa883x.c +9 -0
@@ -444,6 +444,7 @@ struct wsa883x_priv {int active_ports;int dev_mode;int comp_offset; +bool hw_init; };enum {
@@ -1003,6 +1004,9 @@ static int wsa883x_init(struct wsa883x_pstruct regmap *regmap = wsa883x->regmap;int variant, version, ret; +if (wsa883x->hw_init) +return 0 ; + ret =regmap_read (regmap,WSA883X_OTP_REG_0 , &variant);if (ret)return ret;
@@ -1046,6 +1050,8 @@ static int wsa883x_init(struct wsa883x_p wsa883x->comp_offset); } + wsa883x->hw_init = true; +return 0 ; }
@@ -1054,6 +1060,9 @@ static int wsa883x_update_status(struct {struct wsa883x_priv *wsa883x =dev_get_drvdata (&slave->dev); +if (status ==SDW_SLAVE_UNATTACHED ) + wsa883x->hw_init = false; +if (status ==SDW_SLAVE_ATTACHED && slave->dev_num >0 )return wsa883x_init (wsa883x);
Greg Kroah-Hartman
maintainerPATCH 242/254 nvme-fc: rename free_ctrl callback to match name pattern
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Wagner <[email protected]>
[ Upstream commit 205fb5fa6fde1b5b426015eb1ff69f2ff25ef5bb ]
Rename nvme_fc_nvme_ctrl_freed to nvme_fc_free_ctrl to match the name pattern for the callback.
Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition")
--- drivers/nvme/host/fc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/nvme/host/fc.c +2 -2
@@ -2384,7 +2384,7 @@ nvme_fc_ctrl_get(struct nvme_fc_ctrl *ct* controller. Called after last nvme_put_ctrl() call */ static void -nvme_fc_nvme_ctrl_freed (struct nvme_ctrl *nctrl) +nvme_fc_free_ctrl (struct nvme_ctrl *nctrl) {struct nvme_fc_ctrl *ctrl =to_fc_ctrl (nctrl);
@@ -3349,7 +3349,7 @@ static const struct nvme_ctrl_ops nvme_f .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, - .free_ctrl = nvme_fc_nvme_ctrl_freed, + .free_ctrl = nvme_fc_free_ctrl, .submit_async_event = nvme_fc_submit_async_event, .delete_ctrl = nvme_fc_delete_ctrl, .get_address = nvmf_get_address,
Greg Kroah-Hartman
maintainerPATCH 243/254 nvme-pci: do not directly handle subsys reset fallout
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Keith Busch <[email protected]>
[ Upstream commit 210b1f6576e8b367907e7ff51ef425062e1468e4 ]
Scheduling reset_work after a nvme subsystem reset is expected to fail on pcie, but this also prevents potential handling the platform's pcie services may provide that might successfully recovering the link without re-enumeration. Such examples include AER, DPC, and power's EEH.
Provide a pci specific operation that safely initiates a subsystem reset, and instead of scheduling reset work, read back the status register to trigger a pcie read error.
Since this only affects pci, the other fabrics drivers subscribe to a generic nvmf subsystem reset that is exactly the same as before. The loop fabric doesn't use it because nvmet doesn't support setting that property anyway.
And since we're using the magic NSSR value in two places now, provide a symbolic define for it.
Stable-dep-of: 0edb475ac0a7 ("nvme: fix PCIe subsystem reset controller state transition")
--- drivers/nvme/host/fabrics.c | 15 +++++++++++++++ drivers/nvme/host/fabrics.h | 1 + drivers/nvme/host/fc.c | 1 + drivers/nvme/host/nvme.h | 14 +++----------- drivers/nvme/host/pci.c | 36 ++++++++++++++++++++++++++++++++++++ drivers/nvme/host/rdma.c | 1 + drivers/nvme/host/tcp.c | 1 + include/linux/nvme.h | 3 +++ 8 files changed, 61 insertions(+), 11 deletions(-)
drivers/nvme/host/fabrics.c +15 -0
@@ -279,6 +279,21 @@ int nvmf_reg_write32(struct nvme_ctrl *c }EXPORT_SYMBOL_GPL (nvmf_reg_write32); +int nvmf_subsystem_reset (struct nvme_ctrl *ctrl) +{ +int ret; + +if (!nvme_wait_reset (ctrl)) +return -EBUSY ; + + ret = ctrl->ops->reg_write32 (ctrl,NVME_REG_NSSR ,NVME_SUBSYS_RESET ); +if (ret) +return ret; + +return nvme_try_sched_reset (ctrl); +} +EXPORT_SYMBOL_GPL (nvmf_subsystem_reset); +/** * nvmf_log_connect_error() - Error-parsing-diagnostic print out function for * connect() errors.
drivers/nvme/host/fabrics.h +1 -0
@@ -206,6 +206,7 @@ static inline unsigned int nvmf_nr_io_quint nvmf_reg_read32 (struct nvme_ctrl *ctrl,u32 off,u32 *val);int nvmf_reg_read64 (struct nvme_ctrl *ctrl,u32 off,u64 *val);int nvmf_reg_write32 (struct nvme_ctrl *ctrl,u32 off,u32 val); +int nvmf_subsystem_reset (struct nvme_ctrl *ctrl);int nvmf_connect_admin_queue (struct nvme_ctrl *ctrl);int nvmf_connect_io_queue (struct nvme_ctrl *ctrl,u16 qid);int nvmf_register_transport (struct nvmf_transport_ops *ops);
drivers/nvme/host/fc.c +1 -0
@@ -3349,6 +3349,7 @@ static const struct nvme_ctrl_ops nvme_f .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, + .subsystem_reset = nvmf_subsystem_reset, .free_ctrl = nvme_fc_free_ctrl, .submit_async_event = nvme_fc_submit_async_event, .delete_ctrl = nvme_fc_delete_ctrl,
drivers/nvme/host/nvme.h +3 -11
@@ -562,6 +562,7 @@ struct nvme_ctrl_ops {int (*reg_read64)(struct nvme_ctrl *ctrl,u32 off,u64 *val);void (*free_ctrl)(struct nvme_ctrl *ctrl);void (*submit_async_event)(struct nvme_ctrl *ctrl); +int (*subsystem_reset)(struct nvme_ctrl *ctrl);void (*delete_ctrl)(struct nvme_ctrl *ctrl);void (*stop_ctrl)(struct nvme_ctrl *ctrl);int (*get_address)(struct nvme_ctrl *ctrl,char *buf,int size);
@@ -660,18 +661,9 @@ int nvme_try_sched_reset(struct nvme_ctrstatic inline int nvme_reset_subsystem (struct nvme_ctrl *ctrl) { -int ret; - -if (!ctrl->subsystem) +if (!ctrl->subsystem || !ctrl->ops->subsystem_reset)return -ENOTTY ; -if (!nvme_wait_reset (ctrl)) -return -EBUSY ; - - ret = ctrl->ops->reg_write32 (ctrl,NVME_REG_NSSR ,0x4E564D65 ); -if (ret) -return ret; - -return nvme_try_sched_reset (ctrl); +return ctrl->ops->subsystem_reset (ctrl); }/*
drivers/nvme/host/pci.c +36 -0
@@ -1143,6 +1143,41 @@ static void nvme_pci_submit_async_event(spin_unlock (&nvmeq->sq_lock); } +static int nvme_pci_subsystem_reset (struct nvme_ctrl *ctrl) +{ +struct nvme_dev *dev =to_nvme_dev (ctrl); +int ret =0 ; + +/* +* Taking the shutdown_lock ensures the BAR mapping is not being +* altered by reset_work. Holding this lock before the RESETTING state +* change, if successful, also ensures nvme_remove won't be able to +* proceed to iounmap until we're done. +*/ +mutex_lock (&dev->shutdown_lock); +if (!dev->bar_mapped_size) { + ret = -ENODEV ; + goto unlock; + } + +if (!nvme_change_ctrl_state (ctrl,NVME_CTRL_RESETTING )) { + ret = -EBUSY ; + goto unlock; + } + +writel (NVME_SUBSYS_RESET , dev->bar +NVME_REG_NSSR ); +nvme_change_ctrl_state (ctrl,NVME_CTRL_LIVE ); + +/* +* Read controller status to flush the previous write and trigger a +* pcie read error. +*/ +readl (dev->bar +NVME_REG_CSTS ); +unlock: +mutex_unlock (&dev->shutdown_lock); +return ret; +} +static int adapter_delete_queue (struct nvme_dev *dev,u8 opcode,u16 id) {struct nvme_command c = { };
@@ -2910,6 +2945,7 @@ static const struct nvme_ctrl_ops nvme_p .reg_read64 = nvme_pci_reg_read64, .free_ctrl = nvme_pci_free_ctrl, .submit_async_event = nvme_pci_submit_async_event, + .subsystem_reset = nvme_pci_subsystem_reset, .get_address = nvme_pci_get_address, .print_device_info = nvme_pci_print_device_info, .supports_pci_p2pdma = nvme_pci_supports_pci_p2pdma,
drivers/nvme/host/rdma.c +1 -0
@@ -2174,6 +2174,7 @@ static const struct nvme_ctrl_ops nvme_r .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, + .subsystem_reset = nvmf_subsystem_reset, .free_ctrl = nvme_rdma_free_ctrl, .submit_async_event = nvme_rdma_submit_async_event, .delete_ctrl = nvme_rdma_delete_ctrl,
drivers/nvme/host/tcp.c +1 -0
@@ -2561,6 +2561,7 @@ static const struct nvme_ctrl_ops nvme_t .reg_read32 = nvmf_reg_read32, .reg_read64 = nvmf_reg_read64, .reg_write32 = nvmf_reg_write32, + .subsystem_reset = nvmf_subsystem_reset, .free_ctrl = nvme_tcp_free_ctrl, .submit_async_event = nvme_tcp_submit_async_event, .delete_ctrl = nvme_tcp_delete_ctrl,
include/linux/nvme.h +3 -0
@@ -28,6 +28,9 @@#define NVME_NSID_ALL 0xffffffff +/* Special NSSR value, 'NVMe' */ +#define NVME_SUBSYS_RESET 0x4E564D65 +enum nvme_subsys_type {/* Referral to another discovery type target subsystem */ NVME_NQN_DISC =1 ,
Greg Kroah-Hartman
maintainerPATCH 244/254 nvme: fix PCIe subsystem reset controller state transition
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nilay Shroff <[email protected]>
[ Upstream commit 0edb475ac0a7d153318a24d4dca175a270a5cc4f ]
The commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”) disallows controller state transitions directly from RESETTING to LIVE. However, the NVMe PCIe subsystem reset path relies on this transition to recover the controller on PowerPC (PPC) systems.
On PPC systems, issuing a subsystem reset causes a temporary loss of communication with the NVMe adapter. A subsequent PCIe MMIO read then triggers EEH recovery, which restores the PCIe link and brings the controller back online. For EEH recovery to proceed correctly, the controller must transition back to the LIVE state.
Due to the changes introduced by commit d2fe192348f9 (“nvme: only allow entering LIVE from CONNECTING state”), the controller can no longer transition directly from RESETTING to LIVE. As a result, EEH recovery exits prematurely, leaving the controller stuck in the RESETTING state.
Fix this by explicitly transitioning the controller state from RESETTING to CONNECTING and then to LIVE. This satisfies the updated state transition rules and allows the controller to be successfully recovered on PPC systems following a PCIe subsystem reset.
--- drivers/nvme/host/pci.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/nvme/host/pci.c +4 -1
@@ -1166,7 +1166,10 @@ static int nvme_pci_subsystem_reset(stru }writel (NVME_SUBSYS_RESET , dev->bar +NVME_REG_NSSR ); -nvme_change_ctrl_state (ctrl,NVME_CTRL_LIVE ); + +if (!nvme_change_ctrl_state (ctrl,NVME_CTRL_CONNECTING ) || + !nvme_change_ctrl_state (ctrl,NVME_CTRL_LIVE )) + goto unlock;/* * Read controller status to flush the previous write and trigger a
Greg Kroah-Hartman
maintainerPATCH 245/254 NFSD: fix race between nfsd registration and exports_proc
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maninder Singh <[email protected]>
[ Upstream commit f7fb730cac9aafda8b9813b55d04e28a9664d17c ]
As of now nfsd calls create_proc_exports_entry() at start of init_nfsd and cleanup by remove_proc_entry() at last of exit_nfsd.
Which causes kernel OOPs if there is race between below 2 operations:
(i) exportfs -r
(ii) mount -t nfsd none /proc/fs/nfsd
for 5.4 kernel ARM64:
CPU 1:
el1_irq+0xbc/0x180 arch_counter_get_cntvct+0x14/0x18 running_clock+0xc/0x18 preempt_count_add+0x88/0x110 prep_new_page+0xb0/0x220 get_page_from_freelist+0x2d8/0x1778 __alloc_pages_nodemask+0x15c/0xef0 __vmalloc_node_range+0x28c/0x478 __vmalloc_node_flags_caller+0x8c/0xb0 kvmalloc_node+0x88/0xe0 nfsd_init_net+0x6c/0x108 [nfsd] ops_init+0x44/0x170 register_pernet_operations+0x114/0x270 register_pernet_subsys+0x34/0x50 init_nfsd+0xa8/0x718 [nfsd] do_one_initcall+0x54/0x2e0
CPU 2 :
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010
PC is at : exports_net_open+0x50/0x68 [nfsd]
Call trace: exports_net_open+0x50/0x68 [nfsd] exports_proc_open+0x2c/0x38 [nfsd] proc_reg_open+0xb8/0x198 do_dentry_open+0x1c4/0x418 vfs_open+0x38/0x48 path_openat+0x28c/0xf18 do_filp_open+0x70/0xe8 do_sys_open+0x154/0x248
Sometimes it crashes at exports_net_open() and sometimes cache_seq_next_rcu().
and same is happening on latest 6.14 kernel as well:
[ 0.000000] Linux version 6.14.0-rc5-next-20250304-dirty ... [ 285.455918] Unable to handle kernel paging request at virtual address 00001f4800001f48 ... [ 285.464902] pc : cache_seq_next_rcu+0x78/0xa4 ... [ 285.469695] Call trace: [ 285.470083] cache_seq_next_rcu+0x78/0xa4 (P) [ 285.470488] seq_read+0xe0/0x11c [ 285.470675] proc_reg_read+0x9c/0xf0 [ 285.470874] vfs_read+0xc4/0x2fc [ 285.471057] ksys_read+0x6c/0xf4 [ 285.471231] __arm64_sys_read+0x1c/0x28 [ 285.471428] invoke_syscall+0x44/0x100 [ 285.471633] el0_svc_common.constprop.0+0x40/0xe0 [ 285.471870] do_el0_svc_compat+0x1c/0x34 [ 285.472073] el0_svc_compat+0x2c/0x80 [ 285.472265] el0t_32_sync_handler+0x90/0x140 [ 285.472473] el0t_32_sync+0x19c/0x1a0 [ 285.472887] Code: f9400885 93407c23 937d7c27 11000421 (f86378a3) [ 285.473422] ---[ end trace 0000000000000000 ]---
It reproduced simply with below script:
while [ 1 ]
do
/exportfs -r
done &
while [ 1 ]
do
insmod /nfsd.ko
mount -t nfsd none /proc/fs/nfsd
umount /proc/fs/nfsd
rmmod nfsd
done &
So exporting interfaces to user space shall be done at last and cleanup at first place.
With change there is no Kernel OOPs.
[ The context change is due to the commit bd9d6a3efa97 ("NFSD: add rpc_status netlink support")
and the proper adoption is done. ]
--- fs/nfsd/nfsctl.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
fs/nfsd/nfsctl.c +8 -9
@@ -1582,12 +1582,9 @@ static int __init init_nfsd(void)if (retval) goto out_free_pnfs;nfsd_lockd_init ();/* lockd->nfsd callbacks */ - retval =create_proc_exports_entry (); -if (retval) - goto out_free_lockd; retval =register_pernet_subsys (&nfsd_net_ops);if (retval <0 ) - goto out_free_exports; + goto out_free_lockd; retval =register_cld_notifier ();if (retval) goto out_free_subsys;
@@ -1596,17 +1593,19 @@ static int __init init_nfsd(void) goto out_free_cld; retval =register_filesystem (&nfsd_fs_type);if (retval) + goto out_free_nfsd4; + retval =create_proc_exports_entry (); +if (retval) goto out_free_all;return 0 ; out_free_all: +unregister_filesystem (&nfsd_fs_type); +out_free_nfsd4:nfsd4_destroy_laundry_wq (); out_free_cld:unregister_cld_notifier (); out_free_subsys:unregister_pernet_subsys (&nfsd_net_ops); -out_free_exports: -remove_proc_entry ("fs/nfs/exports" ,NULL ); -remove_proc_entry ("fs/nfs" ,NULL ); out_free_lockd:nfsd_lockd_shutdown ();nfsd_drc_slab_free ();
@@ -1619,13 +1618,13 @@ out_free_slabs: static void __exit exit_nfsd(void) { +remove_proc_entry ("fs/nfs/exports" ,NULL ); +remove_proc_entry ("fs/nfs" ,NULL );unregister_filesystem (&nfsd_fs_type);nfsd4_destroy_laundry_wq ();unregister_cld_notifier ();unregister_pernet_subsys (&nfsd_net_ops);nfsd_drc_slab_free (); -remove_proc_entry ("fs/nfs/exports" ,NULL ); -remove_proc_entry ("fs/nfs" ,NULL );nfsd_lockd_shutdown ();nfsd4_free_slabs ();nfsd4_exit_pnfs ();
Greg Kroah-Hartman
maintainerPATCH 246/254 usbnet: Fix using smp_processor_id() in preemptible code warnings
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zqiang <[email protected]>
[ Upstream commit 327cd4b68b4398b6c24f10eb2b2533ffbfc10185 ]
Syzbot reported the following warning:
BUG: using smp_processor_id() in preemptible [00000000] code: dhcpcd/2879 caller is usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331 CPU: 1 UID: 0 PID: 2879 Comm: dhcpcd Not tainted 6.15.0-rc4-syzkaller-00098-g615dca38c2ea #0 PREEMPT(voluntary) Call Trace: <TASK> __dump_stack lib/dump_stack.c:94 [inline] dump_stack_lvl+0x16c/0x1f0 lib/dump_stack.c:120 check_preemption_disabled+0xd0/0xe0 lib/smp_processor_id.c:49 usbnet_skb_return+0x74/0x490 drivers/net/usb/usbnet.c:331 usbnet_resume_rx+0x4b/0x170 drivers/net/usb/usbnet.c:708 usbnet_change_mtu+0x1be/0x220 drivers/net/usb/usbnet.c:417 __dev_set_mtu net/core/dev.c:9443 [inline] netif_set_mtu_ext+0x369/0x5c0 net/core/dev.c:9496 netif_set_mtu+0xb0/0x160 net/core/dev.c:9520 dev_set_mtu+0xae/0x170 net/core/dev_api.c:247 dev_ifsioc+0xa31/0x18d0 net/core/dev_ioctl.c:572 dev_ioctl+0x223/0x10e0 net/core/dev_ioctl.c:821 sock_do_ioctl+0x19d/0x280 net/socket.c:1204 sock_ioctl+0x42f/0x6a0 net/socket.c:1311 vfs_ioctl fs/ioctl.c:51 [inline] __do_sys_ioctl fs/ioctl.c:906 [inline] __se_sys_ioctl fs/ioctl.c:892 [inline] __x64_sys_ioctl+0x190/0x200 fs/ioctl.c:892 do_syscall_x64 arch/x86/entry/syscall_64.c:63 [inline] do_syscall_64+0xcd/0x260 arch/x86/entry/syscall_64.c:94 entry_SYSCALL_64_after_hwframe+0x77/0x7f
For historical and portability reasons, the netif_rx() is usually run in the softirq or interrupt context, this commit therefore add local_bh_disable/enable() protection in the usbnet_resume_rx().
[ The context change is due to the commit 2c04d279e857 ("net: usb: Convert tasklet API to new bottom half workqueue mechanism") in v6.17 which is irrelevant to the logic of this patch.]
--- drivers/net/usb/usbnet.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/usb/usbnet.c +2 -0
@@ -702,6 +702,7 @@ void usbnet_resume_rx(struct usbnet *devstruct sk_buff *skb;int num =0 ; +local_bh_disable ();clear_bit (EVENT_RX_PAUSED , &dev->flags);while ((skb =skb_dequeue (&dev->rxq_pause)) !=NULL ) {
@@ -710,6 +711,7 @@ void usbnet_resume_rx(struct usbnet *dev }tasklet_schedule (&dev->bh); +local_bh_enable ();netif_dbg (dev, rx_status, dev->net,"paused rx queue disabled, %d skbs requeued\n" , num);
Greg Kroah-Hartman
maintainerPATCH 247/254 ksmbd: fix use-after-free in ksmbd_session_rpc_open
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Namjae Jeon <[email protected]>
[ Upstream commit a1f46c99d9ea411f9bf30025b912d881d36fc709 ]
A UAF issue can occur due to a race condition between ksmbd_session_rpc_open() and __session_rpc_close(). Add rpc_lock to the session to protect it.
[ KSMBD_DEFAULT_GFP is introduced by commit 0066f623bce8 ("ksmbd: use __GFP_RETRY_MAYFAIL")
after linux-6.13. Here we still use GFP_KERNEL. ]
--- fs/smb/server/mgmt/user_session.c | 20 ++++++++++++++------ fs/smb/server/mgmt/user_session.h | 1 + 2 files changed, 15 insertions(+), 6 deletions(-)
fs/smb/server/mgmt/user_session.c +14 -6
@@ -59,10 +59,12 @@ static void ksmbd_session_rpc_clear_liststruct ksmbd_session_rpc *entry;long index; +down_write (&sess->rpc_lock);xa_for_each (&sess->rpc_handle_list, index, entry) {xa_erase (&sess->rpc_handle_list, index);__session_rpc_close (sess, entry); } +up_write (&sess->rpc_lock);xa_destroy (&sess->rpc_handle_list); }
@@ -92,7 +94,7 @@ int ksmbd_session_rpc_open(struct ksmbd_ {struct ksmbd_session_rpc *entry, *old;struct ksmbd_rpc_command *resp; -int method; +int method, id; method =__rpc_method (rpc_name);if (!method)
@@ -102,26 +104,29 @@ int ksmbd_session_rpc_open(struct ksmbd_if (!entry)return -ENOMEM ; +down_read (&sess->rpc_lock); entry->method = method; - entry->id =ksmbd_ipc_id_alloc (); -if (entry->id <0 ) + entry->id = id =ksmbd_ipc_id_alloc (); +if (id <0 ) goto free_entry; - old =xa_store (&sess->rpc_handle_list, entry->id, entry,GFP_KERNEL ); + old =xa_store (&sess->rpc_handle_list, id, entry,GFP_KERNEL );if (xa_is_err (old)) goto free_id; - resp =ksmbd_rpc_open (sess, entry->id); + resp =ksmbd_rpc_open (sess, id);if (!resp) goto erase_xa; +up_read (&sess->rpc_lock);kvfree (resp); -return entry->id; +return id; erase_xa:xa_erase (&sess->rpc_handle_list, entry->id); free_id:ksmbd_rpc_id_free (entry->id); free_entry:kfree (entry); +up_read (&sess->rpc_lock);return -EINVAL ; }
@@ -129,9 +134,11 @@ void ksmbd_session_rpc_close(struct ksmb {struct ksmbd_session_rpc *entry; +down_write (&sess->rpc_lock); entry =xa_erase (&sess->rpc_handle_list, id);if (entry)__session_rpc_close (sess, entry); +up_write (&sess->rpc_lock); }int ksmbd_session_rpc_method (struct ksmbd_session *sess,int id)
@@ -438,6 +445,7 @@ static struct ksmbd_session *__session_c sess->sequence_number =1 ;rwlock_init (&sess->tree_conns_lock);atomic_set (&sess->refcnt,2 ); +init_rwsem (&sess->rpc_lock); ret =__init_smb2_session (sess);if (ret)
fs/smb/server/mgmt/user_session.h +1 -0
@@ -63,6 +63,7 @@ struct ksmbd_session {rwlock_t tree_conns_lock;atomic_t refcnt; +struct rw_semaphore rpc_lock; };static inline int test_session_flag (struct ksmbd_session *sess,int bit)
Greg Kroah-Hartman
maintainerPATCH 248/254 fs/ntfs3: Initialize allocated memory before use
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartlomiej Kubik <[email protected]>
[ Upstream commit a8a3ca23bbd9d849308a7921a049330dc6c91398 ]
KMSAN reports: Multiple uninitialized values detected:
- KMSAN: uninit-value in ntfs_read_hdr (3)
- KMSAN: uninit-value in bcmp (3)
Memory is allocated by __getname(), which is a wrapper for kmem_cache_alloc(). This memory is used before being properly cleared. Change kmem_cache_alloc() to kmem_cache_zalloc() to properly allocate and clear memory before use.
--- fs/ntfs3/inode.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-)
fs/ntfs3/inode.c +3 -4
@@ -1327,7 +1327,7 @@ struct inode *ntfs_create_inode(struct m fa |=FILE_ATTRIBUTE_READONLY ;/* Allocate PATH_MAX bytes. */ - new_de =__getname (); + new_de =kmem_cache_zalloc (names_cachep,GFP_KERNEL );if (!new_de) { err = -ENOMEM ; goto out1;
@@ -1756,10 +1756,9 @@ int ntfs_link_inode(struct inode *inode,struct NTFS_DE *de;/* Allocate PATH_MAX bytes. */ - de =__getname (); + de =kmem_cache_zalloc (names_cachep,GFP_KERNEL );if (!de)return -ENOMEM ; -memset (de,0 ,PATH_MAX );/* Mark rw ntfs as dirty. It will be cleared at umount. */ ntfs_set_state (sbi,NTFS_DIRTY_DIRTY );
@@ -1795,7 +1794,7 @@ int ntfs_unlink_inode(struct inode *dir,return -EINVAL ;/* Allocate PATH_MAX bytes. */ - de =__getname (); + de =kmem_cache_zalloc (names_cachep,GFP_KERNEL );if (!de)return -ENOMEM ;
Greg Kroah-Hartman
maintainerPATCH 249/254 drm/amdgpu: csa unmap use uninterruptible lock
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Philip Yang <[email protected]>
[ Upstream commit a0fa7873f2f869087b1e7793f7fac3713a1e3afe ]
After process exit to unmap csa and free GPU vm, if signal is accepted and then waiting to take vm lock is interrupted and return, it causes memory leaking and below warning backtrace.
Change to use uninterruptible wait lock fix the issue.
WARNING: CPU: 69 PID: 167800 at amd/amdgpu/amdgpu_kms.c:1525 amdgpu_driver_postclose_kms+0x294/0x2a0 [amdgpu] Call Trace: <TASK> drm_file_free.part.0+0x1da/0x230 [drm] drm_close_helper.isra.0+0x65/0x70 [drm] drm_release+0x6a/0x120 [drm] amdgpu_drm_release+0x51/0x60 [amdgpu] __fput+0x9f/0x280 ____fput+0xe/0x20 task_work_run+0x67/0xa0 do_exit+0x217/0x3c0 do_group_exit+0x3b/0xb0 get_signal+0x14a/0x8d0 arch_do_signal_or_restart+0xde/0x100 exit_to_user_mode_loop+0xc1/0x1a0 exit_to_user_mode_prepare+0xf4/0x100 syscall_exit_to_user_mode+0x17/0x40 do_syscall_64+0x69/0xc0
[The third parameter of drm_exec_init() was introduced by commit
05d249352f1a ("drm/exec: Pass in initial # of objects") after Linux 6.8. This code targets linux 6.6, so the current implementation is used and the third parameter is not needed.]
--- drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_csa.c +1 -1
@@ -110,7 +110,7 @@ int amdgpu_unmap_static_csa(struct amdgpstruct drm_exec exec;int r; -drm_exec_init (&exec,DRM_EXEC_INTERRUPTIBLE_WAIT ); +drm_exec_init (&exec,0 ); drm_exec_until_all_locked(&exec) { r =amdgpu_vm_lock_pd (vm, &exec,0 );if (likely (!r))
Greg Kroah-Hartman
maintainerPATCH 250/254 wifi: ath11k: fix RCU stall while reaping monitor destination ring
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: P Praneesh <[email protected]>
[ Upstream commit 16c6c35c03ea73054a1f6d3302a4ce4a331b427d ]
While processing the monitor destination ring, MSDUs are reaped from the link descriptor based on the corresponding buf_id.
However, sometimes the driver cannot obtain a valid buffer corresponding to the buf_id received from the hardware. This causes an infinite loop in the destination processing, resulting in a kernel crash.
kernel log:ath11k_pci 0000:58:00.0: data msdu_pop: invalid buf_id 309 ath11k_pci 0000:58:00.0: data dp_rx_monitor_link_desc_return failed ath11k_pci 0000:58:00.0: data msdu_pop: invalid buf_id 309 ath11k_pci 0000:58:00.0: data dp_rx_monitor_link_desc_return failed
Fix this by skipping the problematic buf_id and reaping the next entry, replacing the break with the next MSDU processing.
Tested-on: WCN6855 hw2.0 PCI WLAN.HSP.1.1-03125-QCAHSPSWPL_V1_V2_SILICONZ_LITE-3.6510.30
Tested-on: QCN9074 hw1.0 PCI WLAN.HK.2.7.0.1-01744-QCAHKSWPL_SILICONZ-1
--- drivers/net/wireless/ath/ath11k/dp_rx.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/net/wireless/ath/ath11k/dp_rx.c +2 -2
@@ -4728,7 +4728,7 @@ ath11k_dp_rx_mon_mpdu_pop(struct ath11kif (!msdu) {ath11k_dbg (ar->ab,ATH11K_DBG_DATA ,"msdu_pop: invalid buf_id %d\n" , buf_id); -break ; + goto next_msdu; } rxcb =ATH11K_SKB_RXCB (msdu);if (!rxcb->unmapped) {
@@ -5362,7 +5362,7 @@ ath11k_dp_rx_full_mon_mpdu_pop(struct at"full mon msdu_pop: invalid buf_id %d\n" , buf_id);spin_unlock_bh (&rx_ring->idr_lock); -break ; + goto next_msdu; }idr_remove (&rx_ring->bufs_idr, buf_id);spin_unlock_bh (&rx_ring->idr_lock);
Greg Kroah-Hartman
maintainerPATCH 251/254 x86/fpu: Clear XSTATE_BV[i] in guest XSAVE state whenever XFD[i]=1
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sean Christopherson <[email protected]>
[ Upstream commit b45f721775947a84996deb5c661602254ce25ce6 ]
When loading guest XSAVE state via KVM_SET_XSAVE, and when updating XFD in response to a guest WRMSR, clear XFD-disabled features in the saved (or to be restored) XSTATE_BV to ensure KVM doesn't attempt to load state for features that are disabled via the guest's XFD. Because the kernel executes XRSTOR with the guest's XFD, saving XSTATE_BV[i]=1 with XFD[i]=1 will cause XRSTOR to #NM and panic the kernel.
E.g. if fpu_update_guest_xfd() sets XFD without clearing XSTATE_BV:
------------[ cut here ]------------ WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#29: amx_test/848 Modules linked in: kvm_intel kvm irqbypass CPU: 29 UID: 1000 PID: 848 Comm: amx_test Not tainted 6.19.0-rc2-ffa07f7fd437-x86_amx_nm_xfd_non_init-vm #171 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:exc_device_not_available+0x101/0x110 Call Trace: <TASK> asm_exc_device_not_available+0x1a/0x20 RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90 switch_fpu_return+0x4a/0xb0 kvm_arch_vcpu_ioctl_run+0x1245/0x1e40 [kvm] kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm] __x64_sys_ioctl+0x8f/0xd0 do_syscall_64+0x62/0x940 entry_SYSCALL_64_after_hwframe+0x4b/0x53 </TASK> ---[ end trace 0000000000000000 ]---
This can happen if the guest executes WRMSR(MSR_IA32_XFD) to set XFD[18] = 1, and a host IRQ triggers kernel_fpu_begin() prior to the vmexit handler's call to fpu_update_guest_xfd().
and if userspace stuffs XSTATE_BV[i]=1 via KVM_SET_XSAVE:
------------[ cut here ]------------ WARNING: arch/x86/kernel/traps.c:1524 at exc_device_not_available+0x101/0x110, CPU#14: amx_test/867 Modules linked in: kvm_intel kvm irqbypass CPU: 14 UID: 1000 PID: 867 Comm: amx_test Not tainted 6.19.0-rc2-2dace9faccd6-x86_amx_nm_xfd_non_init-vm #168 NONE Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 0.0.0 02/06/2015 RIP: 0010:exc_device_not_available+0x101/0x110 Call Trace: <TASK> asm_exc_device_not_available+0x1a/0x20 RIP: 0010:restore_fpregs_from_fpstate+0x36/0x90 fpu_swap_kvm_fpstate+0x6b/0x120 kvm_load_guest_fpu+0x30/0x80 [kvm] kvm_arch_vcpu_ioctl_run+0x85/0x1e40 [kvm] kvm_vcpu_ioctl+0x2c3/0x8f0 [kvm] __x64_sys_ioctl+0x8f/0xd0 do_syscall_64+0x62/0x940 entry_SYSCALL_64_after_hwframe+0x4b/0x53 </TASK> ---[ end trace 0000000000000000 ]---
The new behavior is consistent with the AMX architecture. Per Intel's SDM, XSAVE saves XSTATE_BV as '0' for components that are disabled via XFD (and non-compacted XSAVE saves the initial configuration of the state component):
If XSAVE, XSAVEC, XSAVEOPT, or XSAVES is saving the state component i, the instruction does not generate #NM when XCR0[i] = IA32_XFD[i] = 1; instead, it operates as if XINUSE[i] = 0 (and the state component was in its initial state): it saves bit i of XSTATE_BV field of the XSAVE header as 0; in addition, XSAVE saves the initial configuration of the state component (the other instructions do not save state component i).
Alternatively, KVM could always do XRSTOR with XFD=0, e.g. by using a constant XFD based on the set of enabled features when XSAVEing for a struct fpu_guest. However, having XSTATE_BV[i]=1 for XFD-disabled features can only happen in the above interrupt case, or in similar scenarios involving preemption on preemptible kernels, because fpu_swap_kvm_fpstate()'s call to save_fpregs_to_fpstate() saves the outgoing FPU state with the current XFD; and that is (on all but the first WRMSR to XFD) the guest XFD.
Therefore, XFD can only go out of sync with XSTATE_BV in the above interrupt case, or in similar scenarios involving preemption on preemptible kernels, and it we can consider it (de facto) part of KVM ABI that KVM_GET_XSAVE returns XSTATE_BV[i]=0 for XFD-disabled features.
[Move clearing of XSTATE_BV from fpu_copy_uabi_to_guest_fpstate
to kvm_vcpu_ioctl_x86_set_xsave. - Paolo]
--- arch/x86/kernel/fpu/core.c | 32 +++++++++++++++++++++++++++++--- arch/x86/kvm/x86.c | 9 +++++++++ 2 files changed, 38 insertions(+), 3 deletions(-)
arch/x86/kernel/fpu/core.c +29 -3
@@ -294,10 +294,29 @@ EXPORT_SYMBOL_GPL(fpu_enable_guest_xfd_f#ifdef CONFIG_X86_64 void fpu_update_guest_xfd (struct fpu_guest *guest_fpu,u64 xfd) { +struct fpstate *fpstate = guest_fpu->fpstate; +fpregs_lock (); - guest_fpu->fpstate->xfd = xfd; -if (guest_fpu->fpstate->in_use) -xfd_update_state (guest_fpu->fpstate); + +/* +* KVM's guest ABI is that setting XFD[i]=1 *can* immediately revert the +* save state to its initial configuration. Likewise, KVM_GET_XSAVE does +* the same as XSAVE and returns XSTATE_BV[i]=0 whenever XFD[i]=1. +* +* If the guest's FPU state is in hardware, just update XFD: the XSAVE +* in fpu_swap_kvm_fpstate will clear XSTATE_BV[i] whenever XFD[i]=1. +* +* If however the guest's FPU state is NOT resident in hardware, clear +* disabled components in XSTATE_BV now, or a subsequent XRSTOR will +* attempt to load disabled components and generate #NM _in the host_. +*/ +if (xfd &&test_thread_flag (TIF_NEED_FPU_LOAD )) + fpstate->regs.xsave.header.xfeatures &= ~xfd; + + fpstate->xfd = xfd; +if (fpstate->in_use) +xfd_update_state (fpstate); +fpregs_unlock (); }EXPORT_SYMBOL_GPL (fpu_update_guest_xfd);
@@ -406,6 +425,13 @@ int fpu_copy_uabi_to_guest_fpstate(strucreturn -EINVAL ;/* +* Disabled features must be in their initial state, otherwise XRSTOR +* causes an exception. +*/ +if (WARN_ON_ONCE (ustate->xsave.header.xfeatures & kstate->xfd)) +return -EINVAL ; + +/* * Nullify @vpkru to preserve its current value if PKRU's bit isn't set * in the header. KVM's odd ABI is to leave PKRU untouched in this * case (all other components are eventually re-initialized).
arch/x86/kvm/x86.c +9 -0
@@ -5432,9 +5432,18 @@ static void kvm_vcpu_ioctl_x86_get_xsavestatic int kvm_vcpu_ioctl_x86_set_xsave (struct kvm_vcpu *vcpu,struct kvm_xsave *guest_xsave) { +union fpregs_state *xstate = (union fpregs_state *)guest_xsave->region; +if (fpstate_is_confidential (&vcpu->arch.guest_fpu))return 0 ; +/* +* For backwards compatibility, do not expect disabled features to be in +* their initial state. XSTATE_BV[i] must still be cleared whenever +* XFD[i]=1, or XRSTOR would cause a #NM. +*/ + xstate->xsave.header.xfeatures &= ~vcpu->arch.guest_fpu.fpstate->xfd; + return fpu_copy_uabi_to_guest_fpstate(&vcpu->arch.guest_fpu, guest_xsave->region, kvm_caps.supported_xcr0,
Greg Kroah-Hartman
maintainerPATCH 252/254 net: phy: move phy_link_change() prior to mdio_bus_phy_may_suspend()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit f40a673d6b4a128fe95dd9b8c3ed02da50a6a862 ]
In an upcoming change, mdio_bus_phy_may_suspend() will need to distinguish a phylib-based PHY client from a phylink PHY client. For that, it will need to compare the phydev->phy_link_change() function pointer with the eponymous phy_link_change() provided by phylib.
To avoid forward function declarations, the default PHY link state change method should be moved upwards. There is no functional change associated with this patch, it is only to reduce the noise from a real bug fix.
---
--- drivers/net/phy/phy_device.c | 26 +++++++++++++------------- 1 file changed, 13 insertions(+), 13 deletions(-)
drivers/net/phy/phy_device.c +13 -13
@@ -268,6 +268,19 @@ static struct phy_driver genphy_driver;static LIST_HEAD (phy_fixup_list);static DEFINE_MUTEX (phy_fixup_lock); +static void phy_link_change (struct phy_device *phydev,bool up) +{ +struct net_device *netdev = phydev->attached_dev; + +if (up) +netif_carrier_on (netdev); +else +netif_carrier_off (netdev); + phydev->adjust_link (netdev); +if (phydev->mii_ts && phydev->mii_ts->link_state) + phydev->mii_ts->link_state (phydev->mii_ts, phydev); +} +static bool mdio_bus_phy_may_suspend (struct phy_device *phydev) {struct device_driver *drv = phydev->mdio.dev.driver;
@@ -1069,19 +1082,6 @@ struct phy_device *phy_find_first(struct }EXPORT_SYMBOL (phy_find_first); -static void phy_link_change (struct phy_device *phydev,bool up) -{ -struct net_device *netdev = phydev->attached_dev; - -if (up) -netif_carrier_on (netdev); -else -netif_carrier_off (netdev); - phydev->adjust_link (netdev); -if (phydev->mii_ts && phydev->mii_ts->link_state) - phydev->mii_ts->link_state (phydev->mii_ts, phydev); -} -/** * phy_prepare_link - prepares the PHY layer to monitor link status * @phydev: target phy_device struct
Greg Kroah-Hartman
maintainerPATCH 253/254 net: phy: allow MDIO bus PM ops to start/stop state machine for phylink-controlled PHY
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Oltean <[email protected]>
[ Upstream commit fc75ea20ffb452652f0d4033f38fe88d7cfdae35 ]
DSA has 2 kinds of drivers:
1. Those who call dsa_switch_suspend() and dsa_switch_resume() from their device PM ops: qca8k-8xxx, bcm_sf2, microchip ksz
2. Those who don't: all others. The above methods should be optional.
For type 1, dsa_switch_suspend() calls dsa_user_suspend() -> phylink_stop(), and dsa_switch_resume() calls dsa_user_resume() -> phylink_start(). These seem good candidates for setting mac_managed_pm = true because that is essentially its definition [1], but that does not seem to be the biggest problem for now, and is not what this change focuses on.
Talking strictly about the 2nd category of DSA drivers here (which do not have MAC managed PM, meaning that for their attached PHYs, mdio_bus_phy_suspend() and mdio_bus_phy_resume() should run in full), I have noticed that the following warning from mdio_bus_phy_resume() is triggered:
WARN_ON(phydev->state != PHY_HALTED && phydev->state != PHY_READY && phydev->state != PHY_UP);
because the PHY state machine is running.
It's running as a result of a previous dsa_user_open() -> ... -> phylink_start() -> phy_start() having been initiated by the user.
The previous mdio_bus_phy_suspend() was supposed to have called phy_stop_machine(), but it didn't. So this is why the PHY is in state PHY_NOLINK by the time mdio_bus_phy_resume() runs.
mdio_bus_phy_suspend() did not call phy_stop_machine() because for phylink, the phydev->adjust_link function pointer is NULL. This seems a technicality introduced by commit fddd91016d16 ("phylib: fix PAL state machine restart on resume"). That commit was written before phylink existed, and was intended to avoid crashing with consumer drivers which don't use the PHY state machine - phylink always does, when using a PHY. But phylink itself has historically not been developed with suspend/resume in mind, and apparently not tested too much in that scenario, allowing this bug to exist unnoticed for so long. Plus, prior to the WARN_ON(), it would have likely been invisible.
This issue is not in fact restricted to type 2 DSA drivers (according to the above ad-hoc classification), but can be extrapolated to any MAC driver with phylink and MDIO-bus-managed PHY PM ops. DSA is just where the issue was reported. Assuming mac_managed_pm is set correctly, a quick search indicates the following other drivers might be affected:
$ grep -Zlr PHYLINK_NETDEV drivers/ | xargs -0 grep -L mac_managed_pm drivers/net/ethernet/atheros/ag71xx.c drivers/net/ethernet/microchip/sparx5/sparx5_main.c drivers/net/ethernet/microchip/lan966x/lan966x_main.c drivers/net/ethernet/freescale/dpaa2/dpaa2-mac.c drivers/net/ethernet/freescale/fs_enet/fs_enet-main.c drivers/net/ethernet/freescale/dpaa/dpaa_eth.c drivers/net/ethernet/freescale/ucc_geth.c drivers/net/ethernet/freescale/enetc/enetc_pf_common.c drivers/net/ethernet/marvell/mvpp2/mvpp2_main.c drivers/net/ethernet/marvell/mvneta.c drivers/net/ethernet/marvell/prestera/prestera_main.c drivers/net/ethernet/mediatek/mtk_eth_soc.c drivers/net/ethernet/altera/altera_tse_main.c drivers/net/ethernet/wangxun/txgbe/txgbe_phy.c drivers/net/ethernet/meta/fbnic/fbnic_phylink.c drivers/net/ethernet/tehuti/tn40_phy.c drivers/net/ethernet/mscc/ocelot_net.c
Make the existing conditions dependent on the PHY device having a phydev->phy_link_change() implementation equal to the default phy_link_change() provided by phylib. Otherwise, we implicitly know that the phydev has the phylink-provided phylink_phy_change() callback, and when phylink is used, the PHY state machine always needs to be stopped/ started on the suspend/resume path. The code is structured as such that if phydev->phy_link_change() is absent, it is a matter of time until the kernel will crash - no need to further complicate the test.
Thus, for the situation where the PM is not managed by the MAC, we will make the MDIO bus PM ops treat identically the phylink-controlled PHYs with the phylib-controlled PHYs where an adjust_link() callback is supplied. In both cases, the MDIO bus PM ops should stop and restart the PHY state machine.
[1] https://lore.kernel.org/netdev/[email protected]/
---
--- drivers/net/phy/phy_device.c | 31 +++++++++++++++++++++++++++++-- 1 file changed, 29 insertions(+), 2 deletions(-)
drivers/net/phy/phy_device.c +29 -2
@@ -281,6 +281,33 @@ static void phy_link_change(struct phy_d phydev->mii_ts->link_state (phydev->mii_ts, phydev); } +/** +* phy_uses_state_machine - test whether consumer driver uses PAL state machine +* @phydev: the target PHY device structure +* +* Ultimately, this aims to indirectly determine whether the PHY is attached +* to a consumer which uses the state machine by calling phy_start() and +* phy_stop(). +* +* When the PHY driver consumer uses phylib, it must have previously called +* phy_connect_direct() or one of its derivatives, so that phy_prepare_link() +* has set up a hook for monitoring state changes. +* +* When the PHY driver is used by the MAC driver consumer through phylink (the +* only other provider of a phy_link_change() method), using the PHY state +* machine is not optional. +* +* Return: true if consumer calls phy_start() and phy_stop(), false otherwise. +*/ +static bool phy_uses_state_machine (struct phy_device *phydev) +{ +if (phydev->phy_link_change == phy_link_change) +return phydev->attached_dev && phydev->adjust_link; + +/* phydev->phy_link_change is implicitly phylink_phy_change() */ +return true; +} +static bool mdio_bus_phy_may_suspend (struct phy_device *phydev) {struct device_driver *drv = phydev->mdio.dev.driver;
@@ -341,7 +368,7 @@ static __maybe_unused int mdio_bus_phy_s* may call phy routines that try to grab the same lock, and that may * lead to a deadlock. */ -if (phydev->attached_dev && phydev->adjust_link) +if (phy_uses_state_machine (phydev))phy_stop_machine (phydev);if (!mdio_bus_phy_may_suspend (phydev))
@@ -395,7 +422,7 @@ no_resume: } } -if (phydev->attached_dev && phydev->adjust_link) +if (phy_uses_state_machine (phydev))phy_start_machine (phydev);return 0 ;
Greg Kroah-Hartman
maintainerPATCH 254/254 net: phy: fix phy_uses_state_machine()
In reply to Greg Kroah-Hartman6.6-stable review patch. If anyone has any objections, please let me know.
------------------
From: "Russell King (Oracle)" <[email protected]>
[ Upstream commit e0d1c55501d377163eb57feed863777ed1c973ad ]
The blamed commit changed the conditions which phylib uses to stop and start the state machine in the suspend and resume paths, and while improving it, has caused two issues.
The original code used this test:
phydev->attached_dev && phydev->adjust_link
and if true, the paths would handle the PHY state machine. This test evaluates true for normal drivers that are using phylib directly while the PHY is attached to the network device, but false in all other cases, which include the following cases:
- when the PHY has never been attached to a network device.
- when the PHY has been detached from a network device (as phy_detach() sets phydev->attached_dev to NULL, phy_disconnect() calls phy_detach() and additionally sets phydev->adjust_link NULL.)
- when phylink is using the driver (as phydev->adjust_link is NULL.)
Only the third case was incorrect, and the blamed commit attempted to fix this by changing this test to (simplified for brevity, see phy_uses_state_machine()):
phydev->phy_link_change == phy_link_change ? phydev->attached_dev && phydev->adjust_link : true
However, this also incorrectly evaluates true in the first two cases.
Fix the first case by ensuring that phy_uses_state_machine() returns false when phydev->phy_link_change is NULL.
Fix the second case by ensuring that phydev->phy_link_change is set to NULL when phy_detach() is called.
--- drivers/net/phy/phy_device.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-)
drivers/net/phy/phy_device.c +3 -2
@@ -304,8 +304,7 @@ static bool phy_uses_state_machine(strucif (phydev->phy_link_change == phy_link_change)return phydev->attached_dev && phydev->adjust_link; -/* phydev->phy_link_change is implicitly phylink_phy_change() */ -return true; +return !!phydev->phy_link_change; }static bool mdio_bus_phy_may_suspend (struct phy_device *phydev)
@@ -1853,6 +1852,8 @@ void phy_detach(struct phy_device *phyde phydev->attached_dev->phydev =NULL ; phydev->attached_dev =NULL ; } + + phydev->phy_link_change =NULL ; phydev->phylink =NULL ;if (!phydev->is_on_sfp_module)
# Librecast Test Results
020/020 [ OK ] liblcrq
010/010 [ OK ] libmld
120/120 [ OK ] liblibrecast
CPU/kernel: Linux auntie 6.6.122-rc1-g0ca0b0d44403 #1 SMP PREEMPT_DYNAMIC Wed Jan 28 18:18:18 -00 2026 x86_64 AMD Ryzen 9 9950X 16-Core Processor AuthenticAMD GNU/Linux
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 30 Jan 2026 14:53:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.122-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
On ARCH_BRCMSTB using 32-bit and 64-bit ARM kernels, build tested on BMIPS_GENERIC:
Signature · 1 line
Florian
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
test_progs, test_progs-no_alu32, test_progs-cpuv4, test_maps, test_verifier in BPF selftests all passes[1] on x86_64.
1: https://github.com/shunghsiyu/libbpf/actions/runs/21450963930/job/61779347519
Am 28.01.2026 um 16:19 schrieb Greg Kroah-Hartman:
Quoted 4 lines
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Builds, boots and works on my 2-socket Ivy Bridge Xeon E5-2697 v2 server. No dmesg oddities or regressions found.
Beste Grüße,
Peter Schneider
Signature · 8 lines
Climb the mountain not to plant your flag, but to embrace the challenge, enjoy the air and behold the view. Climb it so you can see the world, not so the world can see you. -- David McCullough Jr. OpenPGP: 0xA3828BD796CCE11A8CADE8866E3A92C92C3FF244 Download: https://www.peters-netzplatz.de/download/pschneider1968_pub.asc https://keys.mailvelope.com/pks/lookup?op=get&[email protected] https://keys.mailvelope.com/pks/lookup?op=get&[email protected]
Quoted 8 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 30 Jan 2026 14:53:02 +0000. Anything received after that time might be too late.
6.6.122-rc1 built and run on my x86_64 test system (AMD Ryzen 9 9900X, System76 thelio-mira-r4-n3). No errors or regressions.
Thanks,
Slade
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Compiled and tested on
- Verdin iMX8MM
- Colibri iMX6
- Apalis iMX6
- Colibri iMX6ULL
- Colibri iMX7
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 30 Jan 2026 14:53:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.122-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
All tests passing for Tegra ...
Test results for stable-v6.6:
10 builds: 10 pass, 0 fail
28 boots: 28 pass, 0 fail
133 tests: 133 pass, 0 failLinux version: 6.6.122-rc1-g0ca0b0d44403
Boards tested: tegra124-jetson-tk1, tegra186-p2771-0000,
tegra186-p3509-0000+p3636-0001, tegra194-p2972-0000,
tegra194-p3509-0000+p3668-0000, tegra20-ventana,
tegra210-p2371-2180, tegra210-p3450-0000,
tegra30-cardhu-a04Jon
Quoted 9 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 30 Jan 2026 14:53:02 +0000. Anything received after that time might be too late.
The whole patch series can be found in one patch at:
Quoted 8 lines
https://www.kernel.org/pub/linux/kernel/v6.x/stable-review/patch-6.6.122-rc1.gzor in the git tree and branch at:
git://git.kernel.org/pub/scm/linux/kernel/git/stable/linux-stable-rc.gitlinux-6.6.y
and the diffstat can be found below.thanks,
greg k-h
Built and booted successfully on RISC-V RV64 (HiFive Unmatched).
Quoted 4 lines · Greg Kroah-Hartman
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Quoted 8 lines · On Wed, 28 Jan 2026 16:19:36 +0100 Greg Kroah-Hartman…
This is the start of the stable review cycle for the 6.6.122 release. There are 254 patches in this series, all will be posted as a response to this one. If anyone has any issues with these being applied, please let me know.
Responses should be made by Fri, 30 Jan 2026 14:53:02 +0000. Anything received after that time might be too late.
Boot-tested under QEMU for Rust x86_64:
Thanks!
Cheers,
Miguel