6.19.12-rc1 review
Subsystems (5)
Greg Kroah-Hartman
maintainerPATCH 123/311 eth: fbnic: Increase FBNIC_QUEUE_SIZE_MIN to 64
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dimitri Daskalakis <[email protected]>
[ Upstream commit ec7067e661193403a7a00980bda8612db5954142 ]
On systems with 64K pages, RX queues will be wedged if users set the descriptor count to the current minimum (16). Fbnic fragments large pages into 4K chunks, and scales down the ring size accordingly. With 64K pages and 16 descriptors, the ring size mask is 0 and will never be filled.
32 descriptors is another special case that wedges the RX rings. Internally, the rings track pages for the head/tail pointers, not page fragments. So with 32 descriptors, there's only 1 usable page as one ring slot is kept empty to disambiguate between an empty/full ring. As a result, the head pointer never advances and the HW stalls after consuming 16 page fragments.
--- drivers/net/ethernet/meta/fbnic/fbnic_txrx.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/meta/fbnic/fbnic_txrx.h +1 -1
@@ -38,7 +38,7 @@ struct fbnic_net;#define FBNIC_MAX_XDPQS 128u/* These apply to TWQs, TCQ, RCQ */ -#define FBNIC_QUEUE_SIZE_MIN 16u +#define FBNIC_QUEUE_SIZE_MIN 64u#define FBNIC_QUEUE_SIZE_MAX SZ_64K#define FBNIC_TXQ_SIZE_DEFAULT 1024
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 124/311 bpf: reject direct access to nullable PTR_TO_BUF pointers
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Tang <[email protected]>
[ Upstream commit b0db1accbc7395657c2b79db59fa9fae0d6656f3 ]
check_mem_access() matches PTR_TO_BUF via base_type() which strips PTR_MAYBE_NULL, allowing direct dereference without a null check.
Map iterator ctx->key and ctx->value are PTR_TO_BUF | PTR_MAYBE_NULL. On stop callbacks these are NULL, causing a kernel NULL dereference.
Add a type_may_be_null() guard to the PTR_TO_BUF branch, matching the existing PTR_TO_BTF_ID pattern.
--- kernel/bpf/verifier.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
kernel/bpf/verifier.c +2 -1
@@ -7806,7 +7806,8 @@ static int check_mem_access(struct bpf_verifier_env *env, int insn_idx, u32 regn }else if (reg->type ==CONST_PTR_TO_MAP ) { err =check_ptr_to_map_access (env, regs, regno, off, size, t, value_regno); - }else if (base_type (reg->type) ==PTR_TO_BUF ) { + }else if (base_type (reg->type) ==PTR_TO_BUF && + !type_may_be_null (reg->type)) {bool rdonly_mem =type_is_rdonly_mem (reg->type);u32 *max_access;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 125/311 bpf: Reject sleepable kprobe_multi programs at attach time
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Varun R Mallya <[email protected]>
[ Upstream commit eb7024bfcc5f68ed11ed9dd4891a3073c15f04a8 ]
kprobe.multi programs run in atomic/RCU context and cannot sleep. However, bpf_kprobe_multi_link_attach() did not validate whether the program being attached had the sleepable flag set, allowing sleepable helpers such as bpf_copy_from_user() to be invoked from a non-sleepable context.
This causes a "sleeping function called from invalid context" splat:
BUG: sleeping function called from invalid context at ./include/linux/uaccess.h:169 in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1787, name: sudo preempt_count: 1, expected: 0 RCU nest depth: 2, expected: 0
Fix this by rejecting sleepable programs early in bpf_kprobe_multi_link_attach(), before any further processing.
--- kernel/trace/bpf_trace.c | 4 ++++ 1 file changed, 4 insertions(+)
kernel/trace/bpf_trace.c +4 -0
@@ -2739,6 +2739,10 @@ int bpf_kprobe_multi_link_attach(const union bpf_attr *attr, struct bpf_prog *prif (!is_kprobe_multi (prog))return -EINVAL ; +/* kprobe_multi is not allowed to be sleepable. */ +if (prog->sleepable) +return -EINVAL ; +/* Writing to context is not allowed for kprobes. */ if (prog->aux->kprobe_write_ctx)return -EINVAL ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 126/311 bpf: Fix incorrect pruning due to atomic fetch precision tracking
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniel Borkmann <[email protected]>
[ Upstream commit 179ee84a89114b854ac2dd1d293633a7f6c8dac1 ]
When backtrack_insn encounters a BPF_STX instruction with BPF_ATOMIC and BPF_FETCH, the src register (or r0 for BPF_CMPXCHG) also acts as a destination, thus receiving the old value from the memory location.
The current backtracking logic does not account for this. It treats atomic fetch operations the same as regular stores where the src register is only an input. This leads the backtrack_insn to fail to propagate precision to the stack location, which is then not marked as precise!
Later, the verifier's path pruning can incorrectly consider two states equivalent when they differ in terms of stack state. Meaning, two branches can be treated as equivalent and thus get pruned when they should not be seen as such.
Fix it as follows: Extend the BPF_LDX handling in backtrack_insn to also cover atomic fetch operations via is_atomic_fetch_insn() helper. When the fetch dst register is being tracked for precision, clear it, and propagate precision over to the stack slot. For non-stack memory, the precision walk stops at the atomic instruction, same as regular BPF_LDX. This covers all fetch variants.
Before:
0: (b7) r1 = 8 ; R1=8 1: (7b) *(u64 *)(r10 -8) = r1 ; R1=8 R10=fp0 fp-8=8 2: (b7) r2 = 0 ; R2=0
3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2) ; R2=8 R10=fp0 fp-8=mmmmmmmm
4: (bf) r3 = r10 ; R3=fp0 R10=fp0
5: (0f) r3 += r2
mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r2 stack= before 4: (bf) r3 = r10
mark_precise: frame0: regs=r2 stack= before 3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2)
mark_precise: frame0: regs=r2 stack= before 2: (b7) r2 = 0
6: R2=8 R3=fp8
6: (b7) r0 = 0 ; R0=0
7: (95) exit
After:
0: (b7) r1 = 8 ; R1=8 1: (7b) *(u64 *)(r10 -8) = r1 ; R1=8 R10=fp0 fp-8=8 2: (b7) r2 = 0 ; R2=0
3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2) ; R2=8 R10=fp0 fp-8=mmmmmmmm
4: (bf) r3 = r10 ; R3=fp0 R10=fp0
5: (0f) r3 += r2
mark_precise: frame0: last_idx 5 first_idx 0 subseq_idx -1
mark_precise: frame0: regs=r2 stack= before 4: (bf) r3 = r10
mark_precise: frame0: regs=r2 stack= before 3: (db) r2 = atomic64_fetch_add((u64 *)(r10 -8), r2)
mark_precise: frame0: regs= stack=-8 before 2: (b7) r2 = 0
mark_precise: frame0: regs= stack=-8 before 1: (7b) *(u64 *)(r10 -8) = r1
mark_precise: frame0: regs=r1 stack= before 0: (b7) r1 = 8
6: R2=8 R3=fp8
6: (b7) r0 = 0 ; R0=0
7: (95) exit
--- kernel/bpf/verifier.c | 27 ++++++++++++++++++++++++--- 1 file changed, 24 insertions(+), 3 deletions(-)
kernel/bpf/verifier.c +24 -3
@@ -608,6 +608,13 @@ static bool is_atomic_load_insn(const struct bpf_insn *insn) insn->imm ==BPF_LOAD_ACQ ; } +static bool is_atomic_fetch_insn (const struct bpf_insn *insn) +{ +return BPF_CLASS (insn->code) ==BPF_STX && +BPF_MODE (insn->code) ==BPF_ATOMIC && + (insn->imm &BPF_FETCH ); +} +static int __get_spi (s32 off) {return (-off -1 ) /BPF_REG_SIZE ;
@@ -4356,10 +4363,24 @@ static int backtrack_insn(struct bpf_verifier_env *env, int idx, int subseq_idx,* dreg still needs precision before this insn */ } - }else if (class ==BPF_LDX ||is_atomic_load_insn (insn)) { -if (!bt_is_reg_set (bt, dreg)) + }else if (class ==BPF_LDX || +is_atomic_load_insn (insn) || +is_atomic_fetch_insn (insn)) { +u32 load_reg = dreg; + +/* +* Atomic fetch operation writes the old value into +* a register (sreg or r0) and if it was tracked for +* precision, propagate to the stack slot like we do +* in regular ldx. +*/ +if (is_atomic_fetch_insn (insn)) + load_reg = insn->imm ==BPF_CMPXCHG ? +BPF_REG_0 : sreg; + +if (!bt_is_reg_set (bt, load_reg))return 0 ; -bt_clear_reg (bt, dreg); +bt_clear_reg (bt, load_reg);/* scalars can only be spilled into stack w/o losing precision. * Load from any other memory can be zero extended.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 127/311 Revert "drm: Fix use-after-free on framebuffers and property blobs when calling drm_dev_unplug"
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maarten Lankhorst <[email protected]>
commit 45ebe43ea00d6b9f5b3e0db9c35b8ca2a96b7e70 upstream.
This reverts commit 6bee098b91417654703e17eb5c1822c6dfd0c01d.
Den 2026-03-25 kl. 22:11, skrev Simona Vetter:
Quoted 96 lines · Guenter Roeck
Quoted 8 lines
Hi,
Quoted 5 lines · Maarten Lankhorst
When trying to do a rather aggressive test of igt's "
xe_module_load--r reload" with a full desktop environment and game running I noticed a few OOPSes when dereferencing freed pointers, related to framebuffers and property blobs after the compositor exits.Quoted 7 lines
Quoted 4 lines
Solve this by guarding the freeing in
drm_filewith drm_dev_enter/exit, and immediately put the references from structdrm_fileobjects duringdrm_dev_unplug().With this patch in v6.18.20, I get the warning backtraces below. The backtraces are gone with the patch reverted.
Yeah, this needs to be reverted, reasoning below. Maarten, can you please take care of that and feed the revert through the usual channels? I don't think it's critical enough that we need to fast-track this into drm.git directly.
Quoting the patch here again:
Quoted 17 lines
drivers/gpu/drm/drm_file.c | 5 ++++- drivers/gpu/drm/drm_mode_config.c | 9 ++++++--- 2 files changed, 10 insertions(+), 4 deletions(-)drivers/gpu/drm/drm_file.c +1
-0@@ -233,6 +233,7 @@ static void drm_events_release(struct drm_file *file_priv)void drm_file_free (struct drm_file *file) {struct drm_device *dev; +int idx;if (!file)return ;drivers/gpu/drm/drm_file.c void drm_file_free(struct drm_file *file) · line 254
Quoted 6 lines
drivers/gpu/drm/drm_file.c +2
-1@@ -249,9 +250,11 @@ void drm_file_free(struct drm_file *file)drm_events_release (file); -if (drm_core_check_feature (dev,DRIVER_MODESET )) { +if (drm_core_check_feature (dev,DRIVER_MODESET ) && +drm_dev_enter (dev, &idx)) {This is misplaced for two reasons:
- Even if we'd want to guarantee that we hold a drm_dev_enter/exit reference during framebuffer teardown, we'd need to do this
_consistentlyover all callsites. Not ad-hoc in just one place that a testcase hits. This also means kerneldoc updates of the relevant hooks and at least a bunch of acks from other driver people to document the consensus.- More importantly, this is driver responsibilities in general unless we have extremely good reasons to the contrary. Which means this must be placed in xe.
Quoted 11 lines
drivers/gpu/drm/drm_file.c +1
-0drm_fb_release (file);drm_property_destroy_user_blobs (dev, file); +drm_dev_exit (idx); }if (drm_core_check_feature (dev,DRIVER_SYNCOBJ ))drivers/gpu/drm/drm_mode_config.c +0
-0drivers/gpu/drm/drm_mode_config.c void drm_mode_config_cleanup(struct drm_device *dev) · line 587
Quoted 6 lines
drivers/gpu/drm/drm_mode_config.c +2
-1@@ -583,10 +583,13 @@ void drm_mode_config_cleanup(struct drm_device *dev)*/ WARN_ON (!list_empty (&dev->mode_config.fb_list));list_for_each_entry_safe (fb, fbt, &dev->mode_config.fb_list, head) { -struct drm_printer p =drm_dbg_printer (dev,DRM_UT_KMS ,"[leaked fb]" ); +if (list_empty (&fb->filp_head) ||drm_framebuffer_read_refcount (fb) >1 ) { +struct drm_printer p =drm_dbg_printer (dev,DRM_UT_KMS ,"[leaked fb]" );This is also wrong:
- Firstly, it's a completely independent bug, we do not smash two bugfixes into one patch.
- Secondly, it's again a driver bug:
drm_mode_cleanupmust be called when the lastdrm_devicereference disappears (hence the existence ofdrmm_mode_config_init), not when the driver gets unbound. The fact that this shows up in a callchain from a devres cleanup means the intel driver gets this wrong (like almost everyone else because historically we didn't know better).If we don't follow this rule, then we get races with this code here running concurrently with
drm_filefb cleanups, which just does not work. Review pointed that out, but then shrugged it off with a confused explanation:
Quoted 6 lines
https://lore.kernel.org/all/[email protected]/
Yes this also means a lot of the other
drm_deviceteardown that drivers do happens way too early. There is a massive can of worms here of a magnitude that most likely is much, much bigger than what you can backport to stable kernels. Hotunplug is _hard_.
Back to the drawing board, and fixing it in the intel display driver instead.
--- drivers/gpu/drm/drm_file.c | 5 +---- drivers/gpu/drm/drm_mode_config.c | 9 +++------ 2 files changed, 4 insertions(+), 10 deletions(-)
drivers/gpu/drm/drm_file.c +1 -4
@@ -233,7 +233,6 @@ static void drm_events_release(struct drvoid drm_file_free (struct drm_file *file) {struct drm_device *dev; -int idx;if (!file)return ;
@@ -250,11 +249,9 @@ void drm_file_free(struct drm_file *filedrm_events_release (file); -if (drm_core_check_feature (dev,DRIVER_MODESET ) && -drm_dev_enter (dev, &idx)) { +if (drm_core_check_feature (dev,DRIVER_MODESET )) {drm_fb_release (file);drm_property_destroy_user_blobs (dev, file); -drm_dev_exit (idx); }if (drm_core_check_feature (dev,DRIVER_SYNCOBJ ))
drivers/gpu/drm/drm_mode_config.c +3 -6
@@ -577,13 +577,10 @@ void drm_mode_config_cleanup(struct drm_*/ WARN_ON (!list_empty (&dev->mode_config.fb_list));list_for_each_entry_safe (fb, fbt, &dev->mode_config.fb_list, head) { -if (list_empty (&fb->filp_head) ||drm_framebuffer_read_refcount (fb) >1 ) { -struct drm_printer p =drm_dbg_printer (dev,DRM_UT_KMS ,"[leaked fb]" ); +struct drm_printer p =drm_dbg_printer (dev,DRM_UT_KMS ,"[leaked fb]" ); -drm_printf (&p,"framebuffer[%u]:\n" , fb->base.id); -drm_framebuffer_print_info (&p,1 , fb); - } -list_del_init (&fb->filp_head); +drm_printf (&p,"framebuffer[%u]:\n" , fb->base.id); +drm_framebuffer_print_info (&p,1 , fb);drm_framebuffer_free (&fb->base.refcount); }
Greg Kroah-Hartman
maintainerPATCH 128/311 iio: imu: bno055: fix BNO055_SCAN_CH_COUNT off by one
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit 773ef9f95385bae52dcb7fd129fefba3a71a04db ]
Fix an off-by-one error in the BNO055_SCAN_CH_COUNT macro. The count is derived by taking the difference of the last and first register addresses, dividing by the size of each channel (2 bytes). It needs to also add 1 to account for the fact that the count is inclusive of both the first and last channels.
Thanks to the aligned_s64 timestamp field, there was already extra padding in the buffer, so there were no runtime issues caused by this bug.
--- drivers/iio/imu/bno055/bno055.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/imu/bno055/bno055.c +1 -1
@@ -64,7 +64,7 @@#define BNO055_GRAVITY_DATA_X_LSB_REG 0x2E#define BNO055_GRAVITY_DATA_Y_LSB_REG 0x30#define BNO055_GRAVITY_DATA_Z_LSB_REG 0x32 -#define BNO055_SCAN_CH_COUNT ((BNO055_GRAVITY_DATA_Z_LSB_REG - BNO055_ACC_DATA_X_LSB_REG) / 2) +#define BNO055_SCAN_CH_COUNT ((BNO055_GRAVITY_DATA_Z_LSB_REG - BNO055_ACC_DATA_X_LSB_REG) / 2 + 1)#define BNO055_TEMP_REG 0x34#define BNO055_CALIB_STAT_REG 0x35#define BNO055_CALIB_STAT_MAGN_SHIFT 0
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 129/311 gpiolib: clear requested flag if line is invalid
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Barnabás Pőcze <[email protected]>
[ Upstream commit 6df6ea4b3d1567dbe6442f308735c23b63007c7f ]
If gpiochip_line_is_valid() fails, then -EINVAL is returned, but desc->flags will have GPIOD_FLAG_REQUESTED set, which will result in subsequent calls misleadingly returning -EBUSY.
Fix that by clearing the flag in case of failure.
--- drivers/gpio/gpiolib.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/gpio/gpiolib.c +4 -2
@@ -2466,8 +2466,10 @@ int gpiod_request_commit(struct gpio_desc *desc, const char *label)return -EBUSY ; offset =gpiod_hwgpio (desc); -if (!gpiochip_line_is_valid (guard.gc, offset)) -return -EINVAL ; +if (!gpiochip_line_is_valid (guard.gc, offset)) { + ret = -EINVAL ; + goto out_clear_bit; + }/* NOTE: gpio_request() can be called in early boot, * before IRQs are enabled, for non-sleeping (SOC) GPIOs.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 130/311 interconnect: qcom: sm8450: Fix NULL pointer dereference in icc_link_nodes()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Vladimir Zapolskiy <[email protected]>
[ Upstream commit dbbd550d7c8d90d3af9fe8a12a9caff077ddb8e3 ]
The change to dynamic IDs for SM8450 platform interconnects left two links unconverted, fix it to avoid the NULL pointer dereference in runtime, when a pointer to a destination interconnect is not valid:
Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
<...>
Call trace:
icc_link_nodes+0x3c/0x100 (P)
qcom_icc_rpmh_probe+0x1b4/0x528
platform_probe+0x64/0xc0
really_probe+0xc4/0x2a8
__driver_probe_device+0x80/0x140
driver_probe_device+0x48/0x170
__device_attach_driver+0xc0/0x148
bus_for_each_drv+0x88/0xf0
__device_attach+0xb0/0x1c0
device_initial_probe+0x58/0x68
bus_probe_device+0x40/0xb8
deferred_probe_work_func+0x90/0xd0
process_one_work+0x15c/0x3c0
worker_thread+0x2e8/0x400
kthread+0x150/0x208
ret_from_fork+0x10/0x20
Code: 900310f4 911d6294 91008280 94176078 (f94002a0)
---[ end trace 0000000000000000 ]---
Kernel panic - not syncing: Oops: Fatal exception--- drivers/interconnect/qcom/sm8450.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/interconnect/qcom/sm8450.c +2 -2
@@ -800,7 +800,7 @@ static struct qcom_icc_node qhs_compute_cfg = { .channels = 1, .buswidth = 4, .num_links = 1, - .link_nodes = { MASTER_CDSP_NOC_CFG }, + .link_nodes = { &qhm_nsp_noc_config }, }; static struct qcom_icc_node qhs_cpr_cx = {
@@ -874,7 +874,7 @@ static struct qcom_icc_node qhs_lpass_cfg = { .channels = 1, .buswidth = 4, .num_links = 1, - .link_nodes = { MASTER_CNOC_LPASS_AG_NOC }, + .link_nodes = { &qhm_config_noc }, }; static struct qcom_icc_node qhs_mss_cfg = {
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 131/311 gpio: shared: call gpio_chip::of_xlate() if set
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit 710abda58055ed5eaa8958107633cc12a365c328 ]
OF-based GPIO controller drivers may provide a translation function that calculates the real chip offset from whatever devicetree sources provide. We need to take this into account in the shared GPIO management and call of_xlate() if it's provided and adjust the entry->offset we initially set when scanning the tree.
To that end: modify the shared GPIO API to take the GPIO chip as argument on setup (to avoid having to rcu_dereference() it from the GPIO device) and protect the access to entry->offset with the existing lock.
--- drivers/gpio/gpiolib-shared.c | 27 ++++++++++++++++++++++++++- drivers/gpio/gpiolib-shared.h | 4 ++-- drivers/gpio/gpiolib.c | 2 +- 3 files changed, 29 insertions(+), 4 deletions(-)
drivers/gpio/gpiolib-shared.c +26 -1
@@ -511,8 +511,9 @@ static void gpio_shared_remove_adev(struct auxiliary_device *adev)auxiliary_device_uninit (adev); } -int gpio_device_setup_shared (struct gpio_device *gdev) +int gpiochip_setup_shared (struct gpio_chip *gc) { +struct gpio_device *gdev = gc->gpiodev;struct gpio_shared_entry *entry;struct gpio_shared_ref *ref;struct gpio_desc *desc;
@@ -537,12 +538,34 @@ int gpio_device_setup_shared(struct gpio_device *gdev)* exposing shared pins. Find them and create the proxy devices. */ list_for_each_entry (entry, &gpio_shared_list, list) { +guard (mutex)(&entry->lock); +if (!device_match_fwnode (&gdev->dev, entry->fwnode))continue ;if (list_count_nodes (&entry->refs) <=1 )continue ; +#if IS_ENABLED (CONFIG_OF ) +if (is_of_node (entry->fwnode) && gc->of_xlate) { +/* +* This is the earliest that we can tranlate the +* devicetree offset to the chip offset. +*/ +struct of_phandle_args gpiospec = { }; + + gpiospec.np =to_of_node (entry->fwnode); + gpiospec.args_count =2 ; + gpiospec.args[0 ] = entry->offset; + + ret = gc->of_xlate (gc, &gpiospec,NULL ); +if (ret <0 ) +return ret; + + entry->offset = ret; + } +#endif /* CONFIG_OF */ + desc = &gdev->descs[entry->offset];__set_bit (GPIOD_FLAG_SHARED , &desc->flags);
@@ -580,6 +603,8 @@ void gpio_device_teardown_shared(struct gpio_device *gdev)struct gpio_shared_ref *ref;list_for_each_entry (entry, &gpio_shared_list, list) { +guard (mutex)(&entry->lock); +if (!device_match_fwnode (&gdev->dev, entry->fwnode))continue ;
drivers/gpio/gpiolib-shared.h +2 -2
@@ -14,14 +14,14 @@ struct device;#if IS_ENABLED (CONFIG_GPIO_SHARED ) -int gpio_device_setup_shared (struct gpio_device *gdev); +int gpiochip_setup_shared (struct gpio_chip *gc);void gpio_device_teardown_shared (struct gpio_device *gdev);int gpio_shared_add_proxy_lookup (struct device *consumer,const char *con_id,unsigned long lflags);#else -static inline int gpio_device_setup_shared (struct gpio_device *gdev) +static inline int gpiochip_setup_shared (struct gpio_chip *gc) {return 0 ; }
drivers/gpio/gpiolib.c +1 -1
@@ -1211,7 +1211,7 @@ int gpiochip_add_data_with_key(struct gpio_chip *gc, void *data,if (ret) goto err_remove_irqchip_mask; - ret =gpio_device_setup_shared (gdev); + ret =gpiochip_setup_shared (gc);if (ret) goto err_remove_irqchip;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 132/311 gpio: shared: handle pins shared by child nodes of devices
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit ec42a3a90ae9ae64b16d01a2e5d32ec0865ca8cf ]
Shared GPIOs may be assigned to child nodes of device nodes which don't themselves bind to any struct device. We need to pass the firmware node that is the actual consumer to gpiolib-shared and compare against it instead of unconditionally using the fwnode of the consumer device.
--- drivers/gpio/gpiolib-shared.c | 6 +++--- drivers/gpio/gpiolib-shared.h | 7 +++++-- drivers/gpio/gpiolib.c | 4 ++-- 3 files changed, 10 insertions(+), 7 deletions(-)
drivers/gpio/gpiolib-shared.c +3 -3
@@ -443,8 +443,8 @@ static bool gpio_shared_dev_is_reset_gpio(struct device *consumer, }#endif /* CONFIG_RESET_GPIO */ -int gpio_shared_add_proxy_lookup (struct device *consumer,const char *con_id, -unsigned long lflags) +int gpio_shared_add_proxy_lookup (struct device *consumer,struct fwnode_handle *fwnode, +const char *con_id,unsigned long lflags) {const char *dev_id =dev_name (consumer);struct gpiod_lookup_table *lookup;
@@ -463,7 +463,7 @@ int gpio_shared_add_proxy_lookup(struct device *consumer, const char *con_id,if (!ref->fwnode &&strstarts (dev_name (consumer),"reset.gpio." )) {if (!gpio_shared_dev_is_reset_gpio (consumer, entry, ref))continue ; - }else if (!device_match_fwnode (consumer, ref->fwnode)) { + }else if (fwnode != ref->fwnode) {continue ; }
drivers/gpio/gpiolib-shared.h +5 -2
@@ -11,13 +11,15 @@struct gpio_device ;struct gpio_desc ;struct device ; +struct fwnode_handle ;#if IS_ENABLED (CONFIG_GPIO_SHARED )int gpiochip_setup_shared (struct gpio_chip *gc);void gpio_device_teardown_shared (struct gpio_device *gdev); -int gpio_shared_add_proxy_lookup (struct device *consumer,const char *con_id, -unsigned long lflags); +int gpio_shared_add_proxy_lookup (struct device *consumer, +struct fwnode_handle *fwnode, +const char *con_id,unsigned long lflags);#else
@@ -29,6 +31,7 @@ static inline int gpiochip_setup_shared(struct gpio_chip *gc)static inline void gpio_device_teardown_shared (struct gpio_device *gdev) { }static inline int gpio_shared_add_proxy_lookup (struct device *consumer, +struct fwnode_handle *fwnode,const char *con_id,unsigned long lflags) {
drivers/gpio/gpiolib.c +2 -2
@@ -4720,8 +4720,8 @@ struct gpio_desc *gpiod_find_and_request(struct device *consumer,* lookup table for the proxy device as previously * we only knew the consumer's fwnode. */ - ret =gpio_shared_add_proxy_lookup (consumer, con_id, - lookupflags); + ret =gpio_shared_add_proxy_lookup (consumer, fwnode, + con_id, lookupflags);if (ret)return ERR_PTR (ret);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 133/311 gpio: qixis-fpga: Fix error handling for devm_regmap_init_mmio()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 8de4e0f44c638c66cdc5eeb4d5ab9acd61c31e4f ]
devm_regmap_init_mmio() returns an ERR_PTR() on failure, not NULL. The original code checked for NULL which would never trigger on error, potentially leading to an invalid pointer dereference.
Use IS_ERR() and PTR_ERR() to properly handle the error case.
--- drivers/gpio/gpio-qixis-fpga.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpio/gpio-qixis-fpga.c +2 -2
@@ -60,8 +60,8 @@ static int qixis_cpld_gpio_probe(struct platform_device *pdev)return PTR_ERR (reg); regmap =devm_regmap_init_mmio (&pdev->dev, reg, ®map_config_8r_8v); -if (!regmap) -return -ENODEV ; +if (IS_ERR (regmap)) +return PTR_ERR (regmap);/* In this case, the offset of our register is 0 inside the * regmap area that we just created.
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 134/311 drm/bridge: Fix refcount shown via debugfs for encoder_bridges_show()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liu Ying <[email protected]>
[ Upstream commit f078634c184a9b5ccaa056e8b8d6cd32f7bff1b6 ]
A typical bridge refcount value is 3 after a bridge chain is formed:
- devm_drm_bridge_alloc() initializes the refcount value to be 1.
- drm_bridge_add() gets an additional reference hence 2.
- drm_bridge_attach() gets the third reference hence 3.
This typical refcount value aligns with allbridges_show()'s behaviour. However, since encoder_bridges_show() uses drm_for_each_bridge_in_chain_scoped() to automatically get/put the bridge reference while iterating, a bogus reference is accidentally got when showing the wrong typical refcount value as 4 to users via debugfs. Fix this by caching the refcount value returned from kref_read() while iterating and explicitly decreasing the cached refcount value by 1 before showing it to users.
--- drivers/gpu/drm/drm_bridge.c | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-)
drivers/gpu/drm/drm_bridge.c +11 -5
@@ -1465,11 +1465,17 @@ EXPORT_SYMBOL(devm_drm_put_bridge);static void drm_bridge_debugfs_show_bridge (struct drm_printer *p,struct drm_bridge *bridge,unsigned int idx, -bool lingering) +bool lingering, +bool scoped) { +unsigned int refcount =kref_read (&bridge->refcount); + +if (scoped) + refcount--; +drm_printf (p,"bridge[%u]: %ps\n" , idx, bridge->funcs); -drm_printf (p,"\trefcount: %u%s\n" ,kref_read (&bridge->refcount), +drm_printf (p,"\trefcount: %u%s\n" , refcount, lingering ?" [lingering]" :"" ); drm_printf(p, "\ttype: [%d] %s\n",
@@ -1503,10 +1509,10 @@ static int allbridges_show(struct seq_file *m, void *data)mutex_lock (&bridge_lock);list_for_each_entry (bridge, &bridge_list, list) -drm_bridge_debugfs_show_bridge (&p, bridge, idx++, false); +drm_bridge_debugfs_show_bridge (&p, bridge, idx++, false, false);list_for_each_entry (bridge, &bridge_lingering_list, list) -drm_bridge_debugfs_show_bridge (&p, bridge, idx++, true); +drm_bridge_debugfs_show_bridge (&p, bridge, idx++, true, false);mutex_unlock (&bridge_lock);
@@ -1521,7 +1527,7 @@ static int encoder_bridges_show(struct seq_file *m, void *data)unsigned int idx =0 ;drm_for_each_bridge_in_chain_scoped (encoder, bridge) -drm_bridge_debugfs_show_bridge (&p, bridge, idx++, false); +drm_bridge_debugfs_show_bridge (&p, bridge, idx++, false, true);return 0 ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 135/311 accel/qaic: Handle DBC deactivation if the owner went away
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Youssef Samir <[email protected]>
[ Upstream commit 2feec5ae5df785658924ab6bd91280dc3926507c ]
When a DBC is released, the device sends a QAIC_TRANS_DEACTIVATE_FROM_DEV transaction to the host over the QAIC_CONTROL MHI channel. QAIC handles this by calling decode_deactivate() to release the resources allocated for that DBC. Since that handling is done in the qaic_manage_ioctl() context, if the user goes away before receiving and handling the deactivation, the host will be out-of-sync with the DBCs available for use, and the DBC resources will not be freed unless the device is removed. If another user loads and requests to activate a network, then the device assigns the same DBC to that network, QAIC will "indefinitely" wait for dbc->in_use = false, leading the user process to hang.
As a solution to this, handle QAIC_TRANS_DEACTIVATE_FROM_DEV transactions that are received after the user has gone away.
--- drivers/accel/qaic/qaic_control.c | 47 +++++++++++++++++++++++++++++-- 1 file changed, 45 insertions(+), 2 deletions(-)
drivers/accel/qaic/qaic_control.c +45 -2
@@ -913,7 +913,7 @@ static int decode_deactivate(struct qaic_device *qdev, void *trans, u32 *msg_len*/ return -ENODEV ; -if (status) { +if (usr && status) {/* * Releasing resources failed on the device side, which puts * us in a bind since they may still be in use, so enable the
@@ -1108,6 +1108,9 @@ static void *msg_xfer(struct qaic_device *qdev, struct wrapper_list *wrappers, umutex_lock (&qdev->cntl_mutex);if (!list_empty (&elem.list))list_del (&elem.list); +/* resp_worker() processed the response but the wait was interrupted */ +else if (ret == -ERESTARTSYS ) + ret =0 ;if (!ret && !elem.buf) ret = -ETIMEDOUT ;else if (ret >0 && !elem.buf)
@@ -1418,9 +1421,49 @@ static void resp_worker(struct work_struct *work) }mutex_unlock (&qdev->cntl_mutex); -if (!found) +if (!found) { +/* +* The user might have gone away at this point without waiting +* for QAIC_TRANS_DEACTIVATE_FROM_DEV transaction coming from +* the device. If this is not handled correctly, the host will +* not know that the DBC[n] has been freed on the device. +* Due to this failure in synchronization between the device and +* the host, if another user requests to activate a network, and +* the device assigns DBC[n] again, save_dbc_buf() will hang, +* waiting for dbc[n]->in_use to be set to false, which will not +* happen unless the qaic_dev_reset_clean_local_state() gets +* called by resetting the device (or re-inserting the module). +* +* As a solution, we look for QAIC_TRANS_DEACTIVATE_FROM_DEV +* transactions in the message before disposing of it, then +* handle releasing the DBC resources. +* +* Since the user has gone away, if the device could not +* deactivate the network (status != 0), there is no way to +* enable and reassign the DBC to the user. We can put trust in +* the device that it will release all the active DBCs in +* response to the QAIC_TRANS_TERMINATE_TO_DEV transaction, +* otherwise, the user can issue an soc_reset to the device. +*/ +u32 msg_count =le32_to_cpu (msg->hdr.count); +u32 msg_len =le32_to_cpu (msg->hdr.len); +u32 len =0 ; +int j; + +for (j =0 ; j < msg_count && len < msg_len; ++j) { +struct wire_trans_hdr *trans_hdr; + + trans_hdr = (struct wire_trans_hdr *)(msg->data + len); +if (le32_to_cpu (trans_hdr->type) ==QAIC_TRANS_DEACTIVATE_FROM_DEV ) { +if (decode_deactivate (qdev, trans_hdr, &len,NULL )) + len +=le32_to_cpu (trans_hdr->len); + }else { + len +=le32_to_cpu (trans_hdr->len); + } + }/* request must have timed out, drop packet */ kfree (msg); + }kfree (resp); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 136/311 io_uring/rsrc: reject zero-length fixed buffer import
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qi Tang <[email protected]>
[ Upstream commit 111a12b422a8cfa93deabaef26fec48237163214 ]
validate_fixed_range() admits buf_addr at the exact end of the registered region when len is zero, because the check uses strict greater-than (buf_end > imu->ubuf + imu->len). io_import_fixed() then computes offset == imu->len, which causes the bvec skip logic to advance past the last bio_vec entry and read bv_offset from out-of-bounds slab memory.
Return early from io_import_fixed() when len is zero. A zero-length import has no data to transfer and should not walk the bvec array at all.
BUG: KASAN: slab-out-of-bounds in io_import_reg_buf+0x697/0x7f0 Read of size 4 at addr ffff888002bcc254 by task poc/103 Call Trace: io_import_reg_buf+0x697/0x7f0 io_write_fixed+0xd9/0x250 __io_issue_sqe+0xad/0x710 io_issue_sqe+0x7d/0x1100 io_submit_sqes+0x86a/0x23c0 __do_sys_io_uring_enter+0xa98/0x1590 Allocated by task 103: The buggy address is located 12 bytes to the right of allocated 584-byte region [ffff888002bcc000, ffff888002bcc248)
--- io_uring/rsrc.c | 4 ++++ 1 file changed, 4 insertions(+)
io_uring/rsrc.c +4 -0
@@ -1084,6 +1084,10 @@ static int io_import_fixed(int ddir, struct iov_iter *iter,return ret;if (!(imu->dir & (1 << ddir)))return -EFAULT ; +if (unlikely (!len)) { +iov_iter_bvec (iter, ddir,NULL ,0 ,0 ); +return 0 ; + } offset = buf_addr - imu->ubuf;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 137/311 hwmon: (tps53679) Fix array access with zero-length block read
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
[ Upstream commit 0e211f6aaa6a00fd0ee0c1eea5498f168c6725e6 ]
i2c_smbus_read_block_data() can return 0, indicating a zero-length read. When this happens, tps53679_identify_chip() accesses buf[ret - 1] which is buf[-1], reading one byte before the buffer on the stack.
Fix by changing the check from "ret < 0" to "ret <= 0", treating a zero-length read as an error (-EIO), which prevents the out-of-bounds array access.
Also fix a typo in the adjacent comment: "if present" instead of duplicate "if".
--- drivers/hwmon/pmbus/tps53679.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/hwmon/pmbus/tps53679.c +3 -3
@@ -103,10 +103,10 @@ static int tps53679_identify_chip(struct i2c_client *client, } ret =i2c_smbus_read_block_data (client,PMBUS_IC_DEVICE_ID , buf); -if (ret <0 ) -return ret; +if (ret <=0 ) +return ret <0 ? ret : -EIO ; -/* Adjust length if null terminator if present */ +/* Adjust length if null terminator is present */ buf_len = (buf[ret -1 ] !='\x00' ? ret : ret -1 ); id_len =strlen (id);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 138/311 hwmon: (pxe1610) Check return value of page-select write in probe
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
[ Upstream commit ccf70c41e562b29d1c05d1bbf53391785e09c6fb ]
pxe1610_probe() writes PMBUS_PAGE to select page 0 but does not check the return value. If the write fails, subsequent register reads operate on an indeterminate page, leading to silent misconfiguration.
Check the return value and propagate the error using dev_err_probe(), which also handles -EPROBE_DEFER correctly without log spam.
--- drivers/hwmon/pmbus/pxe1610.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/hwmon/pmbus/pxe1610.c +4 -1
@@ -104,7 +104,10 @@ static int pxe1610_probe(struct i2c_client *client)* By default this device doesn't boot to page 0, so set page 0 * to access all pmbus registers. */ -i2c_smbus_write_byte_data (client,PMBUS_PAGE ,0 ); + ret =i2c_smbus_write_byte_data (client,PMBUS_PAGE ,0 ); +if (ret <0 ) +return dev_err_probe (&client->dev, ret, +"Failed to set page 0\n" );/* Read Manufacturer id */ ret =i2c_smbus_read_block_data (client,PMBUS_MFR_ID , buf);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 139/311 hwmon: (ltc4286) Add missing MODULE_IMPORT_NS("PMBUS")
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
[ Upstream commit a9d2fbd3ad0e6ac588386e699beeccfe7516755f ]
ltc4286.c uses PMBus core symbols exported in the PMBUS namespace, such as pmbus_do_probe(), but does not declare MODULE_IMPORT_NS("PMBUS").
Add the missing namespace import to avoid modpost warnings.
--- drivers/hwmon/pmbus/ltc4286.c | 1 + 1 file changed, 1 insertion(+)
drivers/hwmon/pmbus/ltc4286.c +1 -0
@@ -173,3 +173,4 @@ module_i2c_driver(ltc4286_driver);MODULE_AUTHOR ("Delphine CC Chiu <[email protected]>" );MODULE_DESCRIPTION ("PMBUS driver for LTC4286 and compatibles" );MODULE_LICENSE ("GPL" ); +MODULE_IMPORT_NS ("PMBUS" );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 140/311 gpio: shared: shorten the critical section in gpiochip_setup_shared()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bartosz Golaszewski <[email protected]>
[ Upstream commit 310a4a9cbb17037668ea440f6a3964d00705b400 ]
Commit 710abda58055 ("gpio: shared: call gpio_chip::of_xlate() if set") introduced a critical section around the adjustmenet of entry->offset. However this may cause a deadlock if we create the auxiliary shared proxy devices with this lock taken. We only need to protect entry->offset while it's read/written so shorten the critical section and release the lock before creating the proxy device as the field in question is no longer accessed at this point.
--- drivers/gpio/gpiolib-shared.c | 56 +++++++++++++++++------------------ 1 file changed, 28 insertions(+), 28 deletions(-)
drivers/gpio/gpiolib-shared.c +28 -28
@@ -538,48 +538,48 @@ int gpiochip_setup_shared(struct gpio_chip *gc)* exposing shared pins. Find them and create the proxy devices. */ list_for_each_entry (entry, &gpio_shared_list, list) { -guard (mutex)(&entry->lock); -if (!device_match_fwnode (&gdev->dev, entry->fwnode))continue ;if (list_count_nodes (&entry->refs) <=1 )continue ; + scoped_guard(mutex, &entry->lock) {#if IS_ENABLED (CONFIG_OF ) -if (is_of_node (entry->fwnode) && gc->of_xlate) { -/* -* This is the earliest that we can tranlate the -* devicetree offset to the chip offset. -*/ -struct of_phandle_args gpiospec = { }; +if (is_of_node (entry->fwnode) && gc->of_xlate) { +/* +* This is the earliest that we can tranlate the +* devicetree offset to the chip offset. +*/ +struct of_phandle_args gpiospec = { }; - gpiospec.np =to_of_node (entry->fwnode); - gpiospec.args_count =2 ; - gpiospec.args[0 ] = entry->offset; + gpiospec.np =to_of_node (entry->fwnode); + gpiospec.args_count =2 ; + gpiospec.args[0 ] = entry->offset; - ret = gc->of_xlate (gc, &gpiospec,NULL ); -if (ret <0 ) -return ret; + ret = gc->of_xlate (gc, &gpiospec,NULL ); +if (ret <0 ) +return ret; - entry->offset = ret; - } + entry->offset = ret; + }#endif /* CONFIG_OF */ - desc = &gdev->descs[entry->offset]; + desc = &gdev->descs[entry->offset]; -__set_bit (GPIOD_FLAG_SHARED , &desc->flags); -/* -* Shared GPIOs are not requested via the normal path. Make -* them inaccessible to anyone even before we register the -* chip. -*/ - ret =gpiod_request_commit (desc,"shared" ); -if (ret) -return ret; +__set_bit (GPIOD_FLAG_SHARED , &desc->flags); +/* +* Shared GPIOs are not requested via the normal path. Make +* them inaccessible to anyone even before we register the +* chip. +*/ + ret =gpiod_request_commit (desc,"shared" ); +if (ret) +return ret; -pr_debug ("GPIO %u owned by %s is shared by multiple consumers\n" , - entry->offset,gpio_device_get_label (gdev)); +pr_debug ("GPIO %u owned by %s is shared by multiple consumers\n" , + entry->offset,gpio_device_get_label (gdev)); + }list_for_each_entry (ref, &entry->refs, list) { pr_debug("Setting up a shared GPIO entry for %s (con_id: '%s')\n",
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 141/311 dt-bindings: gpio: fix microchip #interrupt-cells
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jamie Gibbons <[email protected]>
[ Upstream commit 6b5ef8c88854b343b733b574ea8754c9dab61f41 ]
The GPIO controller on PolarFire SoC supports more than one type of interrupt and needs two interrupt cells.
--- .../devicetree/bindings/gpio/microchip,mpfs-gpio.yaml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
Documentation/devicetree/bindings/gpio/microchip,mpfs-gpio.yaml +2 -2
@@ -37,7 +37,7 @@ properties: const: 2 "#interrupt-cells": - const: 1 + const: 2 ngpios: description:
@@ -86,7 +86,7 @@ examples: gpio-controller; #gpio-cells = <2>; interrupt-controller; - #interrupt-cells = <1>; + #interrupt-cells = <2>; interrupts = <53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>, <53>,
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 142/311 spi: stm32-ospi: Fix resource leak in remove() callback
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 73cd1f97946ae3796544448ff12c07f399bb2881 ]
The remove() callback returned early if pm_runtime_resume_and_get() failed, skipping the cleanup of spi controller and other resources.
Remove the early return so cleanup completes regardless of PM resume result.
--- drivers/spi/spi-stm32-ospi.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
drivers/spi/spi-stm32-ospi.c +1 -4
@@ -963,11 +963,8 @@ static int stm32_ospi_probe(struct platform_device *pdev)static void stm32_ospi_remove (struct platform_device *pdev) {struct stm32_ospi *ospi =platform_get_drvdata (pdev); -int ret; - ret =pm_runtime_resume_and_get (ospi->dev); -if (ret <0 ) -return ; +pm_runtime_resume_and_get (ospi->dev);spi_unregister_controller (ospi->ctrl);/* Disable ospi */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 143/311 spi: stm32-ospi: Fix reset control leak on probe error
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit 5a570c8d6e55689253f6fcc4a198c56cca7e39d6 ]
When spi_register_controller() fails after reset_control_acquire() succeeds, the reset control is never released. This causes a resource leak in the error path.
Add the missing reset_control_release() call in the error path.
--- drivers/spi/spi-stm32-ospi.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/spi/spi-stm32-ospi.c +3 -1
@@ -939,13 +939,15 @@ static int stm32_ospi_probe(struct platform_device *pdev)if (ret) {/* Disable ospi */ writel_relaxed (0 , ospi->regs_base +OSPI_CR ); - goto err_pm_resume; + goto err_reset_control; }pm_runtime_put_autosuspend (ospi->dev);return 0 ; +err_reset_control: +reset_control_release (ospi->rstc); err_pm_resume:pm_runtime_put_sync_suspend (ospi->dev);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 144/311 drm/xe/xe_pagefault: Disallow writes to read-only VMAs
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cavitt <[email protected]>
[ Upstream commit 6d192b4f2d644d15d9a9f1d33dab05af936f6540 ]
The page fault handler should reject write/atomic access to read only VMAs. Add code to handle this in xe_pagefault_service after the VMA lookup.
v2:
- Apply max line length (Matthew)
--- drivers/gpu/drm/xe/xe_pagefault.c | 6 ++++++ 1 file changed, 6 insertions(+)
drivers/gpu/drm/xe/xe_pagefault.c +6 -0
@@ -187,6 +187,12 @@ static int xe_pagefault_service(struct xe_pagefault *pf) goto unlock_vm; } +if (xe_vma_read_only (vma) && + pf->consumer.access_type !=XE_PAGEFAULT_ACCESS_TYPE_READ ) { + err = -EPERM ; + goto unlock_vm; + } + atomic =xe_pagefault_access_is_atomic (pf->consumer.access_type);if (xe_vma_is_cpu_addr_mirror (vma))
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 145/311 drm/xe/pxp: Clean up termination status on failure
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Ceraolo Spurio <[email protected]>
[ Upstream commit e2628e670bb0923fcdc00828bfcd67b26a7df020 ]
If the PXP HW termination fails during PXP start, the normal completion code won't be called, so the termination will remain uncomplete. To avoid unnecessary waits, mark the termination as completed from the error path. Note that we already do this if the termination fails when handling a termination irq from the HW.
--- drivers/gpu/drm/xe/xe_pxp.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/xe/xe_pxp.c +1 -0
@@ -603,6 +603,7 @@ static int pxp_start(struct xe_pxp *pxp, u8 type)drm_err (&pxp->xe->drm,"PXP termination failed before start\n" );mutex_lock (&pxp->mutex); pxp->status =XE_PXP_ERROR ; +complete_all (&pxp->termination); goto out_unlock; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 146/311 drm/xe/pxp: Remove incorrect handling of impossible state during suspend
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Ceraolo Spurio <[email protected]>
[ Upstream commit 4fed244954c2dc9aafa333d08f66b14345225e03 ]
The default case of the PXP suspend switch is incorrectly exiting without releasing the lock. However, this case is impossible to hit because we're switching on an enum and all the valid enum values have their own cases. Therefore, we can just get rid of the default case and rely on the compiler to warn us if a new enum value is added and we forget to add it to the switch.
--- drivers/gpu/drm/xe/xe_pxp.c | 6 ------ 1 file changed, 6 deletions(-)
drivers/gpu/drm/xe/xe_pxp.c +0 -6
@@ -891,11 +891,6 @@ int xe_pxp_pm_suspend(struct xe_pxp *pxp) pxp->key_instance++; needs_queue_inval = true;break ; -default : -drm_err (&pxp->xe->drm,"unexpected state during PXP suspend: %u" , - pxp->status); - ret = -EIO ; - goto out; }/*
@@ -920,7 +915,6 @@ int xe_pxp_pm_suspend(struct xe_pxp *pxp) pxp->last_suspend_key_instance = pxp->key_instance; -out:return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 147/311 drm/xe/pxp: Clear restart flag in pxp_start after jumping back
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Daniele Ceraolo Spurio <[email protected]>
[ Upstream commit 76903b2057c8677c2c006e87fede15f496555dc0 ]
If we don't clear the flag we'll keep jumping back at the beginning of the function once we reach the end.
--- drivers/gpu/drm/xe/xe_pxp.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/gpu/drm/xe/xe_pxp.c +3 -1
@@ -532,7 +532,7 @@ static int __exec_queue_add(struct xe_pxp *pxp, struct xe_exec_queue *q)static int pxp_start (struct xe_pxp *pxp,u8 type) {int ret =0 ; -bool restart = false; +bool restart;if (!xe_pxp_is_enabled (pxp))return -ENODEV ;
@@ -561,6 +561,8 @@ static int pxp_start(struct xe_pxp *pxp, u8 type) msecs_to_jiffies(PXP_ACTIVATION_TIMEOUT_MS)))return -ETIMEDOUT ; + restart = false; +mutex_lock (&pxp->mutex);/* If PXP is not already active, turn it on */
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 148/311 hwmon: (tps53679) Fix device ID comparison and printing in tps53676_identify()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
[ Upstream commit ca34ee6d0307a0b4e52c870dfc1bb8a3c3eb956e ]
tps53676_identify() uses strncmp() to compare the device ID buffer against a byte sequence containing embedded non-printable bytes (\x53\x67\x60). strncmp() is semantically wrong for binary data comparison; use memcmp() instead.
Additionally, the buffer from i2c_smbus_read_block_data() is not NUL-terminated, so printing it with "%s" in the error path is undefined behavior and may read past the buffer. Use "%*ph" to hex-dump the actual bytes returned.
Per the datasheet, the expected device ID is the 6-byte sequence 54 49 53 67 60 00 ("TI\x53\x67\x60\x00"), so compare all 6 bytes including the trailing NUL.
--- drivers/hwmon/pmbus/tps53679.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/hwmon/pmbus/tps53679.c +2 -2
@@ -175,8 +175,8 @@ static int tps53676_identify(struct i2c_client *client, ret =i2c_smbus_read_block_data (client,PMBUS_IC_DEVICE_ID , buf);if (ret <0 )return ret; -if (strncmp ("TI\x53\x67\x60" , buf,5 )) { -dev_err (&client->dev,"Unexpected device ID: %s\n" , buf); +if (ret !=6 ||memcmp (buf,"TI\x53\x67\x60\x00" ,6 )) { +dev_err (&client->dev,"Unexpected device ID: %*ph\n" , ret, buf);return -ENODEV ; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 149/311 spi: amlogic: spifc-a4: unregister ECC engine on probe failure and remove() callback
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
[ Upstream commit b0dc7e7c56573e7a52080f25f3179a45f3dd7e6f ]
aml_sfc_probe() registers the on-host NAND ECC engine, but teardown was missing from both probe unwind and remove-time cleanup. Add a devm cleanup action after successful registration so nand_ecc_unregister_on_host_hw_engine() runs automatically on probe failures and during device removal.
--- drivers/spi/spi-amlogic-spifc-a4.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/spi/spi-amlogic-spifc-a4.c +12 -0
@@ -1066,6 +1066,13 @@ static const struct nand_ecc_engine_ops aml_sfc_ecc_engine_ops = { .finish_io_req = aml_sfc_ecc_finish_io_req, }; +static void aml_sfc_unregister_ecc_engine (void *data) +{ +struct nand_ecc_engine *eng = data; + +nand_ecc_unregister_on_host_hw_engine (eng); +} +static int aml_sfc_clk_init (struct aml_sfc *sfc) { sfc->gate_clk =devm_clk_get_enabled (sfc->dev,"gate" );
@@ -1149,6 +1156,11 @@ static int aml_sfc_probe(struct platform_device *pdev)if (ret)return dev_err_probe (&pdev->dev, ret,"failed to register Aml host ecc engine.\n" ); + ret =devm_add_action_or_reset (dev, aml_sfc_unregister_ecc_engine, + &sfc->ecc_eng); +if (ret) +return dev_err_probe (dev, ret,"failed to add ECC unregister action\n" ); + ret =of_property_read_u32 (np,"amlogic,rx-adj" , &val);if (!ret) sfc->rx_adj = val;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 150/311 hwmon: (occ) Fix missing newline in occ_show_extended()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
[ Upstream commit 09773978879ecf71a7990fe9a28ce4eb92bce645 ]
In occ_show_extended() case 0, when the EXTN_FLAG_SENSOR_ID flag is set, the sysfs_emit format string "%u" is missing the trailing newline that the sysfs ABI expects. The else branch correctly uses "%4phN\n", and all other show functions in this file include the trailing newline.
Add the missing "\n" for consistency and correct sysfs output.
--- drivers/hwmon/occ/common.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/hwmon/occ/common.c +1 -1
@@ -725,7 +725,7 @@ static ssize_t occ_show_extended(struct device *dev,switch (sattr->nr) {case 0 :if (extn->flags &EXTN_FLAG_SENSOR_ID ) { - rc =sysfs_emit (buf,"%u" , + rc =sysfs_emit (buf,"%u\n" ,get_unaligned_be32 (&extn->sensor_id)); }else { rc =sysfs_emit (buf,"%4phN\n" , extn->name);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 151/311 irqchip/riscv-aplic: Restrict genpd notifier to device tree only
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jessica Liu <[email protected]>
[ Upstream commit af416cd9b3fb9d17ac7f4cfa12d1ea83dfd0e4be ]
On ACPI systems, the aplic's pm_domain is set to acpi_general_pm_domain, which provides its own power management callbacks (e.g., runtime_suspend via acpi_subsys_runtime_suspend).
aplic_pm_add() unconditionally calls dev_pm_genpd_add_notifier() when dev->pm_domain is non‑NULL, leading to a comparison between runtime_suspend and genpd_runtime_suspend. This results in the following errors when ACPI is enabled:
riscv-aplic RSCV0002:00: failed to create APLIC context riscv-aplic RSCV0002:00: error -ENODEV: failed to setup APLIC in MSI mode
Fix this by checking for dev->of_node before adding or removing the genpd notifier, ensuring it is only used for device tree based systems.
--- drivers/irqchip/irq-riscv-aplic-main.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/irqchip/irq-riscv-aplic-main.c +2 -2
@@ -150,7 +150,7 @@ static void aplic_pm_remove(void *data)struct device *dev = priv->dev;list_del (&priv->head); -if (dev->pm_domain) +if (dev->pm_domain && dev->of_node)dev_pm_genpd_remove_notifier (dev); }
@@ -165,7 +165,7 @@ static int aplic_pm_add(struct device *dev, struct aplic_priv *priv) priv->saved_hw_regs.srcs = srcs;list_add (&priv->head, &aplics); -if (dev->pm_domain) { +if (dev->pm_domain && dev->of_node) { priv->genpd_nb.notifier_call = aplic_pm_notifier; ret =dev_pm_genpd_add_notifier (dev, &priv->genpd_nb);if (ret)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 152/311 drm/sysfb: Fix efidrm error handling and memory type mismatch
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chen Ni <[email protected]>
[ Upstream commit 5e77923a3eb39cce91bf08ed7670f816bf86d4af ]
Fix incorrect error checking and memory type confusion in efidrm_device_create(). devm_memremap() returns error pointers, not NULL, and returns system memory while devm_ioremap() returns I/O memory. The code incorrectly passes system memory to iosys_map_set_vaddr_iomem().
Restructure to handle each memory type separately. Use devm_ioremap*() with ERR_PTR(-ENXIO) for WC/UC, and devm_memremap() with ERR_CAST() for WT/WB.
--- drivers/gpu/drm/sysfb/efidrm.c | 46 +++++++++++++++++++++++----------- 1 file changed, 31 insertions(+), 15 deletions(-)
drivers/gpu/drm/sysfb/efidrm.c +31 -15
@@ -151,7 +151,6 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv,struct drm_sysfb_device *sysfb;struct drm_device *dev;struct resource *mem =NULL ; -void __iomem *screen_base =NULL ;struct drm_plane *primary_plane;struct drm_crtc *crtc;struct drm_encoder *encoder;
@@ -236,21 +235,38 @@ static struct efidrm_device *efidrm_device_create(struct drm_driver *drv, mem_flags =efidrm_get_mem_flags (dev, res->start, vsize); -if (mem_flags &EFI_MEMORY_WC ) - screen_base =devm_ioremap_wc (&pdev->dev, mem->start,resource_size (mem)); -else if (mem_flags &EFI_MEMORY_UC ) - screen_base =devm_ioremap (&pdev->dev, mem->start,resource_size (mem)); -else if (mem_flags &EFI_MEMORY_WT ) - screen_base =devm_memremap (&pdev->dev, mem->start,resource_size (mem), -MEMREMAP_WT ); -else if (mem_flags &EFI_MEMORY_WB ) - screen_base =devm_memremap (&pdev->dev, mem->start,resource_size (mem), -MEMREMAP_WB ); -else +if (mem_flags &EFI_MEMORY_WC ) { +void __iomem *screen_base =devm_ioremap_wc (&pdev->dev, mem->start, +resource_size (mem)); + +if (!screen_base) +return ERR_PTR (-ENXIO ); +iosys_map_set_vaddr_iomem (&sysfb->fb_addr, screen_base); + }else if (mem_flags &EFI_MEMORY_UC ) { +void __iomem *screen_base =devm_ioremap (&pdev->dev, mem->start, +resource_size (mem)); + +if (!screen_base) +return ERR_PTR (-ENXIO ); +iosys_map_set_vaddr_iomem (&sysfb->fb_addr, screen_base); + }else if (mem_flags &EFI_MEMORY_WT ) { +void *screen_base =devm_memremap (&pdev->dev, mem->start, +resource_size (mem),MEMREMAP_WT ); + +if (IS_ERR (screen_base)) +return ERR_CAST (screen_base); +iosys_map_set_vaddr (&sysfb->fb_addr, screen_base); + }else if (mem_flags &EFI_MEMORY_WB ) { +void *screen_base =devm_memremap (&pdev->dev, mem->start, +resource_size (mem),MEMREMAP_WB ); + +if (IS_ERR (screen_base)) +return ERR_CAST (screen_base); +iosys_map_set_vaddr (&sysfb->fb_addr, screen_base); + }else {drm_err (dev,"invalid mem_flags: 0x%llx\n" , mem_flags); -if (!screen_base) -return ERR_PTR (-ENOMEM ); -iosys_map_set_vaddr_iomem (&sysfb->fb_addr, screen_base); +return ERR_PTR (-EINVAL ); + }/* * Modesetting
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 153/311 hwmon: (asus-ec-sensors) Fix T_Sensor for PRIME X670E-PRO WIFI
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Corey Hickey <[email protected]>
[ Upstream commit cffff6df669a438ecac506dadd49a53d4475a796 ]
On the Asus PRIME X670E-PRO WIFI, the driver reports a constant value of zero for T_Sensor. On this board, the register for T_Sensor is at a different address, as found by experimentation and confirmed by comparison to an independent temperature reading.
* sensor disconnected: -62.0°C
* ambient temperature: +22.0°C
* held between fingers: +30.0°C
Introduce SENSOR_TEMP_T_SENSOR_ALT1 to support the PRIME X670E-PRO WIFI without causing a regression for other 600-series boards
--- drivers/hwmon/asus-ec-sensors.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/hwmon/asus-ec-sensors.c +6 -1
@@ -111,6 +111,8 @@ enum ec_sensors { ec_sensor_temp_mb,/* "T_Sensor" temperature sensor reading [℃] */ ec_sensor_temp_t_sensor, +/* like ec_sensor_temp_t_sensor, but at an alternate address [℃] */ + ec_sensor_temp_t_sensor_alt1,/* VRM temperature [℃] */ ec_sensor_temp_vrm,/* VRM east (right) temperature [℃] */
@@ -160,6 +162,7 @@ enum ec_sensors {#define SENSOR_TEMP_CPU_PACKAGE BIT(ec_sensor_temp_cpu_package)#define SENSOR_TEMP_MB BIT(ec_sensor_temp_mb)#define SENSOR_TEMP_T_SENSOR BIT(ec_sensor_temp_t_sensor) +#define SENSOR_TEMP_T_SENSOR_ALT1 BIT(ec_sensor_temp_t_sensor_alt1)#define SENSOR_TEMP_VRM BIT(ec_sensor_temp_vrm)#define SENSOR_TEMP_VRME BIT(ec_sensor_temp_vrme)#define SENSOR_TEMP_VRMW BIT(ec_sensor_temp_vrmw)
@@ -279,6 +282,8 @@ static const struct ec_sensor_info sensors_family_amd_600[] = { EC_SENSOR("VRM", hwmon_temp, 1, 0x00, 0x33), [ec_sensor_temp_t_sensor] = EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x36), + [ec_sensor_temp_t_sensor_alt1] = + EC_SENSOR("T_Sensor", hwmon_temp, 1, 0x00, 0x37), [ec_sensor_fan_cpu_opt] = EC_SENSOR("CPU_Opt", hwmon_fan, 2, 0x00, 0xb0), [ec_sensor_temp_water_in] =
@@ -509,7 +514,7 @@ static const struct ec_board_info board_info_prime_x570_pro = {static const struct ec_board_info board_info_prime_x670e_pro_wifi = { .sensors =SENSOR_TEMP_CPU |SENSOR_TEMP_CPU_PACKAGE |SENSOR_TEMP_MB |SENSOR_TEMP_VRM | -SENSOR_TEMP_T_SENSOR |SENSOR_FAN_CPU_OPT , +SENSOR_TEMP_T_SENSOR_ALT1 |SENSOR_FAN_CPU_OPT , .mutex_path =ACPI_GLOBAL_LOCK_PSEUDO_PATH , .family = family_amd_600_series, };
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 154/311 mips: ralink: update CPU clock index
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shiji Yang <[email protected]>
[ Upstream commit 43985a62bab9d35e5e9af41118ce2f44c01b97d2 ]
Update CPU clock index to match the clock driver changes.
--- arch/mips/ralink/clk.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
arch/mips/ralink/clk.c +4 -4
@@ -21,16 +21,16 @@ static const char *clk_cpu(int *idx) {switch (ralink_soc) {case RT2880_SOC : - *idx =0 ; + *idx =1 ;return "ralink,rt2880-sysc" ;case RT3883_SOC : - *idx =0 ; + *idx =1 ;return "ralink,rt3883-sysc" ;case RT305X_SOC_RT3050 : - *idx =0 ; + *idx =1 ;return "ralink,rt3050-sysc" ;case RT305X_SOC_RT3052 : - *idx =0 ; + *idx =1 ;return "ralink,rt3052-sysc" ;case RT305X_SOC_RT3350 : *idx =1 ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 155/311 sched/fair: Fix zero_vruntime tracking fix
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit 1319ea57529e131822bab56bf417c8edc2db9ae8 ]
John reported that stress-ng-yield could make his machine unhappy and managed to bisect it to commit b3d99f43c72b ("sched/fair: Fix zero_vruntime tracking").
The combination of yield and that commit was specific enough to hypothesize the following scenario:
Suppose we have 2 runnable tasks, both doing yield. Then one will be eligible and one will not be, because the average position must be in between these two entities.
Therefore, the runnable task will be eligible, and be promoted a full slice (all the tasks do is yield after all). This causes it to jump over the other task and now the other task is eligible and current is no longer. So we schedule.
Since we are runnable, there is no {de,en}queue. All we have is the __{en,de}queue_entity() from {put_prev,set_next}_task(). But per the fingered commit, those two no longer move zero_vruntime.
All that moves zero_vruntime are tick and full {de,en}queue.
This means, that if the two tasks playing leapfrog can reach the critical speed to reach the overflow point inside one tick's worth of time, we're up a creek.
Additionally, when multiple cgroups are involved, there is no guarantee the tick will in fact hit every cgroup in a timely manner. Statistically speaking it will, but that same statistics does not rule out the possibility of one cgroup not getting a tick for a significant amount of time -- however unlikely.
Therefore, just like with the yield() case, force an update at the end of every slice. This ensures the update is never more than a single slice behind and the whole thing is within 2 lag bounds as per the comment on entity_key().
--- kernel/sched/fair.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
kernel/sched/fair.c +3 -7
@@ -707,7 +707,7 @@ void update_zero_vruntime(struct cfs_rq *cfs_rq, s64 delta)* Called in: * - place_entity() -- before enqueue * - update_entity_lag() -- before dequeue -* - entity_tick() +* - update_deadline() -- slice expiration * * This means it is one entry 'behind' but that puts it close enough to where * the bound on entity_key() is at most two lag bounds.
@@ -1131,6 +1131,7 @@ static bool update_deadline(struct cfs_rq *cfs_rq, struct sched_entity *se)* EEVDF: vd_i = ve_i + r_i / w_i */ se->deadline = se->vruntime +calc_delta_fair (se->slice, se); +avg_vruntime (cfs_rq);/* * The task has consumed its request, reschedule.
@@ -5636,11 +5637,6 @@ entity_tick(struct cfs_rq *cfs_rq, struct sched_entity *curr, int queued)update_load_avg (cfs_rq, curr,UPDATE_TG );update_cfs_group (curr); -/* -* Pulls along cfs_rq::zero_vruntime. -*/ -avg_vruntime (cfs_rq); -#ifdef CONFIG_SCHED_HRTICK /* * queued ticks are scheduled to match the slice, so don't bother
@@ -9166,7 +9162,7 @@ static void yield_task_fair(struct rq *rq)*/ if (entity_eligible (cfs_rq, se)) { se->vruntime = se->deadline; - se->deadline +=calc_delta_fair (se->slice, se); +update_deadline (cfs_rq, se); } }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 156/311 sched/debug: Fix avg_vruntime() usage
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peter Zijlstra <[email protected]>
[ Upstream commit e08d007f9d813616ce7093600bc4fdb9c9d81d89 ]
John reported that stress-ng-yield could make his machine unhappy and managed to bisect it to commit b3d99f43c72b ("sched/fair: Fix zero_vruntime tracking").
The commit in question changes avg_vruntime() from a function that is a pure reader, to a function that updates variables. This turns an unlocked sched/debug usage of this function from a minor mistake into a data corruptor.
--- kernel/sched/debug.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
kernel/sched/debug.c +3 -1
@@ -798,6 +798,7 @@ static void print_rq(struct seq_file *m, struct rq *rq, int rq_cpu)void print_cfs_rq (struct seq_file *m,int cpu,struct cfs_rq *cfs_rq) {s64 left_vruntime =-1 , zero_vruntime, right_vruntime =-1 , left_deadline =-1 , spread; +u64 avruntime;struct sched_entity *last, *first, *root;struct rq *rq =cpu_rq (cpu);unsigned long flags;
@@ -821,6 +822,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)if (last) right_vruntime = last->vruntime; zero_vruntime = cfs_rq->zero_vruntime; + avruntime =avg_vruntime (cfs_rq);raw_spin_rq_unlock_irqrestore (rq, flags); SEQ_printf(m, " .%-30s: %Ld.%06ld\n", "left_deadline",
@@ -830,7 +832,7 @@ void print_cfs_rq(struct seq_file *m, int cpu, struct cfs_rq *cfs_rq)SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"zero_vruntime" ,SPLIT_NS (zero_vruntime));SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"avg_vruntime" , -SPLIT_NS (avg_vruntime (cfs_rq))); +SPLIT_NS (avruntime));SEQ_printf (m," .%-30s: %Ld.%06ld\n" ,"right_vruntime" ,SPLIT_NS (right_vruntime)); spread = right_vruntime - left_vruntime;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 157/311 perf/x86: Fix potential bad container_of in intel_pmu_hw_config
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Rogers <[email protected]>
[ Upstream commit dbde07f06226438cd2cf1179745fa1bec5d8914a ]
Auto counter reload may have a group of events with software events present within it. The software event PMU isn't the x86_hybrid_pmu and a container_of operation in intel_pmu_set_acr_caused_constr (via the hybrid helper) could cause out of bound memory reads. Avoid this by guarding the call to intel_pmu_set_acr_caused_constr with an is_x86_event check.
--- arch/x86/events/intel/core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
arch/x86/events/intel/core.c +4 -2
@@ -4594,8 +4594,10 @@ static int intel_pmu_hw_config(struct perf_event *event)intel_pmu_set_acr_caused_constr (leader, idx++, cause_mask);if (leader->nr_siblings) { -for_each_sibling_event (sibling, leader) -intel_pmu_set_acr_caused_constr (sibling, idx++, cause_mask); +for_each_sibling_event (sibling, leader) { +if (is_x86_event (sibling)) +intel_pmu_set_acr_caused_constr (sibling, idx++, cause_mask); + } }if (leader != event)
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 158/311 riscv: kgdb: fix several debug register assignment bugs
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Paul Walmsley <[email protected]>
[ Upstream commit 834911eb8eef2501485d819b4eabebadc25c3497 ]
Fix several bugs in the RISC-V kgdb implementation:
- The element of dbg_reg_def[] that is supposed to pertain to the S1 register embeds instead the struct pt_regs offset of the A1 register. Fix this to use the S1 register offset in struct pt_regs.
- The sleeping_thread_to_gdb_regs() function copies the value of the S10 register into the gdb_regs[] array element meant for the S9 register, and copies the value of the S11 register into the array element meant for the S10 register. It also neglects to copy the value of the S11 register. Fix all of these issues.
--- arch/riscv/kernel/kgdb.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
arch/riscv/kernel/kgdb.c +4 -3
@@ -175,7 +175,7 @@ struct dbg_reg_def_t dbg_reg_def[DBG_MAX_REG_NUM] = { {DBG_REG_T1, GDB_SIZEOF_REG, offsetof(struct pt_regs, t1)}, {DBG_REG_T2, GDB_SIZEOF_REG, offsetof(struct pt_regs, t2)}, {DBG_REG_FP, GDB_SIZEOF_REG, offsetof(struct pt_regs, s0)}, - {DBG_REG_S1, GDB_SIZEOF_REG, offsetof(struct pt_regs, a1)}, + {DBG_REG_S1, GDB_SIZEOF_REG, offsetof(struct pt_regs, s1)}, {DBG_REG_A0, GDB_SIZEOF_REG, offsetof(struct pt_regs, a0)}, {DBG_REG_A1, GDB_SIZEOF_REG, offsetof(struct pt_regs, a1)}, {DBG_REG_A2, GDB_SIZEOF_REG, offsetof(struct pt_regs, a2)},
@@ -244,8 +244,9 @@ sleeping_thread_to_gdb_regs(unsigned long *gdb_regs, struct task_struct *task) gdb_regs[DBG_REG_S6_OFF ] = task->thread.s[6 ]; gdb_regs[DBG_REG_S7_OFF ] = task->thread.s[7 ]; gdb_regs[DBG_REG_S8_OFF ] = task->thread.s[8 ]; - gdb_regs[DBG_REG_S9_OFF ] = task->thread.s[10 ]; - gdb_regs[DBG_REG_S10_OFF ] = task->thread.s[11 ]; + gdb_regs[DBG_REG_S9_OFF ] = task->thread.s[9 ]; + gdb_regs[DBG_REG_S10_OFF ] = task->thread.s[10 ]; + gdb_regs[DBG_REG_S11_OFF ] = task->thread.s[11 ]; gdb_regs[DBG_REG_EPC_OFF ] = task->thread.ra; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 159/311 riscv: Reset pmm when PR_TAGGED_ADDR_ENABLE is not set
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zishun Yi <[email protected]>
[ Upstream commit 3033b2b1e3949274f33a140e2a97571b5a307298 ]
In set_tagged_addr_ctrl(), when PR_TAGGED_ADDR_ENABLE is not set, pmlen is correctly set to 0, but it forgets to reset pmm. This results in the CPU pmm state not corresponding to the software pmlen state.
Fix this by resetting pmm along with pmlen.
--- arch/riscv/kernel/process.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
arch/riscv/kernel/process.c +3 -1
@@ -324,8 +324,10 @@ long set_tagged_addr_ctrl(struct task_struct *task, unsigned long arg)if (arg &PR_TAGGED_ADDR_ENABLE && (tagged_addr_disabled || !pmlen))return -EINVAL ; -if (!(arg &PR_TAGGED_ADDR_ENABLE )) +if (!(arg &PR_TAGGED_ADDR_ENABLE )) { pmlen =PMLEN_0 ; + pmm =ENVCFG_PMM_PMLEN_0 ; + }if (mmap_write_lock_killable (mm))return -EINTR ;
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 160/311 ACPI: RIMT: Add dependency between iommu and devices
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sunil V L <[email protected]>
[ Upstream commit 9156585280f161fc1c3552cf1860559edb2bb7e3 ]
EPROBE_DEFER ensures IOMMU devices are probed before the devices that depend on them. During shutdown, however, the IOMMU may be removed first, leading to issues. To avoid this, a device link is added which enforces the correct removal order.
--- drivers/acpi/riscv/rimt.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/acpi/riscv/rimt.c +7 -0
@@ -263,6 +263,13 @@ static int rimt_iommu_xlate(struct device *dev, struct acpi_rimt_node *node, u32if (!rimt_fwnode)return -EPROBE_DEFER ; +/* +* EPROBE_DEFER ensures IOMMU is probed before the devices that +* depend on them. During shutdown, however, the IOMMU may be removed +* first, leading to issues. To avoid this, a device link is added +* which enforces the correct removal order. +*/ +device_link_add (dev, rimt_fwnode->dev,DL_FLAG_AUTOREMOVE_CONSUMER );return acpi_iommu_fwspec_init (dev, deviceid, rimt_fwnode); }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 161/311 drm/ioc32: stop speculation on the drm_compat_ioctl path
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Greg Kroah-Hartman <[email protected]>
commit f8995c2df519f382525ca4bc90553ad2ec611067 upstream.
The drm compat ioctl path takes a user controlled pointer, and then dereferences it into a table of function pointers, the signature method of spectre problems. Fix this up by calling array_index_nospec() on the index to the function pointer list.
--- drivers/gpu/drm/drm_ioc32.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/gpu/drm/drm_ioc32.c +2 -0
@@ -28,6 +28,7 @@* IN THE SOFTWARE. */ #include <linux/compat.h> +#include <linux/nospec.h> #include <linux/ratelimit.h> #include <linux/export.h>
@@ -374,6 +375,7 @@ long drm_compat_ioctl(struct file *filp,if (nr >=ARRAY_SIZE (drm_compat_ioctls))return drm_ioctl (filp, cmd, arg); + nr =array_index_nospec (nr,ARRAY_SIZE (drm_compat_ioctls)); fn = drm_compat_ioctls[nr].fn;if (!fn)return drm_ioctl (filp, cmd, arg);
Greg Kroah-Hartman
maintainerPATCH 162/311 rust_binder: use AssertSync for BINDER_VM_OPS
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alice Ryhl <[email protected]>
commit ec327abae5edd1d5b60ea9f920212970133171d2 upstream.
When declaring an immutable global variable in Rust, the compiler checks that it looks thread safe, because it is generally safe to access said global variable. When using C bindings types for these globals, we don't really want this check, because it is conservative and assumes pointers are not thread safe.
In the case of BINDER_VM_OPS, this is a challenge when combined with the patch 'userfaultfd: introduce vm_uffd_ops' [1], which introduces a pointer field to vm_operations_struct. It previously only held function pointers, which are considered thread safe.
Rust Binder should not be assuming that vm_operations_struct contains no pointer fields, so to fix this, use AssertSync (which Rust Binder has already declared for another similar global of type struct file_operations with the same problem). This ensures that even if another commit adds a pointer field to vm_operations_struct, this does not cause problems.
--- drivers/android/binder/page_range.rs | 8 +++++--- drivers/android/binder/rust_binder_main.rs | 2 +- 2 files changed, 6 insertions(+), 4 deletions(-)
drivers/android/binder/page_range.rs +5 -3
@@ -13,6 +13,8 @@// // The shrinker will use trylock methods because it locks them in a different order. +use crate ::AssertSync ; +use core::{ marker::PhantomPinned , mem::{size_of, size_of_val,MaybeUninit },
@@ -143,14 +145,14 @@ pub(crate) struct ShrinkablePageRange { }// We do not define any ops. For now, used only to check identity of vmas. -static BINDER_VM_OPS : bindings::vm_operations_struct = pin_init::zeroed (); +static BINDER_VM_OPS :AssertSync <bindings::vm_operations_struct > =AssertSync (pin_init::zeroed ());// To ensure that we do not accidentally install pages into or zap pages from the wrong vma, we // check its vm_ops and private data before using it. fn check_vma (vma: &virt::VmaRef , owner: *const ShrinkablePageRange ) ->Option <&virt::VmaMixedMap > {// SAFETY: Just reading the vm_ops pointer of any active vma is safe. let vm_ops =unsafe { (*vma.as_ptr ()).vm_ops }; -if !ptr::eq (vm_ops, &BINDER_VM_OPS ) { +if !ptr::eq (vm_ops, &BINDER_VM_OPS .0 ) {return None ; }
@@ -342,7 +344,7 @@ impl ShrinkablePageRange {// SAFETY: We own the vma, and we don't use any methods on VmaNew that rely on // `vm_ops`. -unsafe { (*vma.as_ptr ()).vm_ops = &BINDER_VM_OPS }; +unsafe { (*vma.as_ptr ()).vm_ops = &BINDER_VM_OPS .0 };Ok (num_pages) }
drivers/android/binder/rust_binder_main.rs +1 -1
@@ -300,7 +300,7 @@ impl kernel::Module for BinderModule {/// Makes the inner type Sync. #[repr(transparent)] pub struct AssertSync <T >(T ); -// SAFETY: Used only to insert `file_operations` into a global, which is safe. +// SAFETY: Used only to insert C bindings types into globals, which is safe. unsafe impl <T >Sync for AssertSync <T > {}/// File operations that rust_binderfs.c can use.
Greg Kroah-Hartman
maintainerPATCH 163/311 wifi: wilc1000: fix u8 overflow in SSID scan buffer size calculation
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yasuaki Torimaru <[email protected]>
commit d049e56b1739101d1c4d81deedb269c52a8dbba0 upstream.
The variable valuesize is declared as u8 but accumulates the total length of all SSIDs to scan. Each SSID contributes up to 33 bytes (IEEE80211_MAX_SSID_LEN + 1), and with WILC_MAX_NUM_PROBED_SSID (10) SSIDs the total can reach 330, which wraps around to 74 when stored in a u8.
This causes kmalloc to allocate only 75 bytes while the subsequent memcpy writes up to 331 bytes into the buffer, resulting in a 256-byte heap buffer overflow.
Widen valuesize from u8 to u32 to accommodate the full range.
--- drivers/net/wireless/microchip/wilc1000/hif.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/microchip/wilc1000/hif.c +1 -1
@@ -163,7 +163,7 @@ int wilc_scan(struct wilc_vif *vif, u8 su32 index =0 ;u32 i, scan_timeout;u8 *buffer; -u8 valuesize =0 ; +u32 valuesize =0 ;u8 *search_ssid_vals =NULL ;const u8 ch_list_len = request->n_channels;struct host_if_drv *hif_drv = vif->hif_drv;
Greg Kroah-Hartman
maintainerPATCH 164/311 wifi: iwlwifi: mvm: fix potential out-of-bounds read in iwl_mvm_nd_match_info_handler()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexey Velichayshiy <[email protected]>
commit 744fabc338e87b95c4d1ff7c95bc8c0f834c6d99 upstream.
The memcpy function assumes the dynamic array notif->matches is at least as large as the number of bytes to copy. Otherwise, results->matches may contain unwanted data. To guarantee safety, extend the validation in one of the checks to ensure sufficient packet length.
Found by Linux Verification Center (linuxtesting.org) with SVACE.
--- drivers/net/wireless/intel/iwlwifi/mvm/d3.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/wireless/intel/iwlwifi/mvm/d3.c +1 -1
@@ -2834,7 +2834,7 @@ static void iwl_mvm_nd_match_info_handleif (IS_ERR_OR_NULL (vif))return ; -if (len <sizeof (struct iwl_scan_offload_match_info )) { +if (len <sizeof (struct iwl_scan_offload_match_info ) + matches_len) {IWL_ERR (mvm,"Invalid scan match info notification\n" );return ; }
Greg Kroah-Hartman
maintainerPATCH 165/311 USB: serial: option: add MeiG Smart SRM825WN
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ernestas Kulik <[email protected]>
commit e8d0ed37bd51da52da6225d278e330c2f18a6198 upstream.
Add support for the SDX62-based MeiG Smart SRM825WN module.
If#= 0: RNDIS
If#= 1: RNDIS
If#= 2: Diag
If#= 3: AT
If#= 4: AT
If#= 5: NMEA
T: Bus=01 Lev=02 Prnt=02 Port=00 Cnt=01 Dev#= 19 Spd=480 MxCh= 0 D: Ver= 2.10 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=2dee ProdID=4d38 Rev= 5.04 S: Manufacturer=MEIG S: Product=LTE-A Module S: SerialNumber=da47a175
C:* #Ifs= 6 Cfg#= 1 Atr=80 MxPwr=500mA
A: FirstIf#= 0 IfCount= 2 Cls=e0(wlcon) Sub=01 Prot=03
I:* If#= 0 Alt= 0 #EPs= 1 Cls=e0(wlcon) Sub=01 Prot=03 Driver=rndis_host
E: Ad=81(I) Atr=03(Int.) MxPS= 8 Ivl=32ms
I:* If#= 1 Alt= 0 #EPs= 2 Cls=0a(data ) Sub=00 Prot=00 Driver=rndis_host
E: Ad=8e(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0f(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 2 Alt= 0 #EPs= 2 Cls=ff(vend.) Sub=ff Prot=30 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 3 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=84(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=83(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 4 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=40 Driver=option E: Ad=86(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=85(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=03(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms I:* If#= 5 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=ff Prot=60 Driver=option E: Ad=88(I) Atr=03(Int.) MxPS= 10 Ivl=32ms E: Ad=87(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=04(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/serial/option.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/serial/option.c +3 -0
@@ -2441,6 +2441,9 @@ static const struct usb_device_id option { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM815 and SRM825L */ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825L */ { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d22, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825L */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x30) }, /* MeiG Smart SRM825WN (Diag) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x40) }, /* MeiG Smart SRM825WN (AT) */ + { USB_DEVICE_AND_INTERFACE_INFO(0x2dee, 0x4d38, 0xff, 0xff, 0x60) }, /* MeiG Smart SRM825WN (NMEA) */ { USB_DEVICE_INTERFACE_CLASS(0x2df3, 0x9d03, 0xff) }, /* LongSung M5710 */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1404, 0xff) }, /* GosunCn GM500 RNDIS */ { USB_DEVICE_INTERFACE_CLASS(0x305a, 0x1405, 0xff) }, /* GosunCn GM500 MBIM */
Greg Kroah-Hartman
maintainerPATCH 166/311 drm/amd/display: Fix NULL pointer dereference in dcn401_init_hw()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Srinivasan Shanmugam <[email protected]>
commit e927b36ae18b66b49219eaa9f46edc7b4fdbb25e upstream.
dcn401_init_hw() assumes that update_bw_bounding_box() is valid when entering the update path. However, the existing condition:
((!fams2_enable && update_bw_bounding_box) || freq_changed)
does not guarantee this, as the freq_changed branch can evaluate to true independently of the callback pointer.
This can result in calling update_bw_bounding_box() when it is NULL.
Fix this by separating the update condition from the pointer checks and ensuring the callback, dc->clk_mgr, and bw_params are validated before use.
Fixes the below:../dc/hwss/dcn401/dcn401_hwseq.c:367 dcn401_init_hw() error: we previously assumed 'dc->res_pool->funcs->update_bw_bounding_box' could be null (see line 362)
--- drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c | 17 +++++++++----- 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/gpu/drm/amd/display/dc/hwss/dcn401/dcn401_hwseq.c +11 -6
@@ -146,6 +146,7 @@ void dcn401_init_hw(struct dc *dc)int edp_num;uint32_t backlight =MAX_BACKLIGHT_LEVEL ;uint32_t user_level =MAX_BACKLIGHT_LEVEL ; +bool dchub_ref_freq_changed;int current_dchub_ref_freq =0 ;if (dc->clk_mgr && dc->clk_mgr->funcs && dc->clk_mgr->funcs->init_clocks) {
@@ -359,14 +360,18 @@ void dcn401_init_hw(struct dc *dc) dc->caps.dmub_caps.psr = dc->ctx->dmub_srv->dmub->feature_caps.psr; dc->caps.dmub_caps.mclk_sw = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver >0 ; dc->caps.dmub_caps.fams_ver = dc->ctx->dmub_srv->dmub->feature_caps.fw_assisted_mclk_switch_ver; + +/* sw and fw FAMS versions must match for support */ dc->debug.fams2_config.bits.enable &= - dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver;// sw & fw fams versions must match for support -if ((!dc->debug.fams2_config.bits.enable && dc->res_pool->funcs->update_bw_bounding_box) - || res_pool->ref_clocks.dchub_ref_clock_inKhz /1000 != current_dchub_ref_freq) { + dc->caps.dmub_caps.fams_ver == dc->debug.fams_version.ver; + dchub_ref_freq_changed = + res_pool->ref_clocks.dchub_ref_clock_inKhz /1000 != current_dchub_ref_freq; +if ((!dc->debug.fams2_config.bits.enable || dchub_ref_freq_changed) && + dc->res_pool->funcs->update_bw_bounding_box && + dc->clk_mgr && dc->clk_mgr->bw_params) {/* update bounding box if FAMS2 disabled, or if dchub clk has changed */ -if (dc->clk_mgr) - dc->res_pool->funcs->update_bw_bounding_box (dc, - dc->clk_mgr->bw_params); + dc->res_pool->funcs->update_bw_bounding_box (dc, + dc->clk_mgr->bw_params); } } }
Greg Kroah-Hartman
maintainerPATCH 167/311 sched_ext: Fix inconsistent NUMA node lookup in scx_select_cpu_dfl()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cheng-Yang Chou <[email protected]>
commit db08b1940f4beb25460b4a4e9da3446454f2e8fe upstream.
In the WAKE_SYNC path of scx_select_cpu_dfl(), waker_node was computed with cpu_to_node(), while node (for prev_cpu) was computed with scx_cpu_node_if_enabled(). When scx_builtin_idle_per_node is disabled, idle_cpumask(waker_node) is called with a real node ID even though per-node idle tracking is disabled, resulting in undefined behavior.
Fix by using scx_cpu_node_if_enabled() for waker_node as well, ensuring both variables are computed consistently.
--- kernel/sched/ext_idle.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/sched/ext_idle.c +1 -1
@@ -543,7 +543,7 @@ s32 scx_select_cpu_dfl(struct task_struc* piled up on it even if there is an idle core elsewhere on * the system. */ - waker_node =cpu_to_node (cpu); + waker_node =scx_cpu_node_if_enabled (cpu); if (!(current->flags & PF_EXITING) && cpu_rq(cpu)->scx.local_dsq.nr == 0 && (!(flags & SCX_PICK_IDLE_IN_NODE) || (waker_node == node)) &&
Greg Kroah-Hartman
maintainerPATCH 168/311 lib/crypto: chacha: Zeroize permuted_state before it leaves scope
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit e5046823f8fa3677341b541a25af2fcb99a5b1e0 upstream.
Since the ChaCha permutation is invertible, the local variable 'permuted_state' is sufficient to compute the original 'state', and thus the key, even after the permutation has been done.
While the kernel is quite inconsistent about zeroizing secrets on the stack (and some prominent userspace crypto libraries don't bother at all since it's not guaranteed to work anyway), the kernel does try to do it as a best practice, especially in cases involving the RNG.
Thus, explicitly zeroize 'permuted_state' before it goes out of scope.
--- lib/crypto/chacha-block-generic.c | 4 ++++ 1 file changed, 4 insertions(+)
lib/crypto/chacha-block-generic.c +4 -0
@@ -87,6 +87,8 @@ void chacha_block_generic(struct chacha_ &out[i * sizeof(u32)]); state->x[12 ]++; + +chacha_zeroize_state (&permuted_state); }EXPORT_SYMBOL (chacha_block_generic);
@@ -110,5 +112,7 @@ void hchacha_block_generic(const structmemcpy (&out[0 ], &permuted_state.x[0 ],16 );memcpy (&out[4 ], &permuted_state.x[12 ],16 ); + +chacha_zeroize_state (&permuted_state); }EXPORT_SYMBOL (hchacha_block_generic);
Greg Kroah-Hartman
maintainerPATCH 169/311 sched_ext: Fix SCX_KICK_WAIT deadlock by deferring wait to balance callback
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tejun Heo <[email protected]>
commit 415cb193bb9736f0e830286c72a6fa8eb2a9cc5c upstream.
SCX_KICK_WAIT busy-waits in kick_cpus_irq_workfn() using smp_cond_load_acquire() until the target CPU's kick_sync advances. Because the irq_work runs in hardirq context, the waiting CPU cannot reschedule and its own kick_sync never advances. If multiple CPUs form a wait cycle, all CPUs deadlock.
Replace the busy-wait in kick_cpus_irq_workfn() with resched_curr() to force the CPU through do_pick_task_scx(), which queues a balance callback to perform the wait. The balance callback drops the rq lock and enables IRQs following the sched_core_balance() pattern, so the CPU can process IPIs while waiting. The local CPU's kick_sync is advanced on entry to do_pick_task_scx() and continuously during the wait, ensuring any CPU that starts waiting for us sees the advancement and cannot form cyclic dependencies.
--- kernel/sched/ext.c | 95 +++++++++++++++++++++++++++++++++++++-------------- kernel/sched/sched.h | 3 + 2 files changed, 73 insertions(+), 25 deletions(-)
kernel/sched/ext.c +70 -25
@@ -2394,7 +2394,7 @@ static void put_prev_task_scx(struct rq {struct scx_sched *sch = scx_root; -/* see kick_cpus_irq_workfn() */ +/* see kick_sync_wait_bal_cb() */ smp_store_release (&rq->scx.kick_sync, rq->scx.kick_sync +1 );update_curr_scx (rq);
@@ -2437,6 +2437,48 @@ switch_class:switch_class (rq, next); } +static void kick_sync_wait_bal_cb (struct rq *rq) +{ +struct scx_kick_syncs __rcu *ks =__this_cpu_read (scx_kick_syncs); +unsigned long *ksyncs =rcu_dereference_sched (ks)->syncs; +bool waited; +s32 cpu; + +/* +* Drop rq lock and enable IRQs while waiting. IRQs must be enabled +* — a target CPU may be waiting for us to process an IPI (e.g. TLB +* flush) while we wait for its kick_sync to advance. +* +* Also, keep advancing our own kick_sync so that new kick_sync waits +* targeting us, which can start after we drop the lock, cannot form +* cyclic dependencies. +*/ +retry: + waited = false; +for_each_cpu (cpu, rq->scx.cpus_to_sync) { +/* +* smp_load_acquire() pairs with smp_store_release() on +* kick_sync updates on the target CPUs. +*/ +if (cpu ==cpu_of (rq) || +smp_load_acquire (&cpu_rq (cpu)->scx.kick_sync) != ksyncs[cpu]) { +cpumask_clear_cpu (cpu, rq->scx.cpus_to_sync); +continue ; + } + +raw_spin_rq_unlock_irq (rq); +while (READ_ONCE (cpu_rq (cpu)->scx.kick_sync) == ksyncs[cpu]) { +smp_store_release (&rq->scx.kick_sync, rq->scx.kick_sync +1 ); +cpu_relax (); + } +raw_spin_rq_lock_irq (rq); + waited = true; + } + +if (waited) + goto retry; +} +static struct task_struct *first_local_task (struct rq *rq) { return list_first_entry_or_null(&rq->scx.local_dsq.list,
@@ -2450,7 +2492,7 @@ do_pick_task_scx(struct rq *rq, struct rbool keep_prev;struct task_struct *p; -/* see kick_cpus_irq_workfn() */ +/* see kick_sync_wait_bal_cb() */ smp_store_release (&rq->scx.kick_sync, rq->scx.kick_sync +1 );rq_modified_clear (rq);
@@ -2461,6 +2503,17 @@ do_pick_task_scx(struct rq *rq, struct rmaybe_queue_balance_callback (rq);/* +* Defer to a balance callback which can drop rq lock and enable +* IRQs. Waiting directly in the pick path would deadlock against +* CPUs sending us IPIs (e.g. TLB flushes) while we wait for them. +*/ +if (unlikely (rq->scx.kick_sync_pending)) { + rq->scx.kick_sync_pending = false; +queue_balance_callback (rq, &rq->scx.kick_sync_bal_cb, + kick_sync_wait_bal_cb); + } + +/* * If any higher-priority sched class enqueued a runnable task on * this rq during balance_one(), abort and return RETRY_TASK, so * that the scheduler loop can restart.
@@ -4673,6 +4726,9 @@ static void scx_dump_state(struct scx_exif (!cpumask_empty (rq->scx.cpus_to_wait))dump_line (&ns," cpus_to_wait : %*pb" ,cpumask_pr_args (rq->scx.cpus_to_wait)); +if (!cpumask_empty (rq->scx.cpus_to_sync)) +dump_line (&ns," cpus_to_sync : %*pb" , +cpumask_pr_args (rq->scx.cpus_to_sync)); used =seq_buf_used (&ns);if (SCX_HAS_OP (sch, dump_cpu)) {
@@ -5571,11 +5627,11 @@ static bool kick_one_cpu(s32 cpu, structif (cpumask_test_cpu (cpu, this_scx->cpus_to_wait)) {if (cur_class == &ext_sched_class) { +cpumask_set_cpu (cpu, this_scx->cpus_to_sync); ksyncs[cpu] = rq->scx.kick_sync; should_wait = true; - }else { -cpumask_clear_cpu (cpu, this_scx->cpus_to_wait); } +cpumask_clear_cpu (cpu, this_scx->cpus_to_wait); }resched_curr (rq);
@@ -5630,27 +5686,15 @@ static void kick_cpus_irq_workfn(structcpumask_clear_cpu (cpu, this_scx->cpus_to_kick_if_idle); } -if (!should_wait) -return ; - -for_each_cpu (cpu, this_scx->cpus_to_wait) { -unsigned long *wait_kick_sync = &cpu_rq (cpu)->scx.kick_sync; - -/* -* Busy-wait until the task running at the time of kicking is no -* longer running. This can be used to implement e.g. core -* scheduling. -* -* smp_cond_load_acquire() pairs with store_releases in -* pick_task_scx() and put_prev_task_scx(). The former breaks -* the wait if SCX's scheduling path is entered even if the same -* task is picked subsequently. The latter is necessary to break -* the wait when $cpu is taken by a higher sched class. -*/ -if (cpu !=cpu_of (this_rq)) -smp_cond_load_acquire (wait_kick_sync,VAL != ksyncs[cpu]); - -cpumask_clear_cpu (cpu, this_scx->cpus_to_wait); +/* +* Can't wait in hardirq — kick_sync can't advance, deadlocking if +* CPUs wait for each other. Defer to kick_sync_wait_bal_cb(). +*/ +if (should_wait) { +raw_spin_rq_lock (this_rq); + this_scx->kick_sync_pending = true; +resched_curr (this_rq); +raw_spin_rq_unlock (this_rq); } }
@@ -5755,6 +5799,7 @@ void __init init_sched_ext_class(void)BUG_ON (!zalloc_cpumask_var_node (&rq->scx.cpus_to_kick_if_idle,GFP_KERNEL , n));BUG_ON (!zalloc_cpumask_var_node (&rq->scx.cpus_to_preempt,GFP_KERNEL , n));BUG_ON (!zalloc_cpumask_var_node (&rq->scx.cpus_to_wait,GFP_KERNEL , n)); +BUG_ON (!zalloc_cpumask_var_node (&rq->scx.cpus_to_sync,GFP_KERNEL , n)); rq->scx.deferred_irq_work =IRQ_WORK_INIT_HARD (deferred_irq_workfn); rq->scx.kick_cpus_irq_work =IRQ_WORK_INIT_HARD (kick_cpus_irq_workfn);
kernel/sched/sched.h +3 -0
@@ -803,9 +803,12 @@ struct scx_rq {cpumask_var_t cpus_to_kick_if_idle;cpumask_var_t cpus_to_preempt;cpumask_var_t cpus_to_wait; +cpumask_var_t cpus_to_sync; +bool kick_sync_pending;unsigned long kick_sync;local_t reenq_local_deferred;struct balance_callback deferred_bal_cb; +struct balance_callback kick_sync_bal_cb;struct irq_work deferred_irq_work;struct irq_work kick_cpus_irq_work;struct scx_dispatch_q bypass_dsq;
Greg Kroah-Hartman
maintainerPATCH 170/311 ALSA: caiaq: fix stack out-of-bounds read in init_card
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Berk Cem Goksel <[email protected]>
commit 45424e871abf2a152e247a9cff78359f18dd95c0 upstream.
The loop creates a whitespace-stripped copy of the card shortname where len < sizeof(card->id) is used for the bounds check. Since sizeof(card->id) is 16 and the local id buffer is also 16 bytes, writing 16 non-space characters fills the entire buffer, overwriting the terminating nullbyte.
When this non-null-terminated string is later passed to snd_card_set_id() -> copy_valid_id_string(), the function scans forward with while (*nid && ...) and reads past the end of the stack buffer, reading the contents of the stack.
A USB device with a product name containing many non-ASCII, non-space characters (e.g. multibyte UTF-8) will reliably trigger this as follows:
BUG: KASAN: stack-out-of-bounds in copy_valid_id_string
sound/core/init.c:696 [inline]
BUG: KASAN: stack-out-of-bounds in snd_card_set_id_no_lock+0x698/0x74c
sound/core/init.c:718The off-by-one has been present since commit bafeee5b1f8d ("ALSA:snd_usb_caiaq: give better shortname") from June 2009 (v2.6.31-rc1), which first introduced this whitespace-stripping loop. The original code never accounted for the null terminator when bounding the copy.
Fix this by changing the loop bound to sizeof(card->id) - 1, ensuring at least one byte remains as the null terminator.
--- sound/usb/caiaq/device.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/caiaq/device.c +1 -1
@@ -488,7 +488,7 @@ static int init_card(struct snd_usb_caiamemset (id,0 ,sizeof (id));for (c = card->shortname, len =0 ; - *c && len <sizeof (card->id); c++) + *c && len <sizeof (card->id) -1 ; c++)if (*c !=' ' ) id[len++] = *c;
Greg Kroah-Hartman
maintainerPATCH 171/311 ALSA: ctxfi: Check the error for index mapping
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 277c6960d4ddb94d16198afd70c92c3d4593d131 upstream.
The ctxfi driver blindly assumed a proper value returned from daio_device_index(), but it's not always true. Add a proper error check to deal with the error from the function.
--- sound/pci/ctxfi/ctdaio.c | 81 +++++++++++++++++++++++++++++------------------ 1 file changed, 50 insertions(+), 31 deletions(-)
sound/pci/ctxfi/ctdaio.c +50 -31
@@ -99,7 +99,7 @@ static const struct rsc_ops daio_in_rsc_ .output_slot = daio_index, }; -static unsigned int daio_device_index (enum DAIOTYP type,struct hw *hw) +static int daio_device_index (enum DAIOTYP type,struct hw *hw) {switch (hw->chip_type) {case ATC20K1 :
@@ -112,7 +112,9 @@ static unsigned int daio_device_index(encase LINEO3 :return 5 ;case LINEO4 :return 6 ;case LINEIM :return 7 ; -default :return -EINVAL ; +default : +pr_err ("ctxfi: Invalid type %d for hw20k1\n" , type); +return -EINVAL ; }case ATC20K2 :switch (type) {
@@ -125,9 +127,12 @@ static unsigned int daio_device_index(encase LINEIM :return 4 ;case MIC :return 5 ;case RCA :return 3 ; -default :return -EINVAL ; +default : +pr_err ("ctxfi: Invalid type %d for hw20k2\n" , type); +return -EINVAL ; }default : +pr_err ("ctxfi: Invalid chip type %d\n" , hw->chip_type);return -EINVAL ; } }
@@ -148,8 +153,11 @@ static int dao_spdif_set_spos(struct daostatic int dao_commit_write (struct dao *dao) { - dao->hw->dao_commit_write (dao->hw, -daio_device_index (dao->daio.type, dao->hw), dao->ctrl_blk); +int idx =daio_device_index (dao->daio.type, dao->hw); + +if (idx <0 ) +return idx; + dao->hw->dao_commit_write (dao->hw, idx, dao->ctrl_blk);return 0 ; }
@@ -287,8 +295,11 @@ static int dai_set_enb_srt(struct dai *dstatic int dai_commit_write (struct dai *dai) { - dai->hw->dai_commit_write (dai->hw, -daio_device_index (dai->daio.type, dai->hw), dai->ctrl_blk); +int idx =daio_device_index (dai->daio.type, dai->hw); + +if (idx <0 ) +return idx; + dai->hw->dai_commit_write (dai->hw, idx, dai->ctrl_blk);return 0 ; }
@@ -367,7 +378,7 @@ static int dao_rsc_init(struct dao *dao, {struct hw *hw = mgr->mgr.hw;unsigned int conf; -int err; +int idx, err; err =daio_rsc_init (&dao->daio, desc, mgr->mgr.hw);if (err)
@@ -386,15 +397,18 @@ static int dao_rsc_init(struct dao *dao,if (err) goto error2; - hw->daio_mgr_dsb_dao (mgr->mgr.ctrl_blk, -daio_device_index (dao->daio.type, hw)); + idx =daio_device_index (dao->daio.type, hw); +if (idx <0 ) { + err = idx; + goto error2; + } + + hw->daio_mgr_dsb_dao (mgr->mgr.ctrl_blk, idx); hw->daio_mgr_commit_write (hw, mgr->mgr.ctrl_blk); conf = (desc->msr &0x7 ) | (desc->passthru <<3 ); - hw->daio_mgr_dao_init (hw, mgr->mgr.ctrl_blk, -daio_device_index (dao->daio.type, hw), conf); - hw->daio_mgr_enb_dao (mgr->mgr.ctrl_blk, -daio_device_index (dao->daio.type, hw)); + hw->daio_mgr_dao_init (hw, mgr->mgr.ctrl_blk, idx, conf); + hw->daio_mgr_enb_dao (mgr->mgr.ctrl_blk, idx); hw->daio_mgr_commit_write (hw, mgr->mgr.ctrl_blk);return 0 ;
@@ -443,7 +457,7 @@ static int dai_rsc_init(struct dai *dai,const struct daio_desc *desc, struct daio_mgr *mgr) { - int err; + int idx, err;struct hw *hw = mgr->mgr.hw;unsigned int rsr, msr;
@@ -457,6 +471,12 @@ static int dai_rsc_init(struct dai *dai,if (err) goto error1; + idx =daio_device_index (dai->daio.type, dai->hw); +if (idx <0 ) { + err = idx; + goto error1; + } +for (rsr =0 , msr = desc->msr; msr >1 ; msr >>=1 ) rsr++;
@@ -465,8 +485,7 @@ static int dai_rsc_init(struct dai *dai,/* default to disabling control of a SRC */ hw->dai_srt_set_ec (dai->ctrl_blk,0 ); hw->dai_srt_set_et (dai->ctrl_blk,0 );/* default to disabling SRT */ - hw->dai_commit_write (hw, -daio_device_index (dai->daio.type, dai->hw), dai->ctrl_blk); + hw->dai_commit_write (hw, idx, dai->ctrl_blk);return 0 ;
@@ -581,28 +600,28 @@ static int put_daio_rsc(struct daio_mgrstatic int daio_mgr_enb_daio (struct daio_mgr *mgr,struct daio *daio) {struct hw *hw = mgr->mgr.hw; +int idx =daio_device_index (daio->type, hw); -if (daio->output) { - hw->daio_mgr_enb_dao (mgr->mgr.ctrl_blk, -daio_device_index (daio->type, hw)); - }else { - hw->daio_mgr_enb_dai (mgr->mgr.ctrl_blk, -daio_device_index (daio->type, hw)); - } +if (idx <0 ) +return idx; +if (daio->output) + hw->daio_mgr_enb_dao (mgr->mgr.ctrl_blk, idx); +else + hw->daio_mgr_enb_dai (mgr->mgr.ctrl_blk, idx);return 0 ; }static int daio_mgr_dsb_daio (struct daio_mgr *mgr,struct daio *daio) {struct hw *hw = mgr->mgr.hw; +int idx =daio_device_index (daio->type, hw); -if (daio->output) { - hw->daio_mgr_dsb_dao (mgr->mgr.ctrl_blk, -daio_device_index (daio->type, hw)); - }else { - hw->daio_mgr_dsb_dai (mgr->mgr.ctrl_blk, -daio_device_index (daio->type, hw)); - } +if (idx <0 ) +return idx; +if (daio->output) + hw->daio_mgr_dsb_dao (mgr->mgr.ctrl_blk, idx); +else + hw->daio_mgr_dsb_dai (mgr->mgr.ctrl_blk, idx);return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 172/311 ALSA: ctxfi: Fix missing SPDIFI1 index handling
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit b045ab3dff97edae6d538eeff900a34c098761f8 upstream.
SPDIF1 DAIO type isn't properly handled in daio_device_index() for hw20k2, and it returned -EINVAL, which ended up with the out-of-bounds array access. Follow the hw20k1 pattern and return the proper index for this type, too.
--- sound/pci/ctxfi/ctdaio.c | 1 + 1 file changed, 1 insertion(+)
sound/pci/ctxfi/ctdaio.c +1 -0
@@ -120,6 +120,7 @@ static int daio_device_index(enum DAIOTYswitch (type) {case SPDIFOO :return 0 ;case SPDIFIO :return 0 ; +case SPDIFI1 :return 1 ;case LINEO1 :return 4 ;case LINEO2 :return 7 ;case LINEO3 :return 5 ;
Greg Kroah-Hartman
maintainerPATCH 173/311 ALSA: ctxfi: Dont enumerate SPDIF1 at DAIO initialization
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Takashi Iwai <[email protected]>
commit 75dc1980cf48826287e43dc7a49e310c6691f97e upstream.
The recent refactoring of xfi driver changed the assignment of atc->daios[] at atc_get_resources(); now it loops over all enum DAIOTYP entries while it looped formerly only a part of them. The problem is that the last entry, SPDIF1, is a special type that is used only for hw20k1 CTSB073X model (as a replacement of SPDIFIO), and there is no corresponding definition for hw20k2. Due to the lack of the info, it caused a kernel crash on hw20k2, which was already worked around by the commit b045ab3dff97 ("ALSA: ctxfi: Fix missing SPDIFI1 index handling").
This patch addresses the root cause of the regression above properly, simply by skipping the incorrect SPDIF1 type in the parser loop.
For making the change clearer, the code is slightly arranged, too.
--- sound/pci/ctxfi/ctatc.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-)
sound/pci/ctxfi/ctatc.c +7 -3
@@ -1427,10 +1427,14 @@ static int atc_get_resources(struct ct_a daio_mgr = (struct daio_mgr *)atc->rsc_mgrs[DAIO ]; da_desc.msr = atc->msr;for (i =0 ; i <NUM_DAIOTYP ; i++) { -if (((i ==MIC ) && !cap.dedicated_mic) || ((i ==RCA ) && !cap.dedicated_rca)) +if (((i ==MIC ) && !cap.dedicated_mic) || + ((i ==RCA ) && !cap.dedicated_rca) || + i ==SPDIFI1 )continue ; - da_desc.type = (atc->model !=CTSB073X ) ? i : - ((i ==SPDIFIO ) ?SPDIFI1 : i); +if (atc->model ==CTSB073X && i ==SPDIFIO ) + da_desc.type =SPDIFI1 ; +else + da_desc.type = i; da_desc.output = (i <LINEIM ) || (i ==RCA ); err = daio_mgr->get_daio (daio_mgr, &da_desc, (struct daio **)&atc->daios[i]);
Greg Kroah-Hartman
maintainerPATCH 174/311 ALSA: hda/realtek: add quirk for Acer Swift SFG14-73
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
commit dd9b99b822684f421f9b7e1e5a69d791ffc1d48f upstream.
fix mute/micmute LEDs and headset microphone for Acer Swift SFG14-73.
--- sound/hda/codecs/realtek/alc269.c | 1 + 1 file changed, 1 insertion(+)
sound/hda/codecs/realtek/alc269.c +1 -0
@@ -6685,6 +6685,7 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x1025 ,0x1597 ,"Acer Nitro 5 AN517-55" ,ALC2XX_FIXUP_HEADSET_MIC ),SND_PCI_QUIRK (0x1025 ,0x169a ,"Acer Swift SFG16" ,ALC256_FIXUP_ACER_SFG16_MICMUTE_LED ),SND_PCI_QUIRK (0x1025 ,0x171e ,"Acer Nitro ANV15-51" ,ALC245_FIXUP_ACER_MICMUTE_LED ), +SND_PCI_QUIRK (0x1025 ,0x173a ,"Acer Swift SFG14-73" ,ALC245_FIXUP_ACER_MICMUTE_LED ),SND_PCI_QUIRK (0x1025 ,0x1826 ,"Acer Helios ZPC" ,ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x1025 ,0x182c ,"Acer Helios ZPD" ,ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2 ), SND_PCI_QUIRK(0x1025, 0x1844, "Acer Helios ZPS", ALC287_FIXUP_PREDATOR_SPK_CS35L41_I2C_2),
Greg Kroah-Hartman
maintainerPATCH 175/311 ALSA: hda/realtek: Add quirk for ASUS ROG Strix SCAR 15
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
commit f1af71d568e55536d9297bfa7907ad497108cf30 upstream.
ASUS ROG Strix SCAR 15, like the Strix G15, requires the ALC285_FIXUP_ASUS_G533Z_PINS quirk to work properly.
--- sound/hda/codecs/realtek/alc269.c | 1 + 1 file changed, 1 insertion(+)
sound/hda/codecs/realtek/alc269.c +1 -0
@@ -7238,6 +7238,7 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x1043 ,0x1533 ,"ASUS GV302XA/XJ/XQ/XU/XV/XI" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x1043 ,0x1573 ,"ASUS GZ301VV/VQ/VU/VJ/VA/VC/VE/VVC/VQC/VUC/VJC/VEC/VCC" ,ALC285_FIXUP_ASUS_HEADSET_MIC ),SND_PCI_QUIRK (0x1043 ,0x1584 ,"ASUS UM3406GA " ,ALC287_FIXUP_CS35L41_I2C_2 ), +SND_PCI_QUIRK (0x1043 ,0x1602 ,"ASUS ROG Strix SCAR 15" ,ALC285_FIXUP_ASUS_G533Z_PINS ),SND_PCI_QUIRK (0x1043 ,0x1652 ,"ASUS ROG Zephyrus Do 15 SE" ,ALC289_FIXUP_ASUS_ZEPHYRUS_DUAL_SPK ),SND_PCI_QUIRK (0x1043 ,0x1662 ,"ASUS GV301QH" ,ALC294_FIXUP_ASUS_DUAL_SPK ), SND_PCI_QUIRK(0x1043, 0x1663, "ASUS GU603ZI/ZJ/ZQ/ZU/ZV", ALC285_FIXUP_ASUS_HEADSET_MIC),
Greg Kroah-Hartman
maintainerPATCH 176/311 ALSA: hda/realtek: add quirk for HP Victus 15-fb0xxx
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sourav Nayak <[email protected]>
commit 1fbf85dbf02c96c318e056fb5b8fc614758fee3c upstream.
This adds a mute led quirck for HP Victus 15-fb0xxx (103c:8a3d) model
- As it used 0x8(full bright)/0x7f(little dim) for mute led on and other values as 0ff (0x0, 0x4, ...)
- So, use ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT insted for safer approach
--- sound/hda/codecs/realtek/alc269.c | 1 + 1 file changed, 1 insertion(+)
sound/hda/codecs/realtek/alc269.c +1 -0
@@ -6981,6 +6981,7 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x103c ,0x8a30 ,"HP Envy 17" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8a31 ,"HP Envy 15" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8a34 ,"HP Pavilion x360 2-in-1 Laptop 14-ek0xxx" ,ALC245_FIXUP_HP_MUTE_LED_COEFBIT ), +SND_PCI_QUIRK (0x103c ,0x8a3d ,"HP Victus 15-fb0xxx (MB 8A3D)" ,ALC245_FIXUP_HP_MUTE_LED_V2_COEFBIT ),SND_PCI_QUIRK (0x103c ,0x8a4f ,"HP Victus 15-fa0xxx (MB 8A4F)" ,ALC245_FIXUP_HP_MUTE_LED_COEFBIT ),SND_PCI_QUIRK (0x103c ,0x8a6e ,"HP EDNA 360" ,ALC287_FIXUP_CS35L41_I2C_4 ), SND_PCI_QUIRK(0x103c, 0x8a74, "HP ProBook 440 G8 Notebook PC", ALC236_FIXUP_HP_GPIO_LED),
Greg Kroah-Hartman
maintainerPATCH 177/311 ALSA: hda/realtek: change quirk for HP OmniBook 7 Laptop 16-bh0xxx
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zhang Heng <[email protected]>
commit 73ff3916d803f7ca3a4325af649e46ff89d6c3a7 upstream.
HP OmniBook 7 Laptop 16-bh0xxx has the same PCI subsystem ID 0x103c8e60, and the ALC245 on it needs this quirk to control the mute LED.
--- sound/hda/codecs/realtek/alc269.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
sound/hda/codecs/realtek/alc269.c +8 -1
@@ -4102,6 +4102,7 @@ enum {ALC233_FIXUP_LENOVO_GPIO2_MIC_HOTKEY ,ALC245_FIXUP_BASS_HP_DAC ,ALC245_FIXUP_ACER_MICMUTE_LED , + ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED, };/* A special fixup for Lenovo C940 and Yoga Duet 7;
@@ -6631,6 +6632,12 @@ static const struct hda_fixup alc269_fix .v.func = alc285_fixup_hp_coef_micmute_led, .chained = true, .chain_id = ALC2XX_FIXUP_HEADSET_MIC, + }, + [ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED] = { + .type = HDA_FIXUP_FUNC, + .v.func = alc245_fixup_hp_mute_led_coefbit, + .chained = true, + .chain_id = ALC287_FIXUP_CS35L41_I2C_2, } };
@@ -7156,7 +7163,7 @@ static const struct hda_quirk alc269_fixSND_PCI_QUIRK (0x103c ,0x8e37 ,"HP 16 Piston OmniBook X" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8e3a ,"HP Agusta" ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8e3b ,"HP Agusta" ,ALC287_FIXUP_CS35L41_I2C_2 ), -SND_PCI_QUIRK (0x103c ,0x8e60 ,"HP Trekker " ,ALC287_FIXUP_CS35L41_I2C_2 ), +SND_PCI_QUIRK (0x103c ,0x8e60 ,"HP OmniBook 7 Laptop 16-bh0xxx" ,ALC245_FIXUP_CS35L41_I2C_2_MUTE_LED ),SND_PCI_QUIRK (0x103c ,0x8e61 ,"HP Trekker " ,ALC287_FIXUP_CS35L41_I2C_2 ),SND_PCI_QUIRK (0x103c ,0x8e62 ,"HP Trekker " ,ALC287_FIXUP_CS35L41_I2C_2 ), SND_PCI_QUIRK(0x103c, 0x8e8a, "HP NexusX", ALC245_FIXUP_HP_TAS2781_I2C_MUTE_LED),
Greg Kroah-Hartman
maintainerPATCH 178/311 io_uring/net: fix slab-out-of-bounds read in io_bundle_nbufs()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxi Qian <[email protected]>
commit b948f9d5d3057b01188e36664e7c7604d1c8ecb5 upstream.
sqe->len is __u32 but gets stored into sr->len which is int. When userspace passes sqe->len values exceeding INT_MAX (e.g. 0xFFFFFFFF), sr->len overflows to a negative value. This negative value propagates through the bundle recv/send path:
1. io_recv(): sel.val = sr->len (ssize_t gets -1)
2. io_recv_buf_select(): arg.max_len = sel->val (size_t gets
0xFFFFFFFFFFFFFFFF)
3. io_ring_buffers_peek(): buf->len is not clamped because max_len is astronomically large
4. iov[].iov_len = 0xFFFFFFFF flows into io_bundle_nbufs()
5. io_bundle_nbufs(): min_t(int, 0xFFFFFFFF, ret) yields -1, causing ret to increase instead of decrease, creating an infinite loop that reads past the allocated iov[] array
This results in a slab-out-of-bounds read in io_bundle_nbufs() from the kmalloc-64 slab, as nbufs increments past the allocated iovec entries.
BUG: KASAN: slab-out-of-bounds in io_bundle_nbufs+0x128/0x160 Read of size 8 at addr ffff888100ae05c8 by task exp/145 Call Trace: io_bundle_nbufs+0x128/0x160 io_recv_finish+0x117/0xe20 io_recv+0x2db/0x1160
Fix this by rejecting negative sr->len values early in both io_sendmsg_prep() and io_recvmsg_prep(). Since sqe->len is __u32, any value > INT_MAX indicates overflow and is not a valid length.
--- io_uring/net.c | 4 ++++ 1 file changed, 4 insertions(+)
io_uring/net.c +4 -0
@@ -421,6 +421,8 @@ int io_sendmsg_prep(struct io_kiocb *req sr->done_io =0 ; sr->len =READ_ONCE (sqe->len); +if (unlikely (sr->len <0 )) +return -EINVAL ; sr->flags =READ_ONCE (sqe->ioprio);if (sr->flags & ~SENDMSG_FLAGS )return -EINVAL ;
@@ -791,6 +793,8 @@ int io_recvmsg_prep(struct io_kiocb *req sr->umsg =u64_to_user_ptr (READ_ONCE (sqe->addr)); sr->len =READ_ONCE (sqe->len); +if (unlikely (sr->len <0 )) +return -EINVAL ; sr->flags =READ_ONCE (sqe->ioprio);if (sr->flags & ~RECVMSG_FLAGS )return -EINVAL ;
Greg Kroah-Hartman
maintainerPATCH 179/311 Bluetooth: SMP: derive legacy responder STK authentication from MITM state
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleh Konko <[email protected]>
commit 20756fec2f0108cb88e815941f1ffff88dc286fe upstream.
The legacy responder path in smp_random() currently labels the stored STK as authenticated whenever pending_sec_level is BT_SECURITY_HIGH. That reflects what the local service requested, not what the pairing flow actually achieved.
For Just Works/Confirm legacy pairing, SMP_FLAG_MITM_AUTH stays clear and the resulting STK should remain unauthenticated even if the local side requested HIGH security. Use the established MITM state when storing the responder STK so the key metadata matches the pairing result.
This also keeps the legacy path aligned with the Secure Connections code, which already treats JUST_WORKS/JUST_CFM as unauthenticated.
--- net/bluetooth/smp.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-)
net/bluetooth/smp.c +1 -4
@@ -1018,10 +1018,7 @@ static u8 smp_random(struct smp_chan *smsmp_s1 (smp->tk, smp->prnd, smp->rrnd, stk); -if (hcon->pending_sec_level ==BT_SECURITY_HIGH ) - auth =1 ; -else - auth =0 ; + auth =test_bit (SMP_FLAG_MITM_AUTH , &smp->flags) ?1 :0 ;/* Even though there's no _RESPONDER suffix this is the * responder STK we're adding for later lookup (the initiator
Greg Kroah-Hartman
maintainerPATCH 180/311 Bluetooth: SMP: force responder MITM requirements before building the pairing response
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleh Konko <[email protected]>
commit d05111bfe37bfd8bd4d2dfe6675d6bdeef43f7c7 upstream.
smp_cmd_pairing_req() currently builds the pairing response from the initiator auth_req before enforcing the local BT_SECURITY_HIGH requirement. If the initiator omits SMP_AUTH_MITM, the response can also omit it even though the local side still requires MITM.
tk_request() then sees an auth value without SMP_AUTH_MITM and may select JUST_CFM, making method selection inconsistent with the pairing policy the responder already enforces.
When the local side requires HIGH security, first verify that MITM can be achieved from the IO capabilities and then force SMP_AUTH_MITM in the response in both rsp.auth_req and auth. This keeps the responder auth bits and later method selection aligned.
--- net/bluetooth/smp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
net/bluetooth/smp.c +5 -1
@@ -1823,7 +1823,7 @@ static u8 smp_cmd_pairing_req(struct l2cif (sec_level > conn->hcon->pending_sec_level) conn->hcon->pending_sec_level = sec_level; -/* If we need MITM check that it can be achieved */ +/* If we need MITM check that it can be achieved. */ if (conn->hcon->pending_sec_level >=BT_SECURITY_HIGH ) {u8 method;
@@ -1831,6 +1831,10 @@ static u8 smp_cmd_pairing_req(struct l2c req->io_capability);if (method ==JUST_WORKS || method ==JUST_CFM )return SMP_AUTH_REQUIREMENTS ; + +/* Force MITM bit if it isn't set by the initiator. */ + auth |=SMP_AUTH_MITM ; + rsp.auth_req |=SMP_AUTH_MITM ; } key_size =min (req->max_key_size, rsp.max_key_size);
Greg Kroah-Hartman
maintainerPATCH 181/311 Bluetooth: hci_sync: fix stack buffer overflow in hci_le_big_create_sync
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: hkbinbin <[email protected]>
commit bc39a094730ce062fa034a529c93147c096cb488 upstream.
hci_le_big_create_sync() uses DEFINE_FLEX to allocate a struct hci_cp_le_big_create_sync on the stack with room for 0x11 (17) BIS entries. However, conn->num_bis can hold up to HCI_MAX_ISO_BIS (31) entries — validated against ISO_MAX_NUM_BIS (0x1f) in the caller hci_conn_big_create_sync(). When conn->num_bis is between 18 and 31, the memcpy that copies conn->bis into cp->bis writes up to 14 bytes past the stack buffer, corrupting adjacent stack memory.
This is trivially reproducible: binding an ISO socket with bc_num_bis = ISO_MAX_NUM_BIS (31) and calling listen() will eventually trigger hci_le_big_create_sync() from the HCI command sync worker, causing a KASAN-detectable stack-out-of-bounds write:
BUG: KASAN: stack-out-of-bounds in hci_le_big_create_sync+0x256/0x3b0 Write of size 31 at addr ffffc90000487b48 by task kworker/u9:0/71
Fix this by changing the DEFINE_FLEX count from the incorrect 0x11 to HCI_MAX_ISO_BIS, which matches the maximum number of BIS entries that conn->bis can actually carry.
--- net/bluetooth/hci_sync.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/hci_sync.c +2 -1
@@ -7210,7 +7210,8 @@ static void create_big_complete(struct hstatic int hci_le_big_create_sync (struct hci_dev *hdev,void *data) { - DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, 0x11); + DEFINE_FLEX(struct hci_cp_le_big_create_sync, cp, bis, num_bis, + HCI_MAX_ISO_BIS);struct hci_conn *conn = data;struct bt_iso_qos *qos = &conn->iso_qos;int err;
Greg Kroah-Hartman
maintainerPATCH 182/311 Bluetooth: hci_event: move wake reason storage into validated event handlers
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oleh Konko <[email protected]>
commit 2b2bf47cd75518c36fa2d41380e4a40641cc89cd upstream.
hci_store_wake_reason() is called from hci_event_packet() immediately after stripping the HCI event header but before hci_event_func() enforces the per-event minimum payload length from hci_ev_table. This means a short HCI event frame can reach bacpy() before any bounds check runs.
Rather than duplicating skb parsing and per-event length checks inside hci_store_wake_reason(), move wake-address storage into the individual event handlers after their existing event-length validation has succeeded. Convert hci_store_wake_reason() into a small helper that only stores an already-validated bdaddr while the caller holds hci_dev_lock(). Use the same helper after hci_event_func() with a NULL address to preserve the existing unexpected-wake fallback semantics when no validated event handler records a wake address.
Annotate the helper with __must_hold(&hdev->lock) and add lockdep_assert_held(&hdev->lock) so future call paths keep the lock contract explicit.
Call the helper from hci_conn_request_evt(), hci_conn_complete_evt(), hci_sync_conn_complete_evt(), le_conn_complete_evt(), hci_le_adv_report_evt(), hci_le_ext_adv_report_evt(), hci_le_direct_adv_report_evt(), hci_le_pa_sync_established_evt(), and hci_le_past_received_evt().
--- net/bluetooth/hci_event.c | 94 +++++++++++++++++----------------------------- 1 file changed, 35 insertions(+), 59 deletions(-)
net/bluetooth/hci_event.c +35 -59
@@ -80,6 +80,10 @@ static void *hci_le_ev_skb_pull(struct hreturn data; } +static void hci_store_wake_reason(struct hci_dev *hdev, + const bdaddr_t *bdaddr, u8 addr_type) + __must_hold(&hdev->lock); +static u8 hci_cc_inquiry_cancel (struct hci_dev *hdev,void *data,struct sk_buff *skb) {
@@ -3111,6 +3115,7 @@ static void hci_conn_complete_evt(structbt_dev_dbg (hdev,"status 0x%2.2x" , status);hci_dev_lock (hdev); +hci_store_wake_reason (hdev, &ev->bdaddr,BDADDR_BREDR );/* Check for existing connection: *
@@ -3274,6 +3279,10 @@ static void hci_conn_request_evt(structbt_dev_dbg (hdev,"bdaddr %pMR type 0x%x" , &ev->bdaddr, ev->link_type); +hci_dev_lock (hdev); +hci_store_wake_reason (hdev, &ev->bdaddr,BDADDR_BREDR ); +hci_dev_unlock (hdev); +/* Reject incoming connection from device with same BD ADDR against * CVE-2020-26555 */
@@ -5021,6 +5030,7 @@ static void hci_sync_conn_complete_evt(sbt_dev_dbg (hdev,"status 0x%2.2x" , status);hci_dev_lock (hdev); +hci_store_wake_reason (hdev, &ev->bdaddr,BDADDR_BREDR ); conn =hci_conn_hash_lookup_ba (hdev, ev->link_type, &ev->bdaddr);if (!conn) {
@@ -5713,6 +5723,7 @@ static void le_conn_complete_evt(structint err;hci_dev_lock (hdev); +hci_store_wake_reason (hdev, bdaddr, bdaddr_type);/* All controllers implicitly stop advertising in the event of a * connection, so ensure that the state bit is cleared.
@@ -6005,6 +6016,7 @@ static void hci_le_past_received_evt(strbt_dev_dbg (hdev,"status 0x%2.2x" , ev->status);hci_dev_lock (hdev); +hci_store_wake_reason (hdev, &ev->bdaddr, ev->bdaddr_type);hci_dev_clear_flag (hdev,HCI_PA_SYNC );
@@ -6403,6 +6415,8 @@ static void hci_le_adv_report_evt(struct info->length + 1))break ; +hci_store_wake_reason (hdev, &info->bdaddr, info->bdaddr_type); +if (info->length <=max_adv_len (hdev)) { rssi = info->data[info->length]; process_adv_report(hdev, info->type, &info->bdaddr,
@@ -6491,6 +6505,8 @@ static void hci_le_ext_adv_report_evt(st info->length))break ; +hci_store_wake_reason (hdev, &info->bdaddr, info->bdaddr_type); + evt_type =__le16_to_cpu (info->type) &LE_EXT_ADV_EVT_TYPE_MASK ; legacy_evt_type =ext_evt_type_to_legacy (hdev, evt_type);
@@ -6536,6 +6552,7 @@ static void hci_le_pa_sync_established_ebt_dev_dbg (hdev,"status 0x%2.2x" , ev->status);hci_dev_lock (hdev); +hci_store_wake_reason (hdev, &ev->bdaddr, ev->bdaddr_type);hci_dev_clear_flag (hdev,HCI_PA_SYNC );
@@ -6841,6 +6858,8 @@ static void hci_le_direct_adv_report_evtfor (i =0 ; i < ev->num; i++) {struct hci_ev_le_direct_adv_info *info = &ev->info[i]; +hci_store_wake_reason (hdev, &info->bdaddr, info->bdaddr_type); + process_adv_report(hdev, info->type, &info->bdaddr, info->bdaddr_type, &info->direct_addr, info->direct_addr_type, HCI_ADV_PHY_1M, 0,
@@ -7509,73 +7528,29 @@ static bool hci_get_cmd_complete(structreturn true; } -static void hci_store_wake_reason (struct hci_dev *hdev,u8 event, -struct sk_buff *skb) +static void hci_store_wake_reason (struct hci_dev *hdev, +const bdaddr_t *bdaddr,u8 addr_type) + __must_hold(&hdev->lock) { -struct hci_ev_le_advertising_info *adv; -struct hci_ev_le_direct_adv_info *direct_adv; -struct hci_ev_le_ext_adv_info *ext_adv; -const struct hci_ev_conn_complete *conn_complete = (void *)skb->data; -const struct hci_ev_conn_request *conn_request = (void *)skb->data; - -hci_dev_lock (hdev); +lockdep_assert_held (&hdev->lock);/* If we are currently suspended and this is the first BT event seen, * save the wake reason associated with the event. */ if (!hdev->suspended || hdev->wake_reason) - goto unlock; +return ; + +if (!bdaddr) { + hdev->wake_reason =MGMT_WAKE_REASON_UNEXPECTED ; +return ; + }/* Default to remote wake. Values for wake_reason are documented in the * Bluez mgmt api docs. */ hdev->wake_reason =MGMT_WAKE_REASON_REMOTE_WAKE ; - -/* Once configured for remote wakeup, we should only wake up for -* reconnections. It's useful to see which device is waking us up so -* keep track of the bdaddr of the connection event that woke us up. -*/ -if (event ==HCI_EV_CONN_REQUEST ) { -bacpy (&hdev->wake_addr, &conn_request->bdaddr); - hdev->wake_addr_type =BDADDR_BREDR ; - }else if (event ==HCI_EV_CONN_COMPLETE ) { -bacpy (&hdev->wake_addr, &conn_complete->bdaddr); - hdev->wake_addr_type =BDADDR_BREDR ; - }else if (event ==HCI_EV_LE_META ) { -struct hci_ev_le_meta *le_ev = (void *)skb->data; -u8 subevent = le_ev->subevent; -u8 *ptr = &skb->data[sizeof (*le_ev)]; -u8 num_reports = *ptr; - -if ((subevent ==HCI_EV_LE_ADVERTISING_REPORT || - subevent ==HCI_EV_LE_DIRECT_ADV_REPORT || - subevent ==HCI_EV_LE_EXT_ADV_REPORT ) && - num_reports) { - adv = (void *)(ptr +1 ); - direct_adv = (void *)(ptr +1 ); - ext_adv = (void *)(ptr +1 ); - -switch (subevent) { -case HCI_EV_LE_ADVERTISING_REPORT : -bacpy (&hdev->wake_addr, &adv->bdaddr); - hdev->wake_addr_type = adv->bdaddr_type; -break ; -case HCI_EV_LE_DIRECT_ADV_REPORT : -bacpy (&hdev->wake_addr, &direct_adv->bdaddr); - hdev->wake_addr_type = direct_adv->bdaddr_type; -break ; -case HCI_EV_LE_EXT_ADV_REPORT : -bacpy (&hdev->wake_addr, &ext_adv->bdaddr); - hdev->wake_addr_type = ext_adv->bdaddr_type; -break ; - } - } - }else { - hdev->wake_reason =MGMT_WAKE_REASON_UNEXPECTED ; - } - -unlock: -hci_dev_unlock (hdev); +bacpy (&hdev->wake_addr, bdaddr); + hdev->wake_addr_type = addr_type; }#define HCI_EV_VL (_op, _func, _min_len, _max_len) \
@@ -7822,14 +7797,15 @@ void hci_event_packet(struct hci_dev *hdskb_pull (skb,HCI_EVENT_HDR_SIZE ); -/* Store wake reason if we're suspended */ -hci_store_wake_reason (hdev, event, skb); -bt_dev_dbg (hdev,"event 0x%2.2x" , event);hci_event_func (hdev, event, skb, &opcode, &status, &req_complete, &req_complete_skb); +hci_dev_lock (hdev); +hci_store_wake_reason (hdev,NULL ,0 ); +hci_dev_unlock (hdev); +if (req_complete) {req_complete (hdev, status, opcode); }else if (req_complete_skb) {
Greg Kroah-Hartman
maintainerPATCH 183/311 ksmbd: fix OOB write in QUERY_INFO for compound requests
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Asim Viladi Oglu Manizada <[email protected]>
commit fda9522ed6afaec45cabc198d8492270c394c7bc upstream.
When a compound request such as READ + QUERY_INFO(Security) is received, and the first command (READ) consumes most of the response buffer, ksmbd could write beyond the allocated buffer while building a security descriptor.
The root cause was that smb2_get_info_sec() checked buffer space using ppntsd_size from xattr, while build_sec_desc() often synthesized a significantly larger descriptor from POSIX ACLs.
This patch introduces smb_acl_sec_desc_scratch_len() to accurately compute the final descriptor size beforehand, performs proper buffer checking with smb2_calc_max_out_buf_len(), and uses exact-sized allocation + iov pinning.
--- fs/smb/server/smb2pdu.c | 121 +++++++++++++++++++++++++++++++++++------------- fs/smb/server/smbacl.c | 43 +++++++++++++++++ fs/smb/server/smbacl.h | 2 3 files changed, 134 insertions(+), 32 deletions(-)
fs/smb/server/smb2pdu.c +89 -32
@@ -3401,20 +3401,24 @@ int smb2_open(struct ksmbd_work *work) KSMBD_SHARE_FLAG_ACL_XATTR)) {struct smb_fattr fattr;struct smb_ntsd *pntsd; -int pntsd_size, ace_num =0 ; +int pntsd_size; +size_t scratch_len;ksmbd_acls_fattr (&fattr, idmap, inode); -if (fattr.cf_acls) - ace_num = fattr.cf_acls->a_count; -if (fattr.cf_dacls) - ace_num += fattr.cf_dacls->a_count; - - pntsd =kmalloc (sizeof (struct smb_ntsd ) + -sizeof (struct smb_sid ) *3 + -sizeof (struct smb_acl ) + -sizeof (struct smb_ace ) * ace_num *2 , -KSMBD_DEFAULT_GFP ); + scratch_len =smb_acl_sec_desc_scratch_len (&fattr, +NULL ,0 , +OWNER_SECINFO |GROUP_SECINFO | +DACL_SECINFO ); +if (!scratch_len || scratch_len ==SIZE_MAX ) { + rc = -EFBIG ; +posix_acl_release (fattr.cf_acls); +posix_acl_release (fattr.cf_dacls); + goto err_out; + } + + pntsd =kvzalloc (scratch_len,KSMBD_DEFAULT_GFP );if (!pntsd) { + rc = -ENOMEM ;posix_acl_release (fattr.cf_acls);posix_acl_release (fattr.cf_dacls); goto err_out;
@@ -3429,7 +3433,7 @@ int smb2_open(struct ksmbd_work *work)posix_acl_release (fattr.cf_acls);posix_acl_release (fattr.cf_dacls);if (rc) { -kfree (pntsd); +kvfree (pntsd); goto err_out; }
@@ -3439,7 +3443,7 @@ int smb2_open(struct ksmbd_work *work) pntsd, pntsd_size, false); -kfree (pntsd); +kvfree (pntsd);if (rc)pr_err ("failed to store ntacl in xattr : %d\n" , rc);
@@ -5371,8 +5375,9 @@ static int smb2_get_info_file(struct ksmif (test_share_config_flag (work->tcon->share_conf,KSMBD_SHARE_FLAG_PIPE )) {/* smb2 info file called for pipe */ -return smb2_get_info_file_pipe (work->sess, req, rsp, + rc =smb2_get_info_file_pipe (work->sess, req, rsp, work->response_buf); + goto iov_pin_out; }if (work->next_smb2_rcv_hdr_off) {
@@ -5472,6 +5477,12 @@ static int smb2_get_info_file(struct ksm rc =buffer_check_err (le32_to_cpu (req->OutputBufferLength), rsp, work->response_buf);ksmbd_fd_put (work, fp); + +iov_pin_out: +if (!rc) + rc =ksmbd_iov_pin_rsp (work, (void *)rsp, + offsetof(struct smb2_query_info_rsp , Buffer) + +le32_to_cpu (rsp->OutputBufferLength));return rc; }
@@ -5698,6 +5709,11 @@ static int smb2_get_info_filesystem(stru rc =buffer_check_err (le32_to_cpu (req->OutputBufferLength), rsp, work->response_buf);path_put (&path); + +if (!rc) + rc =ksmbd_iov_pin_rsp (work, (void *)rsp, + offsetof(struct smb2_query_info_rsp , Buffer) + +le32_to_cpu (rsp->OutputBufferLength));return rc; }
@@ -5707,13 +5723,14 @@ static int smb2_get_info_sec(struct ksmb {struct ksmbd_file *fp;struct mnt_idmap *idmap; -struct smb_ntsd *pntsd = (struct smb_ntsd *)rsp->Buffer, *ppntsd =NULL ; +struct smb_ntsd *pntsd =NULL , *ppntsd =NULL ;struct smb_fattr fattr = {{0 }};struct inode *inode;__u32 secdesclen =0 ;unsigned int id =KSMBD_NO_FID , pid =KSMBD_NO_FID ;int addition_info =le32_to_cpu (req->AdditionalInformation); -int rc =0 , ppntsd_size =0 ; +int rc =0 , ppntsd_size =0 , max_len; +size_t scratch_len =0 ; if (addition_info & ~(OWNER_SECINFO | GROUP_SECINFO | DACL_SECINFO | PROTECTED_DACL_SECINFO |
@@ -5721,6 +5738,11 @@ static int smb2_get_info_sec(struct ksmbksmbd_debug (SMB ,"Unsupported addition info: 0x%x)\n" , addition_info); + pntsd =kzalloc (ALIGN (sizeof (struct smb_ntsd ),8 ), +KSMBD_DEFAULT_GFP ); +if (!pntsd) +return -ENOMEM ; + pntsd->revision =cpu_to_le16 (1 ); pntsd->type =cpu_to_le16 (SELF_RELATIVE |DACL_PROTECTED ); pntsd->osidoffset =0 ;
@@ -5729,9 +5751,7 @@ static int smb2_get_info_sec(struct ksmb pntsd->dacloffset =0 ; secdesclen =sizeof (struct smb_ntsd ); - rsp->OutputBufferLength =cpu_to_le32 (secdesclen); - -return 0 ; + goto iov_pin; }if (work->next_smb2_rcv_hdr_off) {
@@ -5763,18 +5783,58 @@ static int smb2_get_info_sec(struct ksmb &ppntsd);/* Check if sd buffer size exceeds response buffer size */ -if (smb2_resp_buf_len (work,8 ) > ppntsd_size) - rc =build_sec_desc (idmap, pntsd, ppntsd, ppntsd_size, - addition_info, &secdesclen, &fattr); + max_len =smb2_calc_max_out_buf_len (work, + offsetof(struct smb2_query_info_rsp , Buffer), +le32_to_cpu (req->OutputBufferLength)); +if (max_len <0 ) { + rc = -EINVAL ; + goto release_acl; + } + + scratch_len =smb_acl_sec_desc_scratch_len (&fattr, ppntsd, + ppntsd_size, addition_info); +if (!scratch_len || scratch_len ==SIZE_MAX ) { + rc = -EFBIG ; + goto release_acl; + } + + pntsd =kvzalloc (scratch_len,KSMBD_DEFAULT_GFP ); +if (!pntsd) { + rc = -ENOMEM ; + goto release_acl; + } + + rc =build_sec_desc (idmap, pntsd, ppntsd, ppntsd_size, + addition_info, &secdesclen, &fattr); + +release_acl:posix_acl_release (fattr.cf_acls);posix_acl_release (fattr.cf_dacls);kfree (ppntsd);ksmbd_fd_put (work, fp); + +if (!rc &&ALIGN (secdesclen,8 ) > scratch_len) + rc = -EFBIG ;if (rc) -return rc; + goto err_out; +iov_pin: rsp->OutputBufferLength =cpu_to_le32 (secdesclen); -return 0 ; + rc =buffer_check_err (le32_to_cpu (req->OutputBufferLength), + rsp, work->response_buf); +if (rc) + goto err_out; + + rc =ksmbd_iov_pin_rsp_read (work, (void *)rsp, + offsetof(struct smb2_query_info_rsp , Buffer), + pntsd, secdesclen); +err_out: +if (rc) { + rsp->OutputBufferLength =0 ; +kvfree (pntsd); + } + +return rc; }/**
@@ -5798,6 +5858,9 @@ int smb2_query_info(struct ksmbd_work *w goto err_out; } + rsp->StructureSize =cpu_to_le16 (9 ); + rsp->OutputBufferOffset =cpu_to_le16 (72 ); +switch (req->InfoType) {case SMB2_O_INFO_FILE :ksmbd_debug (SMB ,"GOT SMB2_O_INFO_FILE\n" );
@@ -5818,14 +5881,6 @@ int smb2_query_info(struct ksmbd_work *w }ksmbd_revert_fsids (work); -if (!rc) { - rsp->StructureSize =cpu_to_le16 (9 ); - rsp->OutputBufferOffset =cpu_to_le16 (72 ); - rc =ksmbd_iov_pin_rsp (work, (void *)rsp, - offsetof(struct smb2_query_info_rsp , Buffer) + -le32_to_cpu (rsp->OutputBufferLength)); - } - err_out:if (rc <0 ) {if (rc == -EACCES )
@@ -5836,6 +5891,8 @@ err_out: rsp->hdr.Status =STATUS_UNEXPECTED_IO_ERROR ; else if (rc == -ENOMEM) rsp->hdr.Status = STATUS_INSUFFICIENT_RESOURCES; + else if (rc == -EINVAL && rsp->hdr.Status == 0) + rsp->hdr.Status =STATUS_INVALID_PARAMETER ; else if (rc == -EOPNOTSUPP || rsp->hdr.Status == 0) rsp->hdr.Status =STATUS_INVALID_INFO_CLASS ;smb2_set_err_rsp (work);
fs/smb/server/smbacl.c +43 -0
49 lines not on this page · raw message
fs/smb/server/smbacl.h +2 -0
@@ -101,6 +101,8 @@ int set_info_sec(struct ksmbd_conn *conn bool type_check, bool get_write);void id_to_sid (unsigned int cid,uint sidtype,struct smb_sid *ssid);void ksmbd_init_domain (u32 *sub_auth); +size_t smb_acl_sec_desc_scratch_len (struct smb_fattr *fattr, +struct smb_ntsd *ppntsd,int ppntsd_size,int addition_info);static inline uid_t posix_acl_uid_translate (struct mnt_idmap *idmap,struct posix_acl_entry *pace)
Greg Kroah-Hartman
maintainerPATCH 184/311 MIPS: SiByte: Bring back cache initialisation
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit d62cf1511743526f530a4c169424e50c757f5a5e upstream.
Bring back cache initialisation for Broadcom SiByte SB1 cores, which has been removed causing the kernel to hang at bootstrap right after:
Dentry cache hash table entries: 524288 (order: 8, 4194304 bytes, linear) Inode-cache hash table entries: 262144 (order: 7, 2097152 bytes, linear)
The cause of the problem is R4k cache handlers are also used by Broadcom SiByte SB1 cores, however with a different cache error exception handler and therefore not using CPU_R4K_CACHE_TLB:
obj-$(CONFIG_CPU_R4K_CACHE_TLB) += c-r4k.o cex-gen.o tlb-r4k.o
obj-$(CONFIG_CPU_SB1) += c-r4k.o cerr-sb1.o cex-sb1.o tlb-r4k.o
(from arch/mips/mm/Makefile).
--- arch/mips/mm/cache.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
arch/mips/mm/cache.c +2 -1
@@ -207,7 +207,8 @@ void cpu_cache_init(void) {if (IS_ENABLED (CONFIG_CPU_R3000 ) && cpu_has_3k_cache)r3k_cache_init (); -if (IS_ENABLED (CONFIG_CPU_R4K_CACHE_TLB ) && cpu_has_4k_cache) +if ((IS_ENABLED (CONFIG_CPU_R4K_CACHE_TLB ) || +IS_ENABLED (CONFIG_CPU_SB1 )) && cpu_has_4k_cache)r4k_cache_init ();if (IS_ENABLED (CONFIG_CPU_CAVIUM_OCTEON ) && cpu_has_octeon_cache)
Greg Kroah-Hartman
maintainerPATCH 185/311 MIPS: Fix the GCC version check for `__multi3 workaround
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Maciej W. Rozycki <[email protected]>
commit ec8bf18814915460d9c617b556bf024efef26613 upstream.
It was only GCC 10 that fixed a MIPS64r6 code generation issue with a `__multi3' libcall inefficiently produced to perform 64-bit widening multiplication while suitable machine instructions exist to do such a calculation. The fix went in with GCC commit 48b2123f6336 ("re PR target/82981 (unnecessary __multi3 call for mips64r6 linux kernel)").
Adjust our code accordingly, removing build failures such as:
mips64-linux-ld: lib/math/div64.o: in function `mul_u64_add_u64_div_u64':
div64.c:(.text+0x84): undefined reference to `__multi3'
with the GCC versions affected.
--- arch/mips/lib/multi3.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
arch/mips/lib/multi3.c +3 -3
@@ -4,12 +4,12 @@#include "libgcc.h" /* -* GCC 7 & older can suboptimally generate __multi3 calls for mips64r6, so for +* GCC 9 & older can suboptimally generate __multi3 calls for mips64r6, so for * that specific case only we implement that intrinsic here. * * See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=82981 */ -#if defined(CONFIG_64BIT ) && defined(CONFIG_CPU_MIPSR6 ) && (__GNUC__ <8 ) +#if defined(CONFIG_64BIT ) && defined(CONFIG_CPU_MIPSR6 ) && (__GNUC__ <10 )/* multiply 64-bit values, low 64-bits returned */ static inline long long notrace dmulu (long long a,long long b)
@@ -51,4 +51,4 @@ ti_type notrace __multi3(ti_type a, ti_t }EXPORT_SYMBOL (__multi3); -#endif /* 64BIT && CPU_MIPSR6 && GCC7 */ +#endif /* 64BIT && CPU_MIPSR6 && GCC9 */
Greg Kroah-Hartman
maintainerPATCH 186/311 hwmon: (occ) Fix division by zero in occ_show_power_1()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sanman Pradhan <[email protected]>
commit 39e2a5bf970402a8530a319cf06122e216ba57b8 upstream.
In occ_show_power_1() case 1, the accumulator is divided by update_tag without checking for zero. If no samples have been collected yet (e.g. during early boot when the sensor block is included but hasn't been updated), update_tag is zero, causing a kernel divide-by-zero crash.
The 2019 fix in commit 211186cae14d ("hwmon: (occ) Fix division by zero issue") only addressed occ_get_powr_avg() used by occ_show_power_2() and occ_show_power_a0(). This separate code path in occ_show_power_1() was missed.
Fix this by reusing the existing occ_get_powr_avg() helper, which already handles the zero-sample case and uses mul_u64_u32_div() to multiply before dividing for better precision. Move the helper above occ_show_power_1() so it is visible at the call site.
--- drivers/hwmon/occ/common.c | 17 ++++++++--------- 1 file changed, 8 insertions(+), 9 deletions(-)
drivers/hwmon/occ/common.c +8 -9
@@ -420,6 +420,12 @@ static ssize_t occ_show_freq_2(struct dereturn sysfs_emit (buf,"%u\n" , val); } +static u64 occ_get_powr_avg (u64 accum,u32 samples) +{ +return (samples ==0 ) ?0 : +mul_u64_u32_div (accum,1000000UL , samples); +} +static ssize_t occ_show_power_1 (struct device *dev,struct device_attribute *attr,char *buf) {
@@ -441,9 +447,8 @@ static ssize_t occ_show_power_1(struct d val =get_unaligned_be16 (&power->sensor_id);break ;case 1 : - val =get_unaligned_be32 (&power->accumulator) / -get_unaligned_be32 (&power->update_tag); - val *=1000000ULL ; + val =occ_get_powr_avg (get_unaligned_be32 (&power->accumulator), +get_unaligned_be32 (&power->update_tag));break ;case 2 : val = (u64)get_unaligned_be32(&power->update_tag) *
@@ -459,12 +464,6 @@ static ssize_t occ_show_power_1(struct dreturn sysfs_emit (buf,"%llu\n" , val); } -static u64 occ_get_powr_avg (u64 accum,u32 samples) -{ -return (samples ==0 ) ?0 : -mul_u64_u32_div (accum,1000000UL , samples); -} -static ssize_t occ_show_power_2 (struct device *dev,struct device_attribute *attr,char *buf) {
Greg Kroah-Hartman
maintainerPATCH 187/311 mips: mm: Allocate tlb_vpn array atomically
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wiehler <[email protected]>
commit 01cc50ea5167bb14117257ec084637abe9e5f691 upstream.
Found by DEBUG_ATOMIC_SLEEP:
BUG: sleeping function called from invalid context at /include/linux/sched/mm.h:306
in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 0, name: swapper/1
preempt_count: 1, expected: 0
RCU nest depth: 0, expected: 0
no locks held by swapper/1/0.
irq event stamp: 0
hardirqs last enabled at (0): [<0000000000000000>] 0x0
hardirqs last disabled at (0): [<ffffffff801477fc>] copy_process+0x75c/0x1b68
softirqs last enabled at (0): [<ffffffff801477fc>] copy_process+0x75c/0x1b68
softirqs last disabled at (0): [<0000000000000000>] 0x0
CPU: 1 PID: 0 Comm: swapper/1 Not tainted 6.6.119-d79e757675ec-fct #1
Stack : 800000000290bad8 0000000000000000 0000000000000008 800000000290bae8
800000000290bae8 800000000290bc78 0000000000000000 0000000000000000
ffffffff80c80000 0000000000000001 ffffffff80d8dee8 ffffffff810d09c0
784bb2a7ec10647d 0000000000000010 ffffffff80a6fd60 8000000001d8a9c0
0000000000000000 0000000000000000 ffffffff80d90000 0000000000000000
ffffffff80c9e0e8 0000000007ffffff 0000000000000cc0 0000000000000400
ffffffffffffffff 0000000000000001 0000000000000002 ffffffffc0149ed8
fffffffffffffffe 8000000002908000 800000000290bae0 ffffffff80a81b74
ffffffff80129fb0 0000000000000000 0000000000000000 0000000000000000
0000000000000000 0000000000000000 ffffffff80129fd0 0000000000000000
...
Call Trace:
[<ffffffff80129fd0>] show_stack+0x60/0x158
[<ffffffff80a7f894>] dump_stack_lvl+0x88/0xbc
[<ffffffff8018d3c8>] __might_resched+0x268/0x288
[<ffffffff803648b0>] __kmem_cache_alloc_node+0x2e0/0x330
[<ffffffff80302788>] __kmalloc+0x58/0xd0
[<ffffffff80a81b74>] r4k_tlb_uniquify+0x7c/0x428
[<ffffffff80143e8c>] tlb_init+0x7c/0x110
[<ffffffff8012bdb4>] per_cpu_trap_init+0x16c/0x1d0
[<ffffffff80133258>] start_secondary+0x28/0x128--- arch/mips/mm/tlb-r4k.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
arch/mips/mm/tlb-r4k.c +1 -1
@@ -538,7 +538,7 @@ static void __ref r4k_tlb_uniquify(void) tlb_vpn_size = tlbsize *sizeof (*tlb_vpns); tlb_vpns = (use_slab ? -kmalloc (tlb_vpn_size,GFP_KERNEL ) : +kmalloc (tlb_vpn_size,GFP_ATOMIC ) :memblock_alloc_raw (tlb_vpn_size,sizeof (*tlb_vpns)));if (WARN_ON (!tlb_vpns))return ;/* Pray local_flush_tlb_all() is good enough. */
Greg Kroah-Hartman
maintainerPATCH 188/311 x86/kexec: Disable KCOV instrumentation after load_segments()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aleksandr Nogikh <[email protected]>
commit 917e3ad3321e75ca0223d5ccf26ceda116aa51e1 upstream.
The load_segments() function changes segment registers, invalidating GS base (which KCOV relies on for per-cpu data). When CONFIG_KCOV is enabled, any subsequent instrumented C code call (e.g. native_gdt_invalidate()) begins crashing the kernel in an endless loop.
To reproduce the problem, it's sufficient to do kexec on a KCOV-instrumented kernel:
$ kexec -l /boot/otherKernel $ kexec -e
The real-world context for this problem is enabling crash dump collection in syzkaller. For this, the tool loads a panic kernel before fuzzing and then calls makedumpfile after the panic. This workflow requires both CONFIG_KEXEC and CONFIG_KCOV to be enabled simultaneously.
Adding safeguards directly to the KCOV fast-path (__sanitizer_cov_trace_pc()) is also undesirable as it would introduce an extra performance overhead.
Disabling instrumentation for the individual functions would be too fragile, so disable KCOV instrumentation for the entire machine_kexec_64.c and physaddr.c. If coverage-guided fuzzing ever needs these components in the future, other approaches should be considered.
The problem is not relevant for 32 bit kernels as CONFIG_KCOV is not supported there.
[ bp: Space out comment for better readability. ]
--- arch/x86/kernel/Makefile | 14 ++++++++++++++ arch/x86/mm/Makefile | 2 ++ 2 files changed, 16 insertions(+)
arch/x86/kernel/Makefile +14 -0
@@ -44,6 +44,20 @@ KCOV_INSTRUMENT_unwind_orc.o := n KCOV_INSTRUMENT_unwind_frame.o := n KCOV_INSTRUMENT_unwind_guess.o := n +# Disable KCOV to prevent crashes during kexec: load_segments() invalidates +# the GS base, which KCOV relies on for per-CPU data. +# +# As KCOV and KEXEC compatibility should be preserved (e.g. syzkaller is +# using it to collect crash dumps during kernel fuzzing), disabling +# KCOV for KEXEC kernels is not an option. Selectively disabling KCOV +# instrumentation for individual affected functions can be fragile, while +# adding more checks to KCOV would slow it down. +# +# As a compromise solution, disable KCOV instrumentation for the whole +# source code file. If its coverage is ever needed, other approaches +# should be considered. +KCOV_INSTRUMENT_machine_kexec_64.o := n + CFLAGS_head32.o := -fno-stack-protector CFLAGS_head64.o := -fno-stack-protector CFLAGS_irq.o := -I $(src)/../include/asm/trace
arch/x86/mm/Makefile +2 -0
@@ -4,6 +4,8 @@ KCOV_INSTRUMENT_tlb.o := n KCOV_INSTRUMENT_mem_encrypt.o := n KCOV_INSTRUMENT_mem_encrypt_amd.o := n KCOV_INSTRUMENT_pgprot.o := n +# See the "Disable KCOV" comment in arch/x86/kernel/Makefile. +KCOV_INSTRUMENT_physaddr.o := n KASAN_SANITIZE_mem_encrypt.o := n KASAN_SANITIZE_mem_encrypt_amd.o := n
Greg Kroah-Hartman
maintainerPATCH 189/311 drm/amdgpu: fix the idr allocation flags
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Prike Liang <[email protected]>
commit 62f553d60a801384336f5867967c26ddf3b17038 upstream.
Fix the IDR allocation flags by using atomic GFP flags in non‑sleepable contexts to avoid the __might_sleep() complaint.
268.290239] [drm] Initialized amdgpu 3.64.0 for 0000:03:00.0 on minor 0
[ 268.294900] BUG: sleeping function called from invalid context at ./include/linux/sched/mm.h:323
[ 268.295355] in_atomic(): 1, irqs_disabled(): 0, non_block: 0, pid: 1744, name: modprobe
[ 268.295705] preempt_count: 1, expected: 0
[ 268.295886] RCU nest depth: 0, expected: 0
[ 268.296072] 2 locks held by modprobe/1744:
[ 268.296077] #0: ffff8c3a44abd1b8 (&dev->mutex){....}-{4:4}, at: __driver_attach+0xe4/0x210
[ 268.296100] #1: ffffffffc1a6ea78 (amdgpu_pasid_idr_lock){+.+.}-{3:3}, at: amdgpu_pasid_alloc+0x26/0xe0 [amdgpu]
[ 268.296494] CPU: 12 UID: 0 PID: 1744 Comm: modprobe Tainted: G U OE 6.19.0-custom #16 PREEMPT(voluntary)
[ 268.296498] Tainted: [U]=USER, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
[ 268.296499] Hardware name: AMD Majolica-RN/Majolica-RN, BIOS RMJ1009A 06/13/2021
[ 268.296501] Call Trace:--- drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_ids.c +4 -1
@@ -68,8 +68,11 @@ int amdgpu_pasid_alloc(unsigned int bitsreturn -EINVAL ;spin_lock (&amdgpu_pasid_idr_lock); +/* TODO: Need to replace the idr with an xarry, and then +* handle the internal locking with ATOMIC safe paths. +*/ pasid =idr_alloc_cyclic (&amdgpu_pasid_idr,NULL ,1 , -1U << bits,GFP_KERNEL ); +1U << bits,GFP_ATOMIC );spin_unlock (&amdgpu_pasid_idr_lock);if (pasid >=0 )
Greg Kroah-Hartman
maintainerPATCH 190/311 gpib: fix use-after-free in IO ioctl handlers
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adam Crosser <[email protected]>
commit d1857f8296dceb75d00ab857fc3c61bc00c7f5c6 upstream.
The IBRD, IBWRT, IBCMD, and IBWAIT ioctl handlers use a gpib_descriptor pointer after board->big_gpib_mutex has been released. A concurrent IBCLOSEDEV ioctl can free the descriptor via close_dev_ioctl() during this window, causing a use-after-free.
The IO handlers (read_ioctl, write_ioctl, command_ioctl) explicitly release big_gpib_mutex before calling their handler. wait_ioctl() is called with big_gpib_mutex held, but ibwait() releases it internally when wait_mask is non-zero. In all four cases, the descriptor pointer obtained from handle_to_descriptor() becomes unprotected.
Fix this by introducing a kernel-only descriptor_busy reference count in struct gpib_descriptor. Each handler atomically increments descriptor_busy under file_priv->descriptors_mutex before releasing the lock, and decrements it when done. close_dev_ioctl() checks descriptor_busy under the same lock and rejects the close with -EBUSY if the count is non-zero.
A reference count rather than a simple flag is necessary because multiple handlers can operate on the same descriptor concurrently (e.g. IBRD and IBWAIT on the same handle from different threads).
A separate counter is needed because io_in_progress can be cleared from unprivileged userspace via the IBWAIT ioctl (through general_ibstatus() with set_mask containing CMPL), which would allow an attacker to bypass a check based solely on io_in_progress. The new descriptor_busy counter is only modified by the kernel IO paths.
The lock ordering is consistent (big_gpib_mutex -> descriptors_mutex) and the handlers only hold descriptors_mutex briefly during the lookup, so there is no deadlock risk and no impact on IO throughput.
--- drivers/gpib/common/gpib_os.c | 96 ++++++++++++++++++++++++++++---------- drivers/gpib/include/gpib_types.h | 8 +++ 2 files changed, 81 insertions(+), 23 deletions(-)
drivers/gpib/common/gpib_os.c +73 -23
@@ -888,10 +888,6 @@ static int read_ioctl(struct gpib_file_pif (read_cmd.completed_transfer_count > read_cmd.requested_transfer_count)return -EINVAL ; - desc =handle_to_descriptor (file_priv, read_cmd.handle); -if (!desc) -return -EINVAL ; -if (WARN_ON_ONCE (sizeof (userbuf) >sizeof (read_cmd.buffer_ptr)))return -EFAULT ;
@@ -904,6 +900,17 @@ static int read_ioctl(struct gpib_file_pif (!access_ok (userbuf, remain))return -EFAULT ; +/* Lock descriptors to prevent concurrent close from freeing descriptor */ +if (mutex_lock_interruptible (&file_priv->descriptors_mutex)) +return -ERESTARTSYS ; + desc =handle_to_descriptor (file_priv, read_cmd.handle); +if (!desc) { +mutex_unlock (&file_priv->descriptors_mutex); +return -EINVAL ; + } +atomic_inc (&desc->descriptor_busy); +mutex_unlock (&file_priv->descriptors_mutex); +atomic_set (&desc->io_in_progress,1 );/* Read buffer loads till we fill the user supplied buffer */
@@ -937,6 +944,7 @@ static int read_ioctl(struct gpib_file_p retval =copy_to_user ((void __user *)arg, &read_cmd,sizeof (read_cmd));atomic_set (&desc->io_in_progress,0 ); +atomic_dec (&desc->descriptor_busy);wake_up_interruptible (&board->wait);if (retval)
@@ -964,10 +972,6 @@ static int command_ioctl(struct gpib_filif (cmd.completed_transfer_count > cmd.requested_transfer_count)return -EINVAL ; - desc =handle_to_descriptor (file_priv, cmd.handle); -if (!desc) -return -EINVAL ; - userbuf = (u8 __user *)(unsigned long )cmd.buffer_ptr; userbuf += cmd.completed_transfer_count;
@@ -980,6 +984,17 @@ static int command_ioctl(struct gpib_filif (!access_ok (userbuf, remain))return -EFAULT ; +/* Lock descriptors to prevent concurrent close from freeing descriptor */ +if (mutex_lock_interruptible (&file_priv->descriptors_mutex)) +return -ERESTARTSYS ; + desc =handle_to_descriptor (file_priv, cmd.handle); +if (!desc) { +mutex_unlock (&file_priv->descriptors_mutex); +return -EINVAL ; + } +atomic_inc (&desc->descriptor_busy); +mutex_unlock (&file_priv->descriptors_mutex); +/* * Write buffer loads till we empty the user supplied buffer. * Call drivers at least once, even if remain is zero, in
@@ -1003,6 +1018,7 @@ static int command_ioctl(struct gpib_fil userbuf += bytes_written;if (retval <0 ) {atomic_set (&desc->io_in_progress,0 ); +atomic_dec (&desc->descriptor_busy);wake_up_interruptible (&board->wait);break ;
@@ -1022,6 +1038,7 @@ static int command_ioctl(struct gpib_fil*/ if (!no_clear_io_in_prog || fault)atomic_set (&desc->io_in_progress,0 ); +atomic_dec (&desc->descriptor_busy);wake_up_interruptible (&board->wait);if (fault)
@@ -1047,10 +1064,6 @@ static int write_ioctl(struct gpib_file_if (write_cmd.completed_transfer_count > write_cmd.requested_transfer_count)return -EINVAL ; - desc =handle_to_descriptor (file_priv, write_cmd.handle); -if (!desc) -return -EINVAL ; - userbuf = (u8 __user *)(unsigned long )write_cmd.buffer_ptr; userbuf += write_cmd.completed_transfer_count;
@@ -1060,6 +1073,17 @@ static int write_ioctl(struct gpib_file_if (!access_ok (userbuf, remain))return -EFAULT ; +/* Lock descriptors to prevent concurrent close from freeing descriptor */ +if (mutex_lock_interruptible (&file_priv->descriptors_mutex)) +return -ERESTARTSYS ; + desc =handle_to_descriptor (file_priv, write_cmd.handle); +if (!desc) { +mutex_unlock (&file_priv->descriptors_mutex); +return -EINVAL ; + } +atomic_inc (&desc->descriptor_busy); +mutex_unlock (&file_priv->descriptors_mutex); +atomic_set (&desc->io_in_progress,1 );/* Write buffer loads till we empty the user supplied buffer */
@@ -1094,6 +1118,7 @@ static int write_ioctl(struct gpib_file_ fault =copy_to_user ((void __user *)arg, &write_cmd,sizeof (write_cmd));atomic_set (&desc->io_in_progress,0 ); +atomic_dec (&desc->descriptor_busy);wake_up_interruptible (&board->wait);if (fault)
@@ -1276,6 +1301,9 @@ static int close_dev_ioctl(struct file * {struct gpib_close_dev_ioctl cmd;struct gpib_file_private *file_priv = filep->private_data; +struct gpib_descriptor *desc; +unsigned int pad; +int sad;int retval; retval =copy_from_user (&cmd, (void __user *)arg,sizeof (cmd));
@@ -1284,19 +1312,27 @@ static int close_dev_ioctl(struct file *if (cmd.handle >=GPIB_MAX_NUM_DESCRIPTORS )return -EINVAL ; -if (!file_priv->descriptors[cmd.handle]) -return -EINVAL ; - - retval =decrement_open_device_count (board, &board->device_list, - file_priv->descriptors[cmd.handle]->pad, - file_priv->descriptors[cmd.handle]->sad); -if (retval <0 ) -return retval; -kfree (file_priv->descriptors[cmd.handle]); +mutex_lock (&file_priv->descriptors_mutex); + desc = file_priv->descriptors[cmd.handle]; +if (!desc) { +mutex_unlock (&file_priv->descriptors_mutex); +return -EINVAL ; + } +if (atomic_read (&desc->descriptor_busy)) { +mutex_unlock (&file_priv->descriptors_mutex); +return -EBUSY ; + } +/* Remove from table while holding lock to prevent new IO from starting */ file_priv->descriptors[cmd.handle] =NULL ; + pad = desc->pad; + sad = desc->sad; +mutex_unlock (&file_priv->descriptors_mutex); -return 0 ; + retval =decrement_open_device_count (board, &board->device_list, pad, sad); + +kfree (desc); +return retval; }static int serial_poll_ioctl (struct gpib_board *board,unsigned long arg)
@@ -1331,12 +1367,25 @@ static int wait_ioctl(struct gpib_file_pif (retval)return -EFAULT ; +/* +* Lock descriptors to prevent concurrent close from freeing +* descriptor. ibwait() releases big_gpib_mutex when wait_mask +* is non-zero, so desc must be pinned with descriptor_busy. +*/ +mutex_lock (&file_priv->descriptors_mutex); desc =handle_to_descriptor (file_priv, wait_cmd.handle); -if (!desc) +if (!desc) { +mutex_unlock (&file_priv->descriptors_mutex);return -EINVAL ; + } +atomic_inc (&desc->descriptor_busy); +mutex_unlock (&file_priv->descriptors_mutex); retval =ibwait (board, wait_cmd.wait_mask, wait_cmd.clear_mask, wait_cmd.set_mask, &wait_cmd.ibsta, wait_cmd.usec_timeout, desc); + +atomic_dec (&desc->descriptor_busy); +if (retval <0 )return retval;
@@ -2035,6 +2084,7 @@ void init_gpib_descriptor(struct gpib_de desc->is_board =0 ; desc->autopoll_enabled =0 ;atomic_set (&desc->io_in_progress,0 ); +atomic_set (&desc->descriptor_busy,0 ); }int gpib_register_driver (struct gpib_interface *interface,struct module *provider_module)
drivers/gpib/include/gpib_types.h +8 -0
@@ -364,6 +364,14 @@ struct gpib_descriptor {unsigned int pad;/* primary gpib address */ int sad;/* secondary gpib address (negative means disabled) */ atomic_t io_in_progress; +/* +* Kernel-only reference count to prevent descriptor from being +* freed while IO handlers hold a pointer to it. Incremented +* before each IO operation, decremented when done. Unlike +* io_in_progress, this cannot be modified from userspace via +* general_ibstatus(). +*/ +atomic_t descriptor_busy; unsigned is_board : 1; unsigned autopoll_enabled : 1; };
Greg Kroah-Hartman
maintainerPATCH 191/311 iio: add IIO_DECLARE_QUATERNION() macro
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 56bd57e7b161f75535df91b229b0b2c64c6e5581 upstream.
Add a new IIO_DECLARE_QUATERNION() macro that is used to declare the field in an IIO buffer struct that contains a quaternion vector.
Quaternions are currently the only IIO data type that uses the .repeat feature of struct iio_scan_type. This has an implicit rule that the element in the buffer must be aligned to the entire size of the repeated element. This macro will make that requirement explicit. Since this is the only user, we just call the macro IIO_DECLARE_QUATERNION() instead of something more generic.
--- include/linux/iio/iio.h | 12 ++++++++++++ 1 file changed, 12 insertions(+)
include/linux/iio/iio.h +12 -0
@@ -816,6 +816,18 @@ static inline void *iio_device_get_drvda#define IIO_DECLARE_DMA_BUFFER_WITH_TS (type, name, count) \ __IIO_DECLARE_BUFFER_WITH_TS(type, name, count) __aligned(IIO_DMA_MINALIGN) +/** +* IIO_DECLARE_QUATERNION() - Declare a quaternion element +* @type: element type of the individual vectors +* @name: identifier name +* +* Quaternions are a vector composed of 4 elements (W, X, Y, Z). Use this macro +* to declare a quaternion element in a struct to ensure proper alignment in +* an IIO buffer. +*/ +#define IIO_DECLARE_QUATERNION (type, name) \ + type name[4] __aligned(sizeof(type) * 4) +struct iio_dev *iio_device_alloc (struct device *parent,int sizeof_priv);/* The information at the returned address is guaranteed to be cacheline aligned */
Greg Kroah-Hartman
maintainerPATCH 192/311 iio: orientation: hid-sensor-rotation: fix quaternion alignment
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 50d4cc74b8a720a9682a9c94f7e62a5de6b2ed3a upstream.
Restore the alignment of sampled_vals to 16 bytes by using IIO_DECLARE_QUATERNION(). This field contains a quaternion value which has scan_type.repeat = 4 and storagebits = 32. So the alignment must be 16 bytes to match the assumptions of iio_storage_bytes_for_si() and also to not break userspace.
--- drivers/iio/orientation/hid-sensor-rotation.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/orientation/hid-sensor-rotation.c +1 -1
@@ -19,7 +19,7 @@ struct dev_rot_state {struct hid_sensor_common common_attributes;struct hid_sensor_hub_attribute_info quaternion;struct { -s32 sampled_vals[4 ]; + IIO_DECLARE_QUATERNION(s32, sampled_vals);aligned_s64 timestamp; } scan;int scale_pre_decml;
Greg Kroah-Hartman
maintainerPATCH 193/311 iio: orientation: hid-sensor-rotation: add timestamp hack to not break userspace
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 79a86a6cc3669416a21fef32d0767d39ba84b3aa upstream.
Add a hack to push two timestamps in the hid-sensor-rotation scan data to avoid breaking userspace applications that depend on the timestamp being at the incorrect location in the scan data due to unintentional misalignment in older kernels.
When this driver was written, the timestamp was in the correct location because of the way iio_compute_scan_bytes() was implemented at the time. (Samples were 24 bytes each.) Then commit 883f61653069 ("iio: buffer:
align the size of scan bytes to size of the largest element") changed the computed scan_bytes to be a different size (32 bytes), which caused iio_push_to_buffers_with_timestamp() to place the timestamp at an incorrect offset.
There have been long periods of time (6 years each) where the timestamp was in either location, so to not break either case, we open-code the timestamps to be pushed to both locations in the scan data.
--- drivers/iio/orientation/hid-sensor-rotation.c | 22 +++++++++++++++++++--- 1 file changed, 19 insertions(+), 3 deletions(-)
drivers/iio/orientation/hid-sensor-rotation.c +19 -3
@@ -20,7 +20,12 @@ struct dev_rot_state {struct hid_sensor_hub_attribute_info quaternion;struct { IIO_DECLARE_QUATERNION(s32, sampled_vals); -aligned_s64 timestamp; +/* +* ABI regression avoidance: There are two copies of the same +* timestamp in case of userspace depending on broken alignment +* from older kernels. +*/ +aligned_s64 timestamp[2 ]; } scan;int scale_pre_decml;int scale_post_decml;
@@ -154,8 +159,19 @@ static int dev_rot_proc_event(struct hidif (!rot_state->timestamp) rot_state->timestamp =iio_get_time_ns (indio_dev); -iio_push_to_buffers_with_timestamp (indio_dev, &rot_state->scan, - rot_state->timestamp); +/* +* ABI regression avoidance: IIO previously had an incorrect +* implementation of iio_push_to_buffers_with_timestamp() that +* put the timestamp in the last 8 bytes of the buffer, which +* was incorrect according to the IIO ABI. To avoid breaking +* userspace that may be depending on this broken behavior, we +* put the timestamp in both the correct place [0] and the old +* incorrect place [1]. +*/ + rot_state->scan.timestamp[0 ] = rot_state->timestamp; + rot_state->scan.timestamp[1 ] = rot_state->timestamp; + +iio_push_to_buffers (indio_dev, &rot_state->scan); rot_state->timestamp =0 ; }
Greg Kroah-Hartman
maintainerPATCH 194/311 iio: adc: ti-adc161s626: fix buffer read on big-endian
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 24869650dff34a6fc8fd1cc91b2058a72f9abc95 upstream.
Rework ti_adc_trigger_handler() to properly handle data on big-endian architectures. The scan data format is 16-bit CPU-endian, so we can't cast it to a int * on big-endian and expect it to work. Instead, we introduce a local int variable to read the data into, and then copy it to the buffer.
Since the buffer isn't passed to any SPI functions, we don't need it to be DMA-safe. So we can drop it from the driver data struct and just use stack memory for the scan data.
Since there is only one data value (plus timestamp), we don't need an array and can just declare a struct with the correct data type instead.
Also fix alignment of iio_get_time_ns() to ( while we are touching this.
--- drivers/iio/adc/ti-adc161s626.c | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-)
drivers/iio/adc/ti-adc161s626.c +12 -9
@@ -70,8 +70,6 @@ struct ti_adc_data {u8 read_size;u8 shift; - -u8 buffer[16 ]__aligned(IIO_DMA_MINALIGN) ; }; static int ti_adc_read_measurement(struct ti_adc_data *data,
@@ -114,15 +112,20 @@ static irqreturn_t ti_adc_trigger_handlestruct iio_poll_func *pf = private;struct iio_dev *indio_dev = pf->indio_dev;struct ti_adc_data *data =iio_priv (indio_dev); -int ret; +struct { +s16 data; +aligned_s64 timestamp; + } scan = { }; +int ret, val; + + ret =ti_adc_read_measurement (data, &indio_dev->channels[0 ], &val); +if (ret) + goto exit_notify_done; - ret =ti_adc_read_measurement (data, &indio_dev->channels[0 ], - (int *) &data->buffer); -if (!ret) -iio_push_to_buffers_with_timestamp (indio_dev, - data->buffer, -iio_get_time_ns (indio_dev)); + scan.data = val; +iio_push_to_buffers_with_timestamp (indio_dev, &scan,iio_get_time_ns (indio_dev)); + exit_notify_done:iio_trigger_notify_done (indio_dev->trig);return IRQ_HANDLED ;
Greg Kroah-Hartman
maintainerPATCH 195/311 iio: adc: ti-adc161s626: use DMA-safe memory for spi_read()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 768461517a28d80fe81ea4d5d03a90cd184ea6ad upstream.
Add a DMA-safe buffer and use it for spi_read() instead of a stack memory. All SPI buffers must be DMA-safe.
Since we only need up to 3 bytes, we just use a u8[] instead of __be16 and __be32 and change the conversion functions appropriately.
--- drivers/iio/adc/ti-adc161s626.c | 20 ++++++++------------ 1 file changed, 8 insertions(+), 12 deletions(-)
drivers/iio/adc/ti-adc161s626.c +8 -12
@@ -15,6 +15,7 @@#include <linux/init.h> #include <linux/err.h> #include <linux/spi/spi.h> +#include <linux/unaligned.h> #include <linux/iio/iio.h> #include <linux/iio/trigger.h> #include <linux/iio/buffer.h>
@@ -70,6 +71,7 @@ struct ti_adc_data {u8 read_size;u8 shift; +u8 buf[3 ]__aligned(IIO_DMA_MINALIGN) ; }; static int ti_adc_read_measurement(struct ti_adc_data *data,
@@ -78,26 +80,20 @@ static int ti_adc_read_measurement(strucint ret;switch (data->read_size) { -case 2 : { -__be16 buf; - - ret =spi_read (data->spi, (void *) &buf,2 ); +case 2 : + ret =spi_read (data->spi, data->buf,2 );if (ret)return ret; - *val =be16_to_cpu (buf); + *val =get_unaligned_be16 (data->buf);break ; - } -case 3 : { -__be32 buf; - - ret =spi_read (data->spi, (void *) &buf,3 ); +case 3 : + ret =spi_read (data->spi, data->buf,3 );if (ret)return ret; - *val =be32_to_cpu (buf) >>8 ; + *val =get_unaligned_be24 (data->buf);break ; - }default :return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 196/311 iio: adc: ti-ads1119: Fix unbalanced pm reference count in ds1119_single_conversion()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
commit 48a5c36577ebe0144f8ede70e59b59ea18b75089 upstream.
In ads1119_single_conversion(), if pm_runtime_resume_and_get() fails, the code jumps to the pdown label, which calls pm_runtime_put_autosuspend().
Since pm_runtime_resume_and_get() automatically decrements the usage counter on failure, the subsequent call to pm_runtime_put_autosuspend() causes an unbalanced reference counter.
--- drivers/iio/adc/ti-ads1119.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ti-ads1119.c +1 -1
@@ -274,7 +274,7 @@ static int ads1119_single_conversion(str ret =pm_runtime_resume_and_get (dev);if (ret) - goto pdown; +return ret; ret =ads1119_configure_channel (st, mux, gain, datarate);if (ret)
Greg Kroah-Hartman
maintainerPATCH 197/311 iio: adc: ti-ads1119: Reinit completion before wait_for_completion_timeout()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
commit 2f168094177f8553a36046afce139001801ca917 upstream.
The completion is not reinit before wait_for_completion_timeout(), so wait_for_completion_timeout() will return immediately after the first successful completion.
--- drivers/iio/adc/ti-ads1119.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/iio/adc/ti-ads1119.c +3 -0
@@ -280,6 +280,9 @@ static int ads1119_single_conversion(strif (ret) goto pdown; +if (st->client->irq) +reinit_completion (&st->completion); + ret =i2c_smbus_write_byte (st->client,ADS1119_CMD_START_SYNC );if (ret) goto pdown;
Greg Kroah-Hartman
maintainerPATCH 198/311 iio: adc: ti-ads1119: Replace IRQF_ONESHOT with IRQF_NO_THREAD
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
commit 36f6d4db3c5cb0f58fb02b1f54f9e86522d2f918 upstream.
As there is no threaded handler, replace devm_request_threaded_irq() with devm_request_irq(), and as the handler calls iio_trigger_poll() which may not be called from a threaded handler replace IRQF_ONESHOT with IRQF_NO_THREAD.
Since commit aef30c8d569c ("genirq: Warn about using IRQF_ONESHOT without a threaded handler"), the IRQ core checks IRQF_ONESHOT flag in IRQ request and gives a warning if there is no threaded handler.
--- drivers/iio/adc/ti-ads1119.c | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-)
drivers/iio/adc/ti-ads1119.c +2 -4
@@ -738,10 +738,8 @@ static int ads1119_probe(struct i2c_cliereturn dev_err_probe (dev, ret,"Failed to setup IIO buffer\n" );if (client->irq >0 ) { - ret =devm_request_threaded_irq (dev, client->irq, - ads1119_irq_handler, -NULL ,IRQF_ONESHOT , -"ads1119" , indio_dev); + ret =devm_request_irq (dev, client->irq, ads1119_irq_handler, +IRQF_NO_THREAD ,"ads1119" , indio_dev);if (ret)return dev_err_probe (dev, ret,"Failed to allocate irq\n" );
Greg Kroah-Hartman
maintainerPATCH 199/311 drm/ast: dp501: Fix initialization of SCU2C
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
commit 2f42c1a6161646cbd29b443459fd635d29eda634 upstream.
Ast's DP501 initialization reads the register SCU2C at offset 0x1202c and tries to set it to source data from VGA. But writes the update to offset 0x0, with unknown results. Write the result to SCU instead.
The bug only happens in ast_init_analog(). There's similar code in ast_init_dvo(), which works correctly.
--- drivers/gpu/drm/ast/ast_dp501.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/ast/ast_dp501.c +1 -1
@@ -436,7 +436,7 @@ static void ast_init_analog(struct ast_d/* Finally, clear bits [17:16] of SCU2c */ data =ast_read32 (ast,0x1202c ); data &=0xfffcffff ; -ast_write32 (ast,0 , data); +ast_write32 (ast,0x1202c , data);/* Disable DVO */ ast_set_index_reg_mask (ast,AST_IO_VGACRI ,0xa3 ,0xcf ,0x00 );
Greg Kroah-Hartman
maintainerPATCH 200/311 drm/i915/dsi: Dont do DSC horizontal timing adjustments in command mode
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit 4dfce79e098915d8e5fc2b9e1d980bc3251dd32c upstream.
Stop adjusting the horizontal timing values based on the compression ratio in command mode. Bspec seems to be telling us to do this only in video mode, and this is also how the Windows driver does things.
This should also fix a div-by-zero on some machines because the adjusted htotal ends up being so small that we end up with line_time_us==0 when trying to determine the vtotal value in command mode.
Note that this doesn't actually make the display on the Huawei Matebook E work, but at least the kernel no longer explodes when the driver loads.
--- drivers/gpu/drm/i915/display/icl_dsi.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/i915/display/icl_dsi.c +2 -2
@@ -889,7 +889,7 @@ gen11_dsi_set_transcoder_timings(struct* non-compressed link speeds, and simplifies down to the ratio between * compressed and non-compressed bpp. */ -if (crtc_state->dsc.compression_enable) { +if (is_vid_mode (intel_dsi) && crtc_state->dsc.compression_enable) { mul =fxp_q4_to_int (crtc_state->dsc.compressed_bpp_x16); div =mipi_dsi_pixel_format_to_bpp (intel_dsi->pixel_format); }
@@ -1503,7 +1503,7 @@ static void gen11_dsi_get_timings(structstruct drm_display_mode *adjusted_mode = &pipe_config->hw.adjusted_mode; -if (pipe_config->dsc.compressed_bpp_x16) { +if (is_vid_mode (intel_dsi) && pipe_config->dsc.compressed_bpp_x16) {int div =fxp_q4_to_int (pipe_config->dsc.compressed_bpp_x16);int mul =mipi_dsi_pixel_format_to_bpp (intel_dsi->pixel_format);
Greg Kroah-Hartman
maintainerPATCH 201/311 drm/i915/dp: Use crtc_state->enhanced_framing properly on ivb/hsw CPU eDP
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit 9c9a57e4e337f94e23ddf69263fd0685c91155fb upstream.
Looks like I missed the drm_dp_enhanced_frame_cap() in the ivb/hsw CPU eDP code when I introduced crtc_state->enhanced_framing. Fix it up so that the state we program to the hardware is guaranteed to match what we computed earlier.
--- drivers/gpu/drm/i915/display/g4x_dp.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/i915/display/g4x_dp.c +1 -1
@@ -137,7 +137,7 @@ static void intel_dp_prepare(struct inte intel_dp->DP |=DP_SYNC_VS_HIGH ; intel_dp->DP |=DP_LINK_TRAIN_OFF_CPT ; -if (drm_dp_enhanced_frame_cap (intel_dp->dpcd)) +if (pipe_config->enhanced_framing) intel_dp->DP |=DP_ENHANCED_FRAMING ; intel_dp->DP |=DP_PIPE_SEL_IVB (crtc->pipe);
Greg Kroah-Hartman
maintainerPATCH 202/311 drm/i915/cdclk: Do the full CDCLK dance for min_voltage_level changes
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ville Syrjälä <[email protected]>
commit e08e0754e690e4909cab83ac43fd2c93c6200514 upstream.
Apparently I forgot about the pipe min_voltage_level when I decoupled the CDCLK calculations from modesets. Even if the CDCLK frequency doesn't need changing we may still need to bump the voltage level to accommodate an increase in the port clock frequency.
Currently, even if there is a full modeset, we won't notice the need to go through the full CDCLK calculations/programming, unless the set of enabled/active pipes changes, or the pipe/dbuf min CDCLK changes.
Duplicate the same logic we use the pipe's min CDCLK frequency to also deal with its min voltage level.
Note that the 'allow_voltage_level_decrease' stuff isn't really useful here since the min voltage level can only change during a full modeset. But I think sticking to the same approach in the three similar parts (pipe min cdclk, pipe min voltage level, dbuf min cdclk) is a good idea.
--- drivers/gpu/drm/i915/display/intel_cdclk.c | 54 +++++++++++++++++++++++++++++ 1 file changed, 54 insertions(+)
drivers/gpu/drm/i915/display/intel_cdclk.c +54 -0
@@ -2930,6 +2930,53 @@ static int intel_cdclk_update_crtc_min_creturn 0 ; } +static int intel_cdclk_update_crtc_min_voltage_level (struct intel_atomic_state *state, +struct intel_crtc *crtc, +u8 old_min_voltage_level, +u8 new_min_voltage_level, +bool *need_cdclk_calc) +{ +struct intel_display *display =to_intel_display (state); +struct intel_cdclk_state *cdclk_state; +bool allow_voltage_level_decrease =intel_any_crtc_needs_modeset (state); +int ret; + +if (new_min_voltage_level == old_min_voltage_level) +return 0 ; + +if (!allow_voltage_level_decrease && + new_min_voltage_level < old_min_voltage_level) +return 0 ; + + cdclk_state =intel_atomic_get_cdclk_state (state); +if (IS_ERR (cdclk_state)) +return PTR_ERR (cdclk_state); + + old_min_voltage_level = cdclk_state->min_voltage_level[crtc->pipe]; + +if (new_min_voltage_level == old_min_voltage_level) +return 0 ; + +if (!allow_voltage_level_decrease && + new_min_voltage_level < old_min_voltage_level) +return 0 ; + + cdclk_state->min_voltage_level[crtc->pipe] = new_min_voltage_level; + + ret =intel_atomic_lock_global_state (&cdclk_state->base); +if (ret) +return ret; + + *need_cdclk_calc = true; + +drm_dbg_kms (display->drm, +"[CRTC:%d:%s] min voltage level: %d -> %d\n" , + crtc->base.base.id, crtc->base.name, + old_min_voltage_level, new_min_voltage_level); + +return 0 ; +} +int intel_cdclk_update_dbuf_bw_min_cdclk (struct intel_atomic_state *state,int old_min_cdclk,int new_min_cdclk,bool *need_cdclk_calc)
@@ -3345,6 +3392,13 @@ static int intel_crtcs_calc_min_cdclk(st need_cdclk_calc);if (ret)return ret; + + ret =intel_cdclk_update_crtc_min_voltage_level (state, crtc, + old_crtc_state->min_voltage_level, + new_crtc_state->min_voltage_level, + need_cdclk_calc); +if (ret) +return ret; }return 0 ;
Greg Kroah-Hartman
maintainerPATCH 203/311 drm/amdgpu: Fix wait after reset sequence in S4
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Lijo Lazar <[email protected]>
commit daf470b8882b6f7f53cbfe9ec2b93a1b21528cdc upstream.
For a mode-1 reset done at the end of S4 on PSPv11 dGPUs, only check if TOS is unloaded.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c | 8 ++++++-- drivers/gpu/drm/amd/amdgpu/psp_v11_0.c | 3 ++- 2 files changed, 8 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_drv.c +6 -2
@@ -2703,8 +2703,12 @@ static int amdgpu_pmops_freeze(struct deif (r)return r; -if (amdgpu_acpi_should_gpu_reset (adev)) -return amdgpu_asic_reset (adev); +if (amdgpu_acpi_should_gpu_reset (adev)) { +amdgpu_device_lock_reset_domain (adev->reset_domain); + r =amdgpu_asic_reset (adev); +amdgpu_device_unlock_reset_domain (adev->reset_domain); +return r; + }return 0 ; }
drivers/gpu/drm/amd/amdgpu/psp_v11_0.c +2 -1
@@ -170,7 +170,8 @@ static int psp_v11_0_wait_for_bootloaderint retry_loop;/* For a reset done at the end of S3, only wait for TOS to be unloaded */ -if (adev->in_s3 && !(adev->flags &AMD_IS_APU ) &&amdgpu_in_reset (adev)) +if ((adev->in_s4 || adev->in_s3) && !(adev->flags &AMD_IS_APU ) && +amdgpu_in_reset (adev))return psp_v11_wait_for_tos_unload (psp);for (retry_loop =0 ; retry_loop <20 ; retry_loop++) {
Greg Kroah-Hartman
maintainerPATCH 204/311 drm/amdgpu: validate doorbell_offset in user queue creation
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junrui Luo <[email protected]>
commit a018d1819f158991b7308e4f74609c6c029b670c upstream.
amdgpu_userq_get_doorbell_index() passes the user-provided doorbell_offset to amdgpu_doorbell_index_on_bar() without bounds checking. An arbitrarily large doorbell_offset can cause the calculated doorbell index to fall outside the allocated doorbell BO, potentially corrupting kernel doorbell space.
Validate that doorbell_offset falls within the doorbell BO before computing the BAR index, using u64 arithmetic to prevent overflow.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/gpu/drm/amd/amdgpu/amdgpu_userq.c +7 -0
@@ -550,6 +550,13 @@ amdgpu_userq_get_doorbell_index(struct a goto unpin_bo; } +/* Validate doorbell_offset is within the doorbell BO */ +if ((u64 )db_info->doorbell_offset * db_size + db_size > +amdgpu_bo_size (db_obj->obj)) { + r = -EINVAL ; + goto unpin_bo; + } + index =amdgpu_doorbell_index_on_bar (uq_mgr->adev, db_obj->obj, db_info->doorbell_offset, db_size); drm_dbg_driver(adev_to_drm(uq_mgr->adev),
Greg Kroah-Hartman
maintainerPATCH 205/311 drm/amdgpu: Change AMDGPU_VA_RESERVED_TRAP_SIZE to 64KB
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Donet Tom <[email protected]>
commit 4487571ef17a30d274600b3bd6965f497a881299 upstream.
Currently, AMDGPU_VA_RESERVED_TRAP_SIZE is hardcoded to 8KB, while KFD_CWSR_TBA_TMA_SIZE is defined as 2 * PAGE_SIZE. On systems with 4K pages, both values match (8KB), so allocation and reserved space are consistent.
However, on 64K page-size systems, KFD_CWSR_TBA_TMA_SIZE becomes 128KB, while the reserved trap area remains 8KB. This mismatch causes the kernel to crash when running rocminfo or rccl unit tests.
Kernel attempted to read user page (2) - exploit attempt? (uid: 1001)
BUG: Kernel NULL pointer dereference on read at 0x00000002 Faulting instruction address: 0xc0000000002c8a64 Oops: Kernel access of bad area, sig: 11 [#1] LE PAGE_SIZE=64K MMU=Radix SMP NR_CPUS=2048 NUMA pSeries CPU: 34 UID: 1001 PID: 9379 Comm: rocminfo Tainted: G E 6.19.0-rc4-amdgpu-00320-gf23176405700 #56 VOLUNTARY Tainted: [E]=UNSIGNED_MODULE Hardware name: IBM,9105-42A POWER10 (architected) 0x800200 0xf000006 of:IBM,FW1060.30 (ML1060_896) hv:phyp pSeries NIP: c0000000002c8a64 LR: c00000000125dbc8 CTR: c00000000125e730 REGS: c0000001e0957580 TRAP: 0300 Tainted: G E MSR: 8000000000009033 <SF,EE,ME,IR,DR,RI,LE> CR: 24008268 XER: 00000036 CFAR: c00000000125dbc4 DAR: 0000000000000002 DSISR: 40000000 IRQMASK: 1 GPR00: c00000000125d908 c0000001e0957820 c0000000016e8100
c00000013d814540
GPR04: 0000000000000002 c00000013d814550 0000000000000045 0000000000000000
GPR08: c00000013444d000 c00000013d814538 c00000013d814538 0000000084002268
GPR12: c00000000125e730 c000007e2ffd5f00 ffffffffffffffff 0000000000020000
GPR16: 0000000000000000 0000000000000002 c00000015f653000 0000000000000000
GPR20: c000000138662400 c00000013d814540 0000000000000000 c00000013d814500
GPR24: 0000000000000000 0000000000000002 c0000001e0957888 c0000001e0957878
GPR28: c00000013d814548 0000000000000000 c00000013d814540 c0000001e0957888
NIP [c0000000002c8a64] __mutex_add_waiter+0x24/0xc0 LR [c00000000125dbc8] __mutex_lock.constprop.0+0x318/0xd00
Call Trace: 0xc0000001e0957890 (unreliable) __mutex_lock.constprop.0+0x58/0xd00 amdgpu_amdkfd_gpuvm_alloc_memory_of_gpu+0x6fc/0xb60 [amdgpu] kfd_process_alloc_gpuvm+0x54/0x1f0 [amdgpu] kfd_process_device_init_cwsr_dgpu+0xa4/0x1a0 [amdgpu] kfd_process_device_init_vm+0xd8/0x2e0 [amdgpu] kfd_ioctl_acquire_vm+0xd0/0x130 [amdgpu] kfd_ioctl+0x514/0x670 [amdgpu] sys_ioctl+0x134/0x180 system_call_exception+0x114/0x300 system_call_vectored_common+0x15c/0x2ec
This patch changes AMDGPU_VA_RESERVED_TRAP_SIZE to 64 KB and KFD_CWSR_TBA_TMA_SIZE to the AMD GPU page size. This means we reserve 64 KB for the trap in the address space, but only allocate 8 KB within it. With this approach, the allocation size never exceeds the reserved area.
--- drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h | 2 +- drivers/gpu/drm/amd/amdkfd/kfd_priv.h | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-)
drivers/gpu/drm/amd/amdgpu/amdgpu_vm.h +1 -1
@@ -172,7 +172,7 @@ struct amdgpu_bo_vm;#define AMDGPU_VA_RESERVED_SEQ64_SIZE (2ULL << 20)#define AMDGPU_VA_RESERVED_SEQ64_START (adev) (AMDGPU_VA_RESERVED_CSA_START(adev) \ - AMDGPU_VA_RESERVED_SEQ64_SIZE) -#define AMDGPU_VA_RESERVED_TRAP_SIZE (2ULL << 12) +#define AMDGPU_VA_RESERVED_TRAP_SIZE (1ULL << 16)#define AMDGPU_VA_RESERVED_TRAP_START (adev) (AMDGPU_VA_RESERVED_SEQ64_START(adev) \ - AMDGPU_VA_RESERVED_TRAP_SIZE)#define AMDGPU_VA_RESERVED_BOTTOM (1ULL << 16)
drivers/gpu/drm/amd/amdkfd/kfd_priv.h +2 -2
@@ -102,8 +102,8 @@* The first chunk is the TBA used for the CWSR ISA code. The second * chunk is used as TMA for user-mode trap handler setup in daisy-chain mode. */ -#define KFD_CWSR_TBA_TMA_SIZE (PAGE_SIZE * 2) -#define KFD_CWSR_TMA_OFFSET (PAGE_SIZE + 2048) +#define KFD_CWSR_TBA_TMA_SIZE (AMDGPU_GPU_PAGE_SIZE * 2) +#define KFD_CWSR_TMA_OFFSET (AMDGPU_GPU_PAGE_SIZE + 2048)#define KFD_MAX_NUM_OF_QUEUES_PER_DEVICE \ (KFD_MAX_NUM_OF_PROCESSES * \
Greg Kroah-Hartman
maintainerPATCH 206/311 drm/amdgpu/pm: drop SMU driver if version not matched messages
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Deucher <[email protected]>
commit a3ffaa5b397f4df9d6ac16b10583e9df8e6fa471 upstream.
It just leads to user confusion.
--- drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c | 1 - drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c | 1 - drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c | 1 - 3 files changed, 3 deletions(-)
drivers/gpu/drm/amd/pm/swsmu/smu11/smu_v11_0.c +0 -1
@@ -262,7 +262,6 @@ int smu_v11_0_check_fw_version(struct sm"smu fw program = %d, version = 0x%08x (%d.%d.%d)\n" , smu->smc_driver_if_version, if_version, smu_program, smu_version, smu_major, smu_minor, smu_debug); -dev_info (smu->adev->dev,"SMU driver if version not matched\n" ); }return ret;
drivers/gpu/drm/amd/pm/swsmu/smu12/smu_v12_0.c +0 -1
@@ -101,7 +101,6 @@ int smu_v12_0_check_fw_version(struct sm"smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n" , smu->smc_driver_if_version, if_version, smu_program, smu_version, smu_major, smu_minor, smu_debug); -dev_info (smu->adev->dev,"SMU driver if version not matched\n" ); }return ret;
drivers/gpu/drm/amd/pm/swsmu/smu14/smu_v14_0.c +0 -1
@@ -284,7 +284,6 @@ int smu_v14_0_check_fw_version(struct sm"smu fw program = %d, smu fw version = 0x%08x (%d.%d.%d)\n" , smu->smc_driver_if_version, if_version, smu_program, smu_version, smu_major, smu_minor, smu_debug); -dev_info (adev->dev,"SMU driver if version not matched\n" ); }return ret;
Greg Kroah-Hartman
maintainerPATCH 207/311 USB: serial: io_edgeport: add support for Blackbox IC135A
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Frej Drejhammar <[email protected]>
commit 0e01c3416eb863ee7f156a9d7e7421ec0a9f68a0 upstream.
The Blackbox 724-746-5500 USB Director USB-RS-232 HUB, part number IC135A, is a rebadged Edgeport/4 with its own USB device id.
--- drivers/usb/serial/io_edgeport.c | 3 +++ drivers/usb/serial/io_usbvend.h | 1 + 2 files changed, 4 insertions(+)
drivers/usb/serial/io_edgeport.c +3 -0
@@ -73,6 +73,7 @@ static const struct usb_device_id edgepo { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_22I) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_4) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_COMPATIBLE) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BLACKBOX_IC135A) }, { } };
@@ -121,6 +122,7 @@ static const struct usb_device_id id_tab { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8R) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_8RR) }, { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_EDGEPORT_412_8) }, + { USB_DEVICE(USB_VENDOR_ID_ION, ION_DEVICE_ID_BLACKBOX_IC135A) }, { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0202) }, { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0203) }, { USB_DEVICE(USB_VENDOR_ID_NCR, NCR_DEVICE_ID_EPIC_0310) },
@@ -470,6 +472,7 @@ static void get_product_info(struct edgecase ION_DEVICE_ID_EDGEPORT_2_DIN :case ION_DEVICE_ID_EDGEPORT_4_DIN :case ION_DEVICE_ID_EDGEPORT_16_DUAL_CPU : +case ION_DEVICE_ID_BLACKBOX_IC135A : product_info->IsRS232 =1 ;break ;
drivers/usb/serial/io_usbvend.h +1 -0
@@ -211,6 +211,7 @@// // Definitions for other product IDs +#define ION_DEVICE_ID_BLACKBOX_IC135A 0x0801 // OEM device (rebranded Edgeport/4)#define ION_DEVICE_ID_MT4X56USB 0x1403 // OEM device#define ION_DEVICE_ID_E5805A 0x1A01 // OEM device (rebranded Edgeport/4)
Greg Kroah-Hartman
maintainerPATCH 208/311 USB: serial: option: add support for Rolling Wireless RW135R-GL
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wanquan Zhong <[email protected]>
commit 01e8d0f742222f1e68f48180d5480097adf7ae9f upstream.
Add VID/PID 33f8:1003 for the Rolling Wireless RW135R-GL M.2 module, which is used in laptop debug cards with MBIM interface for Linux/Chrome OS. The device supports mbim, pipe functionalities.
Here are the outputs of usb-devices:
T: Bus=04 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 2 Spd=5000 MxCh= 0 D: Ver= 3.20 Cls=00(>ifc ) Sub=00 Prot=00 MxPS= 9 #Cfgs= 1 P: Vendor=33f8 ProdID=1003 Rev=05.15 S: Manufacturer=Rolling Wireless S.a.r.l. S: Product=Rolling RW135R-GL Module S: SerialNumber=12345678 C: #Ifs= 3 Cfg#= 1 Atr=a0 MxPwr=896mA I: If#= 0 Alt= 0 #EPs= 1 Cls=02(commc) Sub=0e Prot=00 Driver=cdc_mbim E: Ad=81(I) Atr=03(Int.) MxPS= 64 Ivl=32ms I: If#= 1 Alt= 1 #EPs= 2 Cls=0a(data ) Sub=00 Prot=02 Driver=cdc_mbim E: Ad=0f(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=8e(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms I: If#= 2 Alt= 0 #EPs= 3 Cls=ff(vend.) Sub=00 Prot=40 Driver=option E: Ad=01(O) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=82(I) Atr=02(Bulk) MxPS=1024 Ivl=0ms E: Ad=83(I) Atr=03(Int.) MxPS= 10 Ivl=32ms
--- drivers/usb/serial/option.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/serial/option.c +1 -0
@@ -2464,6 +2464,7 @@ static const struct usb_device_id option { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0302, 0xff) }, /* Rolling RW101R-GL (laptop MBIM) */ { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x0802, 0xff), /* Rolling RW350-GL (laptop MBIM) */ .driver_info = RSVD(5) }, + { USB_DEVICE_INTERFACE_CLASS(0x33f8, 0x1003, 0xff) }, /* Rolling RW135R-GL (laptop MBIM) */ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x30) }, /* NetPrisma LCUK54-WWD for Global */ { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0x00, 0x40) }, { USB_DEVICE_AND_INTERFACE_INFO(0x3731, 0x0100, 0xff, 0xff, 0x40) },
Greg Kroah-Hartman
maintainerPATCH 209/311 USB: core: add NO_LPM quirk for Razer Kiyo Pro webcam
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: JP Hein <[email protected]>
commit 8b7a42ecdcdeb55580d9345412f7f8fc5aca3f6c upstream.
The Razer Kiyo Pro (1532:0e05) is a USB 3.0 UVC webcam whose firmware does not handle USB Link Power Management transitions reliably. When LPM is active, the device can enter a state where it fails to respond to control transfers, producing EPIPE (-32) errors on UVC probe control SET_CUR requests. In the worst case, the stalled endpoint triggers an xHCI stop-endpoint command that times out, causing the host controller to be declared dead and every USB device on the bus to be disconnected.
This has been reported as Ubuntu Launchpad Bug #2061177. The failure mode is:
1. UVC probe control SET_CUR returns -32 (EPIPE)
2. xHCI host not responding to stop endpoint command
3. xHCI host controller not responding, assume dead
4. All USB devices on the affected xHCI controller disconnect
Disabling LPM prevents the firmware from entering the problematic low- power states that precede the stall. This is the same approach used for other webcams with similar firmware issues (e.g., Logitech HD Webcam C270).
--- drivers/usb/core/quirks.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/core/quirks.c +2 -0
@@ -493,6 +493,8 @@ static const struct usb_device_id usb_qu/* Razer - Razer Blade Keyboard */ { USB_DEVICE(0x1532, 0x0116), .driver_info = USB_QUIRK_LINEAR_UFRAME_INTR_BINTERVAL }, + /* Razer - Razer Kiyo Pro Webcam */ + { USB_DEVICE(0x1532, 0x0e05), .driver_info = USB_QUIRK_NO_LPM }, /* Lenovo ThinkPad OneLink+ Dock twin hub controllers (VIA Labs VL812) */ { USB_DEVICE(0x17ef, 0x1018), .driver_info = USB_QUIRK_RESET_RESUME },
Greg Kroah-Hartman
maintainerPATCH 210/311 Input: synaptics-rmi4 - fix a locking bug in an error path
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
commit 7adaaee5edd35a423ae199c41b86bd1ed60ed483 upstream.
Lock f54->data_mutex when entering the function statement since jumping to the 'error' label when checking report_size fails causes that mutex to be unlocked.
This bug has been detected by the Clang thread-safety checker.
--- drivers/input/rmi4/rmi_f54.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/input/rmi4/rmi_f54.c +2 -2
@@ -538,6 +538,8 @@ static void rmi_f54_work(struct work_strint error;int i; +mutex_lock (&f54->data_mutex); + report_size =rmi_f54_get_report_size (f54);if (report_size ==0 ) { dev_err(&fn->dev, "Bad report size, report type=%d\n",
@@ -546,8 +548,6 @@ static void rmi_f54_work(struct work_str goto error;/* retry won't help */ } -mutex_lock (&f54->data_mutex); -/* * Need to check if command has completed. * If not try again later.
Greg Kroah-Hartman
maintainerPATCH 211/311 Input: i8042 - add TUXEDO InfinityBook Max 16 Gen10 AMD to i8042 quirk table
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christoffer Sandberg <[email protected]>
commit 5839419cffc7788a356428d321e3ec18055c0286 upstream.
The device occasionally wakes up from suspend with missing input on the internal keyboard and the following suspend attempt results in an instant wake-up. The quirks fix both issues for this device.
--- drivers/input/serio/i8042-acpipnpio.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/input/serio/i8042-acpipnpio.h +7 -0
@@ -1189,6 +1189,13 @@ static const struct dmi_system_id i8042_ }, { .matches = { + DMI_MATCH(DMI_BOARD_NAME, "X6KK45xU_X6SP45xU"), + }, + .driver_data = (void *)(SERIO_QUIRK_NOMUX |SERIO_QUIRK_RESET_ALWAYS | +SERIO_QUIRK_NOLOOP |SERIO_QUIRK_NOPNP ) + }, + { + .matches = { DMI_MATCH(DMI_BOARD_NAME, "WUJIE Series-X5SP4NAG"), }, .driver_data = (void *)(SERIO_QUIRK_NOMUX | SERIO_QUIRK_RESET_ALWAYS |
Greg Kroah-Hartman
maintainerPATCH 212/311 Input: bcm5974 - recover from failed mode switch
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liam Mitchell <[email protected]>
commit fc1e8a6f129d87c64ac8e58b50d9dfa66217cfda upstream.
Mode switches sent before control response are ignored. This results in an unresponsive trackpad and "bcm5974: bad trackpad package, length: 8" repeated in logs.
On receiving unknown 8-byte packets, assume that mode switch was ignored and schedule an asynchronous mode reset. The reset will switch the device to normal mode, wait, then switch back to wellspring mode.
--- drivers/input/mouse/bcm5974.c | 42 +++++++++++++++++++++++++++++++++++++++++- 1 file changed, 41 insertions(+), 1 deletion(-)
drivers/input/mouse/bcm5974.c +41 -1
@@ -286,6 +286,8 @@ struct bcm5974 {const struct tp_finger *index[MAX_FINGERS ];/* finger index data */ struct input_mt_pos pos[MAX_FINGERS ];/* position array */ int slots[MAX_FINGERS ];/* slot assignments */ +struct work_struct mode_reset_work; +unsigned long last_mode_reset; };/* trackpad finger block data, le16-aligned */
@@ -696,6 +698,32 @@ static int bcm5974_wellspring_mode(strucreturn retval; } +/* +* Mode switches sent before the control response are ignored. +* Fixing this state requires switching to normal mode and waiting +* about 1ms before switching back to wellspring mode. +*/ +static void bcm5974_mode_reset_work (struct work_struct *work) +{ + struct bcm5974 *dev = container_of(work, struct bcm5974, mode_reset_work); +int error; + +guard (mutex)(&dev->pm_mutex); + dev->last_mode_reset = jiffies; + + error =bcm5974_wellspring_mode (dev, false); +if (error) { +dev_err (&dev->intf->dev,"reset to normal mode failed\n" ); +return ; + } + +fsleep (1000 ); + + error =bcm5974_wellspring_mode (dev, true); +if (error) +dev_err (&dev->intf->dev,"mode switch after reset failed\n" ); +} +static void bcm5974_irq_button (struct urb *urb) {struct bcm5974 *dev = urb->context;
@@ -752,10 +780,20 @@ static void bcm5974_irq_trackpad(structif (dev->tp_urb->actual_length ==2 ) goto exit; -if (report_tp_state (dev, dev->tp_urb->actual_length)) +if (report_tp_state (dev, dev->tp_urb->actual_length)) {dprintk (1 ,"bcm5974: bad trackpad package, length: %d\n" , dev->tp_urb->actual_length); +/* +* Receiving a HID packet means we aren't in wellspring mode. +* If we haven't tried a reset in the last second, try now. +*/ +if (dev->tp_urb->actual_length ==8 && +time_after (jiffies, dev->last_mode_reset +msecs_to_jiffies (1000 ))) { +schedule_work (&dev->mode_reset_work); + } + } + exit: error =usb_submit_urb (dev->tp_urb,GFP_ATOMIC );if (error)
@@ -906,6 +944,7 @@ static int bcm5974_probe(struct usb_inte dev->intf = iface; dev->input = input_dev; dev->cfg = *cfg; +INIT_WORK (&dev->mode_reset_work, bcm5974_mode_reset_work);mutex_init (&dev->pm_mutex);/* setup urbs */
@@ -998,6 +1037,7 @@ static void bcm5974_disconnect(struct us {struct bcm5974 *dev =usb_get_intfdata (iface); +disable_work_sync (&dev->mode_reset_work);usb_set_intfdata (iface,NULL );input_unregister_device (dev->input);
Greg Kroah-Hartman
maintainerPATCH 213/311 Input: xpad - add support for BETOP BTP-KP50B/C controllers wireless mode
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Shengyu Qu <[email protected]>
commit 0d9363a764d9d601a05591f9695cea8b429e9be3 upstream.
BETOP's BTP-KP50B and BTP-KP50C controller's wireless dongles are both working as standard Xbox 360 controllers. Add USB device IDs for them to xpad driver.
--- drivers/input/joystick/xpad.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/input/joystick/xpad.c +3 -0
@@ -360,6 +360,8 @@ static const struct xpad_device { { 0x1bad, 0xfd00, "Razer Onza TE", 0, XTYPE_XBOX360 }, { 0x1bad, 0xfd01, "Razer Onza", 0, XTYPE_XBOX360 }, { 0x1ee9, 0x1590, "ZOTAC Gaming Zone", 0, XTYPE_XBOX360 }, + { 0x20bc, 0x5134, "BETOP BTP-KP50B Xinput Dongle", 0, XTYPE_XBOX360 }, + { 0x20bc, 0x514a, "BETOP BTP-KP50C Xinput Dongle", 0, XTYPE_XBOX360 }, { 0x20d6, 0x2001, "BDA Xbox Series X Wired Controller", 0, XTYPE_XBOXONE }, { 0x20d6, 0x2009, "PowerA Enhanced Wired Controller for Xbox Series X|S", 0, XTYPE_XBOXONE }, { 0x20d6, 0x2064, "PowerA Wired Controller for Xbox", MAP_SHARE_BUTTON, XTYPE_XBOXONE },
@@ -562,6 +564,7 @@ static const struct usb_device_id xpad_tXPAD_XBOX360_VENDOR (0x1a86 ),/* Nanjing Qinheng Microelectronics (WCH) */ XPAD_XBOX360_VENDOR (0x1bad ),/* Harmonix Rock Band guitar and drums */ XPAD_XBOX360_VENDOR (0x1ee9 ),/* ZOTAC Technology Limited */ +XPAD_XBOX360_VENDOR (0x20bc ),/* BETOP wireless dongles */ XPAD_XBOX360_VENDOR (0x20d6 ),/* PowerA controllers */ XPAD_XBOXONE_VENDOR (0x20d6 ),/* PowerA controllers */ XPAD_XBOX360_VENDOR(0x2345), /* Machenike Controllers */
Greg Kroah-Hartman
maintainerPATCH 214/311 Input: xpad - add support for Razer Wolverine V3 Pro
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zoltan Illes <[email protected]>
commit e2b0ae529db4766584e77647cefe3ec15c3d842e upstream.
Add device IDs for the Razer Wolverine V3 Pro controller in both wired (0x0a57) and wireless 2.4 GHz dongle (0x0a59) modes.
The controller uses the Xbox 360 protocol (vendor-specific class, subclass 93, protocol 1) on interface 0 with an identical 20-byte input report layout, so no additional processing is needed.
--- drivers/input/joystick/xpad.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/input/joystick/xpad.c +2 -0
@@ -313,6 +313,8 @@ static const struct xpad_device { { 0x1532, 0x0a00, "Razer Atrox Arcade Stick", MAP_TRIGGERS_TO_BUTTONS, XTYPE_XBOXONE }, { 0x1532, 0x0a03, "Razer Wildcat", 0, XTYPE_XBOXONE }, { 0x1532, 0x0a29, "Razer Wolverine V2", 0, XTYPE_XBOXONE }, + { 0x1532, 0x0a57, "Razer Wolverine V3 Pro (Wired)", 0, XTYPE_XBOX360 }, + { 0x1532, 0x0a59, "Razer Wolverine V3 Pro (2.4 GHz Dongle)", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f00, "Power A Mini Pro Elite", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f0a, "Xbox Airflo wired controller", 0, XTYPE_XBOX360 }, { 0x15e4, 0x3f10, "Batarang Xbox 360 controller", 0, XTYPE_XBOX360 },
Greg Kroah-Hartman
maintainerPATCH 215/311 iio: adc: ti-ads7950: normalize return value of gpio_get
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit e2fa075d5ce1963e7cb7b0ac708ba567e5af66db upstream.
The GPIO get callback is expected to return 0 or 1 (or a negative error code). Ensure that the value returned by ti_ads7950_get() for output pins is normalized to the [0, 1] range.
--- drivers/iio/adc/ti-ads7950.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ti-ads7950.c +1 -1
@@ -433,7 +433,7 @@ static int ti_ads7950_get(struct gpio_ch/* If set as output, return the output */ if (st->gpio_cmd_settings_bitmask &BIT (offset)) { - ret = st->cmd_settings_bitmask &BIT (offset); + ret = (st->cmd_settings_bitmask &BIT (offset)) ?1 :0 ; goto out; }
Greg Kroah-Hartman
maintainerPATCH 216/311 iio: adc: ti-ads7950: do not clobber gpio state in ti_ads7950_get()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit d20bbae6e5d408a8a7c2a4344d76dd1ac557a149 upstream.
GPIO state was inadvertently overwritten by the result of spi_sync(), resulting in ti_ads7950_get() only returning 0 as GPIO state (or error).
Fix this by introducing a separate variable to hold the state.
--- drivers/iio/adc/ti-ads7950.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/iio/adc/ti-ads7950.c +5 -3
@@ -427,13 +427,15 @@ static int ti_ads7950_set(struct gpio_chstatic int ti_ads7950_get (struct gpio_chip *chip,unsigned int offset) {struct ti_ads7950_state *st =gpiochip_get_data (chip); +bool state;int ret;mutex_lock (&st->slock);/* If set as output, return the output */ if (st->gpio_cmd_settings_bitmask &BIT (offset)) { - ret = (st->cmd_settings_bitmask &BIT (offset)) ?1 :0 ; + state = st->cmd_settings_bitmask &BIT (offset); + ret =0 ; goto out; }
@@ -444,7 +446,7 @@ static int ti_ads7950_get(struct gpio_chif (ret) goto out; - ret = ((st->single_rx >>12 ) &BIT (offset)) ?1 :0 ; + state = (st->single_rx >>12 ) &BIT (offset);/* Revert back to original settings */ st->cmd_settings_bitmask &= ~TI_ADS7950_CR_GPIO_DATA ;
@@ -456,7 +458,7 @@ static int ti_ads7950_get(struct gpio_ch out:mutex_unlock (&st->slock); -return ret; +return ret ?: state; } static int ti_ads7950_get_direction(struct gpio_chip *chip,
Greg Kroah-Hartman
maintainerPATCH 217/311 iio: adc: ade9000: fix wrong return type in streaming push
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giorgi Tchankvetadze <[email protected]>
commit 57b207e38d414a27fda9fff638a0d3e7ef16b917 upstream.
The else branch of ade9000_iio_push_streaming() incorrectly returns IRQ_HANDLED on regmap_write failure. This function returns int (0 on success, negative errno on failure), so IRQ_HANDLED (1) would be misinterpreted as a non-error by callers.
Return ret instead, consistent with every other error path in the function.
--- drivers/iio/adc/ade9000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ade9000.c +1 -1
@@ -787,7 +787,7 @@ static int ade9000_iio_push_streaming(st ADE9000_MIDDLE_PAGE_BIT);if (ret) {dev_err_ratelimited (dev,"IRQ0 WFB write fail" ); -return IRQ_HANDLED ; +return ret; }ade9000_configure_scan (indio_dev,ADE9000_REG_WF_BUFF );
Greg Kroah-Hartman
maintainerPATCH 218/311 iio: adc: ade9000: fix wrong register in CALIBBIAS case for active power
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Giorgi Tchankvetadze <[email protected]>
commit 86133fb1ec36b2f5cec29d71fbae84877c3a1358 upstream.
The switch statement in ade9000_write_raw() attempts to match chan->address against ADE9000_REG_AWATTOS (0x00F) to dispatch the calibration offset write for active power channels. However, chan->address is set via ADE9000_ADDR_ADJUST(ADE9000_REG_AWATT, num), so after masking the phase bits, tmp holds ADE9000_REG_AWATT (0x210), which never matches 0x00F.
As a result, writing IIO_CHAN_INFO_CALIBBIAS for IIO_POWER always falls through to the default case and returns -EINVAL, making active power offset calibration silently broken.
Fix this by matching against ADE9000_REG_AWATT instead, which is the actual base address stored in chan->address for watt channels.
Reference:ADE9000 datasheet (Rev. B), AWATTOS is the offset correction register at 0x00F (p. 44), while AWATT is the total active power register at 0x210 (p. 48).
--- drivers/iio/adc/ade9000.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/ade9000.c +1 -1
@@ -1123,7 +1123,7 @@ static int ade9000_write_raw(struct iio_ tmp &= ~ADE9000_PHASE_C_POS_BIT ;switch (tmp) { -case ADE9000_REG_AWATTOS : +case ADE9000_REG_AWATT :return regmap_write (st->regmap,ADE9000_ADDR_ADJUST (ADE9000_REG_AWATTOS , chan->channel), val);
Greg Kroah-Hartman
maintainerPATCH 219/311 iio: adc: ade9000: move mutex init before IRQ registration
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
commit 0206dd36418c104c0b3dea4ed7047e21eccb30b0 upstream.
Move devm_mutex_init() before ade9000_request_irq() calls so that st->lock is initialized before any handler that depends on it can run.
--- drivers/iio/adc/ade9000.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/iio/adc/ade9000.c +4 -4
@@ -1706,19 +1706,19 @@ static int ade9000_probe(struct spi_deviinit_completion (&st->reset_completion); - ret =ade9000_request_irq (dev,"irq0" , ade9000_irq0_thread, indio_dev); + ret =devm_mutex_init (dev, &st->lock);if (ret)return ret; - ret =ade9000_request_irq (dev,"irq1" , ade9000_irq1_thread, indio_dev); + ret =ade9000_request_irq (dev,"irq0" , ade9000_irq0_thread, indio_dev);if (ret)return ret; - ret =ade9000_request_irq (dev,"dready" , ade9000_dready_thread, indio_dev); + ret =ade9000_request_irq (dev,"irq1" , ade9000_irq1_thread, indio_dev);if (ret)return ret; - ret =devm_mutex_init (dev, &st->lock); + ret =ade9000_request_irq (dev,"dready" , ade9000_dready_thread, indio_dev);if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 220/311 iio: adc: aspeed: clear reference voltage bits before configuring vref
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Billy Tsai <[email protected]>
commit 7cf2f6ed8e7a3bf481ef70b6b4a2edb8abfa5c57 upstream.
Ensures the reference voltage bits are cleared in the ADC engine control register before configuring the voltage reference. This avoids potential misconfigurations caused by residual bits.
--- drivers/iio/adc/aspeed_adc.c | 1 + 1 file changed, 1 insertion(+)
drivers/iio/adc/aspeed_adc.c +1 -0
@@ -415,6 +415,7 @@ static int aspeed_adc_vref_config(struct } adc_engine_control_reg_val =readl (data->base +ASPEED_REG_ENGINE_CONTROL ); + adc_engine_control_reg_val &= ~ASPEED_ADC_REF_VOLTAGE ; ret =devm_regulator_get_enable_read_voltage (data->dev,"vref" );if (ret <0 && ret != -ENODEV )
Greg Kroah-Hartman
maintainerPATCH 221/311 iio: accel: fix ADXL355 temperature signature value
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Valek Andrej <[email protected]>
commit 4f51e6c0baae80e52bd013092e82a55678be31fc upstream.
Temperature was wrongly represented as 12-bit signed, confirmed by checking the datasheet. Even if the temperature is negative, the value in the register stays unsigned.
--- drivers/iio/accel/adxl355_core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/accel/adxl355_core.c +1 -1
@@ -745,7 +745,7 @@ static const struct iio_chan_spec adxl35BIT (IIO_CHAN_INFO_OFFSET ), .scan_index = 3, .scan_type = { - .sign ='s' , + .sign ='u' , .realbits =12 , .storagebits =16 , .endianness =IIO_BE ,
Greg Kroah-Hartman
maintainerPATCH 222/311 iio: accel: adxl380: fix FIFO watermark bit 8 always written as 0
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
commit bd66aa1c8b8cabf459064a46d3430a5ec5138418 upstream.
FIELD_PREP(BIT(0), fifo_samples & BIT(8)) produces either 0 or 256, and since FIELD_PREP masks to bit 0, 256 & 1 evaluates to 0. Use !! to convert the result to a proper 0-or-1 value.
--- drivers/iio/accel/adxl380.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/accel/adxl380.c +1 -1
@@ -860,7 +860,7 @@ static int adxl380_set_fifo_samples(stru ret =regmap_update_bits (st->regmap,ADXL380_FIFO_CONFIG_0_REG ,ADXL380_FIFO_SAMPLES_8_MSK ,FIELD_PREP (ADXL380_FIFO_SAMPLES_8_MSK , - (fifo_samples &BIT (8 )))); + !!(fifo_samples &BIT (8 ))));if (ret)return ret;
Greg Kroah-Hartman
maintainerPATCH 223/311 iio: accel: adxl313: add missing error check in predisable
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
commit 9d3fa23d5d55a137fd4396d3d4799102587a7f2b upstream.
Check the return value of the FIFO bypass regmap_write() before proceeding to disable interrupts.
--- drivers/iio/accel/adxl313_core.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/iio/accel/adxl313_core.c +2 -0
@@ -998,6 +998,8 @@ static int adxl313_buffer_predisable(str ret =regmap_write (data->regmap,ADXL313_REG_FIFO_CTL ,FIELD_PREP (ADXL313_REG_FIFO_CTL_MODE_MSK ,ADXL313_FIFO_BYPASS )); +if (ret) +return ret; ret =regmap_write (data->regmap,ADXL313_REG_INT_ENABLE ,0 );if (ret)
Greg Kroah-Hartman
maintainerPATCH 224/311 iio: dac: ad5770r: fix error return in ad5770r_read_raw()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
commit c354521708175d776d896f8bdae44b18711eccb6 upstream.
Return the error code from regmap_bulk_read() instead of 0 so that I/O failures are properly propagated.
--- drivers/iio/dac/ad5770r.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/dac/ad5770r.c +1 -1
@@ -322,7 +322,7 @@ static int ad5770r_read_raw(struct iio_d chan->address, st->transf_buf, 2);if (ret) -return 0 ; +return ret; buf16 =get_unaligned_le16 (st->transf_buf); *val = buf16 >>2 ;
Greg Kroah-Hartman
maintainerPATCH 225/311 iio: imu: adis16550: fix swapped gyro/accel filter functions
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Antoniu Miclaus <[email protected]>
commit ea7e2e43d768102e2601dbbda42041c78d7a99f9 upstream.
The low-pass filter handlers for IIO_ANGL_VEL and IIO_ACCEL call each other's filter functions in both read_raw and write_raw. Swap them so each channel type uses its correct filter accessor.
--- drivers/iio/imu/adis16550.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/iio/imu/adis16550.c +4 -4
@@ -643,12 +643,12 @@ static int adis16550_read_raw(struct iiocase IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY :switch (chan->type) {case IIO_ANGL_VEL : - ret =adis16550_get_accl_filter_freq (st, val); + ret =adis16550_get_gyro_filter_freq (st, val);if (ret)return ret;return IIO_VAL_INT ;case IIO_ACCEL : - ret =adis16550_get_gyro_filter_freq (st, val); + ret =adis16550_get_accl_filter_freq (st, val);if (ret)return ret;return IIO_VAL_INT ;
@@ -681,9 +681,9 @@ static int adis16550_write_raw(struct iicase IIO_CHAN_INFO_LOW_PASS_FILTER_3DB_FREQUENCY :switch (chan->type) {case IIO_ANGL_VEL : -return adis16550_set_accl_filter_freq (st, val); -case IIO_ACCEL :return adis16550_set_gyro_filter_freq (st, val); +case IIO_ACCEL : +return adis16550_set_accl_filter_freq (st, val);default :return -EINVAL ; }
Greg Kroah-Hartman
maintainerPATCH 226/311 iio: light: vcnl4035: fix scan buffer on big-endian
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit fdc7aa54a5d44c05880a4aad7cfb41aacfd16d7b upstream.
Rework vcnl4035_trigger_consumer_handler() so that we are not passing what should be a u16 value as an int * to regmap_read(). This won't work on bit endian systems.
Instead, add a new unsigned int variable to pass to regmap_read(). Then copy that value into the buffer struct.
The buffer array is replaced with a struct since there is only one value being read. This allows us to use the correct u16 data type and has a side-effect of simplifying the alignment specification.
Also fix the endianness of the scan format from little-endian to CPU endianness. Since we are using regmap to read the value, it will be CPU-endian.
--- drivers/iio/light/vcnl4035.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-)
drivers/iio/light/vcnl4035.c +12 -6
@@ -103,17 +103,23 @@ static irqreturn_t vcnl4035_trigger_consstruct iio_dev *indio_dev = pf->indio_dev;struct vcnl4035_data *data =iio_priv (indio_dev);/* Ensure naturally aligned timestamp */ -u8 buffer[ALIGN (sizeof (u16),sizeof (s64)) +sizeof (s64)]__aligned(8) = { }; +struct { +u16 als_data; +aligned_s64 timestamp; + } buffer = { }; +unsigned int val;int ret; - ret =regmap_read (data->regmap,VCNL4035_ALS_DATA , (int *)buffer); + ret =regmap_read (data->regmap,VCNL4035_ALS_DATA , &val);if (ret <0 ) {dev_err (&data->client->dev,"Trigger consumer can't read from sensor.\n" ); goto fail_read; } -iio_push_to_buffers_with_timestamp (indio_dev, buffer, -iio_get_time_ns (indio_dev)); + + buffer.als_data = val; +iio_push_to_buffers_with_timestamp (indio_dev, &buffer, +iio_get_time_ns (indio_dev)); fail_read:iio_trigger_notify_done (indio_dev->trig);
@@ -381,7 +387,7 @@ static const struct iio_chan_spec vcnl40 .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_LE, + .endianness = IIO_CPU, }, }, {
@@ -395,7 +401,7 @@ static const struct iio_chan_spec vcnl40 .sign = 'u', .realbits = 16, .storagebits = 16, - .endianness = IIO_LE, + .endianness = IIO_CPU, }, }, };
Greg Kroah-Hartman
maintainerPATCH 227/311 iio: light: veml6070: fix veml6070_read() return value
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Aldo Conte <[email protected]>
commit d0b224cf9ab12e86a4d1ca55c760dfaa5c19cbe7 upstream.
veml6070_read() computes the sensor value in ret but returns 0 instead of the actual result. This causes veml6070_read_raw() to always report 0.
Return the computed value instead of 0.
Running make W=1 returns no errors. I was unable to test the patch because I do not have the hardware. Found by code inspection.
--- drivers/iio/light/veml6070.c | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-)
drivers/iio/light/veml6070.c +1 -3
@@ -134,9 +134,7 @@ static int veml6070_read(struct veml6070if (ret <0 )return ret; - ret = (msb <<8 ) | lsb; - -return 0 ; +return (msb <<8 ) | lsb; }static const struct iio_chan_spec veml6070_channels[] = {
Greg Kroah-Hartman
maintainerPATCH 228/311 iio: imu: bmi160: Remove potential undefined behavior in bmi160_config_pin()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Josh Poimboeuf <[email protected]>
commit c05a87d9ec3bf8727a5d746ce855003c6f2f8bb4 upstream.
If 'pin' is not one of its expected values, the value of 'int_out_ctrl_shift' is undefined. With UBSAN enabled, this causes Clang to generate undefined behavior, resulting in the following warning:
drivers/iio/imu/bmi160/bmi160_core.o: warning: objtool: bmi160_setup_irq() falls through to next function __cfi_bmi160_core_runtime_resume()
Prevent the UB and improve error handling by returning an error if 'pin' has an unexpected value.
While at it, simplify the code a bit by moving the 'pin_name' assignment to the first switch statement.
--- drivers/iio/imu/bmi160/bmi160_core.c | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-)
drivers/iio/imu/bmi160/bmi160_core.c +5 -10
@@ -573,12 +573,16 @@ static int bmi160_config_pin(struct regm int_out_ctrl_shift =BMI160_INT1_OUT_CTRL_SHIFT ; int_latch_mask =BMI160_INT1_LATCH_MASK ; int_map_mask =BMI160_INT1_MAP_DRDY_EN ; + pin_name ="INT1" ;break ;case BMI160_PIN_INT2 : int_out_ctrl_shift =BMI160_INT2_OUT_CTRL_SHIFT ; int_latch_mask =BMI160_INT2_LATCH_MASK ; int_map_mask =BMI160_INT2_MAP_DRDY_EN ; + pin_name ="INT2" ;break ; +default : +return -EINVAL ; } int_out_ctrl_mask =BMI160_INT_OUT_CTRL_MASK << int_out_ctrl_shift;
@@ -612,17 +616,8 @@ static int bmi160_config_pin(struct regm ret =bmi160_write_conf_reg (regmap,BMI160_REG_INT_MAP , int_map_mask, int_map_mask, write_usleep); -if (ret) { -switch (pin) { -case BMI160_PIN_INT1 : - pin_name ="INT1" ; -break ; -case BMI160_PIN_INT2 : - pin_name ="INT2" ; -break ; - } +if (ret)dev_err (dev,"Failed to configure %s IRQ pin" , pin_name); - }return ret; }
Greg Kroah-Hartman
maintainerPATCH 229/311 iio: imu: st_lsm6dsx: Set FIFO ODR for accelerometer and gyroscope only
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Lavra <[email protected]>
commit 630748afa7030b272b7bee5df857e7bcf132ed51 upstream.
The st_lsm6dsx_set_fifo_odr() function, which is called when enabling and disabling the hardware FIFO, checks the contents of the hw->settings->batch array at index sensor->id, and then sets the current ODR value in sensor registers that depend on whether the register address is set in the above array element. This logic is valid for internal sensors only, i.e. the accelerometer and gyroscope; however, since commit c91c1c844ebd ("iio: imu:st_lsm6dsx: add i2c embedded controller support"), this function is called also when configuring the hardware FIFO for external sensors (i.e. sensors accessed through the sensor hub functionality), which can result in unrelated device registers being written.
Add a check to the beginning of st_lsm6dsx_set_fifo_odr() so that it does not touch any registers unless it is called for internal sensors.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +4 -0
@@ -225,6 +225,10 @@ static int st_lsm6dsx_set_fifo_odr(strucconst struct st_lsm6dsx_reg *batch_reg;u8 data; +/* Only internal sensors have a FIFO ODR configuration register. */ +if (sensor->id >=ARRAY_SIZE (hw->settings->batch)) +return 0 ; + batch_reg = &hw->settings->batch[sensor->id];if (batch_reg->addr) {int val;
Greg Kroah-Hartman
maintainerPATCH 230/311 iio: imu: st_lsm6dsx: Set buffer sampling frequency for accelerometer only
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Francesco Lavra <[email protected]>
commit 679c04c10d65d32a3f269e696b22912ff0a001b9 upstream.
The st_lsm6dsx_hwfifo_odr_store() function, which is called when userspace writes the buffer sampling frequency sysfs attribute, calls st_lsm6dsx_check_odr(), which accesses the odr_table array at index sensor->id; since this array is only 2 entries long, an access for any sensor type other than accelerometer or gyroscope is an out-of-bounds access.
The motivation for being able to set a buffer frequency different from the sensor sampling frequency is to support use cases that need accurate event detection (which requires a high sampling frequency) while retrieving sensor data at low frequency. Since all the supported event types are generated from acceleration data only, do not create the buffer sampling frequency attribute for sensor types other than the accelerometer.
--- drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-)
drivers/iio/imu/st_lsm6dsx/st_lsm6dsx_buffer.c +10 -1
@@ -862,12 +862,21 @@ int st_lsm6dsx_fifo_setup(struct st_lsm6int i, ret;for (i =0 ; i <ST_LSM6DSX_ID_MAX ; i++) { +const struct iio_dev_attr **attrs; +if (!hw->iio_devs[i])continue ; +/* +* For the accelerometer, allow setting FIFO sampling frequency +* values different from the sensor sampling frequency, which +* may be needed to keep FIFO data rate low while sampling +* acceleration data at high rates for accurate event detection. +*/ + attrs = i ==ST_LSM6DSX_ID_ACC ? st_lsm6dsx_buffer_attrs :NULL ; ret =devm_iio_kfifo_buffer_setup_ext (hw->dev, hw->iio_devs[i], &st_lsm6dsx_buffer_ops, - st_lsm6dsx_buffer_attrs); + attrs);if (ret)return ret; }
Greg Kroah-Hartman
maintainerPATCH 231/311 iio: gyro: mpu3050: Fix incorrect free_irq() variable
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
commit edb11a1aef4011a4b7b22cc3c3396c6fe371f4a6 upstream.
The handler for the IRQ part of this driver is mpu3050->trig but, in the teardown free_irq() is called with handler mpu3050.
Use correct IRQ handler when calling free_irq().
--- drivers/iio/gyro/mpu3050-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/gyro/mpu3050-core.c +1 -1
@@ -1269,7 +1269,7 @@ void mpu3050_common_remove(struct devicepm_runtime_disable (dev);iio_triggered_buffer_cleanup (indio_dev);if (mpu3050->irq) -free_irq (mpu3050->irq, mpu3050); +free_irq (mpu3050->irq, mpu3050->trig);iio_device_unregister (indio_dev);mpu3050_power_down (mpu3050); }
Greg Kroah-Hartman
maintainerPATCH 232/311 iio: gyro: mpu3050: Fix irq resource leak
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
commit 4216db1043a3be72ef9c2b7b9f393d7fa72496e6 upstream.
The interrupt handler is setup but only a few lines down if iio_trigger_register() fails the function returns without properly releasing the handler.
Add cleanup goto to resolve resource leak.
Detected by Smatch:drivers/iio/gyro/mpu3050-core.c:1128 mpu3050_trigger_probe() warn:
'irq' from request_threaded_irq() not released on lines: 1124.
--- drivers/iio/gyro/mpu3050-core.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
drivers/iio/gyro/mpu3050-core.c +6 -1
@@ -1129,11 +1129,16 @@ static int mpu3050_trigger_probe(struct ret =iio_trigger_register (mpu3050->trig);if (ret) -return ret; + goto err_iio_trigger; indio_dev->trig =iio_trigger_get (mpu3050->trig);return 0 ; + +err_iio_trigger: +free_irq (mpu3050->irq, mpu3050->trig); + +return ret; } int mpu3050_common_probe(struct device *dev,
Greg Kroah-Hartman
maintainerPATCH 233/311 iio: gyro: mpu3050: Move iio_device_register() to correct location
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
commit 4c05799449108fb0e0a6bd30e65fffc71e60db4d upstream.
iio_device_register() should be at the end of the probe function to prevent race conditions.
Place iio_device_register() at the end of the probe function and place iio_device_unregister() accordingly.
--- drivers/iio/gyro/mpu3050-core.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-)
drivers/iio/gyro/mpu3050-core.c +13 -8
@@ -1226,12 +1226,6 @@ int mpu3050_common_probe(struct device * goto err_power_down; } - ret =iio_device_register (indio_dev); -if (ret) { -dev_err (dev,"device register failed\n" ); - goto err_cleanup_buffer; - } -dev_set_drvdata (dev, indio_dev);/* Check if we have an assigned IRQ to use as trigger */
@@ -1254,9 +1248,20 @@ int mpu3050_common_probe(struct device *pm_runtime_use_autosuspend (dev);pm_runtime_put (dev); + ret =iio_device_register (indio_dev); +if (ret) { +dev_err (dev,"device register failed\n" ); + goto err_iio_device_register; + } +return 0 ; -err_cleanup_buffer: +err_iio_device_register: +pm_runtime_get_sync (dev); +pm_runtime_put_noidle (dev); +pm_runtime_disable (dev); +if (irq) +free_irq (mpu3050->irq, mpu3050->trig);iio_triggered_buffer_cleanup (indio_dev); err_power_down:mpu3050_power_down (mpu3050);
@@ -1269,13 +1274,13 @@ void mpu3050_common_remove(struct devicestruct iio_dev *indio_dev =dev_get_drvdata (dev);struct mpu3050 *mpu3050 =iio_priv (indio_dev); +iio_device_unregister (indio_dev);pm_runtime_get_sync (dev);pm_runtime_put_noidle (dev);pm_runtime_disable (dev);iio_triggered_buffer_cleanup (indio_dev);if (mpu3050->irq)free_irq (mpu3050->irq, mpu3050->trig); -iio_device_unregister (indio_dev);mpu3050_power_down (mpu3050); }
Greg Kroah-Hartman
maintainerPATCH 234/311 iio: gyro: mpu3050: Fix out-of-sequence free_irq()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ethan Tidmore <[email protected]>
commit d14116f6529fa085b1a1b1f224dc9604e4d2a29c upstream.
The triggered buffer is initialized before the IRQ is requested. The removal path currently calls iio_triggered_buffer_cleanup() before free_irq(). This violates the expected LIFO.
Place free_irq() in the correct location relative to iio_triggered_buffer_cleanup().
--- drivers/iio/gyro/mpu3050-core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/gyro/mpu3050-core.c +1 -1
@@ -1278,9 +1278,9 @@ void mpu3050_common_remove(struct devicepm_runtime_get_sync (dev);pm_runtime_put_noidle (dev);pm_runtime_disable (dev); -iio_triggered_buffer_cleanup (indio_dev);if (mpu3050->irq)free_irq (mpu3050->irq, mpu3050->trig); +iio_triggered_buffer_cleanup (indio_dev);mpu3050_power_down (mpu3050); }
Greg Kroah-Hartman
maintainerPATCH 235/311 mei: me: reduce the scope on unexpected reset
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alexander Usyskin <[email protected]>
commit 8c27b1bce059a11a8d3c8682984e13866f0714af upstream.
After commit 2cedb296988c ("mei: me: trigger link reset if hw ready is unexpected") some devices started to show long resume times (5-7 seconds).
This happens as mei falsely detects unready hardware,
starts parallel link reset flow and triggers link reset timeouts
in the resume callback.
Address it by performing detection of unready hardware only when driver is in the MEI_DEV_ENABLED state instead of blacklisting states as done in the original patch.
This eliminates active waitqueue check as in MEI_DEV_ENABLED state there will be no active waitqueue.
--- drivers/misc/mei/hw-me.c | 14 ++++---------- 1 file changed, 4 insertions(+), 10 deletions(-)
drivers/misc/mei/hw-me.c +4 -10
@@ -1337,19 +1337,13 @@ irqreturn_t mei_me_irq_thread_handler(in/* check if we need to start the dev */ if (!mei_host_is_ready (dev)) {if (mei_hw_is_ready (dev)) { -/* synchronized by dev mutex */ -if (waitqueue_active (&dev->wait_hw_ready)) { -dev_dbg (&dev->dev,"we need to start the dev.\n" ); - dev->recvd_hw_ready = true; -wake_up (&dev->wait_hw_ready); - }else if (dev->dev_state !=MEI_DEV_UNINITIALIZED && - dev->dev_state !=MEI_DEV_POWERING_DOWN && - dev->dev_state !=MEI_DEV_POWER_DOWN ) { +if (dev->dev_state ==MEI_DEV_ENABLED ) {dev_dbg (&dev->dev,"Force link reset.\n" );schedule_work (&dev->reset_work); }else { -dev_dbg (&dev->dev,"Ignore this interrupt in state = %d\n" , - dev->dev_state); +dev_dbg (&dev->dev,"we need to start the dev.\n" ); + dev->recvd_hw_ready = true; +wake_up (&dev->wait_hw_ready); } }else {dev_dbg (&dev->dev,"Spurious Interrupt\n" );
Greg Kroah-Hartman
maintainerPATCH 236/311 gpib: lpvo_usb: fix memory leak on disconnect
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Johan Hovold <[email protected]>
commit 5cefb52c1af6f69ea719e42788f6ec6a087eb74c upstream.
The driver iterates over the registered USB interfaces during GPIB attach and takes a reference to their USB devices until a match is found. These references are never released which leads to a memory leak when devices are disconnected.
Fix the leak by dropping the unnecessary references.
--- drivers/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpib/lpvo_usb_gpib/lpvo_usb_gpib.c +2 -2
@@ -406,7 +406,7 @@ static int usb_gpib_attach(struct gpib_bfor (j =0 ; j <MAX_DEV ; j++) {if ((assigned_usb_minors &1 << j) ==0 )continue ; - udev =usb_get_dev (interface_to_usbdev (lpvo_usb_interfaces[j])); + udev =interface_to_usbdev (lpvo_usb_interfaces[j]); device_path =kobject_get_path (&udev->dev.kobj,GFP_KERNEL ); match =gpib_match_device_path (&lpvo_usb_interfaces[j]->dev, config->device_path);
@@ -421,7 +421,7 @@ static int usb_gpib_attach(struct gpib_bfor (j =0 ; j <MAX_DEV ; j++) {if ((assigned_usb_minors &1 << j) ==0 )continue ; - udev =usb_get_dev (interface_to_usbdev (lpvo_usb_interfaces[j])); + udev =interface_to_usbdev (lpvo_usb_interfaces[j]);DIA_LOG (1 ,"dev. %d: bus %d -> %d dev: %d -> %d\n" , j, udev->bus->busnum, config->pci_bus, udev->devnum, config->pci_slot); if (config->pci_bus == udev->bus->busnum &&
Greg Kroah-Hartman
maintainerPATCH 237/311 usb: quirks: add DELAY_INIT quirk for another Silicon Motion flash drive
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miao Li <[email protected]>
commit dd36014ec6042f424ef51b923e607772f7502ee7 upstream.
Another Silicon Motion flash drive also randomly work incorrectly (lsusb does not list the device) on Huawei hisi platforms during 500 reboot cycles, and the DELAY_INIT quirk fixes this issue.
--- drivers/usb/core/quirks.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/core/quirks.c +1 -0
@@ -402,6 +402,7 @@ static const struct usb_device_id usb_qu/* Silicon Motion Flash Drive */ { USB_DEVICE(0x090c, 0x1000), .driver_info = USB_QUIRK_DELAY_INIT }, + { USB_DEVICE(0x090c, 0x2000), .driver_info = USB_QUIRK_DELAY_INIT }, /* Sound Devices USBPre2 */ { USB_DEVICE(0x0926, 0x0202), .driver_info =
Greg Kroah-Hartman
maintainerPATCH 238/311 usb: ulpi: fix double free in ulpi_register_interface() error path
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
commit 01af542392b5d41fd659d487015a71f627accce3 upstream.
When device_register() fails, ulpi_register() calls put_device() on ulpi->dev.
The device release callback ulpi_dev_release() drops the OF node reference and frees ulpi, but the current error path in ulpi_register_interface() then calls kfree(ulpi) again, causing a double free.
Let put_device() handle the cleanup through ulpi_dev_release() and avoid freeing ulpi again in ulpi_register_interface().
--- drivers/usb/common/ulpi.c | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-)
drivers/usb/common/ulpi.c +2 -3
@@ -331,10 +331,9 @@ struct ulpi *ulpi_register_interface(str ulpi->ops = ops; ret =ulpi_register (dev, ulpi); -if (ret) { -kfree (ulpi); +if (ret)return ERR_PTR (ret); - } +return ulpi; }
Greg Kroah-Hartman
maintainerPATCH 239/311 usb: usbtmc: Flush anchored URBs in usbtmc_release
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heitor Alves de Siqueira <[email protected]>
commit 8a768552f7a8276fb9e01d49773d2094ace7c8f1 upstream.
When calling usbtmc_release, pending anchored URBs must be flushed or killed to prevent use-after-free errors (e.g. in the HCD giveback path). Call usbtmc_draw_down() to allow anchored URBs to be completed.
--- drivers/usb/class/usbtmc.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/class/usbtmc.c +3 -0
@@ -254,6 +254,9 @@ static int usbtmc_release(struct inode *list_del (&file_data->file_elem);spin_unlock_irq (&file_data->data->dev_lock); + +/* flush anchored URBs */ +usbtmc_draw_down (file_data);mutex_unlock (&file_data->data->io_mutex);kref_put (&file_data->data->kref, usbtmc_delete);
Greg Kroah-Hartman
maintainerPATCH 240/311 usb: misc: usbio: Fix URB memory leak on submit failure
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Felix Gu <[email protected]>
commit 33cfe0709b6bf1a7f1a16d5e8d65d003a71b6a21 upstream.
When usb_submit_urb() fails in usbio_probe(), the previously allocated URB is never freed, causing a memory leak.
Fix this by jumping to err_free_urb label to properly release the URB on the error path.
--- drivers/usb/misc/usbio.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
drivers/usb/misc/usbio.c +5 -2
@@ -614,8 +614,10 @@ static int usbio_probe(struct usb_interfusb_fill_bulk_urb (usbio->urb, udev, usbio->rx_pipe, usbio->rxbuf, usbio->rxbuf_len, usbio_bulk_recv, usbio); ret =usb_submit_urb (usbio->urb,GFP_KERNEL ); -if (ret) -return dev_err_probe (dev, ret,"Submitting usb urb\n" ); +if (ret) { +dev_err_probe (dev, ret,"Submitting usb urb\n" ); + goto err_free_urb; + }mutex_lock (&usbio->ctrl_mutex);
@@ -663,6 +665,7 @@ static int usbio_probe(struct usb_interf err_unlock:mutex_unlock (&usbio->ctrl_mutex);usb_kill_urb (usbio->urb); +err_free_urb:usb_free_urb (usbio->urb);return ret;
Greg Kroah-Hartman
maintainerPATCH 241/311 usb: host: xhci-sideband: delegate offload_usage tracking to class drivers
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guan-Yu Lin <[email protected]>
commit 5abbe6ecc6203355c770bf232ade88e29c960049 upstream.
Remove usb_offload_get() and usb_offload_put() from the xHCI sideband interrupter creation and removal paths.
The responsibility of manipulating offload_usage now lies entirely with the USB class drivers. They have the precise context of when an offload data stream actually starts and stops, ensuring a much more accurate representation of offload activity for power management.
--- drivers/usb/host/xhci-sideband.c | 14 +------------- sound/usb/qcom/qc_audio_offload.c | 10 +++++++++- 2 files changed, 10 insertions(+), 14 deletions(-)
drivers/usb/host/xhci-sideband.c +1 -13
@@ -93,8 +93,6 @@ __xhci_sideband_remove_endpoint(struct xstatic void __xhci_sideband_remove_interrupter (struct xhci_sideband *sb) { -struct usb_device *udev; -lockdep_assert_held (&sb->mutex);if (!sb->ir)
@@ -102,10 +100,6 @@ __xhci_sideband_remove_interrupter(strucxhci_remove_secondary_interrupter (xhci_to_hcd (sb->xhci), sb->ir); sb->ir =NULL ; - udev = sb->vdev->udev; - -if (udev->state !=USB_STATE_NOTATTACHED ) -usb_offload_put (udev); }/* sideband api functions */
@@ -328,9 +322,6 @@ int xhci_sideband_create_interrupter(struct xhci_sideband *sb, int num_seg, bool ip_autoclear, u32 imod_interval, int intr_num) { - int ret = 0; -struct usb_device *udev; - if (!sb || !sb->xhci) return -ENODEV;
@@ -348,12 +339,9 @@ xhci_sideband_create_interrupter(structif (!sb->ir)return -ENOMEM ; - udev = sb->vdev->udev; - ret =usb_offload_get (udev); - sb->ir->ip_autoclear = ip_autoclear; -return ret; +return 0 ; }EXPORT_SYMBOL_GPL (xhci_sideband_create_interrupter);
sound/usb/qcom/qc_audio_offload.c +9 -1
@@ -699,6 +699,7 @@ static void uaudio_event_ring_cleanup_fruaudio_iommu_unmap (MEM_EVENT_RING ,IOVA_BASE ,PAGE_SIZE ,PAGE_SIZE );xhci_sideband_remove_interrupter (uadev[dev->chip->card->number].sb); +usb_offload_put (dev->udev); } }
@@ -1182,12 +1183,16 @@ static int uaudio_event_ring_setup(struc dma_coherent =dev_is_dma_coherent (subs->dev->bus->sysdev); er_pa =0 ; + ret =usb_offload_get (subs->dev); +if (ret <0 ) + goto exit; +/* event ring */ ret =xhci_sideband_create_interrupter (uadev[card_num].sb,1 , false,0 , uaudio_qdev->data->intr_num);if (ret <0 ) {dev_err (&subs->dev->dev,"failed to fetch interrupter\n" ); - goto exit; + goto put_offload; } sgt =xhci_sideband_get_event_buffer (uadev[card_num].sb);
@@ -1219,6 +1224,8 @@ clear_pa: mem_info->dma =0 ; remove_interrupter:xhci_sideband_remove_interrupter (uadev[card_num].sb); +put_offload: +usb_offload_put (subs->dev); exit:return ret; }
@@ -1483,6 +1490,7 @@ unmap_er:uaudio_iommu_unmap (MEM_EVENT_RING ,IOVA_BASE ,PAGE_SIZE ,PAGE_SIZE ); free_sec_ring:xhci_sideband_remove_interrupter (uadev[card_num].sb); +usb_offload_put (subs->dev); drop_sync_ep:if (subs->sync_endpoint) { uaudio_iommu_unmap(MEM_XFER_RING,
Greg Kroah-Hartman
maintainerPATCH 242/311 usb: ehci-brcm: fix sleep during atomic
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Chen <[email protected]>
commit 679b771ea05ad0f8eeae83e14a91b8f4f39510c4 upstream.
echi_brcm_wait_for_sof() gets called after disabling interrupts in ehci_brcm_hub_control(). Use the atomic version of poll_timeout to fix the warning.
--- drivers/usb/host/ehci-brcm.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/usb/host/ehci-brcm.c +2 -2
@@ -31,8 +31,8 @@ static inline void ehci_brcm_wait_for_soint res;/* Wait for next microframe (every 125 usecs) */ - res =readl_relaxed_poll_timeout (&ehci->regs->frame_index, val, - val != frame_idx,1 ,130 ); + res =readl_relaxed_poll_timeout_atomic (&ehci->regs->frame_index, + val, val != frame_idx,1 ,130 );if (res)ehci_err (ehci,"Error waiting for SOF\n" );udelay (delay);
Greg Kroah-Hartman
maintainerPATCH 243/311 usb: dwc2: gadget: Fix spin_lock/unlock mismatch in dwc2_hsotg_udc_stop()
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Juno Choi <[email protected]>
commit 9bb4b5ed7f8c4f95cc556bdf042b0ba2fa13557a upstream.
dwc2_gadget_exit_clock_gating() internally calls call_gadget() macro, which expects hsotg->lock to be held since it does spin_unlock/spin_lock around the gadget driver callback invocation.
However, dwc2_hsotg_udc_stop() calls dwc2_gadget_exit_clock_gating() without holding the lock. This leads to:
- spin_unlock on a lock that is not held (undefined behavior)
- The lock remaining held after dwc2_gadget_exit_clock_gating() returns, causing a deadlock when spin_lock_irqsave() is called later in the same function.
Fix this by acquiring hsotg->lock before calling dwc2_gadget_exit_clock_gating() and releasing it afterwards, which satisfies the locking requirement of the call_gadget() macro.
--- drivers/usb/dwc2/gadget.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/dwc2/gadget.c +2 -0
@@ -4607,7 +4607,9 @@ static int dwc2_hsotg_udc_stop(struct us/* Exit clock gating when driver is stopped. */ if (hsotg->params.power_down ==DWC2_POWER_DOWN_PARAM_NONE && hsotg->bus_suspended && !hsotg->params.no_clock_gating) { +spin_lock_irqsave (&hsotg->lock, flags);dwc2_gadget_exit_clock_gating (hsotg,0 ); +spin_unlock_irqrestore (&hsotg->lock, flags); }/* all endpoints should be shutdown */
Greg Kroah-Hartman
maintainerPATCH 244/311 usb: core: phy: avoid double use of usb3-phy
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
commit 0179c6da0793ae03607002c284b53b6d584172d0 upstream.
Commit 53a2d95df836 ("usb: core: add phy notify connect and disconnect") causes double use of the 'usb3-phy' in certain cases.
Since that commit, if a generic PHY named 'usb3-phy' is specified in the device tree, that is getting added to the 'phy_roothub' list of the secondary HCD by the usb_phy_roothub_alloc_usb3_phy() function. However, that PHY is getting added also to the primary HCD's 'phy_roothub' list by usb_phy_roothub_alloc() if there is no generic PHY specified with 'usb2-phy' name.
This causes that the usb_add_hcd() function executes each phy operations twice on the 'usb3-phy'. Once when the primary HCD is added, then once again when the secondary HCD is added.
The issue affects the Marvell Armada 3700 platform at least, where a custom name is used for the USB2 PHY:
$ git grep 'phy-names.*usb3' arch/arm64/boot/dts/marvell/armada-37xx.dtsi | tr '\t' ' ' arch/arm64/boot/dts/marvell/armada-37xx.dtsi: phy-names = "usb3-phy", "usb2-utmi-otg-phy";
Extend the usb_phy_roothub_alloc_usb3_phy() function to skip adding the 'usb3-phy' to the 'phy_roothub' list of the secondary HCD when 'usb2-phy' is not specified in the device tree to avoid the double use.
--- drivers/usb/core/phy.c | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-)
drivers/usb/core/phy.c +11 -1
@@ -114,7 +114,7 @@ EXPORT_SYMBOL_GPL(usb_phy_roothub_alloc)struct usb_phy_roothub *usb_phy_roothub_alloc_usb3_phy (struct device *dev) {struct usb_phy_roothub *phy_roothub; -int num_phys; +int num_phys, usb2_phy_index;if (!IS_ENABLED (CONFIG_GENERIC_PHY ))return NULL ;
@@ -124,6 +124,16 @@ struct usb_phy_roothub *usb_phy_roothub_if (num_phys <=0 )return NULL ; +/* +* If 'usb2-phy' is not present, usb_phy_roothub_alloc() added +* all PHYs to the primary HCD's phy_roothub already, so skip +* adding 'usb3-phy' here to avoid double use of that. +*/ + usb2_phy_index =of_property_match_string (dev->of_node,"phy-names" , +"usb2-phy" ); +if (usb2_phy_index <0 ) +return NULL ; + phy_roothub =devm_kzalloc (dev,sizeof (*phy_roothub),GFP_KERNEL );if (!phy_roothub)return ERR_PTR (-ENOMEM );
Greg Kroah-Hartman
maintainerPATCH 245/311 usb: cdns3: gadget: fix NULL pointer dereference in ep_queue
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongchao Wu <[email protected]>
commit 7f6f127b9bc34bed35f56faf7ecb1561d6b39000 upstream.
When the gadget endpoint is disabled or not yet configured, the ep->desc pointer can be NULL. This leads to a NULL pointer dereference when __cdns3_gadget_ep_queue() is called, causing a kernel crash.
Add a check to return -ESHUTDOWN if ep->desc is NULL, which is the standard return code for unconfigured endpoints.
This prevents potential crashes when ep_queue is called on endpoints that are not ready.
--- drivers/usb/cdns3/cdns3-gadget.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/usb/cdns3/cdns3-gadget.c +3 -0
@@ -2589,6 +2589,9 @@ static int __cdns3_gadget_ep_queue(strucstruct cdns3_request *priv_req;int ret =0 ; +if (!ep->desc) +return -ESHUTDOWN ; + request->actual =0 ; request->status = -EINPROGRESS ; priv_req =to_cdns3_request (request);
Greg Kroah-Hartman
maintainerPATCH 246/311 usb: cdns3: gadget: fix state inconsistency on gadget init failure
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yongchao Wu <[email protected]>
commit c32f8748d70c8fc77676ad92ed76cede17bf2c48 upstream.
When cdns3_gadget_start() fails, the DRD hardware is left in gadget mode while software state remains INACTIVE, creating hardware/software state inconsistency.
When switching to host mode via sysfs:
echo host > /sys/class/usb_role/13180000.usb-role-switch/role
The role state is not set to CDNS_ROLE_STATE_ACTIVE due to the error, so cdns_role_stop() skips cleanup because state is still INACTIVE. This violates the DRD controller design specification (Figure22), which requires returning to idle state before switching roles.
This leads to a synchronous external abort in xhci_gen_setup() when setting up the host controller:
[ 516.440698] configfs-gadget 13180000.usb: failed to start g1: -19
[ 516.442035] cdns-usb3 13180000.usb: Failed to add gadget
[ 516.443278] cdns-usb3 13180000.usb: set role 2 has failed
...
[ 1301.375722] xhci-hcd xhci-hcd.1.auto: xHCI Host Controller
[ 1301.377716] Internal error: synchronous external abort: 96000010 [#1] PREEMPT SMP
[ 1301.382485] pc : xhci_gen_setup+0xa4/0x408
[ 1301.393391] backtrace:
...
xhci_gen_setup+0xa4/0x408 <-- CRASH
xhci_plat_setup+0x44/0x58
usb_add_hcd+0x284/0x678
...
cdns_role_set+0x9c/0xbc <-- Role switchFix by calling cdns_drd_gadget_off() in the error path to properly clean up the DRD gadget state.
--- drivers/usb/cdns3/cdns3-gadget.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/cdns3/cdns3-gadget.c +1 -0
@@ -3431,6 +3431,7 @@ static int __cdns3_gadget_init(struct cd ret =cdns3_gadget_start (cdns);if (ret) {pm_runtime_put_sync (cdns->dev); +cdns_drd_gadget_off (cdns);return ret; }
Greg Kroah-Hartman
maintainerPATCH 247/311 usb: core: use dedicated spinlock for offload state
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guan-Yu Lin <[email protected]>
commit bd3d245b0fef571f93504904df62b8865b1c0d34 upstream.
Replace the coarse USB device lock with a dedicated offload_lock spinlock to reduce contention during offload operations. Use offload_pm_locked to synchronize with PM transitions and replace the legacy offload_at_suspend flag.
Optimize usb_offload_get/put by switching from auto-resume/suspend to pm_runtime_get_if_active(). This ensures offload state is only modified when the device is already active, avoiding unnecessary power transitions.
--- drivers/usb/core/driver.c | 23 +++++--- drivers/usb/core/offload.c | 102 ++++++++++++++++++++++----------------- drivers/usb/core/usb.c | 1 drivers/usb/host/xhci-sideband.c | 4 - include/linux/usb.h | 10 +++ 5 files changed, 84 insertions(+), 56 deletions(-)
drivers/usb/core/driver.c +14 -9
@@ -1415,14 +1415,16 @@ static int usb_suspend_both(struct usb_dint status =0 ;int i =0 , n =0 ;struct usb_interface *intf; +bool offload_active = false;if (udev->state ==USB_STATE_NOTATTACHED || udev->state ==USB_STATE_SUSPENDED ) goto done; +usb_offload_set_pm_locked (udev, true);if (msg.event ==PM_EVENT_SUSPEND &&usb_offload_check (udev)) {dev_dbg (&udev->dev,"device offloaded, skip suspend.\n" ); - udev->offload_at_suspend =1 ; + offload_active = true; }/* Suspend all the interfaces and then udev itself */
@@ -1436,8 +1438,7 @@ static int usb_suspend_both(struct usb_d* interrupt urbs, allowing interrupt events to be * handled during system suspend. */ -if (udev->offload_at_suspend && - intf->needs_remote_wakeup) { +if (offload_active && intf->needs_remote_wakeup) {dev_dbg (&intf->dev,"device offloaded, skip suspend.\n" );continue ;
@@ -1452,7 +1453,7 @@ static int usb_suspend_both(struct usb_d } }if (status ==0 ) { -if (!udev->offload_at_suspend) +if (!offload_active) status =usb_suspend_device (udev, msg);/*
@@ -1498,7 +1499,7 @@ static int usb_suspend_both(struct usb_d*/ }else { udev->can_submit =0 ; -if (!udev->offload_at_suspend) { +if (!offload_active) {for (i =0 ; i <16 ; ++i) {usb_hcd_flush_endpoint (udev, udev->ep_out[i]);usb_hcd_flush_endpoint (udev, udev->ep_in[i]);
@@ -1507,6 +1508,8 @@ static int usb_suspend_both(struct usb_d } done: +if (status !=0 ) +usb_offload_set_pm_locked (udev, false);dev_vdbg (&udev->dev,"%s: status %d\n" , __func__, status);return status; }
@@ -1536,16 +1539,19 @@ static int usb_resume_both(struct usb_deint status =0 ;int i;struct usb_interface *intf; +bool offload_active = false;if (udev->state ==USB_STATE_NOTATTACHED ) { status = -ENODEV ; goto done; } udev->can_submit =1 ; +if (msg.event ==PM_EVENT_RESUME ) + offload_active =usb_offload_check (udev);/* Resume the device */ if (udev->state ==USB_STATE_SUSPENDED || udev->reset_resume) { -if (!udev->offload_at_suspend) +if (!offload_active) status =usb_resume_device (udev, msg);else dev_dbg(&udev->dev,
@@ -1562,8 +1568,7 @@ static int usb_resume_both(struct usb_de* pending interrupt urbs, allowing interrupt events * to be handled during system suspend. */ -if (udev->offload_at_suspend && - intf->needs_remote_wakeup) { +if (offload_active && intf->needs_remote_wakeup) {dev_dbg (&intf->dev,"device offloaded, skip resume.\n" );continue ;
@@ -1572,11 +1577,11 @@ static int usb_resume_both(struct usb_de udev->reset_resume); } } - udev->offload_at_suspend =0 ;usb_mark_last_busy (udev); done:dev_vdbg (&udev->dev,"%s: status %d\n" , __func__, status); +usb_offload_set_pm_locked (udev, false);if (!status) udev->reset_resume =0 ;return status;
drivers/usb/core/offload.c +59 -43
152 lines not on this page · raw message
drivers/usb/core/usb.c +1 -0
@@ -671,6 +671,7 @@ struct usb_device *usb_alloc_dev(structset_dev_node (&dev->dev,dev_to_node (bus->sysdev)); dev->state =USB_STATE_ATTACHED ; dev->lpm_disable_count =1 ; +spin_lock_init (&dev->offload_lock); dev->offload_usage =0 ;atomic_set (&dev->urbnum,0 );
drivers/usb/host/xhci-sideband.c +2 -2
@@ -285,8 +285,8 @@ EXPORT_SYMBOL_GPL(xhci_sideband_get_even* Allow other drivers, such as usb controller driver, to check if there are * any sideband activity on the host controller. This information could be used * for power management or other forms of resource management. The caller should -* ensure downstream usb devices are all either suspended or marked as -* "offload_at_suspend" to ensure the correctness of the return value. +* ensure downstream usb devices are all marked as "offload_pm_locked" to ensure +* the correctness of the return value. * * Returns true on any active sideband existence, false otherwise. */
include/linux/usb.h +8 -2
@@ -21,6 +21,7 @@#include <linux/completion.h> /* for struct completion */ #include <linux/sched.h> /* for current && schedule_timeout */ #include <linux/mutex.h> /* for struct mutex */ +#include <linux/spinlock.h> /* for spinlock_t */ #include <linux/pm_runtime.h> /* for runtime PM */ struct usb_device ;
@@ -636,8 +637,9 @@ struct usb3_lpm_parameters {* @do_remote_wakeup: remote wakeup should be enabled * @reset_resume: needs reset instead of resume * @port_is_suspended: the upstream port is suspended (L2 or U3) -* @offload_at_suspend: offload activities during suspend is enabled. +* @offload_pm_locked: prevents offload_usage changes during PM transitions. * @offload_usage: number of offload activities happening on this usb device. +* @offload_lock: protects offload_usage and offload_pm_locked * @slot_id: Slot ID assigned by xHCI * @l1_params: best effor service latency for USB2 L1 LPM state, and L1 timeout. * @u1_params: exit latencies for USB3 U1 LPM state, and hub-initiated timeout.
@@ -726,8 +728,9 @@ struct usb_device { unsigned do_remote_wakeup:1; unsigned reset_resume:1; unsigned port_is_suspended:1; - unsigned offload_at_suspend:1; + unsigned offload_pm_locked:1;int offload_usage; +spinlock_t offload_lock;enum usb_link_tunnel_mode tunnel_mode;struct device_link *usb4_link;
@@ -849,6 +852,7 @@ static inline void usb_mark_last_busy(stint usb_offload_get (struct usb_device *udev);int usb_offload_put (struct usb_device *udev);bool usb_offload_check (struct usb_device *udev); +void usb_offload_set_pm_locked (struct usb_device *udev,bool locked);#else static inline int usb_offload_get (struct usb_device *udev)
@@ -857,6 +861,8 @@ static inline int usb_offload_put(struct {return 0 ; }static inline bool usb_offload_check (struct usb_device *udev) {return false; } +static inline void usb_offload_set_pm_locked (struct usb_device *udev,bool locked) +{ }#endif extern int usb_disable_lpm (struct usb_device *udev);
Greg Kroah-Hartman
maintainerPATCH 248/311 x86/platform/geode: Fix on-stack property data use-after-return bug
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit b981e9e94c687b7b19ae8820963f005b842cb2f2 upstream.
The PROPERTY_ENTRY_GPIO macro (and by extension PROPERTY_ENTRY_REF) creates a temporary software_node_ref_args structure on the stack when used in a runtime assignment. This results in the property pointing to data that is invalid once the function returns.
Fix this by ensuring the GPIO reference data is not stored on stack and using PROPERTY_ENTRY_REF_ARRAY_LEN() to point directly to the persistent reference data.
--- arch/x86/platform/geode/geode-common.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-)
arch/x86/platform/geode/geode-common.c +18 -6
@@ -28,8 +28,10 @@ static const struct software_node geode_ .properties = geode_gpio_keys_props, }; -static struct property_entry geode_restart_key_props[] = { - {/* Placeholder for GPIO property */ }, +static struct software_node_ref_args geode_restart_gpio_ref; + +static const struct property_entry geode_restart_key_props[] = { +PROPERTY_ENTRY_REF_ARRAY_LEN ("gpios" , &geode_restart_gpio_ref,1 ),PROPERTY_ENTRY_U32 ("linux,code" ,KEY_RESTART ),PROPERTY_ENTRY_STRING ("label" ,"Reset button" ),PROPERTY_ENTRY_U32 ("debounce-interval" ,100 ),
@@ -64,8 +66,7 @@ int __init geode_create_restart_key(unsistruct platform_device *pd;int err; - geode_restart_key_props[0 ] =PROPERTY_ENTRY_GPIO ("gpios" , - &geode_gpiochip_node, + geode_restart_gpio_ref =SOFTWARE_NODE_REFERENCE (&geode_gpiochip_node, pin,GPIO_ACTIVE_LOW ); err =software_node_register_node_group (geode_gpio_keys_swnodes);
@@ -99,6 +100,7 @@ int __init geode_create_leds(const charconst struct software_node *group[MAX_LEDS +2 ] = {0 };struct software_node *swnodes;struct property_entry *props; +struct software_node_ref_args *gpio_refs;struct platform_device_info led_info = { .name ="leds-gpio" , .id =PLATFORM_DEVID_NONE ,
@@ -127,6 +129,12 @@ int __init geode_create_leds(const char goto err_free_swnodes; } + gpio_refs =kzalloc_objs (*gpio_refs, n_leds); +if (!gpio_refs) { + err = -ENOMEM ; + goto err_free_props; + } + group[0 ] = &geode_gpio_leds_node;for (i =0 ; i < n_leds; i++) { node_name =kasprintf (GFP_KERNEL ,"%s:%d" , label, i);
@@ -135,9 +143,11 @@ int __init geode_create_leds(const char goto err_free_names; } + gpio_refs[i] =SOFTWARE_NODE_REFERENCE (&geode_gpiochip_node, + leds[i].pin, +GPIO_ACTIVE_LOW ); props[i *3 +0 ] = -PROPERTY_ENTRY_GPIO ("gpios" , &geode_gpiochip_node, - leds[i].pin,GPIO_ACTIVE_LOW ); +PROPERTY_ENTRY_REF_ARRAY_LEN ("gpios" , &gpio_refs[i],1 ); props[i *3 +1 ] = PROPERTY_ENTRY_STRING("linux,default-trigger", leds[i].default_on ?
@@ -171,6 +181,8 @@ err_unregister_group: err_free_names:while (--i >=0 )kfree (swnodes[i].name); +kfree (gpio_refs); +err_free_props:kfree (props); err_free_swnodes:kfree (swnodes);
Re: [PATCH 6.19 248/311] x86/platform/geode: Fix on-stack property data use-after-return bug
Hi,
Quoted 7 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit
b981e9e94c687b7b19ae8820963f005b842cb2f2upstream.
...
Quoted 2 lines
arch/x86/platform/geode/geode-common.c +0
-0
...
arch/x86/platform/geode/geode-common.c int __init geode_create_leds(const char · line 132
Quoted 5 lines
arch/x86/platform/geode/geode-common.c +1
-0@@ -127,6 +129,12 @@ int __init geode_create_leds(const char goto err_free_swnodes; } + gpio_refs =kzalloc_objs (*gpio_refs, n_leds);
On x86_32, this fails to build:arch/x86/platform/geode/geode-common.c:132:21: error: implicit declaration of function ‘kzalloc_objs’; did you mean ‘kzalloc_node’? [-Wimplicit-function-declaration] arch/x86/platform/geode/geode-common.c:132:19: error: assignment to ‘struct software_node_ref_args *’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
132 | gpio_refs = kzalloc_objs(*gpio_refs, n_leds);
6.19 does not have kzalloc_objs() yet.
thanks,
Signature · 2 lines
js suse labs
Greg Kroah-Hartman
maintainerRe: [PATCH 6.19 248/311] x86/platform/geode: Fix on-stack property data use-after-return bug
Quoted 29 lines · Jiri Slaby
Hi,
Quoted 7 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit
b981e9e94c687b7b19ae8820963f005b842cb2f2upstream....
Quoted 2 lines
arch/x86/platform/geode/geode-common.c +0
-0...
arch/x86/platform/geode/geode-common.c int __init geode_create_leds(const char · line 131
Quoted 4 lines
arch/x86/platform/geode/geode-common.c +1
-0@@ -127,6 +129,12 @@ int __init geode_create_leds(const char goto err_free_swnodes; } + gpio_refs =kzalloc_objs (*gpio_refs, n_leds);On
x86_32, this fails to build:arch/x86/platform/geode/geode-common.c:132:21: error: implicit declaration of function ‘kzalloc_objs’; did you mean ‘kzalloc_node’? [-Wimplicit-function-declaration]arch/x86/platform/geode/geode-common.c:132:19: error: assignment to ‘structsoftware_node_ref_args*’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
132 |gpio_refs=kzalloc_objs(*gpio_refs, n_leds);
Quoted 1 line
6.19 does not have
kzalloc_objs()yet.
Ugh, yeah, Sasha caught this too, let me go fix this up, my fault. I guess I never build x32 kernels anymore :(
Greg Kroah-Hartman
maintainerRe: [PATCH 6.19 248/311] x86/platform/geode: Fix on-stack property data use-after-return bug
Quoted 30 lines · Greg Kroah-Hartman
Quoted 29 lines · Jiri Slaby
Hi,
Quoted 7 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit
b981e9e94c687b7b19ae8820963f005b842cb2f2upstream....
Quoted 2 lines
arch/x86/platform/geode/geode-common.c +0
-0...
arch/x86/platform/geode/geode-common.c int __init geode_create_leds(const char · line 131
Quoted 4 lines
arch/x86/platform/geode/geode-common.c +1
-0@@ -127,6 +129,12 @@ int __init geode_create_leds(const char goto err_free_swnodes; } + gpio_refs =kzalloc_objs (*gpio_refs, n_leds);On
x86_32, this fails to build:arch/x86/platform/geode/geode-common.c:132:21: error: implicit declaration of function ‘kzalloc_objs’; did you mean ‘kzalloc_node’? [-Wimplicit-function-declaration]arch/x86/platform/geode/geode-common.c:132:19: error: assignment to ‘structsoftware_node_ref_args*’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
132 |gpio_refs=kzalloc_objs(*gpio_refs, n_leds);
Quoted 4 lines
Quoted 1 line
6.19 does not have
kzalloc_objs()yet.Ugh, yeah, Sasha caught this too, let me go fix this up, my fault. I guess I never build x32 kernels anymore :(
Ok, now fixed up, I'll go push out new -rc2 releases with this fix in it to make sure I didn't get it wrong.
thanks,
greg k-h
Greg Kroah-Hartman
maintainerRe: [PATCH 6.19 248/311] x86/platform/geode: Fix on-stack property data use-after-return bug
Quoted 31 lines · Greg Kroah-Hartman
Quoted 30 lines · Greg Kroah-Hartman
Quoted 29 lines · Jiri Slaby
Hi,
Quoted 7 lines · Greg Kroah-Hartman
6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dmitry Torokhov <[email protected]>
commit
b981e9e94c687b7b19ae8820963f005b842cb2f2upstream....
Quoted 2 lines
arch/x86/platform/geode/geode-common.c +0
-0...
arch/x86/platform/geode/geode-common.c int __init geode_create_leds(const char · line 131
Quoted 4 lines
arch/x86/platform/geode/geode-common.c +1
-0@@ -127,6 +129,12 @@ int __init geode_create_leds(const char goto err_free_swnodes; } + gpio_refs =kzalloc_objs (*gpio_refs, n_leds);On
x86_32, this fails to build:arch/x86/platform/geode/geode-common.c:132:21: error: implicit declaration of function ‘kzalloc_objs’; did you mean ‘kzalloc_node’? [-Wimplicit-function-declaration]arch/x86/platform/geode/geode-common.c:132:19: error: assignment to ‘structsoftware_node_ref_args*’ from ‘int’ makes pointer from integer without a cast [-Wint-conversion]
132 |gpio_refs=kzalloc_objs(*gpio_refs, n_leds);
Quoted 7 lines
Quoted 4 lines
Quoted 1 line
6.19 does not have
kzalloc_objs()yet.Ugh, yeah, Sasha caught this too, let me go fix this up, my fault. I guess I never build x32 kernels anymore :(
Ok, now fixed up, I'll go push out new -rc2 releases with this fix in it to make sure I didn't get it wrong.
Ah, Sasha just dropped the commit, that was easier to do :)
Greg Kroah-Hartman
maintainerPATCH 249/311 io_uring: protect remaining lockless ctx->rings accesses with RCU
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jens Axboe <[email protected]>
Commit 61a11cf4812726aceaee17c96432e1c08f6ed6cb upstream.
Commit 96189080265e addressed one case of ctx->rings being potentially accessed while a resize is happening on the ring, but there are still a few others that need handling. Add a helper for retrieving the rings associated with an io_uring context, and add some sanity checking to that to catch bad uses. ->rings_rcu is always valid, as long as it's used within RCU read lock. Any use of ->rings_rcu or ->rings inside either ->uring_lock or ->completion_lock is sane as well.
Do the minimum fix for the current kernel, but set it up such that this basic infra can be extended for later kernels to make this harder to mess up in the future.
Thanks to Junxi Qian for finding and debugging this issue.
--- io_uring/io_uring.c | 62 +++++++++++++++++++++++++++++---------------- io_uring/io_uring.h | 34 +++++++++++++++++++++---- 2 files changed, 69 insertions(+), 27 deletions(-)
io_uring/io_uring.c +40 -22
@@ -189,12 +189,15 @@ static void io_poison_req(struct io_kiocb *req)static inline unsigned int __io_cqring_events (struct io_ring_ctx *ctx) { -return ctx->cached_cq_tail -READ_ONCE (ctx->rings->cq.head); +struct io_rings *rings =io_get_rings (ctx); +return ctx->cached_cq_tail -READ_ONCE (rings->cq.head); }static inline unsigned int __io_cqring_events_user (struct io_ring_ctx *ctx) { -return READ_ONCE (ctx->rings->cq.tail) -READ_ONCE (ctx->rings->cq.head); +struct io_rings *rings =io_get_rings (ctx); + +return READ_ONCE (rings->cq.tail) -READ_ONCE (rings->cq.head); }static inline void req_fail_link_node (struct io_kiocb *req,int res)
@@ -2536,12 +2539,15 @@ static enum hrtimer_restart io_cqring_min_timer_wakeup(struct hrtimer *timer)if (io_has_work (ctx)) goto out_wake;/* got events since we started waiting, min timeout is done */ -if (iowq->cq_min_tail !=READ_ONCE (ctx->rings->cq.tail)) - goto out_wake; -/* if we have any events and min timeout expired, we're done */ -if (io_cqring_events (ctx)) - goto out_wake; +scoped_guard (rcu) { +struct io_rings *rings =io_get_rings (ctx); +if (iowq->cq_min_tail !=READ_ONCE (rings->cq.tail)) + goto out_wake; +/* if we have any events and min timeout expired, we're done */ +if (io_cqring_events (ctx)) + goto out_wake; + }/* * If using deferred task_work running and application is waiting on * more than one request, ensure we reset it now where we are switching
@@ -2652,9 +2658,9 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, u32 flags, struct ext_arg *ext_arg) {struct io_wait_queue iowq; -struct io_rings *rings = ctx->rings; +struct io_rings *rings;ktime_t start_time; -int ret; +int ret, nr_wait; min_events =min_t (int, min_events, ctx->cq_entries);
@@ -2667,15 +2673,23 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, u32 flags,if (unlikely (test_bit (IO_CHECK_CQ_OVERFLOW_BIT , &ctx->check_cq)))io_cqring_do_overflow_flush (ctx); -if (__io_cqring_events_user (ctx) >= min_events) + +rcu_read_lock (); + rings =io_get_rings (ctx); +if (__io_cqring_events_user (ctx) >= min_events) { +rcu_read_unlock ();return 0 ; + }init_waitqueue_func_entry (&iowq.wq, io_wake_function); iowq.wq.private = current;INIT_LIST_HEAD (&iowq.wq.entry); iowq.ctx = ctx; - iowq.cq_tail =READ_ONCE (ctx->rings->cq.head) + min_events; - iowq.cq_min_tail =READ_ONCE (ctx->rings->cq.tail); + iowq.cq_tail =READ_ONCE (rings->cq.head) + min_events; + iowq.cq_min_tail =READ_ONCE (rings->cq.tail); + nr_wait = (int ) iowq.cq_tail -READ_ONCE (rings->cq.tail); +rcu_read_unlock (); + rings =NULL ; iowq.nr_timeouts =atomic_read (&ctx->cq_timeouts); iowq.hit_timeout =0 ; iowq.min_timeout = ext_arg->min_time;
@@ -2706,14 +2720,6 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, u32 flags,trace_io_uring_cqring_wait (ctx, min_events); do { unsigned long check_cq; - int nr_wait; - - /* if min timeout has been hit, don't reset wait count */ - if (!iowq.hit_timeout) - nr_wait = (int) iowq.cq_tail - - READ_ONCE(ctx->rings->cq.tail); - else - nr_wait = 1; if (ctx->flags & IORING_SETUP_DEFER_TASKRUN) { atomic_set(&ctx->cq_wait_nr, nr_wait);
@@ -2764,13 +2770,22 @@ static int io_cqring_wait(struct io_ring_ctx *ctx, int min_events, u32 flags,break ; }cond_resched (); + +/* if min timeout has been hit, don't reset wait count */ +if (!iowq.hit_timeout) +scoped_guard (rcu) + nr_wait = (int) iowq.cq_tail - +READ_ONCE (io_get_rings (ctx)->cq.tail); +else + nr_wait =1 ; }while (1 );if (!(ctx->flags &IORING_SETUP_DEFER_TASKRUN ))finish_wait (&ctx->cq_wait, &iowq.wq);restore_saved_sigmask_unless (ret == -EINTR ); -return READ_ONCE (rings->cq.head) ==READ_ONCE (rings->cq.tail) ? ret :0 ; +guard (rcu)(); +return READ_ONCE (io_get_rings (ctx)->cq.head) ==READ_ONCE (io_get_rings (ctx)->cq.tail) ? ret :0 ; }static void io_rings_free (struct io_ring_ctx *ctx)
@@ -2954,7 +2969,9 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait)*/ poll_wait (file, &ctx->poll_wq, wait); -if (!io_sqring_full (ctx)) +rcu_read_lock (); + +if (!__io_sqring_full (ctx)) mask |=EPOLLOUT |EPOLLWRNORM ;/*
@@ -2974,6 +2991,7 @@ static __poll_t io_uring_poll(struct file *file, poll_table *wait)if (__io_cqring_events_user (ctx) ||io_has_work (ctx)) mask |=EPOLLIN |EPOLLRDNORM ; +rcu_read_unlock ();return mask; }
io_uring/io_uring.h +29 -5
@@ -132,16 +132,28 @@ struct io_wait_queue {#endif }; +static inline struct io_rings *io_get_rings (struct io_ring_ctx *ctx) +{ +return rcu_dereference_check (ctx->rings_rcu, +lockdep_is_held (&ctx->uring_lock) || +lockdep_is_held (&ctx->completion_lock)); +} +static inline bool io_should_wake (struct io_wait_queue *iowq) {struct io_ring_ctx *ctx = iowq->ctx; -int dist =READ_ONCE (ctx->rings->cq.tail) - (int ) iowq->cq_tail; +struct io_rings *rings; +int dist; + +guard (rcu)(); + rings =io_get_rings (ctx);/* * Wake up if we have enough events, or if a timeout occurred since we * started waiting. For timeouts, we always want to return to userspace, * regardless of event count. */ + dist =READ_ONCE (rings->cq.tail) - (int ) iowq->cq_tail;return dist >=0 ||atomic_read (&ctx->cq_timeouts) != iowq->nr_timeouts; }
@@ -432,9 +444,9 @@ static inline void io_cqring_wake(struct io_ring_ctx *ctx)__io_wq_wake (&ctx->cq_wait); } -static inline bool io_sqring_full (struct io_ring_ctx *ctx) +static inline bool __io_sqring_full (struct io_ring_ctx *ctx) { -struct io_rings *r = ctx->rings; +struct io_rings *r =io_get_rings (ctx);/* * SQPOLL must use the actual sqring head, as using the cached_sq_head
@@ -446,9 +458,15 @@ static inline bool io_sqring_full(struct io_ring_ctx *ctx)return READ_ONCE (r->sq.tail) -READ_ONCE (r->sq.head) == ctx->sq_entries; } -static inline unsigned int io_sqring_entries (struct io_ring_ctx *ctx) +static inline bool io_sqring_full (struct io_ring_ctx *ctx) { -struct io_rings *rings = ctx->rings; +guard (rcu)(); +return __io_sqring_full (ctx); +} + +static inline unsigned int __io_sqring_entries (struct io_ring_ctx *ctx) +{ +struct io_rings *rings =io_get_rings (ctx);unsigned int entries;/* make sure SQ entry isn't read before tail */
@@ -509,6 +527,12 @@ static inline void io_tw_lock(struct io_ring_ctx *ctx, io_tw_token_t tw)lockdep_assert_held (&ctx->uring_lock); } +static inline unsigned int io_sqring_entries (struct io_ring_ctx *ctx) +{ +guard (rcu)(); +return __io_sqring_entries (ctx); +} +/* * Don't complete immediately but use deferred completion infrastructure. * Protected by ->uring_lock and can only be used either with
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 250/311 auxdisplay: line-display: fix NULL dereference in linedisp_release
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
commit 7f138de156b20d9f9da6f72f90b63c01941d97d3 upstream.
linedisp_release() currently retrieves the enclosing struct linedisp via to_linedisp(). That lookup depends on the attachment list, but the attachment may already have been removed before put_device() invokes the release callback. This can happen in linedisp_unregister(), and can also be reached from some linedisp_register() error paths.
In that case, to_linedisp() returns NULL and linedisp_release() dereferences it while freeing the display resources.
The struct device released here is the embedded linedisp->dev used by linedisp_register(), so retrieve the enclosing object directly with container_of() instead.
--- drivers/auxdisplay/line-display.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/auxdisplay/line-display.c +1 -1
@@ -365,7 +365,7 @@ static DEFINE_IDA(linedisp_id);static void linedisp_release (struct device *dev) { -struct linedisp *linedisp =to_linedisp (dev); + struct linedisp *linedisp = container_of(dev, struct linedisp, dev);kfree (linedisp->map);kfree (linedisp->message);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 251/311 bridge: br_nd_send: validate ND option lengths
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yang <[email protected]>
commit 850837965af15707fd3142c1cf3c5bfaf022299b upstream.
br_nd_send() walks ND options according to option-provided lengths. A malformed option can make the parser advance beyond the computed option span or use a too-short source LLADDR option payload.
Validate option lengths against the remaining NS option area before advancing, and only read source LLADDR when the option is large enough for an Ethernet address.
--- net/bridge/br_arp_nd_proxy.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
net/bridge/br_arp_nd_proxy.c +4 -2
@@ -288,12 +288,14 @@ static void br_nd_send(struct net_bridge ns_olen = request->len - (skb_network_offset (request) +sizeof (struct ipv6hdr )) -sizeof (*ns);for (i =0 ; i < ns_olen -1 ; i += (ns->opt[i +1 ] <<3 )) { -if (!ns->opt[i +1 ]) { +if (!ns->opt[i +1 ] || i + (ns->opt[i +1 ] <<3 ) > ns_olen) {kfree_skb (reply);return ; }if (ns->opt[i] ==ND_OPT_SOURCE_LL_ADDR ) { - daddr = ns->opt + i +sizeof (struct nd_opt_hdr ); +if ((ns->opt[i +1 ] <<3 ) >= +sizeof (struct nd_opt_hdr ) +ETH_ALEN ) + daddr = ns->opt + i +sizeof (struct nd_opt_hdr );break ; } }
Greg Kroah-Hartman
maintainerPATCH 252/311 cdc-acm: new quirk for EPSON HMD
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Oliver Neukum <[email protected]>
commit f97e96c303d689708f7f713d8f3afcc31f1237e9 upstream.
This device has a union descriptor that is just garbage and needs a custom descriptor.
In principle this could be done with a (conditionally activated) heuristic. That would match more devices without a need for defining a new quirk. However, this always carries the risk that the heuristics does the wrong thing and leads to more breakage. Defining the quirk and telling it exactly what to do is the safe and conservative approach.
--- drivers/usb/class/cdc-acm.c | 9 +++++++++ drivers/usb/class/cdc-acm.h | 1 + 2 files changed, 10 insertions(+)
drivers/usb/class/cdc-acm.c +9 -0
@@ -1225,6 +1225,12 @@ static int acm_probe(struct usb_interfacif (!data_interface || !control_interface)return -ENODEV ; goto skip_normal_probe; + }else if (quirks ==NO_UNION_12 ) { + data_interface =usb_ifnum_to_if (usb_dev,2 ); + control_interface =usb_ifnum_to_if (usb_dev,1 ); +if (!data_interface || !control_interface) +return -ENODEV ; + goto skip_normal_probe; }/* normal probing*/
@@ -1748,6 +1754,9 @@ static const struct usb_device_id acm_id { USB_DEVICE(0x045b, 0x024D), /* Renesas R-Car E3 USB Download mode */ .driver_info =DISABLE_ECHO ,/* Don't echo banner */ }, + { USB_DEVICE(0x04b8, 0x0d12), /* EPSON HMD Com&Sens */ + .driver_info = NO_UNION_12, /* union descriptor is garbage */ + }, { USB_DEVICE(0x0e8d, 0x0003), /* FIREFLY, MediaTek Inc; [email protected] */ .driver_info = NO_UNION_NORMAL, /* has no union descriptor */ },
drivers/usb/class/cdc-acm.h +1 -0
@@ -114,3 +114,4 @@ struct acm {#define SEND_ZERO_PACKET BIT(6)#define DISABLE_ECHO BIT(7)#define MISSING_CAP_BRK BIT(8) +#define NO_UNION_12 BIT(9)
Greg Kroah-Hartman
maintainerPATCH 253/311 comedi: dt2815: add hardware detection to prevent crash
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Deepanshu Kartikey <[email protected]>
commit 93853512f565e625df2397f0d8050d6aafd7c3ad upstream.
The dt2815 driver crashes when attached to I/O ports without actual hardware present. This occurs because syzkaller or users can attach the driver to arbitrary I/O addresses via COMEDI_DEVCONFIG ioctl.
When no hardware exists at the specified port, inb() operations return 0xff (floating bus), but outb() operations can trigger page faults due to undefined behavior, especially under race conditions:
BUG: unable to handle page fault for address: 000000007fffff90 #PF: supervisor write access in kernel mode #PF: error_code(0x0002) - not-present page RIP: 0010:dt2815_attach+0x6e0/0x1110
Add hardware detection by reading the status register before attempting any write operations. If the read returns 0xff, assume no hardware is present and fail the attach with -ENODEV. This prevents crashes from outb() operations on non-existent hardware.
--- drivers/comedi/drivers/dt2815.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
drivers/comedi/drivers/dt2815.c +12 -0
@@ -175,6 +175,18 @@ static int dt2815_attach(struct comedi_d ? current_range_type : voltage_range_type; } +/* +* Check if hardware is present before attempting any I/O operations. +* Reading 0xff from status register typically indicates no hardware +* on the bus (floating bus reads as all 1s). +*/ +if (inb (dev->iobase +DT2815_STATUS ) ==0xff ) { +dev_err (dev->class_dev, +"No hardware detected at I/O base 0x%lx\n" , + dev->iobase); +return -ENODEV ; + } +/* Init the 2815 */ outb (0x00 , dev->iobase +DT2815_STATUS );for (i =0 ; i <100 ; i++) {
Greg Kroah-Hartman
maintainerPATCH 254/311 comedi: runflags cannot determine whether to reclaim chanlist
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
commit 29f644f14b89e6c4965e3c89251929e451190a66 upstream.
syzbot reported a memory leak [1], because commit 4e1da516debb ("comedi:
Add reference counting for Comedi command handling") did not consider the exceptional exit case in do_cmd_ioctl() where runflags is not set. This caused chanlist not to be properly freed by do_become_nonbusy(), as it only frees chanlist when runflags is correctly set.
Added a check in do_become_nonbusy() for the case where runflags is not set, to properly free the chanlist memory.
[1]
BUG: memory leak
backtrace (crc 844a0efa):
__comedi_get_user_chanlist drivers/comedi/comedi_fops.c:1815 [inline]
do_cmd_ioctl.part.0+0x112/0x350 drivers/comedi/comedi_fops.c:1890
do_cmd_ioctl drivers/comedi/comedi_fops.c:1858 [inline]--- drivers/comedi/comedi_fops.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-)
drivers/comedi/comedi_fops.c +5 -3
@@ -793,13 +793,15 @@ static void do_become_nonbusy(struct comedi_device *dev,__comedi_clear_subdevice_runflags (s,COMEDI_SRF_RUNNING |COMEDI_SRF_BUSY );spin_unlock_irqrestore (&s->spin_lock, flags); -if (comedi_is_runflags_busy (runflags)) { +if (async) {/* * "Run active" counter was set to 1 when setting up the * command. Decrement it and wait for it to become 0. */ -comedi_put_is_subdevice_running (s); -wait_for_completion (&async->run_complete); +if (comedi_is_runflags_busy (runflags)) { +comedi_put_is_subdevice_running (s); +wait_for_completion (&async->run_complete); + }comedi_buf_reset (s); async->inttrig =NULL ;kfree (async->cmd.chanlist);
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 255/311 comedi: Reinit dev->spinlock between attachments to low-level drivers
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 4b9a9a6d71e3e252032f959fb3895a33acb5865c upstream.
struct comedi_device is the main controlling structure for a COMEDI device created by the COMEDI subsystem. It contains a member spinlock containing a spin-lock that is initialized by the COMEDI subsystem, but is reserved for use by a low-level driver attached to the COMEDI device (at least since commit 25436dc9d84f ("Staging: comedi: remove RT code")).
Some COMEDI devices (those created on initialization of the COMEDI subsystem when the "comedi.comedi_num_legacy_minors" parameter is non-zero) can be attached to different low-level drivers over their lifetime using the COMEDI_DEVCONFIG ioctl command. This can result in inconsistent lock states being reported when there is a mismatch in the spin-lock locking levels used by each low-level driver to which the COMEDI device has been attached. Fix it by reinitializing dev->spinlock before calling the low-level driver's attach function pointer if CONFIG_LOCKDEP is enabled.
--- drivers/comedi/drivers.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/comedi/drivers.c +8 -0
@@ -1063,6 +1063,14 @@ int comedi_device_attach(struct comedi_d ret = -EIO ; goto out; } +if (IS_ENABLED (CONFIG_LOCKDEP )) { +/* +* dev->spinlock is for private use by the attached low-level +* driver. Reinitialize it to stop lock-dependency tracking +* between attachments to different low-level drivers. +*/ +spin_lock_init (&dev->spinlock); + } dev->driver = driv; dev->board_name = dev->board_ptr ? *(const char **)dev->board_ptr : dev->driver->driver_name;
Greg Kroah-Hartman
maintainerPATCH 256/311 comedi: ni_atmio16d: Fix invalid clean-up after failed attach
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 101ab946b79ad83b36d5cfd47de587492a80acf0 upstream.
If the driver's COMEDI "attach" handler function (atmio16d_attach()) returns an error, the COMEDI core will call the driver's "detach" handler function (atmio16d_detach()) to clean up. This calls reset_atmio16d() unconditionally, but depending on where the error occurred in the attach handler, the device may not have been sufficiently initialized to call reset_atmio16d(). It uses dev->iobase as the I/O port base address and dev->private as the pointer to the COMEDI device's private data structure. dev->iobase may still be set to its initial value of 0, which would result in undesired writes to low I/O port addresses. dev->private may still be NULL, which would result in null pointer dereferences.
Fix atmio16d_detach() by checking that dev->private is valid (non-null) before calling reset_atmio16d(). This implies that dev->iobase was set correctly since that is set up before dev->private.
--- drivers/comedi/drivers/ni_atmio16d.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/comedi/drivers/ni_atmio16d.c +2 -1
@@ -698,7 +698,8 @@ static int atmio16d_attach(struct comedistatic void atmio16d_detach (struct comedi_device *dev) { -reset_atmio16d (dev); +if (dev->private) +reset_atmio16d (dev);comedi_legacy_detach (dev); }
Greg Kroah-Hartman
maintainerPATCH 257/311 comedi: me_daq: Fix potential overrun of firmware buffer
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit cc797d4821c754c701d9714b58bea947e31dbbe0 upstream.
me2600_xilinx_download() loads the firmware that was requested by request_firmware(). It is possible for it to overrun the source buffer because it blindly trusts the file format. It reads a data stream length from the first 4 bytes into variable file_length and reads the data stream contents of length file_length from offset 16 onwards. Although it checks that the supplied firmware is at least 16 bytes long, it does not check that it is long enough to contain the data stream.
Add a test to ensure that the supplied firmware is long enough to contain the header and the data stream. On failure, log an error and return -EINVAL.
--- drivers/comedi/drivers/me_daq.c | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-)
drivers/comedi/drivers/me_daq.c +19 -16
@@ -344,6 +344,25 @@ static int me2600_xilinx_download(structunsigned int file_length;unsigned int i; +/* +* Format of the firmware +* Build longs from the byte-wise coded header +* Byte 1-3: length of the array +* Byte 4-7: version +* Byte 8-11: date +* Byte 12-15: reserved +*/ +if (size >=4 ) { + file_length = (((unsigned int )data[0 ] &0xff ) <<24 ) + + (((unsigned int )data[1 ] &0xff ) <<16 ) + + (((unsigned int )data[2 ] &0xff ) <<8 ) + + ((unsigned int )data[3 ] &0xff ); + } +if (size <16 || file_length > size -16 ) { +dev_err (dev->class_dev,"Firmware length inconsistency\n" ); +return -EINVAL ; + } +/* disable irq's on PLX */ writel (0x00 , devpriv->plx_regbase +PLX9052_INTCSR );
@@ -358,22 +377,6 @@ static int me2600_xilinx_download(structsleep (1 );/* -* Format of the firmware -* Build longs from the byte-wise coded header -* Byte 1-3: length of the array -* Byte 4-7: version -* Byte 8-11: date -* Byte 12-15: reserved -*/ -if (size <16 ) -return -EINVAL ; - - file_length = (((unsigned int )data[0 ] &0xff ) <<24 ) + - (((unsigned int )data[1 ] &0xff ) <<16 ) + - (((unsigned int )data[2 ] &0xff ) <<8 ) + - ((unsigned int )data[3 ] &0xff ); - -/* * Loop for writing firmware byte by byte to xilinx * Firmware data start at offset 16 */
Greg Kroah-Hartman
maintainerPATCH 258/311 comedi: me4000: Fix potential overrun of firmware buffer
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 3fb43a7a5b44713f892c58ead2e5f3a1bc9f4ee7 upstream.
me4000_xilinx_download() loads the firmware that was requested by request_firmware(). It is possible for it to overrun the source buffer because it blindly trusts the file format. It reads a data stream length from the first 4 bytes into variable file_length and reads the data stream contents of length file_length from offset 16 onwards.
Add a test to ensure that the supplied firmware is long enough to contain the header and the data stream. On failure, log an error and return -EINVAL.
Note: The firmware loading was totally broken before commit ac584af59945 ("staging: comedi: me4000: fix firmware downloading"), but that is the most sensible target for this fix.
--- drivers/comedi/drivers/me4000.c | 16 ++++++++++++---- 1 file changed, 12 insertions(+), 4 deletions(-)
drivers/comedi/drivers/me4000.c +12 -4
@@ -315,6 +315,18 @@ static int me4000_xilinx_download(structunsigned int val;unsigned int i; +/* Get data stream length from header. */ +if (size >=4 ) { + file_length = (((unsigned int )data[0 ] &0xff ) <<24 ) + + (((unsigned int )data[1 ] &0xff ) <<16 ) + + (((unsigned int )data[2 ] &0xff ) <<8 ) + + ((unsigned int )data[3 ] &0xff ); + } +if (size <16 || file_length > size -16 ) { +dev_err (dev->class_dev,"Firmware length inconsistency\n" ); +return -EINVAL ; + } +if (!xilinx_iobase)return -ENODEV ;
@@ -346,10 +358,6 @@ static int me4000_xilinx_download(structoutl (val, devpriv->plx_regbase +PLX9052_CNTRL );/* Download Xilinx firmware */ - file_length = (((unsigned int )data[0 ] &0xff ) <<24 ) + - (((unsigned int )data[1 ] &0xff ) <<16 ) + - (((unsigned int )data[2 ] &0xff ) <<8 ) + - ((unsigned int )data[3 ] &0xff );usleep_range (10 ,1000 );for (i =0 ; i < file_length; i++) {
Greg Kroah-Hartman
maintainerPATCH 259/311 firmware: microchip: fail auto-update probe if no flash found
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Conor Dooley <[email protected]>
commit c7596f9001e2b83293e3658e4e1addde69bb335d upstream.
There's no point letting the driver probe if there is no flash, as trying to do a firmware upload will fail. Move the code that attempts to get the flash from firmware upload to probe, and let it emit a message to users stating why auto-update is not supported. The code currently could have a problem if there's a flash in devicetree, but the system controller driver fails to get a pointer to it from the mtd subsystem, which will cause mpfs_sys_controller_get_flash() to return an error. Check for errors and null, instead of just null, in the new clause.
--- drivers/firmware/microchip/mpfs-auto-update.c | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-)
drivers/firmware/microchip/mpfs-auto-update.c +6 -4
@@ -113,10 +113,6 @@ static enum fw_upload_err mpfs_auto_upda* be added here. */ - priv->flash =mpfs_sys_controller_get_flash (priv->sys_controller); -if (!priv->flash) -return FW_UPLOAD_ERR_HW_ERROR ; - erase_size =round_up (erase_size, (u64 )priv->flash->erasesize);/*
@@ -427,6 +423,12 @@ static int mpfs_auto_update_probe(structreturn dev_err_probe (dev,PTR_ERR (priv->sys_controller),"Could not register as a sub device of the system controller\n" ); + priv->flash =mpfs_sys_controller_get_flash (priv->sys_controller); +if (IS_ERR_OR_NULL (priv->flash)) { +dev_dbg (dev,"No flash connected to the system controller, auto-update not supported\n" ); +return -ENODEV ; + } + priv->dev = dev;platform_set_drvdata (pdev, priv);
Greg Kroah-Hartman
maintainerPATCH 260/311 dt-bindings: connector: add pd-disable dependency
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
commit 269c26464dcf8b54b0dd9c333721c30ee44ae297 upstream.
When Power Delivery is not supported, the source is unable to obtain the current capability from the Source PDO. As a result, typec-power-opmode needs to be added to advertise such capability.
--- Documentation/devicetree/bindings/connector/usb-connector.yaml | 1 + 1 file changed, 1 insertion(+)
Documentation/devicetree/bindings/connector/usb-connector.yaml +1 -0
@@ -301,6 +301,7 @@ properties: maxItems: 4 dependencies: + pd-disable: [typec-power-opmode] sink-vdos-v1: [ sink-vdos ] sink-vdos: [ sink-vdos-v1 ]
Greg Kroah-Hartman
maintainerPATCH 261/311 spi: cadence-qspi: Fix exec_mem_op error handling
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Emanuele Ghidoli <[email protected]>
commit 59e1be1278f064d7172b00473b7e0c453cb1ec52 upstream.
cqspi_exec_mem_op() increments the runtime PM usage counter before all refcount checks are performed. If one of these checks fails, the function returns without dropping the PM reference.
Move the pm_runtime_resume_and_get() call after the refcount checks so that runtime PM is only acquired when the operation can proceed and drop the inflight_ops refcount if the PM resume fails.
--- drivers/spi/spi-cadence-quadspi.c | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-)
drivers/spi/spi-cadence-quadspi.c +9 -8
@@ -1478,14 +1478,6 @@ static int cqspi_exec_mem_op(struct spi_if (refcount_read (&cqspi->inflight_ops) ==0 )return -ENODEV ; -if (!(ddata && (ddata->quirks &CQSPI_DISABLE_RUNTIME_PM ))) { - ret =pm_runtime_resume_and_get (dev); -if (ret) { -dev_err (&mem->spi->dev,"resume failed with %d\n" , ret); -return ret; - } - } -if (!refcount_read (&cqspi->refcount))return -EBUSY ;
@@ -1497,6 +1489,14 @@ static int cqspi_exec_mem_op(struct spi_return -EBUSY ; } +if (!(ddata && (ddata->quirks &CQSPI_DISABLE_RUNTIME_PM ))) { + ret =pm_runtime_resume_and_get (dev); +if (ret) { +dev_err (&mem->spi->dev,"resume failed with %d\n" , ret); + goto dec_inflight_refcount; + } + } + ret =cqspi_mem_process (mem, op);if (!(ddata && (ddata->quirks &CQSPI_DISABLE_RUNTIME_PM )))
@@ -1505,6 +1505,7 @@ static int cqspi_exec_mem_op(struct spi_if (ret)dev_err (&mem->spi->dev,"operation failed with %d\n" , ret); +dec_inflight_refcount:if (refcount_read (&cqspi->inflight_ops) >1 )refcount_dec (&cqspi->inflight_ops);
Greg Kroah-Hartman
maintainerPATCH 262/311 s390/zcrypt: Fix memory leak with CCA cards used as accelerator
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harald Freudenberger <[email protected]>
commit c8d46f17c2fc7d25c18e60c008928aecab26184d upstream.
Tests showed that there is a memory leak if CCA cards are used as accelerator for clear key RSA requests (ME and CRT). With the last rework for the memory allocation the AP messages are allocated by ap_init_apmsg() but for some reason on two places (ME and CRT) the older allocation was still in place. So the first allocation simple was never freed.
--- drivers/s390/crypto/zcrypt_msgtype6.c | 32 ++++++++++++++------------------ 1 file changed, 14 insertions(+), 18 deletions(-)
drivers/s390/crypto/zcrypt_msgtype6.c +14 -18
@@ -953,6 +953,10 @@ static atomic_t zcrypt_step = ATOMIC_INI/* * The request distributor calls this function if it picked the CEXxC * device to handle a modexpo request. +* This function assumes that ap_msg has been initialized with +* ap_init_apmsg() and thus a valid buffer with the size of +* ap_msg->bufsize is available within ap_msg. Also the caller has +* to make sure ap_release_apmsg() is always called even on failure. * @zq: pointer to zcrypt_queue structure that identifies the * CEXxC device to the request distributor * @mex: pointer to the modexpo request buffer
@@ -964,21 +968,17 @@ static long zcrypt_msgtype6_modexpo(strustruct ap_response_type *resp_type = &ap_msg->response;int rc; - ap_msg->msg = (void *)get_zeroed_page (GFP_KERNEL ); -if (!ap_msg->msg) -return -ENOMEM ; - ap_msg->bufsize =PAGE_SIZE ; ap_msg->receive = zcrypt_msgtype6_receive; ap_msg->psmid = (((unsigned long )current->pid) <<32 ) +atomic_inc_return (&zcrypt_step); rc =icamex_msg_to_type6mex_msgx (zq, ap_msg, mex);if (rc) - goto out_free; + goto out; resp_type->type =CEXXC_RESPONSE_TYPE_ICA ;init_completion (&resp_type->work); rc =ap_queue_message (zq->queue, ap_msg);if (rc) - goto out_free; + goto out; rc =wait_for_completion_interruptible (&resp_type->work);if (rc ==0 ) { rc = ap_msg->rc;
@@ -991,15 +991,17 @@ static long zcrypt_msgtype6_modexpo(struap_cancel_message (zq->queue, ap_msg); } -out_free: -free_page ((unsigned long )ap_msg->msg); - ap_msg->msg =NULL ; +out:return rc; }/* * The request distributor calls this function if it picked the CEXxC * device to handle a modexpo_crt request. +* This function assumes that ap_msg has been initialized with +* ap_init_apmsg() and thus a valid buffer with the size of +* ap_msg->bufsize is available within ap_msg. Also the caller has +* to make sure ap_release_apmsg() is always called even on failure. * @zq: pointer to zcrypt_queue structure that identifies the * CEXxC device to the request distributor * @crt: pointer to the modexpoc_crt request buffer
@@ -1011,21 +1013,17 @@ static long zcrypt_msgtype6_modexpo_crt(struct ap_response_type *resp_type = &ap_msg->response;int rc; - ap_msg->msg = (void *)get_zeroed_page (GFP_KERNEL ); -if (!ap_msg->msg) -return -ENOMEM ; - ap_msg->bufsize =PAGE_SIZE ; ap_msg->receive = zcrypt_msgtype6_receive; ap_msg->psmid = (((unsigned long )current->pid) <<32 ) +atomic_inc_return (&zcrypt_step); rc =icacrt_msg_to_type6crt_msgx (zq, ap_msg, crt);if (rc) - goto out_free; + goto out; resp_type->type =CEXXC_RESPONSE_TYPE_ICA ;init_completion (&resp_type->work); rc =ap_queue_message (zq->queue, ap_msg);if (rc) - goto out_free; + goto out; rc =wait_for_completion_interruptible (&resp_type->work);if (rc ==0 ) { rc = ap_msg->rc;
@@ -1038,9 +1036,7 @@ static long zcrypt_msgtype6_modexpo_crt(ap_cancel_message (zq->queue, ap_msg); } -out_free: -free_page ((unsigned long )ap_msg->msg); - ap_msg->msg =NULL ; +out:return rc; }
Greg Kroah-Hartman
maintainerPATCH 263/311 s390/cpum_sf: Cap sampling rate to prevent lsctl exception
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Richter <[email protected]>
commit 57ad0d4a00f5d3e80f33ba2da8d560c73d83dc22 upstream.
commit fcc43a7e294f ("s390/configs: Set HZ=1000") changed the interrupt frequency of the system. On machines with heavy load and many perf event overflows, this might lead to an exception. Dmesg displays these entries:
[112.242542] cpum_sf: Loading sampling controls failed: op 1 err -22
One line per CPU online.
The root cause is the CPU Measurement sampling facility overflow adjustment. Whenever an overflow (too much samples per tick) occurs, the sampling rate is adjusted and increased. This was done without observing the maximum sampling rate limit. When the current sampling interval is higher than the maximum sampling rate limit, the lsctl instruction raises an exception. The error messages is the result of such an exception. Observe the upper limit when the new sampling rate is recalculated.
--- arch/s390/kernel/perf_cpum_sf.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
arch/s390/kernel/perf_cpum_sf.c +5 -1
@@ -1168,6 +1168,7 @@ static void hw_collect_samples(struct pestatic void hw_perf_event_update (struct perf_event *event,int flush_all) {unsigned long long event_overflow, sampl_overflow, num_sdb; +struct cpu_hw_sf *cpuhw =this_cpu_ptr (&cpu_hw_sf);struct hw_perf_event *hwc = &event->hw;union hws_trailer_header prev, new;struct hws_trailer_entry *te;
@@ -1247,8 +1248,11 @@ static void hw_perf_event_update(struct* are dropped. * Slightly increase the interval to avoid hitting this limit. */ -if (event_overflow) +if (event_overflow) {SAMPL_RATE (hwc) +=DIV_ROUND_UP (SAMPL_RATE (hwc),10 ); +if (SAMPL_RATE (hwc) > cpuhw->qsi.max_sampl_rate) +SAMPL_RATE (hwc) = cpuhw->qsi.max_sampl_rate; + } } static inline unsigned long aux_sdb_index(struct aux_buffer *aux,
Greg Kroah-Hartman
maintainerPATCH 264/311 reset: gpio: fix double free in reset_add_gpio_aux_device() error path
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Guangshuo Li <[email protected]>
commit fbffb8c7c7bb4d38e9f65e0bee446685011de5d8 upstream.
When __auxiliary_device_add() fails, reset_add_gpio_aux_device() calls auxiliary_device_uninit(adev).
The device release callback reset_gpio_aux_device_release() frees adev, but the current error path then calls kfree(adev) again, causing a double free.
Keep kfree(adev) for the auxiliary_device_init() failure path, but avoid freeing adev after auxiliary_device_uninit().
--- drivers/reset/core.c | 1 - 1 file changed, 1 deletion(-)
drivers/reset/core.c +0 -1
@@ -856,7 +856,6 @@ static int reset_add_gpio_aux_device(struct device *parent, ret =__auxiliary_device_add (adev,"reset" );if (ret) {auxiliary_device_uninit (adev); -kfree (adev);return ret; }
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 265/311 PM: EM: Fix NULL pointer dereference when perf domain ID is not found
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Changwoo Min <[email protected]>
commit 9badc2a84e688be1275bb740942d5f6f51746908 upstream.
dev_energymodel_nl_get_perf_domains_doit() calls em_perf_domain_get_by_id() but does not check the return value before passing it to __em_nl_get_pd_size(). When a caller supplies a non-existent perf domain ID, em_perf_domain_get_by_id() returns NULL, and __em_nl_get_pd_size() immediately dereferences pd->cpus (struct offset 0x30), causing a NULL pointer dereference.
The sister handler dev_energymodel_nl_get_perf_table_doit() already handles this correctly via __em_nl_get_pd_table_id(), which returns NULL and causes the caller to return -EINVAL. Add the same NULL check in the get-perf-domains do handler.
--- kernel/power/em_netlink.c | 2 ++ 1 file changed, 2 insertions(+)
kernel/power/em_netlink.c +2 -0
@@ -109,6 +109,8 @@ int dev_energymodel_nl_get_perf_domains_doit(struct sk_buff *skb, id =nla_get_u32 (info->attrs[DEV_ENERGYMODEL_A_PERF_DOMAIN_PERF_DOMAIN_ID ]); pd =em_perf_domain_get_by_id (id); +if (!pd) +return -EINVAL ;__em_nl_get_pd_size (pd, &msg_sz); msg =genlmsg_new (msg_sz,GFP_KERNEL );
Signature · 1 line
2.53.0
Greg Kroah-Hartman
maintainerPATCH 266/311 nvmem: imx: assign nvmem_cell_info::raw_len
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Christian Eggers <[email protected]>
commit 48b5163c957548f5854f14c90bfdedc33afbea3c upstream.
Avoid getting error messages at startup like the following on i.MX6ULL:
nvmem imx-ocotp0: cell mac-addr raw len 6 unaligned to nvmem word size 4 nvmem imx-ocotp0: cell mac-addr raw len 6 unaligned to nvmem word size 4
This shouldn't cause any functional change as this alignment would otherwise be done in nvmem_cell_info_to_nvmem_cell_entry_nodup().
--- drivers/nvmem/imx-ocotp-ele.c | 1 + drivers/nvmem/imx-ocotp.c | 1 + 2 files changed, 2 insertions(+)
drivers/nvmem/imx-ocotp-ele.c +1 -0
@@ -131,6 +131,7 @@ static int imx_ocotp_cell_pp(void *contestatic void imx_ocotp_fixup_dt_cell_info (struct nvmem_device *nvmem,struct nvmem_cell_info *cell) { + cell->raw_len =round_up (cell->bytes,4 ); cell->read_post_process = imx_ocotp_cell_pp; }
drivers/nvmem/imx-ocotp.c +1 -0
@@ -589,6 +589,7 @@ MODULE_DEVICE_TABLE(of, imx_ocotp_dt_idsstatic void imx_ocotp_fixup_dt_cell_info (struct nvmem_device *nvmem,struct nvmem_cell_info *cell) { + cell->raw_len =round_up (cell->bytes,4 ); cell->read_post_process = imx_ocotp_cell_pp; }
Greg Kroah-Hartman
maintainerPATCH 267/311 nvmem: zynqmp_nvmem: Fix buffer size in DMA and memcpy
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ivan Vera <[email protected]>
commit f9b88613ff402aa6fe8fd020573cb95867ae947e upstream.
Buffer size used in dma allocation and memcpy is wrong. It can lead to undersized DMA buffer access and possible memory corruption. use correct buffer size in dma_alloc_coherent and memcpy.
--- drivers/nvmem/zynqmp_nvmem.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/nvmem/zynqmp_nvmem.c +4 -4
@@ -66,7 +66,7 @@ static int zynqmp_efuse_access(void *condma_addr_t dma_buf;size_t words = bytes /WORD_INBYTES ;int ret; -int value; +unsigned int value;char *data;if (bytes %WORD_INBYTES !=0 ) {
@@ -80,7 +80,7 @@ static int zynqmp_efuse_access(void *con }if (pufflag ==1 && flag ==EFUSE_WRITE ) { -memcpy (&value, val, bytes); +memcpy (&value, val,sizeof (value));if ((offset ==EFUSE_PUF_START_OFFSET || offset ==EFUSE_PUF_MID_OFFSET ) && value &P_USER_0_64_UPPER_MASK ) {
@@ -100,7 +100,7 @@ static int zynqmp_efuse_access(void *conif (!efuse)return -ENOMEM ; - data =dma_alloc_coherent (dev,sizeof (bytes), + data =dma_alloc_coherent (dev, bytes, &dma_buf,GFP_KERNEL );if (!data) { ret = -ENOMEM ;
@@ -134,7 +134,7 @@ static int zynqmp_efuse_access(void *conif (flag ==EFUSE_READ )memcpy (val, data, bytes); efuse_access_err: -dma_free_coherent (dev,sizeof (bytes), +dma_free_coherent (dev, bytes, data, dma_buf); efuse_data_fail: dma_free_coherent(dev, sizeof(struct xilinx_efuse),
Greg Kroah-Hartman
maintainerPATCH 268/311 netfilter: ipset: drop logically empty buckets in mtype_del
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yifan Wu <[email protected]>
commit 9862ef9ab0a116c6dca98842aab7de13a252ae02 upstream.
mtype_del() counts empty slots below n->pos in k, but it only drops the bucket when both n->pos and k are zero. This misses buckets whose live entries have all been removed while n->pos still points past deleted slots.
Treat a bucket as empty when all positions below n->pos are unused and release it directly instead of shrinking it further.
--- net/netfilter/ipset/ip_set_hash_gen.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
net/netfilter/ipset/ip_set_hash_gen.h +1 -1
@@ -1099,7 +1099,7 @@ mtype_del(struct ip_set *set, void *valuif (!test_bit (i, n->used)) k++; } -if (n->pos ==0 && k ==0 ) { +if (k == n->pos) { t->hregion[r].ext_size -=ext_size (n->size, dsize);rcu_assign_pointer (hbucket (t, key),NULL );kfree_rcu (n, rcu);
Greg Kroah-Hartman
maintainerPATCH 269/311 gpib: Fix fluke driver s390 compile issue
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dave Penkler <[email protected]>
commit 579af7204d762587f9cce0d6236a710a771f1f6f upstream.
The following errors were reported for a s390 randconfig build of the fluke gpib driver:
Quoted 1 line
Quoted 1 line
drivers/gpib/eastwood/fluke_gpib.c:1002:23: error: call to undeclared function 'ioremap'; ISO C99 and later do not support implicit function declarations [-Wimplicit-function-declaration]
1002 | nec_priv->mmiobase = ioremap(e_priv->gpib_iomem_res->start,
| ^Quoted 1 line
Quoted 1 line
drivers/gpib/eastwood/fluke_gpib.c:1002:21: error: incompatible integer to pointer conversion assigning to 'void *' from 'int' [-Wint-conversion]
1002 | nec_priv->mmiobase = ioremap(e_priv->gpib_iomem_res->start,
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1003 | resource_size(e_priv->gpib_iomem_res));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
drivers/gpib/eastwood/fluke_gpib.c:1036:33: error: incompatible integer to pointer conversion assigning to 'void *' from 'int' [-Wint-conversion]
1036 | e_priv->write_transfer_counter = ioremap(e_priv->write_transfer_counter_res->start,
| ^ ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
1037 | resource_size(e_priv->write_transfer_counter_res));
| ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~Add HAS_IOMEM dependency to Kconfig for fluke driver option
--- drivers/gpib/Kconfig | 1 + 1 file changed, 1 insertion(+)
drivers/gpib/Kconfig +1 -0
@@ -122,6 +122,7 @@ config GPIB_FLUKE depends on OF select GPIB_COMMON select GPIB_NEC7210 + depends on HAS_IOMEM help GPIB driver for Fluke based cda devices.
Greg Kroah-Hartman
maintainerPATCH 270/311 vt: discard stale unicode buffer on alt screen exit after resize
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Liav Mordouch <[email protected]>
commit 40014493cece72a0be5672cd86763e53fb3ec613 upstream.
When enter_alt_screen() saves vc_uni_lines into vc_saved_uni_lines and sets vc_uni_lines to NULL, a subsequent console resize via vc_do_resize() skips reallocating the unicode buffer because vc_uni_lines is NULL. However, vc_saved_uni_lines still points to the old buffer allocated for the original dimensions.
When leave_alt_screen() later restores vc_saved_uni_lines, the buffer dimensions no longer match vc_rows/vc_cols. Any operation that iterates over the unicode buffer using the current dimensions (e.g. csi_J clearing the screen) will access memory out of bounds, causing a kernel oops:
BUG: unable to handle page fault for address: 0x0000002000000020 RIP: 0010:csi_J+0x133/0x2d0
The faulting address 0x0000002000000020 is two adjacent u32 space characters (0x20) interpreted as a pointer, read from the row data area past the end of the 25-entry pointer array in a buffer allocated for 80x25 but accessed with 240x67 dimensions.
Fix this by checking whether the console dimensions changed while in the alternate screen. If they did, free the stale saved buffer instead of restoring it. The unicode screen will be lazily rebuilt via vc_uniscr_check() when next needed.
--- drivers/tty/vt/vt.c | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-)
drivers/tty/vt/vt.c +13 -1
@@ -1907,6 +1907,7 @@ static void leave_alt_screen(struct vc_dunsigned int rows =min (vc->vc_saved_rows, vc->vc_rows);unsigned int cols =min (vc->vc_saved_cols, vc->vc_cols);u16 *src, *dest; +bool uni_lines_stale;if (vc->vc_saved_screen ==NULL )return ;/* Not inside an alt-screen */
@@ -1915,7 +1916,18 @@ static void leave_alt_screen(struct vc_d dest = ((u16 *)vc->vc_origin) + r * vc->vc_cols;memcpy (dest, src,2 * cols); } -vc_uniscr_set (vc, vc->vc_saved_uni_lines); +/* +* If the console was resized while in the alternate screen, +* vc_saved_uni_lines was allocated for the old dimensions. +* Restoring it would cause out-of-bounds accesses. Discard it +* and let the unicode screen be lazily rebuilt. +*/ + uni_lines_stale = vc->vc_saved_rows != vc->vc_rows || + vc->vc_saved_cols != vc->vc_cols; +if (uni_lines_stale) +vc_uniscr_free (vc->vc_saved_uni_lines); +else +vc_uniscr_set (vc, vc->vc_saved_uni_lines); vc->vc_saved_uni_lines =NULL ;restore_cur (vc);/* Update the entire screen */
Greg Kroah-Hartman
maintainerPATCH 271/311 vt: resize saved unicode buffer on alt screen exit after resize
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nicolas Pitre <[email protected]>
commit 3ddbea7542ae529c1a88ef9a8b1ce169126211f6 upstream.
Instead of discarding the saved unicode buffer when the console was resized while in the alternate screen, resize it to the current dimensions using vc_uniscr_copy_area() to preserve its content. This properly restores the unicode screen on alt screen exit rather than lazily rebuilding it from a lossy reverse glyph translation.
On allocation failure the stale buffer is freed and vc_uni_lines is set to NULL so it gets lazily rebuilt via vc_uniscr_check() when next needed.
--- drivers/tty/vt/vt.c | 24 +++++++++++++++--------- 1 file changed, 15 insertions(+), 9 deletions(-)
drivers/tty/vt/vt.c +15 -9
@@ -1907,7 +1907,6 @@ static void leave_alt_screen(struct vc_dunsigned int rows =min (vc->vc_saved_rows, vc->vc_rows);unsigned int cols =min (vc->vc_saved_cols, vc->vc_cols);u16 *src, *dest; -bool uni_lines_stale;if (vc->vc_saved_screen ==NULL )return ;/* Not inside an alt-screen */
@@ -1918,16 +1917,23 @@ static void leave_alt_screen(struct vc_d }/* * If the console was resized while in the alternate screen, -* vc_saved_uni_lines was allocated for the old dimensions. -* Restoring it would cause out-of-bounds accesses. Discard it -* and let the unicode screen be lazily rebuilt. +* resize the saved unicode buffer to the current dimensions. +* On allocation failure new_uniscr is NULL, causing the old +* buffer to be freed and vc_uni_lines to be lazily rebuilt +* via vc_uniscr_check() when next needed. */ - uni_lines_stale = vc->vc_saved_rows != vc->vc_rows || - vc->vc_saved_cols != vc->vc_cols; -if (uni_lines_stale) +if (vc->vc_saved_uni_lines && + (vc->vc_saved_rows != vc->vc_rows || + vc->vc_saved_cols != vc->vc_cols)) { +u32 **new_uniscr =vc_uniscr_alloc (vc->vc_cols, vc->vc_rows); + +if (new_uniscr) +vc_uniscr_copy_area (new_uniscr, vc->vc_cols, vc->vc_rows, + vc->vc_saved_uni_lines, cols,0 , rows);vc_uniscr_free (vc->vc_saved_uni_lines); -else -vc_uniscr_set (vc, vc->vc_saved_uni_lines); + vc->vc_saved_uni_lines = new_uniscr; + } +vc_uniscr_set (vc, vc->vc_saved_uni_lines); vc->vc_saved_uni_lines =NULL ;restore_cur (vc);/* Update the entire screen */
Greg Kroah-Hartman
maintainerPATCH 272/311 counter: rz-mtu3-cnt: prevent counter from being toggled multiple times
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cosmin Tanislav <[email protected]>
commit 67c3f99bed6f422ba343d2b70a2eeeccdfd91bef upstream.
Runtime PM counter is incremented / decremented each time the sysfs enable file is written to.
If user writes 0 to the sysfs enable file multiple times, runtime PM usage count underflows, generating the following message.
rz-mtu3-counter rz-mtu3-counter.0: Runtime PM usage count underflow!
At the same time, hardware registers end up being accessed with clocks off in rz_mtu3_terminate_counter() to disable an already disabled channel.
If user writes 1 to the sysfs enable file multiple times, runtime PM usage count will be incremented each time, requiring the same number of 0 writes to get it back to 0.
If user writes 0 to the sysfs enable file while PWM is in progress, PWM is stopped without counter being the owner of the underlying MTU3 channel.
Check against the cached count_is_enabled value and exit if the user is trying to set the same enable value.
--- drivers/counter/rz-mtu3-cnt.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
drivers/counter/rz-mtu3-cnt.c +8 -4
@@ -499,21 +499,25 @@ static int rz_mtu3_count_enable_write(ststruct rz_mtu3_cnt *const priv =counter_priv (counter);int ret =0 ; +mutex_lock (&priv->lock); + +if (priv->count_is_enabled[count->id] == enable) + goto exit; +if (enable) { -mutex_lock (&priv->lock);pm_runtime_get_sync (ch->dev); ret =rz_mtu3_initialize_counter (counter, count->id);if (ret ==0 ) priv->count_is_enabled[count->id] = true; -mutex_unlock (&priv->lock); }else { -mutex_lock (&priv->lock);rz_mtu3_terminate_counter (counter, count->id); priv->count_is_enabled[count->id] = false;pm_runtime_put (ch->dev); -mutex_unlock (&priv->lock); } +exit: +mutex_unlock (&priv->lock); +return ret; }
Greg Kroah-Hartman
maintainerPATCH 273/311 counter: rz-mtu3-cnt: do not use struct rz_mtu3_channels dev member
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Cosmin Tanislav <[email protected]>
commit 2932095c114b98cbb40ccf34fc00d613cb17cead upstream.
The counter driver can use HW channels 1 and 2, while the PWM driver can use HW channels 0, 1, 2, 3, 4, 6, 7.
The dev member is assigned both by the counter driver and the PWM driver for channels 1 and 2, to their own struct device instance, overwriting the previous value.
The sub-drivers race to assign their own struct device pointer to the same struct rz_mtu3_channel's dev member.
The dev member of struct rz_mtu3_channel is used by the counter sub-driver for runtime PM.
Depending on the probe order of the counter and PWM sub-drivers, the dev member may point to the wrong struct device instance, causing the counter sub-driver to do runtime PM actions on the wrong device.
To fix this, use the parent pointer of the counter, which is assigned during probe to the correct struct device, not the struct device pointer inside the shared struct rz_mtu3_channel.
--- drivers/counter/rz-mtu3-cnt.c | 55 ++++++++++++++++++++---------------------- 1 file changed, 27 insertions(+), 28 deletions(-)
drivers/counter/rz-mtu3-cnt.c +27 -28
@@ -107,9 +107,9 @@ static bool rz_mtu3_is_counter_invalid(sstruct rz_mtu3_cnt *const priv =counter_priv (counter);unsigned long tmdr; -pm_runtime_get_sync (priv->ch->dev); +pm_runtime_get_sync (counter->parent); tmdr =rz_mtu3_shared_reg_read (priv->ch,RZ_MTU3_TMDR3 ); -pm_runtime_put (priv->ch->dev); +pm_runtime_put (counter->parent);if (id ==RZ_MTU3_32_BIT_CH &&test_bit (RZ_MTU3_TMDR3_LWA , &tmdr))return false;
@@ -165,12 +165,12 @@ static int rz_mtu3_count_read(struct couif (ret)return ret; -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent);if (count->id ==RZ_MTU3_32_BIT_CH ) *val =rz_mtu3_32bit_ch_read (ch,RZ_MTU3_TCNTLW );else *val =rz_mtu3_16bit_ch_read (ch,RZ_MTU3_TCNT ); -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent);mutex_unlock (&priv->lock);return 0 ;
@@ -187,26 +187,26 @@ static int rz_mtu3_count_write(struct coif (ret)return ret; -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent);if (count->id ==RZ_MTU3_32_BIT_CH )rz_mtu3_32bit_ch_write (ch,RZ_MTU3_TCNTLW , val);else rz_mtu3_16bit_ch_write (ch,RZ_MTU3_TCNT , val); -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent);mutex_unlock (&priv->lock);return 0 ; }static int rz_mtu3_count_function_read_helper (struct rz_mtu3_channel *const ch, -struct rz_mtu3_cnt *const priv, +struct counter_device *const counter,enum counter_function *function) {u8 timer_mode; -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent); timer_mode =rz_mtu3_8bit_ch_read (ch,RZ_MTU3_TMDR1 ); -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent);switch (timer_mode &RZ_MTU3_TMDR1_PH_CNT_MODE_MASK ) {case RZ_MTU3_TMDR1_PH_CNT_MODE_1 :
@@ -240,7 +240,7 @@ static int rz_mtu3_count_function_read(sif (ret)return ret; - ret =rz_mtu3_count_function_read_helper (ch, priv, function); + ret =rz_mtu3_count_function_read_helper (ch, counter, function);mutex_unlock (&priv->lock);return ret;
@@ -279,9 +279,9 @@ static int rz_mtu3_count_function_write(return -EINVAL ; } -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent);rz_mtu3_8bit_ch_write (ch,RZ_MTU3_TMDR1 , timer_mode); -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent);mutex_unlock (&priv->lock);return 0 ;
@@ -300,9 +300,9 @@ static int rz_mtu3_count_direction_read(if (ret)return ret; -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent); tsr =rz_mtu3_8bit_ch_read (ch,RZ_MTU3_TSR ); -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent); *direction = (tsr &RZ_MTU3_TSR_TCFD ) ?COUNTER_COUNT_DIRECTION_FORWARD :COUNTER_COUNT_DIRECTION_BACKWARD ;
@@ -377,14 +377,14 @@ static int rz_mtu3_count_ceiling_write(sreturn -EINVAL ; } -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent);if (count->id ==RZ_MTU3_32_BIT_CH )rz_mtu3_32bit_ch_write (ch,RZ_MTU3_TGRALW , ceiling);else rz_mtu3_16bit_ch_write (ch,RZ_MTU3_TGRA , ceiling);rz_mtu3_8bit_ch_write (ch,RZ_MTU3_TCR ,RZ_MTU3_TCR_CCLR_TGRA ); -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent);mutex_unlock (&priv->lock);return 0 ;
@@ -495,7 +495,6 @@ static int rz_mtu3_count_enable_read(strstatic int rz_mtu3_count_enable_write (struct counter_device *counter,struct counter_count *count,u8 enable) { -struct rz_mtu3_channel *const ch =rz_mtu3_get_ch (counter, count->id);struct rz_mtu3_cnt *const priv =counter_priv (counter);int ret =0 ;
@@ -505,14 +504,14 @@ static int rz_mtu3_count_enable_write(st goto exit;if (enable) { -pm_runtime_get_sync (ch->dev); +pm_runtime_get_sync (counter->parent); ret =rz_mtu3_initialize_counter (counter, count->id);if (ret ==0 ) priv->count_is_enabled[count->id] = true; }else {rz_mtu3_terminate_counter (counter, count->id); priv->count_is_enabled[count->id] = false; -pm_runtime_put (ch->dev); +pm_runtime_put (counter->parent); } exit:
@@ -544,9 +543,9 @@ static int rz_mtu3_cascade_counts_enableif (ret)return ret; -pm_runtime_get_sync (priv->ch->dev); +pm_runtime_get_sync (counter->parent); tmdr =rz_mtu3_shared_reg_read (priv->ch,RZ_MTU3_TMDR3 ); -pm_runtime_put (priv->ch->dev); +pm_runtime_put (counter->parent); *cascade_enable =test_bit (RZ_MTU3_TMDR3_LWA , &tmdr);mutex_unlock (&priv->lock);
@@ -563,10 +562,10 @@ static int rz_mtu3_cascade_counts_enableif (ret)return ret; -pm_runtime_get_sync (priv->ch->dev); +pm_runtime_get_sync (counter->parent);rz_mtu3_shared_reg_update_bit (priv->ch,RZ_MTU3_TMDR3 ,RZ_MTU3_TMDR3_LWA , cascade_enable); -pm_runtime_put (priv->ch->dev); +pm_runtime_put (counter->parent);mutex_unlock (&priv->lock);return 0 ;
@@ -583,9 +582,9 @@ static int rz_mtu3_ext_input_phase_clockif (ret)return ret; -pm_runtime_get_sync (priv->ch->dev); +pm_runtime_get_sync (counter->parent); tmdr =rz_mtu3_shared_reg_read (priv->ch,RZ_MTU3_TMDR3 ); -pm_runtime_put (priv->ch->dev); +pm_runtime_put (counter->parent); *ext_input_phase_clock_select =test_bit (RZ_MTU3_TMDR3_PHCKSEL , &tmdr);mutex_unlock (&priv->lock);
@@ -602,11 +601,11 @@ static int rz_mtu3_ext_input_phase_clockif (ret)return ret; -pm_runtime_get_sync (priv->ch->dev); +pm_runtime_get_sync (counter->parent);rz_mtu3_shared_reg_update_bit (priv->ch,RZ_MTU3_TMDR3 ,RZ_MTU3_TMDR3_PHCKSEL , ext_input_phase_clock_select); -pm_runtime_put (priv->ch->dev); +pm_runtime_put (counter->parent);mutex_unlock (&priv->lock);return 0 ;
@@ -644,7 +643,7 @@ static int rz_mtu3_action_read(struct coif (ret)return ret; - ret =rz_mtu3_count_function_read_helper (ch, priv, &function); + ret =rz_mtu3_count_function_read_helper (ch, counter, &function);if (ret) {mutex_unlock (&priv->lock);return ret;
Greg Kroah-Hartman
maintainerPATCH 274/311 crypto: tegra - Add missing CRYPTO_ALG_ASYNC
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Eric Biggers <[email protected]>
commit 4b56770d345524fc2acc143a2b85539cf7d74bc1 upstream.
The tegra crypto driver failed to set the CRYPTO_ALG_ASYNC on its asynchronous algorithms, causing the crypto API to select them for users that request only synchronous algorithms. This causes crashes (at least). Fix this by adding the flag like what the other drivers do. Also remove the unnecessary CRYPTO_ALG_TYPE_* flags, since those just get ignored and overridden by the registration function anyway.
--- drivers/crypto/tegra/tegra-se-aes.c | 11 +++++++---- drivers/crypto/tegra/tegra-se-hash.c | 30 +++++++++++++++++------------- 2 files changed, 24 insertions(+), 17 deletions(-)
drivers/crypto/tegra/tegra-se-aes.c +7 -4
@@ -529,7 +529,7 @@ static struct tegra_se_alg tegra_aes_alg .cra_name = "cbc(aes)", .cra_driver_name = "cbc-aes-tegra", .cra_priority = 500, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_alignmask = 0xf,
@@ -550,7 +550,7 @@ static struct tegra_se_alg tegra_aes_alg .cra_name = "ecb(aes)", .cra_driver_name = "ecb-aes-tegra", .cra_priority = 500, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_alignmask = 0xf,
@@ -572,7 +572,7 @@ static struct tegra_se_alg tegra_aes_alg .cra_name = "ctr(aes)", .cra_driver_name = "ctr-aes-tegra", .cra_priority = 500, - .cra_flags = CRYPTO_ALG_TYPE_SKCIPHER | CRYPTO_ALG_ASYNC, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_alignmask = 0xf,
@@ -594,6 +594,7 @@ static struct tegra_se_alg tegra_aes_alg .cra_name = "xts(aes)", .cra_driver_name = "xts-aes-tegra", .cra_priority = 500, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_aes_ctx), .cra_alignmask = (__alignof__(u64) - 1),
@@ -1922,6 +1923,7 @@ static struct tegra_se_alg tegra_aead_al .cra_name = "gcm(aes)", .cra_driver_name = "gcm-aes-tegra", .cra_priority = 500, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct tegra_aead_ctx), .cra_alignmask = 0xf,
@@ -1944,6 +1946,7 @@ static struct tegra_se_alg tegra_aead_al .cra_name = "ccm(aes)", .cra_driver_name = "ccm-aes-tegra", .cra_priority = 500, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = 1, .cra_ctxsize = sizeof(struct tegra_aead_ctx), .cra_alignmask = 0xf,
@@ -1971,7 +1974,7 @@ static struct tegra_se_alg tegra_cmac_al .cra_name = "cmac(aes)", .cra_driver_name = "tegra-se-cmac", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = AES_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_cmac_ctx), .cra_alignmask = 0,
drivers/crypto/tegra/tegra-se-hash.c +17 -13
@@ -761,7 +761,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha1", .cra_driver_name = "tegra-se-sha1", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA1_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -786,7 +786,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha224", .cra_driver_name = "tegra-se-sha224", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA224_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -811,7 +811,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha256", .cra_driver_name = "tegra-se-sha256", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA256_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -836,7 +836,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha384", .cra_driver_name = "tegra-se-sha384", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA384_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -861,7 +861,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha512", .cra_driver_name = "tegra-se-sha512", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA512_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -886,7 +886,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha3-224", .cra_driver_name = "tegra-se-sha3-224", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA3_224_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -911,7 +911,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha3-256", .cra_driver_name = "tegra-se-sha3-256", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA3_256_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -936,7 +936,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha3-384", .cra_driver_name = "tegra-se-sha3-384", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA3_384_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -961,7 +961,7 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "sha3-512", .cra_driver_name = "tegra-se-sha3-512", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH, + .cra_flags = CRYPTO_ALG_ASYNC, .cra_blocksize = SHA3_512_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -988,7 +988,8 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "hmac(sha224)", .cra_driver_name = "tegra-se-hmac-sha224", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, + .cra_flags =CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA224_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -1015,7 +1016,8 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "hmac(sha256)", .cra_driver_name = "tegra-se-hmac-sha256", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, + .cra_flags =CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA256_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -1042,7 +1044,8 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "hmac(sha384)", .cra_driver_name = "tegra-se-hmac-sha384", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, + .cra_flags =CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA384_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
@@ -1069,7 +1072,8 @@ static struct tegra_se_alg tegra_hash_al .cra_name = "hmac(sha512)", .cra_driver_name = "tegra-se-hmac-sha512", .cra_priority = 300, - .cra_flags = CRYPTO_ALG_TYPE_AHASH | CRYPTO_ALG_NEED_FALLBACK, + .cra_flags =CRYPTO_ALG_ASYNC | + CRYPTO_ALG_NEED_FALLBACK, .cra_blocksize = SHA512_BLOCK_SIZE, .cra_ctxsize = sizeof(struct tegra_sha_ctx), .cra_alignmask = 0,
Greg Kroah-Hartman
maintainerPATCH 275/311 vxlan: validate ND option lengths in vxlan_na_create
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Yang <[email protected]>
commit afa9a05e6c4971bd5586f1b304e14d61fb3d9385 upstream.
vxlan_na_create() walks ND options according to option-provided lengths. A malformed option can make the parser advance beyond the computed option span or use a too-short source LLADDR option payload.
Validate option lengths against the remaining NS option area before advancing, and only read source LLADDR when the option is large enough for an Ethernet address.
--- drivers/net/vxlan/vxlan_core.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-)
drivers/net/vxlan/vxlan_core.c +4 -2
@@ -1965,12 +1965,14 @@ static struct sk_buff *vxlan_na_create(s ns_olen = request->len -skb_network_offset (request) -sizeof (struct ipv6hdr ) -sizeof (*ns);for (i =0 ; i < ns_olen-1 ; i += (ns->opt[i+1 ]<<3 )) { -if (!ns->opt[i +1 ]) { +if (!ns->opt[i +1 ] || i + (ns->opt[i +1 ] <<3 ) > ns_olen) {kfree_skb (reply);return NULL ; }if (ns->opt[i] ==ND_OPT_SOURCE_LL_ADDR ) { - daddr = ns->opt + i +sizeof (struct nd_opt_hdr ); +if ((ns->opt[i +1 ] <<3 ) >= +sizeof (struct nd_opt_hdr ) +ETH_ALEN ) + daddr = ns->opt + i +sizeof (struct nd_opt_hdr );break ; } }
Greg Kroah-Hartman
maintainerPATCH 276/311 net: ftgmac100: fix ring allocation unwind on open failure
In reply to Greg Kroah-Hartman6.19-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yufan Chen <[email protected]>
commit c0fd0fe745f5e8c568d898cd1513d0083e46204a upstream.
ftgmac100_alloc_rings() allocates rx_skbs, tx_skbs, rxdes, txdes, and rx_scratch in stages. On intermediate failures it returned -ENOMEM directly, leaking resources allocated earlier in the function.
Rework the failure path to use staged local unwind labels and free allocated resources in reverse order before returning -ENOMEM. This matches common netdev allocation cleanup style.
--- drivers/net/ethernet/faraday/ftgmac100.c | 28 ++++++++++++++++++++++++---- 1 file changed, 24 insertions(+), 4 deletions(-)
drivers/net/ethernet/faraday/ftgmac100.c +24 -4
@@ -964,19 +964,19 @@ static int ftgmac100_alloc_rings(struct priv->tx_skbs =kcalloc (MAX_TX_QUEUE_ENTRIES ,sizeof (void *),GFP_KERNEL );if (!priv->tx_skbs) -return -ENOMEM ; + goto err_free_rx_skbs;/* Allocate descriptors */ priv->rxdes =dma_alloc_coherent (priv->dev,MAX_RX_QUEUE_ENTRIES *sizeof (struct ftgmac100_rxdes ), &priv->rxdes_dma,GFP_KERNEL );if (!priv->rxdes) -return -ENOMEM ; + goto err_free_tx_skbs; priv->txdes =dma_alloc_coherent (priv->dev,MAX_TX_QUEUE_ENTRIES *sizeof (struct ftgmac100_txdes ), &priv->txdes_dma,GFP_KERNEL );if (!priv->txdes) -return -ENOMEM ; + goto err_free_rxdes;/* Allocate scratch packet buffer */ priv->rx_scratch = dma_alloc_coherent(priv->dev,
@@ -984,9 +984,29 @@ static int ftgmac100_alloc_rings(struct &priv->rx_scratch_dma, GFP_KERNEL);if (!priv->rx_scratch) -return -ENOMEM ; + goto err_free_txdes;return 0 ; + +err_free_txdes: +dma_free_coherent (priv->dev, +MAX_TX_QUEUE_ENTRIES * +sizeof (struct ftgmac100_txdes ), + priv->txdes, priv->txdes_dma); + priv->txdes =NULL ; +err_free_rxdes: +dma_free_coherent (priv->dev, +MAX_RX_QUEUE_ENTRIES * +sizeof (struct ftgmac100_rxdes ), + priv->rxdes, priv->rxdes_dma); + priv->rxdes =NULL ; +err_free_tx_skbs: +kfree (priv->tx_skbs); + priv->tx_skbs =NULL ; +err_free_rx_skbs: +kfree (priv->rx_skbs); + priv->rx_skbs =NULL ; +return -ENOMEM ; }static void ftgmac100_init_rings (struct ftgmac100 *priv)