6.16.4-rc1 review
Subsystems (6)
Greg Kroah-Hartman
maintainerPATCH 286/457 smb: server: split ksmbd_rdma_stop_listening() out of ksmbd_rdma_destroy()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Metzmacher <[email protected]>
[ Upstream commit bac7b996d42e458a94578f4227795a0d4deef6fa ]
We can't call destroy_workqueue(smb_direct_wq); before stop_sessions()!
Otherwise already existing connections try to use smb_direct_wq as a NULL pointer.
--- fs/smb/server/connection.c | 3 ++- fs/smb/server/transport_rdma.c | 5 ++++- fs/smb/server/transport_rdma.h | 4 +++- 3 files changed, 9 insertions(+), 3 deletions(-)
fs/smb/server/connection.c +2 -1
@@ -504,7 +504,8 @@ void ksmbd_conn_transport_destroy(void) {mutex_lock (&init_lock);ksmbd_tcp_destroy (); -ksmbd_rdma_destroy (); +ksmbd_rdma_stop_listening ();stop_sessions (); +ksmbd_rdma_destroy ();mutex_unlock (&init_lock); }
fs/smb/server/transport_rdma.c +4 -1
@@ -2194,7 +2194,7 @@ int ksmbd_rdma_init(void)return 0 ; } -void ksmbd_rdma_destroy (void ) +void ksmbd_rdma_stop_listening (void ) {if (!smb_direct_listener.cm_id)return ;
@@ -2203,7 +2203,10 @@ void ksmbd_rdma_destroy(void)rdma_destroy_id (smb_direct_listener.cm_id); smb_direct_listener.cm_id =NULL ; +} +void ksmbd_rdma_destroy (void ) +{if (smb_direct_wq) {destroy_workqueue (smb_direct_wq); smb_direct_wq =NULL ;
fs/smb/server/transport_rdma.h +3 -1
@@ -54,13 +54,15 @@ struct smb_direct_data_transfer {#ifdef CONFIG_SMB_SERVER_SMBDIRECT int ksmbd_rdma_init (void ); +void ksmbd_rdma_stop_listening (void );void ksmbd_rdma_destroy (void );bool ksmbd_rdma_capable_netdev (struct net_device *netdev);void init_smbd_max_io_size (unsigned int sz);unsigned int get_smbd_max_read_write_size (void );#else static inline int ksmbd_rdma_init (void ) {return 0 ; } -static inline int ksmbd_rdma_destroy (void ) {return 0 ; } +static inline void ksmbd_rdma_stop_listening (void ) { } +static inline void ksmbd_rdma_destroy (void ) { }static inline bool ksmbd_rdma_capable_netdev (struct net_device *netdev) {return false; }static inline void init_smbd_max_io_size (unsigned int sz) { }static inline unsigned int get_smbd_max_read_write_size (void ) {return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 287/457 fs/buffer: fix use-after-free when call bh_read() helper
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ye Bin <[email protected]>
[ Upstream commit 7375f22495e7cd1c5b3b5af9dcc4f6dffe34ce49 ]
There's issue as follows:
BUG: KASAN: stack-out-of-bounds in end_buffer_read_sync+0xe3/0x110 Read of size 8 at addr ffffc9000168f7f8 by task swapper/3/0 CPU: 3 UID: 0 PID: 0 Comm: swapper/3 Not tainted 6.16.0-862.14.0.6.x86_64 Hardware name: QEMU Standard PC (i440FX + PIIX, 1996) Call Trace: <IRQ> dump_stack_lvl+0x55/0x70 print_address_description.constprop.0+0x2c/0x390 print_report+0xb4/0x270 kasan_report+0xb8/0xf0 end_buffer_read_sync+0xe3/0x110 end_bio_bh_io_sync+0x56/0x80 blk_update_request+0x30a/0x720 scsi_end_request+0x51/0x2b0 scsi_io_completion+0xe3/0x480 ? scsi_device_unbusy+0x11e/0x160 blk_complete_reqs+0x7b/0x90 handle_softirqs+0xef/0x370 irq_exit_rcu+0xa5/0xd0 sysvec_apic_timer_interrupt+0x6e/0x90 </IRQ>
Above issue happens when do ntfs3 filesystem mount, issue may happens as follows:
mount IRQntfs_fill_super
read_cache_page
do_read_cache_folio
filemap_read_folio
mpage_read_folio
do_mpage_readpage
ntfs_get_block_vbo
bh_read
submit_bh
wait_on_buffer(bh);
blk_complete_reqs
scsi_io_completion
scsi_end_request
blk_update_request
end_bio_bh_io_sync
end_buffer_read_sync
__end_buffer_read_notouch
unlock_buffer
wait_on_buffer(bh);--> return will return to caller
put_bh
--> trigger stack-out-of-boundsIn the mpage_read_folio() function, the stack variable 'map_bh' is passed to ntfs_get_block_vbo(). Once unlock_buffer() unlocks and wait_on_buffer() returns to continue processing, the stack variable is likely to be reclaimed. Consequently, during the end_buffer_read_sync() process, calling put_bh() may result in stack overrun.
If the bh is not allocated on the stack, it belongs to a folio. Freeing a buffer head which belongs to a folio is done by drop_buffers() which will fail to free buffers which are still locked. So it is safe to call put_bh() before __end_buffer_read_notouch().
--- fs/buffer.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/buffer.c +1 -1
@@ -157,8 +157,8 @@ static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)*/ void end_buffer_read_sync (struct buffer_head *bh,int uptodate) { -__end_buffer_read_notouch (bh, uptodate);put_bh (bh); +__end_buffer_read_notouch (bh, uptodate); }EXPORT_SYMBOL (end_buffer_read_sync);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 288/457 signal: Fix memory leak for PIDFD_SELF* sentinels
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Adrian Huang (Lenovo) <[email protected]>
[ Upstream commit a2c1f82618b0b65f1ef615aa9cfdac8122537d69 ]
Commit f08d0c3a7111 ("pidfd: add PIDFD_SELF* sentinels to refer to own thread/process") introduced a leak by acquiring a pid reference through get_task_pid(), which increments pid->count but never drops it with put_pid().
As a result, kmemleak reports unreferenced pid objects after running tools/testing/selftests/pidfd/pidfd_test, for example:
unreferenced object 0xff1100206757a940 (size 160):
comm "pidfd_test", pid 16965, jiffies 4294853028
hex dump (first 32 bytes):
01 00 00 00 00 00 00 00 00 00 00 00 fd 57 50 04 .............WP.
5e 44 00 00 00 00 00 00 18 de 34 17 01 00 11 ff ^D........4.....
backtrace (crc cd8844d4):
kmem_cache_alloc_noprof+0x2f4/0x3f0
alloc_pid+0x54/0x3d0
copy_process+0xd58/0x1740
kernel_clone+0x99/0x3b0
__do_sys_clone3+0xbe/0x100
do_syscall_64+0x7b/0x2c0
entry_SYSCALL_64_after_hwframe+0x76/0x7eFix this by calling put_pid() after do_pidfd_send_signal() returns.
--- kernel/signal.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
kernel/signal.c +5 -1
@@ -4067,6 +4067,7 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig, {struct pid *pid;enum pid_type type; +int ret;/* Enforce flags be set to 0 until we add an extension. */ if (flags & ~PIDFD_SEND_SIGNAL_FLAGS )
@@ -4108,7 +4109,10 @@ SYSCALL_DEFINE4(pidfd_send_signal, int, pidfd, int, sig, } } -return do_pidfd_send_signal (pid, sig, type, info, flags); + ret =do_pidfd_send_signal (pid, sig, type, info, flags); +put_pid (pid); + +return ret; } static int
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 289/457 use uniform permission checks for all mount propagation changes
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Al Viro <[email protected]>
[ Upstream commit cffd0441872e7f6b1fce5e78fb1c99187a291330 ]
do_change_type() and do_set_group() are operating on different aspects of the same thing - propagation graph. The latter asks for mounts involved to be mounted in namespace(s) the caller has CAP_SYS_ADMIN for. The former is a mess - originally it didn't even check that mount *is* mounted. That got fixed, but the resulting check turns out to be too strict for userland - in effect, we check that mount is in our namespace, having already checked that we have CAP_SYS_ADMIN there.
What we really need (in both cases) is
* only touch mounts that are mounted. That's a must-have
constraint - data corruption happens if it get violated.
* don't allow to mess with a namespace unless you already
have enough permissions to do so (i.e. CAP_SYS_ADMIN in its userns).
That's an equivalent of what do_set_group() does; let's extract that into a helper (may_change_propagation()) and use it in both do_set_group() and do_change_type().
--- fs/namespace.c | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-)
fs/namespace.c +20 -14
@@ -2925,6 +2925,19 @@ static int graft_tree(struct mount *mnt, struct mount *p, struct mountpoint *mp)return attach_recursive_mnt (mnt, p, mp,0 ); } +static int may_change_propagation (const struct mount *m) +{ +struct mnt_namespace *ns = m->mnt_ns; + +// it must be mounted in some namespace +if (IS_ERR_OR_NULL (ns))// is_mounted() +return -EINVAL ; +// and the caller must be admin in userns of that namespace +if (!ns_capable (ns->user_ns,CAP_SYS_ADMIN )) +return -EPERM ; +return 0 ; +} +/* * Sanity check the flags to change_mnt_propagation. */
@@ -2961,10 +2974,10 @@ static int do_change_type(struct path *path, int ms_flags)return -EINVAL ;namespace_lock (); -if (!check_mnt (mnt)) { - err = -EINVAL ; + err =may_change_propagation (mnt); +if (err) goto out_unlock; - } +if (type ==MS_SHARED ) { err =invent_group_ids (mnt, recurse);if (err)
@@ -3419,18 +3432,11 @@ static int do_set_group(struct path *from_path, struct path *to_path)namespace_lock (); - err = -EINVAL ; -/* To and From must be mounted */ -if (!is_mounted (&from->mnt)) - goto out; -if (!is_mounted (&to->mnt)) - goto out; - - err = -EPERM ; -/* We should be allowed to modify mount namespaces of both mounts */ -if (!ns_capable (from->mnt_ns->user_ns,CAP_SYS_ADMIN )) + err =may_change_propagation (from); +if (err) goto out; -if (!ns_capable (to->mnt_ns->user_ns,CAP_SYS_ADMIN )) + err =may_change_propagation (to); +if (err) goto out; err = -EINVAL ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 290/457 iommu: Remove ops.pgsize_bitmap from drivers that dont use it
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jason Gunthorpe <[email protected]>
[ Upstream commit 8901812485de1356e3757958af40fe0d3a48e986 ]
These drivers all set the domain->pgsize_bitmap in their domain_alloc_paging() functions, so the ops value is never used. Delete it.
Stable-dep-of: 72b6f7cd89ce ("iommu/virtio: Make instance lookup robust")
--- drivers/iommu/apple-dart.c | 1 - drivers/iommu/intel/iommu.c | 1 - drivers/iommu/iommufd/selftest.c | 1 - drivers/iommu/riscv/iommu.c | 1 - drivers/iommu/virtio-iommu.c | 6 ++---- 5 files changed, 2 insertions(+), 8 deletions(-)
drivers/iommu/apple-dart.c +0 -1
@@ -991,7 +991,6 @@ static const struct iommu_ops apple_dart .of_xlate = apple_dart_of_xlate, .def_domain_type = apple_dart_def_domain_type, .get_resv_regions = apple_dart_get_resv_regions, - .pgsize_bitmap = -1UL, /* Restricted during dart probe */ .owner = THIS_MODULE, .default_domain_ops = &(const struct iommu_domain_ops ) { .attach_dev = apple_dart_attach_dev_paging,
drivers/iommu/intel/iommu.c +0 -1
@@ -4390,7 +4390,6 @@ const struct iommu_ops intel_iommu_ops = .device_group = intel_iommu_device_group, .is_attach_deferred = intel_iommu_is_attach_deferred, .def_domain_type = device_def_domain_type, - .pgsize_bitmap = SZ_4K, .page_response = intel_iommu_page_response, .default_domain_ops = &(const struct iommu_domain_ops ) { .attach_dev = intel_iommu_attach_device,
drivers/iommu/iommufd/selftest.c +0 -1
@@ -801,7 +801,6 @@ static const struct iommu_ops mock_ops = .default_domain = &mock_blocking_domain, .blocked_domain = &mock_blocking_domain, .owner = THIS_MODULE, - .pgsize_bitmap = MOCK_IO_PAGE_SIZE, .hw_info = mock_domain_hw_info, .domain_alloc_paging_flags = mock_domain_alloc_paging_flags, .domain_alloc_nested = mock_domain_alloc_nested,
drivers/iommu/riscv/iommu.c +0 -1
@@ -1533,7 +1533,6 @@ static void riscv_iommu_release_device(s }static const struct iommu_ops riscv_iommu_ops = { - .pgsize_bitmap =SZ_4K , .of_xlate = riscv_iommu_of_xlate, .identity_domain = &riscv_iommu_identity_domain, .blocked_domain = &riscv_iommu_blocking_domain,
drivers/iommu/virtio-iommu.c +2 -4
@@ -998,7 +998,7 @@ static void viommu_get_resv_regions(struiommu_dma_get_resv_regions (dev, head); } -static struct iommu_ops viommu_ops; +static const struct iommu_ops viommu_ops;static struct virtio_driver virtio_iommu_drv;static int viommu_match_node (struct device *dev,const void *data)
@@ -1086,7 +1086,7 @@ static bool viommu_capable(struct device } } -static struct iommu_ops viommu_ops = { +static const struct iommu_ops viommu_ops = { .capable = viommu_capable, .domain_alloc_identity = viommu_domain_alloc_identity, .domain_alloc_paging = viommu_domain_alloc_paging,
@@ -1217,8 +1217,6 @@ static int viommu_probe(struct virtio_de viommu->first_domain++; } - viommu_ops.pgsize_bitmap = viommu->pgsize_bitmap; -virtio_device_ready (vdev);/* Populate the event queue with buffers */
Greg Kroah-Hartman
maintainerPATCH 291/457 iommu/virtio: Make instance lookup robust
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Robin Murphy <[email protected]>
[ Upstream commit 72b6f7cd89cea8251979b65528d302f9c0ed37bf ]
Much like arm-smmu in commit 7d835134d4e1 ("iommu/arm-smmu: Make instance lookup robust"), virtio-iommu appears to have the same issue where iommu_device_register() makes the IOMMU instance visible to other API callers (including itself) straight away, but internally the instance isn't ready to recognise itself for viommu_probe_device() to work correctly until after viommu_probe() has returned. This matters a lot more now that bus_iommu_probe() has the DT/VIOT knowledge to probe client devices the way that was always intended. Tweak the lookup and initialisation in much the same way as for arm-smmu, to ensure that what we register is functional and ready to go.
--- drivers/iommu/virtio-iommu.c | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-)
drivers/iommu/virtio-iommu.c +9 -6
@@ -998,8 +998,7 @@ static void viommu_get_resv_regions(struiommu_dma_get_resv_regions (dev, head); } -static const struct iommu_ops viommu_ops; -static struct virtio_driver virtio_iommu_drv; +static const struct bus_type *virtio_bus_type;static int viommu_match_node (struct device *dev,const void *data) {
@@ -1008,8 +1007,9 @@ static int viommu_match_node(struct devistatic struct viommu_dev *viommu_get_by_fwnode (struct fwnode_handle *fwnode) { -struct device *dev =driver_find_device (&virtio_iommu_drv.driver,NULL , - fwnode, viommu_match_node); +struct device *dev =bus_find_device (virtio_bus_type,NULL , fwnode, + viommu_match_node); +put_device (dev);return dev ?dev_to_virtio (dev)->priv :NULL ;
@@ -1160,6 +1160,9 @@ static int viommu_probe(struct virtio_deif (!viommu)return -ENOMEM ; +/* Borrow this for easy lookups later */ + virtio_bus_type = dev->bus; +spin_lock_init (&viommu->request_lock);ida_init (&viommu->domain_ids); viommu->dev = dev;
@@ -1229,10 +1232,10 @@ static int viommu_probe(struct virtio_deif (ret) goto err_free_vqs; -iommu_device_register (&viommu->iommu, &viommu_ops, parent_dev); - vdev->priv = viommu; +iommu_device_register (&viommu->iommu, &viommu_ops, parent_dev); +dev_info (dev,"input address: %u bits\n" ,order_base_2 (viommu->geometry.aperture_end));dev_info (dev,"page mask: %#llx\n" , viommu->pgsize_bitmap);
Greg Kroah-Hartman
maintainerPATCH 292/457 drm/amd: Restore cached manual clock settings during resume
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mario Limonciello <[email protected]>
[ Upstream commit 796ff8a7e01bd18738d3bb4111f9d6f963145d29 ]
If the SCLK limits have been set before S3 they will not be restored. The limits are however cached in the driver and so they can be restored by running a commit sequence during resume.
--- drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c | 10 ++++++++++ 1 file changed, 10 insertions(+)
drivers/gpu/drm/amd/pm/swsmu/amdgpu_smu.c +10 -0
@@ -76,6 +76,9 @@ static void smu_power_profile_mode_get(s enum PP_SMC_POWER_PROFILE profile_mode);static void smu_power_profile_mode_put (struct smu_context *smu,enum PP_SMC_POWER_PROFILE profile_mode); +static int smu_od_edit_dpm_table (void *handle, +enum PP_OD_DPM_TABLE_COMMAND type, +long *input,uint32_t size);static int smu_sys_get_pp_feature_mask (void *handle,char *buf)
@@ -2144,6 +2147,7 @@ static int smu_resume(struct amdgpu_ip_bint ret;struct amdgpu_device *adev = ip_block->adev;struct smu_context *smu = adev->powerplay.pp_handle; +struct smu_dpm_context *smu_dpm_ctx = &(smu->smu_dpm);if (amdgpu_sriov_multi_vf_mode (adev))return 0 ;
@@ -2181,6 +2185,12 @@ static int smu_resume(struct amdgpu_ip_breturn ret; } +if (smu_dpm_ctx->dpm_level ==AMD_DPM_FORCED_LEVEL_MANUAL ) { + ret =smu_od_edit_dpm_table (smu,PP_OD_COMMIT_DPM_TABLE ,NULL ,0 ); +if (ret) +return ret; + } +dev_info (adev->dev,"SMU is resumed successfully!\n" );return 0 ;
Greg Kroah-Hartman
maintainerPATCH 293/457 drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
[ Upstream commit a40c5d727b8111b5db424a1e43e14a1dcce1e77f ]
Reading DPCD registers has side-effects in general. In particular accessing registers outside of the link training register range (0x102-0x106, 0x202-0x207, 0x200c-0x200f, 0x2216) is explicitly forbidden by the DP v2.1 Standard, see
3.6.5.1 DPTX AUX Transaction Handling Mandates 3.6.7.4 128b/132b DP Link Layer LTTPR Link Training Mandates
Based on my tests, accessing the DPCD_REV register during the link training of an UHBR TBT DP tunnel sink leads to link training failures.
Solve the above by using the DP_LANE0_1_STATUS (0x202) register for the DPCD register access quirk.
--- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/display/drm_dp_helper.c +1 -1
@@ -725,7 +725,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_a* monitor doesn't power down exactly after the throw away read. */ if (!aux->is_remote) { - ret =drm_dp_dpcd_probe (aux,DP_TRAINING_PATTERN_SET ); + ret =drm_dp_dpcd_probe (aux,DP_LANE0_1_STATUS );if (ret <0 )return ret; }
Re: [PATCH 6.16 293/457] drm/dp: Change AUX DPCD probe address from DPCD_REV to LANE0_1_STATUS
Hi Greg,
could you please drop this patch from all the stable tree queues? I got a review notification now for the 6.12 and 6.16 stable tree, but I also see the patch in all the stable queues (5.4, 5.10, 5.15, 6.1, 6.6, 6.12, 6.16). The change would cause a regression which I described at
https://lore.kernel.org/all/aKwQfhfSu5aCUktw@ideak-desk
and
https://lore.kernel.org/stable/aGaiASySvb3BVXlM@ideak-desk
Thanks,
Imre
Quoted 48 lines · Greg Kroah-Hartman
6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Imre Deak <[email protected]>
[ Upstream commit
a40c5d727b8111b5db424a1e43e14a1dcce1e77f]Reading DPCD registers has side-effects in general. In particular accessing registers outside of the link training register range (0x102-0x106, 0x202-0x207, 0x200c-0x200f,
0x2216) is explicitly forbidden by the DP v2.1 Standard, see3.6.5.1 DPTX AUX Transaction Handling Mandates 3.6.7.4 128b/132b DP Link Layer LTTPR Link Training Mandates
Based on my tests, accessing the
DPCD_REVregister during the link training of an UHBR TBT DP tunnel sink leads to link training failures.Solve the above by using the
DP_LANE0_1_STATUS(0x202) register for the DPCD register access quirk.Cc <[email protected]>Cc Ville Syrjälä <[email protected]>Cc Jani Nikula <[email protected]>Acked-by Jani Nikula <[email protected]>Signed-off-by Imre Deak <[email protected]>[ DP_TRAINING_PATTERN_SET => DP_LANE0_1_STATUS ]Signed-off-by Sasha Levin <[email protected]>Signed-off-by Greg Kroah-Hartman <[email protected]>--- drivers/gpu/drm/display/drm_dp_helper.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)drivers/gpu/drm/display/drm_dp_helper.c +1
-1@@ -725,7 +725,7 @@ ssize_t drm_dp_dpcd_read(struct drm_dp_a* monitor doesn't power down exactly after the throw away read. */ if (!aux->is_remote) { - ret =drm_dp_dpcd_probe (aux,DP_TRAINING_PATTERN_SET ); + ret =drm_dp_dpcd_probe (aux,DP_LANE0_1_STATUS );if (ret <0 )return ret; }
Greg Kroah-Hartman
maintainerPATCH 294/457 fpga: zynq_fpga: Fix the wrong usage of dma_map_sgtable()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yilun <[email protected]>
commit 1ca61060de92a4320d73adfe5dc8d335653907ac upstream.
dma_map_sgtable() returns only 0 or the error code. Read sgt->nents to get the number of mapped segments.
--- drivers/fpga/zynq-fpga.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/fpga/zynq-fpga.c +4 -4
@@ -405,12 +405,12 @@ static int zynq_fpga_ops_write(struct fp } } - priv->dma_nelms = -dma_map_sgtable (mgr->dev.parent, sgt,DMA_TO_DEVICE ,0 ); -if (priv->dma_nelms ==0 ) { + err =dma_map_sgtable (mgr->dev.parent, sgt,DMA_TO_DEVICE ,0 ); +if (err) {dev_err (&mgr->dev,"Unable to DMA map (TO_DEVICE)\n" ); -return -ENOMEM ; +return err; } + priv->dma_nelms = sgt->nents;/* enable clock */ err =clk_enable (priv->clk);
Greg Kroah-Hartman
maintainerPATCH 295/457 iio: adc: ad7380: fix missing max_conversion_rate_hz on adaq4381-4
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit b04e4551893fb8a06106a175ed7055d41a9279c4 upstream.
Add max_conversion_rate_hz to the chip info for "adaq4381-4". Without this, the driver fails to probe because it tries to set the initial sample rate to 0 Hz, which is not valid.
--- drivers/iio/adc/ad7380.c | 1 + 1 file changed, 1 insertion(+)
drivers/iio/adc/ad7380.c +1 -0
@@ -873,6 +873,7 @@ static const struct ad7380_chip_info adaq4381_4_chip_info = { .has_hardware_gain = true, .available_scan_masks = ad7380_4_channel_scan_masks, .timing_specs = &ad7380_4_timing, + .max_conversion_rate_hz = 4 * MEGA, };static const struct spi_offload_config ad7380_offload_config = {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 296/457 iio: accel: sca3300: fix uninitialized iio scan data
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 4e5b705cc6147f0b9173c6219079f41416bdd3c0 upstream.
Fix potential leak of uninitialized stack data to userspace by ensuring that the channels array is zeroed before use.
--- drivers/iio/accel/sca3300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/accel/sca3300.c +1 -1
@@ -479,7 +479,7 @@ static irqreturn_t sca3300_trigger_handlstruct iio_dev *indio_dev = pf->indio_dev;struct sca3300_data *data =iio_priv (indio_dev);int bit, ret, val, i =0 ; -IIO_DECLARE_BUFFER_WITH_TS (s16, channels,SCA3300_SCAN_MAX ); + IIO_DECLARE_BUFFER_WITH_TS(s16, channels, SCA3300_SCAN_MAX) = { };iio_for_each_active_channel (indio_dev, bit) { ret =sca3300_read_reg (data, indio_dev->channels[bit].address, &val);
Greg Kroah-Hartman
maintainerPATCH 297/457 ftrace: Also allocate and copy hash for reading of filter files
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
commit bfb336cf97df7b37b2b2edec0f69773e06d11955 upstream.
Currently the reader of set_ftrace_filter and set_ftrace_notrace just adds the pointer to the global tracer hash to its iterator. Unlike the writer that allocates a copy of the hash, the reader keeps the pointer to the filter hashes. This is problematic because this pointer is static across function calls that release the locks that can update the global tracer hashes. This can cause UAF and similar bugs.
Allocate and copy the hash for reading the filter files like it is done for the writers. This not only fixes UAF bugs, but also makes the code a bit simpler as it doesn't have to differentiate when to free the iterator's hash between writers and readers.
--- kernel/trace/ftrace.c | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-)
kernel/trace/ftrace.c +10 -9
@@ -4665,13 +4665,17 @@ ftrace_regex_open(struct ftrace_ops *ops }else { iter->hash =alloc_and_copy_ftrace_hash (size_bits, hash); } + }else { +if (hash) + iter->hash =alloc_and_copy_ftrace_hash (hash->size_bits, hash); +else + iter->hash =EMPTY_HASH ; + } -if (!iter->hash) { -trace_parser_put (&iter->parser); - goto out_unlock; - } - }else - iter->hash = hash; +if (!iter->hash) { +trace_parser_put (&iter->parser); + goto out_unlock; + } ret =0 ;
@@ -6547,9 +6551,6 @@ int ftrace_regex_release(struct inode *iftrace_hash_move_and_update_ops (iter->ops, orig_hash, iter->hash, filter_hash);mutex_unlock (&ftrace_lock); - }else { -/* For read only, the hash is the ops hash */ - iter->hash =NULL ; }mutex_unlock (&iter->ops->func_hash->regex_lock);
Greg Kroah-Hartman
maintainerPATCH 298/457 iio: temperature: maxim_thermocouple: use DMA-safe buffer for spi_read()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit ae5bc07ec9f73a41734270ef3f800c5c8a7e0ad3 upstream.
Replace using stack-allocated buffers with a DMA-safe buffer for use with spi_read(). This allows the driver to be safely used with DMA-enabled SPI controllers.
The buffer array is also converted to a struct with a union to make the usage of the memory in the buffer more clear and ensure proper alignment.
--- drivers/iio/temperature/maxim_thermocouple.c | 26 ++++++++++++++++---------- 1 file changed, 16 insertions(+), 10 deletions(-)
drivers/iio/temperature/maxim_thermocouple.c +16 -10
@@ -11,6 +11,7 @@#include <linux/module.h> #include <linux/err.h> #include <linux/spi/spi.h> +#include <linux/types.h> #include <linux/iio/iio.h> #include <linux/iio/sysfs.h> #include <linux/iio/trigger.h>
@@ -121,8 +122,15 @@ struct maxim_thermocouple_data {struct spi_device *spi;const struct maxim_thermocouple_chip *chip;char tc_type; - -u8 buffer[16 ]__aligned(IIO_DMA_MINALIGN) ; +/* Buffer for reading up to 2 hardware channels. */ +struct { +union { +__be16 raw16; +__be32 raw32; +__be16 raw[2 ]; + }; +aligned_s64 timestamp; + } buffer__aligned(IIO_DMA_MINALIGN) ; }; static int maxim_thermocouple_read(struct maxim_thermocouple_data *data,
@@ -130,18 +138,16 @@ static int maxim_thermocouple_read(struc {unsigned int storage_bytes = data->chip->read_size;unsigned int shift = chan->scan_type.shift + (chan->address *8 ); -__be16 buf16; -__be32 buf32;int ret;switch (storage_bytes) {case 2 : - ret =spi_read (data->spi, (void *)&buf16, storage_bytes); - *val =be16_to_cpu (buf16); + ret =spi_read (data->spi, &data->buffer.raw16, storage_bytes); + *val =be16_to_cpu (data->buffer.raw16);break ;case 4 : - ret =spi_read (data->spi, (void *)&buf32, storage_bytes); - *val =be32_to_cpu (buf32); + ret =spi_read (data->spi, &data->buffer.raw32, storage_bytes); + *val =be32_to_cpu (data->buffer.raw32);break ;default : ret = -EINVAL ;
@@ -166,9 +172,9 @@ static irqreturn_t maxim_thermocouple_trstruct maxim_thermocouple_data *data =iio_priv (indio_dev);int ret; - ret =spi_read (data->spi, data->buffer, data->chip->read_size); + ret =spi_read (data->spi, data->buffer.raw, data->chip->read_size);if (!ret) { -iio_push_to_buffers_with_ts (indio_dev, data->buffer, +iio_push_to_buffers_with_ts (indio_dev, &data->buffer,sizeof (data->buffer),iio_get_time_ns (indio_dev)); }
Greg Kroah-Hartman
maintainerPATCH 299/457 iio: adc: ad7124: fix channel lookup in syscalib functions
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 197e299aae42ffa19028eaea92b2f30dd9fb8445 upstream.
Fix possible incorrect channel lookup in the syscalib functions by using the correct channel address instead of the channel number.
In the ad7124 driver, the channel field of struct iio_chan_spec is the input pin number of the positive input of the channel. This can be, but is not always the same as the index in the channels array. The correct index in the channels array is stored in the address field (and also scan_index). We use the address field to perform the correct lookup.
--- drivers/iio/adc/ad7124.c | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-)
drivers/iio/adc/ad7124.c +7 -7
@@ -855,7 +855,7 @@ enum {static int ad7124_syscalib_locked (struct ad7124_state *st,const struct iio_chan_spec *chan) {struct device *dev = &st->sd.spi->dev; -struct ad7124_channel *ch = &st->channels[chan->channel]; +struct ad7124_channel *ch = &st->channels[chan->address];int ret;if (ch->syscalib_mode ==AD7124_SYSCALIB_ZERO_SCALE ) {
@@ -871,8 +871,8 @@ static int ad7124_syscalib_locked(structif (ret <0 )return ret; -dev_dbg (dev,"offset for channel %d after zero-scale calibration: 0x%x\n" , - chan->channel, ch->cfg.calibration_offset); +dev_dbg (dev,"offset for channel %lu after zero-scale calibration: 0x%x\n" , + chan->address, ch->cfg.calibration_offset); }else { ch->cfg.calibration_gain = st->gain_default;
@@ -886,8 +886,8 @@ static int ad7124_syscalib_locked(structif (ret <0 )return ret; -dev_dbg (dev,"gain for channel %d after full-scale calibration: 0x%x\n" , - chan->channel, ch->cfg.calibration_gain); +dev_dbg (dev,"gain for channel %lu after full-scale calibration: 0x%x\n" , + chan->address, ch->cfg.calibration_gain); }return 0 ;
@@ -930,7 +930,7 @@ static int ad7124_set_syscalib_mode(stru {struct ad7124_state *st =iio_priv (indio_dev); - st->channels[chan->channel].syscalib_mode = mode; + st->channels[chan->address].syscalib_mode = mode;return 0 ; }
@@ -940,7 +940,7 @@ static int ad7124_get_syscalib_mode(stru {struct ad7124_state *st =iio_priv (indio_dev); -return st->channels[chan->channel].syscalib_mode; +return st->channels[chan->address].syscalib_mode; }static const struct iio_enum ad7124_syscalib_mode_enum = {
Greg Kroah-Hartman
maintainerPATCH 300/457 iio: light: as73211: Ensure buffer holes are zeroed
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jonathan Cameron <[email protected]>
commit 433b99e922943efdfd62b9a8e3ad1604838181f2 upstream.
Given that the buffer is copied to a kfifo that ultimately user space can read, ensure we zero it.
--- drivers/iio/light/as73211.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/light/as73211.c +1 -1
@@ -639,7 +639,7 @@ static irqreturn_t as73211_trigger_handlstruct {__le16 chan[4 ];aligned_s64 ts; - } scan; + } scan = { };int data_result, ret;mutex_lock (&data->mutex);
Greg Kroah-Hartman
maintainerPATCH 301/457 iio: pressure: bmp280: Use IS_ERR() in bmp280_common_probe()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Salah Triki <[email protected]>
commit 43c0f6456f801181a80b73d95def0e0fd134e1cc upstream.
devm_gpiod_get_optional() may return non-NULL error pointer on failure. Check its return value using IS_ERR() and propagate the error if necessary.
--- drivers/iio/pressure/bmp280-core.c | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-)
drivers/iio/pressure/bmp280-core.c +5 -4
@@ -3216,11 +3216,12 @@ int bmp280_common_probe(struct device *d/* Bring chip out of reset if there is an assigned GPIO line */ gpiod =devm_gpiod_get_optional (dev,"reset" ,GPIOD_OUT_HIGH ); +if (IS_ERR (gpiod)) +return dev_err_probe (dev,PTR_ERR (gpiod),"failed to get reset GPIO\n" ); +/* Deassert the signal */ -if (gpiod) { -dev_info (dev,"release reset\n" ); -gpiod_set_value (gpiod,0 ); - } +dev_info (dev,"release reset\n" ); +gpiod_set_value (gpiod,0 ); data->regmap = regmap;
Greg Kroah-Hartman
maintainerPATCH 302/457 iio: adc: rzg2l_adc: Set driver data before enabling runtime PM
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
commit c69e13965f26b8058f538ea8bdbd2d7718cf1fbe upstream.
When stress-testing the system by repeatedly unbinding and binding the ADC device in a loop, and the ADC is a supplier for another device (e.g., a thermal hardware block that reads temperature through the ADC), it may happen that the ADC device is runtime-resumed immediately after runtime PM is enabled, triggered by its consumer. At this point, since drvdata is not yet set and the driver's runtime PM callbacks rely on it, a crash can occur. To avoid this, set drvdata just after it was allocated.
--- drivers/iio/adc/rzg2l_adc.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iio/adc/rzg2l_adc.c +2 -2
@@ -428,6 +428,8 @@ static int rzg2l_adc_probe(struct platfoif (!indio_dev)return -ENOMEM ; +platform_set_drvdata (pdev, indio_dev); + adc =iio_priv (indio_dev); adc->hw_params =device_get_match_data (dev);
@@ -460,8 +462,6 @@ static int rzg2l_adc_probe(struct platfoif (ret)return ret; -platform_set_drvdata (pdev, indio_dev); - ret =rzg2l_adc_hw_init (dev, adc);if (ret) return dev_err_probe(&pdev->dev, ret,
Greg Kroah-Hartman
maintainerPATCH 303/457 iio: adc: bd79124: Add GPIOLIB dependency
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Matti Vaittinen <[email protected]>
commit 8a6ededaad2d2dcaac8e545bffee1073dca9db95 upstream.
The bd79124 has ADC inputs which can be muxed to be GPIOs. The driver supports this by registering a GPIO-chip for channels which aren't used as ADC.
The Kconfig entry does not handle the dependency to GPIOLIB, which causes errors:
ERROR: modpost: "devm_gpiochip_add_data_with_key" [drivers/iio/adc/rohm-bd79124.ko] undefined!
ERROR: modpost: "gpiochip_get_data" [drivers/iio/adc/rohm-bd79124.ko] undefined!
at linking phase if GPIOLIB is not configured to be used.
Fix this by adding dependency to the GPIOLIB.
--- drivers/iio/adc/Kconfig | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/iio/adc/Kconfig +1 -1
@@ -1257,7 +1257,7 @@ config RN5T618_ADC config ROHM_BD79124 tristate "Rohm BD79124 ADC driver" - depends on I2C + depends on I2C && GPIOLIB select REGMAP_I2C select IIO_ADC_HELPER help
Greg Kroah-Hartman
maintainerPATCH 304/457 iio: adc: ad7173: prevent scan if too many setups requested
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit 1cfb22c277c7274f54babaa5b416dfbc00181e16 upstream.
Add a check to ad7173_update_scan_mode() to ensure that we didn't exceed the maximum number of unique channel configurations.
In the AD7173 family of chips, there are some chips that have 16 CHANNELx registers but only 8 setups (combination of CONFIGx, FILTERx, GAINx and OFFSETx registers). Since commit 92c247216918 ("iio: adc:
ad7173: fix num_slots"), it is possible to have more than 8 channels enabled in a scan at the same time, so it is possible to get a bad configuration when more than 8 channels are using unique configurations. This happens because the algorithm to allocate the setup slots only takes into account which slot has been least recently used and doesn't know about the maximum number of slots available.
Since the algorithm to allocate the setup slots is quite complex, it is simpler to check after the fact if the current state is valid or not. So this patch adds a check in ad7173_update_scan_mode() after setting up all of the configurations to make sure that the actual setup still matches the requested setup for each enabled channel. If not, we prevent the scan from being enabled and return an error.
The setup comparison in ad7173_setup_equal() is refactored to a separate function since we need to call it in two places now.
--- drivers/iio/adc/ad7173.c | 87 ++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 75 insertions(+), 12 deletions(-)
drivers/iio/adc/ad7173.c +75 -12
@@ -200,7 +200,7 @@ struct ad7173_channel_config {/* * Following fields are used to compare equality. If you * make adaptations in it, you most likely also have to adapt -* ad7173_find_live_config(), too. +* ad7173_is_setup_equal(), too. */ struct_group(config_props, bool bipolar;
@@ -562,12 +562,19 @@ static void ad7173_reset_usage_cnts(stru st->config_usage_counter =0 ; } -static struct ad7173_channel_config * -ad7173_find_live_config (struct ad7173_state *st,struct ad7173_channel_config *cfg) +/** +* ad7173_is_setup_equal - Compare two channel setups +* @cfg1: First channel configuration +* @cfg2: Second channel configuration +* +* Compares all configuration options that affect the registers connected to +* SETUP_SEL, namely CONFIGx, FILTERx, GAINx and OFFSETx. +* +* Returns: true if the setups are identical, false otherwise +*/ +static bool ad7173_is_setup_equal (const struct ad7173_channel_config *cfg1, +const struct ad7173_channel_config *cfg2) { -struct ad7173_channel_config *cfg_aux; -int i; -/* * This is just to make sure that the comparison is adapted after * struct ad7173_channel_config was changed.
@@ -580,14 +587,22 @@ ad7173_find_live_config(struct ad7173_stu8 ref_sel; })); +return cfg1->bipolar == cfg2->bipolar && + cfg1->input_buf == cfg2->input_buf && + cfg1->odr == cfg2->odr && + cfg1->ref_sel == cfg2->ref_sel; +} + +static struct ad7173_channel_config * +ad7173_find_live_config (struct ad7173_state *st,struct ad7173_channel_config *cfg) +{ +struct ad7173_channel_config *cfg_aux; +int i; +for (i =0 ; i < st->num_channels; i++) { cfg_aux = &st->channels[i].cfg; -if (cfg_aux->live && - cfg->bipolar == cfg_aux->bipolar && - cfg->input_buf == cfg_aux->input_buf && - cfg->odr == cfg_aux->odr && - cfg->ref_sel == cfg_aux->ref_sel) +if (cfg_aux->live &&ad7173_is_setup_equal (cfg, cfg_aux))return cfg_aux; }return NULL ;
@@ -1229,7 +1244,7 @@ static int ad7173_update_scan_mode(struc const unsigned long *scan_mask) {struct ad7173_state *st =iio_priv (indio_dev); -int i, ret; +int i, j, k, ret;for (i =0 ; i < indio_dev->num_channels; i++) {if (test_bit (i, scan_mask))
@@ -1240,6 +1255,54 @@ static int ad7173_update_scan_mode(strucreturn ret; } +/* +* On some chips, there are more channels that setups, so if there were +* more unique setups requested than the number of available slots, +* ad7173_set_channel() will have written over some of the slots. We +* can detect this by making sure each assigned cfg_slot matches the +* requested configuration. If it doesn't, we know that the slot was +* overwritten by a different channel. +*/ +for_each_set_bit (i, scan_mask, indio_dev->num_channels) { +const struct ad7173_channel_config *cfg1, *cfg2; + + cfg1 = &st->channels[i].cfg; + +for_each_set_bit (j, scan_mask, indio_dev->num_channels) { + cfg2 = &st->channels[j].cfg; + +/* +* Only compare configs that are assigned to the same +* SETUP_SEL slot and don't compare channel to itself. +*/ +if (i == j || cfg1->cfg_slot != cfg2->cfg_slot) +continue ; + +/* +* If we find two different configs trying to use the +* same SETUP_SEL slot, then we know that the that we +* have too many unique configurations requested for +* the available slots and at least one was overwritten. +*/ +if (!ad7173_is_setup_equal (cfg1, cfg2)) { +/* +* At this point, there isn't a way to tell +* which setups are actually programmed in the +* ADC anymore, so we could read them back to +* see, but it is simpler to just turn off all +* of the live flags so that everything gets +* reprogramed on the next attempt read a sample. +*/ +for (k =0 ; k < st->num_channels; k++) + st->channels[k].cfg.live = false; + +dev_err (&st->sd.spi->dev, +"Too many unique channel configurations requested for scan\n" ); +return -EINVAL ; + } + } + } +return 0 ; }
Greg Kroah-Hartman
maintainerPATCH 305/457 iio: proximity: isl29501: fix buffered read on big-endian systems
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
commit de18e978d0cda23e4c102e18092b63a5b0b3a800 upstream.
Fix passing a u32 value as a u16 buffer scan item. This works on little- endian systems, but not on big-endian systems.
A new local variable is introduced for getting the register value and the array is changed to a struct to make the data layout more explicit rather than just changing the type and having to recalculate the proper length needed for the timestamp.
--- drivers/iio/proximity/isl29501.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-)
drivers/iio/proximity/isl29501.c +10 -4
@@ -938,12 +938,18 @@ static irqreturn_t isl29501_trigger_handstruct iio_dev *indio_dev = pf->indio_dev;struct isl29501_private *isl29501 =iio_priv (indio_dev);const unsigned long *active_mask = indio_dev->active_scan_mask; -u32 buffer[4 ]__aligned(8) = {};/* 1x16-bit + naturally aligned ts */ +u32 value; +struct { +u16 data; +aligned_s64 ts; + } scan = { }; -if (test_bit (ISL29501_DISTANCE_SCAN_INDEX , active_mask)) -isl29501_register_read (isl29501,REG_DISTANCE , buffer); +if (test_bit (ISL29501_DISTANCE_SCAN_INDEX , active_mask)) { +isl29501_register_read (isl29501,REG_DISTANCE , &value); + scan.data = value; + } -iio_push_to_buffers_with_timestamp (indio_dev, buffer, pf->timestamp); +iio_push_to_buffers_with_timestamp (indio_dev, &scan, pf->timestamp);iio_trigger_notify_done (indio_dev->trig);return IRQ_HANDLED ;
Greg Kroah-Hartman
maintainerPATCH 306/457 iio: adc: rzg2l: Cleanup suspend/resume path
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Claudiu Beznea <[email protected]>
commit a3c6eabe3bbd6b0e7124d68b2d3bc32fed17362e upstream.
There is no need to manually track the runtime PM status in the driver. The pm_runtime_force_suspend() and pm_runtime_force_resume() functions already call pm_runtime_status_suspended() to check the runtime PM state.
Additionally, avoid calling pm_runtime_put_autosuspend() during the suspend/resume path, as this would decrease the usage counter of a potential user that had the ADC open before the suspend/resume cycle.
--- drivers/iio/adc/rzg2l_adc.c | 29 ++++++++--------------------- 1 file changed, 8 insertions(+), 21 deletions(-)
drivers/iio/adc/rzg2l_adc.c +8 -21
@@ -89,7 +89,6 @@ struct rzg2l_adc {struct completion completion;struct mutex lock;u16 last_val[RZG2L_ADC_MAX_CHANNELS ]; -bool was_rpm_active; };/**
@@ -541,14 +540,9 @@ static int rzg2l_adc_suspend(struct device *dev) };int ret; -if (pm_runtime_suspended (dev)) { - adc->was_rpm_active = false; - }else { - ret =pm_runtime_force_suspend (dev); -if (ret) -return ret; - adc->was_rpm_active = true; - } + ret =pm_runtime_force_suspend (dev); +if (ret) +return ret; ret =reset_control_bulk_assert (ARRAY_SIZE (resets), resets);if (ret)
@@ -557,9 +551,7 @@ static int rzg2l_adc_suspend(struct device *dev)return 0 ; rpm_restore: -if (adc->was_rpm_active) -pm_runtime_force_resume (dev); - +pm_runtime_force_resume (dev);return ret; }
@@ -577,11 +569,9 @@ static int rzg2l_adc_resume(struct device *dev)if (ret)return ret; -if (adc->was_rpm_active) { - ret =pm_runtime_force_resume (dev); -if (ret) - goto resets_restore; - } + ret =pm_runtime_force_resume (dev); +if (ret) + goto resets_restore; ret =rzg2l_adc_hw_init (dev, adc);if (ret)
@@ -590,10 +580,7 @@ static int rzg2l_adc_resume(struct device *dev)return 0 ; rpm_restore: -if (adc->was_rpm_active) { -pm_runtime_mark_last_busy (dev); -pm_runtime_put_autosuspend (dev); - } +pm_runtime_force_suspend (dev); resets_restore:reset_control_bulk_assert (ARRAY_SIZE (resets), resets);return ret;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 307/457 most: core: Drop device reference after usage in get_channel()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miaoqian Lin <[email protected]>
commit b47b493d6387ae437098112936f32be27f73516c upstream.
In get_channel(), the reference obtained by bus_find_device_by_name() was dropped via put_device() before accessing the device's driver data Move put_device() after usage to avoid potential issues.
--- drivers/most/core.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/most/core.c +1 -1
@@ -538,8 +538,8 @@ static struct most_channel *get_channel( dev =bus_find_device_by_name (&mostbus,NULL , mdev);if (!dev)return NULL ; -put_device (dev); iface =dev_get_drvdata (dev); +put_device (dev);list_for_each_entry_safe (c, tmp, &iface->p->channel_list, list) {if (!strcmp (dev_name (&c->dev), mdev_ch))return c;
Greg Kroah-Hartman
maintainerPATCH 308/457 kcov, usb: Dont disable interrupts in kcov_remote_start_usb_softirq()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sebastian Andrzej Siewior <[email protected]>
commit 9528d32873b38281ae105f2f5799e79ae9d086c2 upstream.
kcov_remote_start_usb_softirq() the begin of urb's completion callback. HCDs marked HCD_BH will invoke this function from the softirq and in_serving_softirq() will detect this properly.
Root-HUB (RH) requests will not be delayed to softirq but complete immediately in IRQ context.
This will confuse kcov because in_serving_softirq() will report true if the softirq is served after the hardirq and if the softirq got interrupted by the hardirq in which currently runs.
This was addressed by simply disabling interrupts in kcov_remote_start_usb_softirq() which avoided the interruption by the RH while a regular completion callback was invoked.
This not only changes the behaviour while kconv is enabled but also breaks PREEMPT_RT because now sleeping locks can no longer be acquired.
Revert the previous fix. Address the issue by invoking kcov_remote_start_usb() only if the context is just "serving softirqs" which is identified by checking in_serving_softirq() and in_hardirq() must be false.
--- drivers/usb/core/hcd.c | 12 +++++------- include/linux/kcov.h | 47 +++++++++-------------------------------------- 2 files changed, 14 insertions(+), 45 deletions(-)
drivers/usb/core/hcd.c +5 -7
@@ -1623,7 +1623,6 @@ static void __usb_hcd_giveback_urb(strucstruct usb_hcd *hcd =bus_to_hcd (urb->dev->bus);struct usb_anchor *anchor = urb->anchor;int status = urb->unlinked; -unsigned long flags; urb->hcpriv =NULL ; if (unlikely((urb->transfer_flags & URB_SHORT_NOT_OK) &&
@@ -1641,14 +1640,13 @@ static void __usb_hcd_giveback_urb(struc/* pass ownership to the completion handler */ urb->status = status;/* -* Only collect coverage in the softirq context and disable interrupts -* to avoid scenarios with nested remote coverage collection sections -* that KCOV does not support. -* See the comment next to kcov_remote_start_usb_softirq() for details. +* This function can be called in task context inside another remote +* coverage collection section, but kcov doesn't support that kind of +* recursion yet. Only collect coverage in softirq context for now. */ - flags =kcov_remote_start_usb_softirq ((u64 )urb->dev->bus->busnum); +kcov_remote_start_usb_softirq ((u64 )urb->dev->bus->busnum); urb->complete (urb); -kcov_remote_stop_softirq (flags); +kcov_remote_stop_softirq ();usb_anchor_resume_wakeups (anchor);atomic_dec (&urb->use_count);
include/linux/kcov.h +9 -38
67 lines not on this page · raw message
Greg Kroah-Hartman
maintainerPATCH 309/457 cdx: Fix off-by-one error in cdx_rpmsg_probe()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 300a0cfe9f375b2843bcb331bcfa7503475ef5dd upstream.
In cdx_rpmsg_probe(), strscpy() is incorrectly called with the length of the source string (excluding the NUL terminator) rather than the size of the destination buffer. This results in one character less being copied from 'cdx_rpmsg_id_table[0].name' to 'chinfo.name'.
Use the destination buffer size instead to ensure the name is copied correctly.
--- drivers/cdx/controller/cdx_rpmsg.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/cdx/controller/cdx_rpmsg.c +1 -2
@@ -129,8 +129,7 @@ static int cdx_rpmsg_probe(struct rpmsg_ chinfo.src =RPMSG_ADDR_ANY ; chinfo.dst = rpdev->dst; -strscpy (chinfo.name, cdx_rpmsg_id_table[0 ].name, -strlen (cdx_rpmsg_id_table[0 ].name)); +strscpy (chinfo.name, cdx_rpmsg_id_table[0 ].name,sizeof (chinfo.name)); cdx_mcdi->ept =rpmsg_create_ept (rpdev, cdx_rpmsg_cb,NULL , chinfo);if (!cdx_mcdi->ept) {
Greg Kroah-Hartman
maintainerPATCH 310/457 usb: quirks: Add DELAY_INIT quick for another SanDisk 3.2Gen1 Flash Drive
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miao Li <[email protected]>
commit e664036cf36480414936cd91f4cfa2179a3d8367 upstream.
Another SanDisk 3.2Gen1 Flash Drive also need DELAY_INIT quick, or it will randomly work incorrectly on Huawei hisi platforms when doing reboot test.
--- drivers/usb/core/quirks.c | 1 + 1 file changed, 1 insertion(+)
drivers/usb/core/quirks.c +1 -0
@@ -371,6 +371,7 @@ static const struct usb_device_id usb_qu { USB_DEVICE(0x0781, 0x5591), .driver_info = USB_QUIRK_NO_LPM }, /* SanDisk Corp. SanDisk 3.2Gen1 */ + { USB_DEVICE(0x0781, 0x5596), .driver_info = USB_QUIRK_DELAY_INIT }, { USB_DEVICE(0x0781, 0x55a3), .driver_info = USB_QUIRK_DELAY_INIT },/* SanDisk Extreme 55AE */
Greg Kroah-Hartman
maintainerPATCH 311/457 comedi: Make insn_rw_emulate_bits() do insn->n samples
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 7afba9221f70d4cbce0f417c558879cba0eb5e66 upstream.
The insn_rw_emulate_bits() function is used as a default handler for INSN_READ instructions for subdevices that have a handler for INSN_BITS but not for INSN_READ. Similarly, it is used as a default handler for INSN_WRITE instructions for subdevices that have a handler for INSN_BITS but not for INSN_WRITE. It works by emulating the INSN_READ or INSN_WRITE instruction handling with a constructed INSN_BITS instruction. However, INSN_READ and INSN_WRITE instructions are supposed to be able read or write multiple samples, indicated by the insn->n value, but insn_rw_emulate_bits() currently only handles a single sample. For INSN_READ, the comedi core will copy insn->n samples back to user-space. (That triggered KASAN kernel-infoleak errors when insn->n was greater than 1, but that is being fixed more generally elsewhere in the comedi core.)
Make insn_rw_emulate_bits() either handle insn->n samples, or return an error, to conform to the general expectation for INSN_READ and INSN_WRITE handlers.
--- drivers/comedi/drivers.c | 25 +++++++++++++------------ 1 file changed, 13 insertions(+), 12 deletions(-)
drivers/comedi/drivers.c +13 -12
@@ -620,11 +620,9 @@ static int insn_rw_emulate_bits(struct cunsigned int chan =CR_CHAN (insn->chanspec);unsigned int base_chan = (chan <32 ) ?0 : chan;unsigned int _data[2 ]; +unsigned int i;int ret; -if (insn->n ==0 ) -return 0 ; -memset (_data,0 ,sizeof (_data));memset (&_insn,0 ,sizeof (_insn)); _insn.insn =INSN_BITS ;
@@ -635,18 +633,21 @@ static int insn_rw_emulate_bits(struct cif (insn->insn ==INSN_WRITE ) {if (!(s->subdev_flags &SDF_WRITABLE ))return -EINVAL ; - _data[0 ] =1U << (chan - base_chan);/* mask */ - _data[1 ] = data[0 ] ? (1U << (chan - base_chan)) :0 ;/* bits */ + _data[0 ] =1U << (chan - base_chan);/* mask */ } +for (i =0 ; i < insn->n; i++) { +if (insn->insn ==INSN_WRITE ) + _data[1 ] = data[i] ? _data[0 ] :0 ;/* bits */ + + ret = s->insn_bits (dev, s, &_insn, _data); +if (ret <0 ) +return ret; - ret = s->insn_bits (dev, s, &_insn, _data); -if (ret <0 ) -return ret; - -if (insn->insn ==INSN_READ ) - data[0 ] = (_data[1 ] >> (chan - base_chan)) &1 ; +if (insn->insn ==INSN_READ ) + data[i] = (_data[1 ] >> (chan - base_chan)) &1 ; + } -return 1 ; +return insn->n; } static int __comedi_device_postconfig_async(struct comedi_device *dev,
Greg Kroah-Hartman
maintainerPATCH 312/457 comedi: pcl726: Prevent invalid irq number
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Edward Adam Davis <[email protected]>
commit 96cb948408b3adb69df7e451ba7da9d21f814d00 upstream.
The reproducer passed in an irq number(0x80008000) that was too large, which triggered the oob.
Added an interrupt number check to prevent users from passing in an irq number that was too large.
If it->options[1] is 31, then 1 << it->options[1] is still invalid because it shifts a 1-bit into the sign bit (which is UB in C). Possible solutions include reducing the upper bound on the it->options[1] value to 30 or lower, or using 1U << it->options[1].
The old code would just not attempt to request the IRQ if the options[1] value were invalid. And it would still configure the device without interrupts even if the call to request_irq returned an error. So it would be better to combine this test with the test below.
--- drivers/comedi/drivers/pcl726.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/comedi/drivers/pcl726.c +2 -1
@@ -328,7 +328,8 @@ static int pcl726_attach(struct comedi_d* Hook up the external trigger source interrupt only if the * user config option is valid and the board supports interrupts. */ -if (it->options[1 ] && (board->irq_mask & (1 << it->options[1 ]))) { +if (it->options[1 ] >0 && it->options[1 ] <16 && + (board->irq_mask & (1U << it->options[1 ]))) { ret =request_irq (it->options[1 ], pcl726_interrupt,0 , dev->board_name, dev);if (ret ==0 ) {
Greg Kroah-Hartman
maintainerPATCH 313/457 comedi: Fix use of uninitialized memory in do_insn_ioctl() and do_insnlist_ioctl()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ian Abbott <[email protected]>
commit 3cd212e895ca2d58963fdc6422502b10dd3966bb upstream.
syzbot reports a KMSAN kernel-infoleak in do_insn_ioctl(). A kernel buffer is allocated to hold insn->n samples (each of which is an unsigned int). For some instruction types, insn->n samples are copied back to user-space, unless an error code is being returned. The problem is that not all the instruction handlers that need to return data to userspace fill in the whole insn->n samples, so that there is an information leak. There is a similar syzbot report for do_insnlist_ioctl(), although it does not have a reproducer for it at the time of writing.
One culprit is insn_rw_emulate_bits() which is used as the handler for INSN_READ or INSN_WRITE instructions for subdevices that do not have a specific handler for that instruction, but do have an INSN_BITS handler. For INSN_READ it only fills in at most 1 sample, so if insn->n is greater than 1, the remaining insn->n - 1 samples copied to userspace will be uninitialized kernel data.
Another culprit is vm80xx_ai_insn_read() in the "vm80xx" driver. It never returns an error, even if it fails to fill the buffer.
Fix it in do_insn_ioctl() and do_insnlist_ioctl() by making sure that uninitialized parts of the allocated buffer are zeroed before handling each instruction.
Thanks to Arnaud Lecomte for their fix to do_insn_ioctl(). That fix replaced the call to kmalloc_array() with kcalloc(), but it is not always necessary to clear the whole buffer.
--- drivers/comedi/comedi_fops.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/comedi/comedi_fops.c +5 -0
@@ -1587,6 +1587,9 @@ static int do_insnlist_ioctl(struct comememset (&data[n],0 , (MIN_SAMPLES - n) *sizeof (unsigned int )); } + }else { + memset(data, 0, max_t(unsigned int, n, MIN_SAMPLES) * +sizeof (unsigned int )); } ret =parse_insn (dev, insns + i, data, file);if (ret <0 )
@@ -1670,6 +1673,8 @@ static int do_insn_ioctl(struct comedi_dmemset (&data[insn->n],0 , (MIN_SAMPLES - insn->n) *sizeof (unsigned int )); } + }else { +memset (data,0 , n_data *sizeof (unsigned int )); } ret =parse_insn (dev, insn, data, file);if (ret <0 )
Greg Kroah-Hartman
maintainerPATCH 314/457 usb: core: hcd: fix accessing unmapped memory in SINGLE_STEP_SET_FEATURE test
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Xu Yang <[email protected]>
commit 8fe06185e11ae753414aa6117f0e798aa77567ff upstream.
The USB core will unmap urb->transfer_dma after SETUP stage completes. Then the USB controller will access unmapped memory when it received device descriptor. If iommu is equipped, the entire test can't be completed due to the memory accessing is blocked.
Fix it by calling map_urb_for_dma() again for IN stage. To reduce redundant map for urb->transfer_buffer, this will also set URB_NO_TRANSFER_DMA_MAP flag before first map_urb_for_dma() to skip dma map for urb->transfer_buffer and clear URB_NO_TRANSFER_DMA_MAP flag before second map_urb_for_dma().
--- drivers/usb/core/hcd.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-)
drivers/usb/core/hcd.c +7 -1
@@ -2151,7 +2151,7 @@ static struct urb *request_single_step_s urb->complete = usb_ehset_completion; urb->status = -EINPROGRESS ; urb->actual_length =0 ; - urb->transfer_flags =URB_DIR_IN ; + urb->transfer_flags =URB_DIR_IN |URB_NO_TRANSFER_DMA_MAP ;usb_get_urb (urb);atomic_inc (&urb->use_count);atomic_inc (&urb->dev->urbnum);
@@ -2215,9 +2215,15 @@ int ehset_single_step_set_feature(struct/* Complete remaining DATA and STATUS stages using the same URB */ urb->status = -EINPROGRESS ; + urb->transfer_flags &= ~URB_NO_TRANSFER_DMA_MAP ;usb_get_urb (urb);atomic_inc (&urb->use_count);atomic_inc (&urb->dev->urbnum); +if (map_urb_for_dma (hcd, urb,GFP_KERNEL )) { +usb_put_urb (urb); + goto out1; + } + retval = hcd->driver->submit_single_step_set_feature (hcd, urb,0 );if (!retval && !wait_for_completion_timeout (&done,msecs_to_jiffies (2000 ))) {
Greg Kroah-Hartman
maintainerPATCH 315/457 usb: renesas-xhci: Fix External ROM access timeouts
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Marek Vasut <[email protected]>
commit f9420f4757752f056144896024d5ea89e5a611f1 upstream.
Increase the External ROM access timeouts to prevent failures during programming of External SPI EEPROM chips. The current timeouts are too short for some SPI EEPROMs used with uPD720201 controllers.
The current timeout for Chip Erase in renesas_rom_erase() is 100 ms , the current timeout for Sector Erase issued by the controller before Page Program in renesas_fw_download_image() is also 100 ms. Neither timeout is sufficient for e.g. the Macronix MX25L5121E or MX25V5126F.
MX25L5121E reference manual [1] page 35 section "ERASE AND PROGRAMMING PERFORMANCE" and page 23 section "Table 8. AC CHARACTERISTICS (Temperature = 0°C to 70°C for Commercial grade, VCC = 2.7V ~ 3.6V)" row "tCE" indicate that the maximum time required for Chip Erase opcode to complete is 2 s, and for Sector Erase it is 300 ms .
MX25V5126F reference manual [2] page 47 section "13. ERASE AND PROGRAMMING PERFORMANCE (2.3V - 3.6V)" and page 42 section "Table 8. AC CHARACTERISTICS (Temperature = -40°C to 85°C for Industrial grade, VCC = 2.3V - 3.6V)" row "tCE" indicate that the maximum time required for Chip Erase opcode to complete is 3.2 s, and for Sector Erase it is 400 ms .
Update the timeouts such, that Chip Erase timeout is set to 5 seconds, and Sector Erase timeout is set to 500 ms. Such lengthy timeouts ought to be sufficient for majority of SPI EEPROM chips.
[1] https://www.macronix.com/Lists/Datasheet/Attachments/8634/MX25L5121E,%203V,%20512Kb,%20v1.3.pdf
[2] https://www.macronix.com/Lists/Datasheet/Attachments/8750/MX25V5126F,%202.5V,%20512Kb,%20v1.1.pdf
--- drivers/usb/host/xhci-pci-renesas.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
drivers/usb/host/xhci-pci-renesas.c +4 -3
@@ -47,8 +47,9 @@#define RENESAS_ROM_ERASE_MAGIC 0x5A65726F#define RENESAS_ROM_WRITE_MAGIC 0x53524F4D -#define RENESAS_RETRY 10000 -#define RENESAS_DELAY 10 +#define RENESAS_RETRY 50000/* 50000 * RENESAS_DELAY ~= 500ms */ +#define RENESAS_CHIP_ERASE_RETRY 500000/* 500000 * RENESAS_DELAY ~= 5s */ +#define RENESAS_DELAY 10#define RENESAS_FW_NAME "renesas_usb_fw.mem"
@@ -407,7 +408,7 @@ static void renesas_rom_erase(struct pci/* sleep a bit while ROM is erased */ msleep (20 ); -for (i =0 ; i <RENESAS_RETRY ; i++) { +for (i =0 ; i <RENESAS_CHIP_ERASE_RETRY ; i++) { retval =pci_read_config_byte (pdev,RENESAS_ROM_STATUS , &status); status &=RENESAS_ROM_STATUS_ERASE ;
Greg Kroah-Hartman
maintainerPATCH 316/457 USB: storage: Add unusual-devs entry for Novatek NTK96550-based camera
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Mael GUERIN <[email protected]>
commit 6ca8af3c8fb584f3424a827f554ff74f898c27cd upstream.
Add the US_FL_BULK_IGNORE_TAG quirk for Novatek NTK96550-based camera to fix USB resets after sending SCSI vendor commands due to CBW and CSW tags difference, leading to undesired slowness while communicating with the device.
Please find below the copy of /sys/kernel/debug/usb/devices with my device plugged in (listed as TechSys USB mass storage here, the underlying chipset being the Novatek NTK96550-based camera):
T: Bus=03 Lev=01 Prnt=01 Port=00 Cnt=01 Dev#= 3 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0603 ProdID=8611 Rev= 0.01 S: Manufacturer=TechSys S: Product=USB Mass Storage S: SerialNumber=966110000000100 C:* #Ifs= 1 Cfg#= 1 Atr=c0 MxPwr=100mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=usb-storage E: Ad=81(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=02(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 7 +++++++ 1 file changed, 7 insertions(+)
drivers/usb/storage/unusual_devs.h +7 -0
@@ -934,6 +934,13 @@ UNUSUAL_DEV( 0x05e3, 0x0723, 0x9451, 0x USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_SANE_SENSE ), +/* Added by Maël GUERIN <[email protected]> */ +UNUSUAL_DEV (0x0603 ,0x8611 ,0x0000 ,0xffff , +"Novatek" , +"NTK96550-based camera" , +USB_SC_SCSI ,USB_PR_BULK ,NULL , + US_FL_BULK_IGNORE_TAG ), +/* * Reported by Hanno Boeck <[email protected]> * Taken from the Lycoris Kernel
Greg Kroah-Hartman
maintainerPATCH 317/457 usb: storage: realtek_cr: Use correct byte order for bcs->Residue
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thorsten Blum <[email protected]>
commit 98da66a70ad2396e5a508c4245367797ebc052ce upstream.
Since 'bcs->Residue' has the data type '__le32', convert it to the correct byte order of the CPU using this driver when assigning it to the local variable 'residue'.
--- drivers/usb/storage/realtek_cr.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/usb/storage/realtek_cr.c +1 -1
@@ -252,7 +252,7 @@ static int rts51x_bulk_transport(structreturn USB_STOR_TRANSPORT_ERROR ; } - residue = bcs->Residue; + residue =le32_to_cpu (bcs->Residue);if (bcs->Tag != us->tag)return USB_STOR_TRANSPORT_ERROR ;
Greg Kroah-Hartman
maintainerPATCH 318/457 USB: storage: Ignore driver CD mode for Realtek multi-mode Wi-Fi dongles
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zenm Chen <[email protected]>
commit a3dc32c635bae0ae569f489e00de0e8f015bfc25 upstream.
Many Realtek USB Wi-Fi dongles released in recent years have two modes:
one is driver CD mode which has Windows driver onboard, another one is Wi-Fi mode. Add the US_FL_IGNORE_DEVICE quirk for these multi-mode devices. Otherwise, usb_modeswitch may fail to switch them to Wi-Fi mode.
Currently there are only two USB IDs known to be used by these multi-mode Wi-Fi dongles: 0bda:1a2b and 0bda:a192.
Information about Mercury MW310UH in /sys/kernel/debug/usb/devices.
T: Bus=02 Lev=01 Prnt=01 Port=01 Cnt=01 Dev#= 12 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=a192 Rev= 2.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=80 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=8a(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=0b(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
Information about D-Link AX9U rev. A1 in /sys/kernel/debug/usb/devices.
T: Bus=03 Lev=01 Prnt=01 Port=02 Cnt=01 Dev#= 55 Spd=480 MxCh= 0 D: Ver= 2.00 Cls=00(>ifc ) Sub=00 Prot=00 MxPS=64 #Cfgs= 1 P: Vendor=0bda ProdID=1a2b Rev= 0.00 S: Manufacturer=Realtek S: Product=DISK C:* #Ifs= 1 Cfg#= 1 Atr=e0 MxPwr=500mA I:* If#= 0 Alt= 0 #EPs= 2 Cls=08(stor.) Sub=06 Prot=50 Driver=(none) E: Ad=84(I) Atr=02(Bulk) MxPS= 512 Ivl=0ms E: Ad=05(O) Atr=02(Bulk) MxPS= 512 Ivl=0ms
--- drivers/usb/storage/unusual_devs.h | 22 ++++++++++++++++++++++ 1 file changed, 22 insertions(+)
drivers/usb/storage/unusual_devs.h +22 -0
@@ -1501,6 +1501,28 @@ UNUSUAL_DEV( 0x0bc2, 0x3332, 0x0000, 0x9 USB_SC_DEVICE, USB_PR_DEVICE, NULL, US_FL_NO_WP_DETECT ), +/* +* Reported by Zenm Chen <[email protected]> +* Ignore driver CD mode, otherwise usb_modeswitch may fail to switch +* the device into Wi-Fi mode. +*/ +UNUSUAL_DEV (0x0bda ,0x1a2b ,0x0000 ,0xffff , +"Realtek" , +"DISK" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_IGNORE_DEVICE ), + +/* +* Reported by Zenm Chen <[email protected]> +* Ignore driver CD mode, otherwise usb_modeswitch may fail to switch +* the device into Wi-Fi mode. +*/ +UNUSUAL_DEV (0x0bda ,0xa192 ,0x0000 ,0xffff , +"Realtek" , +"DISK" , +USB_SC_DEVICE ,USB_PR_DEVICE ,NULL , +US_FL_IGNORE_DEVICE ), + UNUSUAL_DEV( 0x0d49, 0x7310, 0x0000, 0x9999, "Maxtor", "USB to SATA",
Greg Kroah-Hartman
maintainerPATCH 319/457 usb: typec: maxim_contaminant: disable low power mode when reading comparator values
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Sunil Dhamne <[email protected]>
commit cabb6c5f4d9e7f49bdf8c0a13c74bd93ee35f45a upstream.
Low power mode is enabled when reading CC resistance as part of max_contaminant_read_resistance_kohm() and left in that state. However, it's supposed to work with 1uA current source. To read CC comparator values current source is changed to 80uA. This causes a storm of CC interrupts as it (falsely) detects a potential contaminant. To prevent this, disable low power mode current sourcing before reading comparator values.
--- drivers/usb/typec/tcpm/maxim_contaminant.c | 5 +++++ drivers/usb/typec/tcpm/tcpci_maxim.h | 1 + 2 files changed, 6 insertions(+)
drivers/usb/typec/tcpm/maxim_contaminant.c +5 -0
@@ -188,6 +188,11 @@ static int max_contaminant_read_comparatif (ret <0 )return ret; +/* Disable low power mode */ + ret =regmap_update_bits (regmap,TCPC_VENDOR_CC_CTRL2 ,CCLPMODESEL , +FIELD_PREP (CCLPMODESEL , +LOW_POWER_MODE_DISABLE )); +/* Sleep to allow comparators settle */ usleep_range (5000 ,6000 ); ret =regmap_update_bits (regmap,TCPC_TCPC_CTRL ,TCPC_TCPC_CTRL_ORIENTATION ,PLUG_ORNT_CC1 );
drivers/usb/typec/tcpm/tcpci_maxim.h +1 -0
@@ -21,6 +21,7 @@#define CCOVPDIS BIT(6)#define SBURPCTRL BIT(5)#define CCLPMODESEL GENMASK(4, 3) +#define LOW_POWER_MODE_DISABLE 0#define ULTRA_LOW_POWER_MODE 1#define CCRPCTRL GENMASK(2, 0)#define UA_1_SRC 1
Greg Kroah-Hartman
maintainerPATCH 320/457 usb: typec: maxim_contaminant: re-enable cc toggle if cc is open and port is clean
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Amit Sunil Dhamne <[email protected]>
commit a381c6d6f646226924809d0ad01a9465786da463 upstream.
Presently in max_contaminant_is_contaminant() if there's no contaminant detected previously, CC is open & stopped toggling and no contaminant is currently present, TCPC.RC would be programmed to do DRP toggling. However, it didn't actively look for a connection. This would lead to Type-C not detect *any* new connections. Hence, in the above situation, re-enable toggling & program TCPC to look for a new connection.
Also, return early if TCPC was looking for connection as this indicates TCPC has neither detected a potential connection nor a change in contaminant state.
In addition, once dry detection is complete (port is dry), restart toggling.
--- drivers/usb/typec/tcpm/maxim_contaminant.c | 53 +++++++++++++++++++++++++++++ 1 file changed, 53 insertions(+)
drivers/usb/typec/tcpm/maxim_contaminant.c +53 -0
@@ -329,6 +329,39 @@ static int max_contaminant_enable_dry_dereturn 0 ; } +static int max_contaminant_enable_toggling (struct max_tcpci_chip *chip) +{ +struct regmap *regmap = chip->data.regmap; +int ret; + +/* Disable dry detection if enabled. */ + ret =regmap_update_bits (regmap,TCPC_VENDOR_CC_CTRL2 ,CCLPMODESEL , +FIELD_PREP (CCLPMODESEL , +LOW_POWER_MODE_DISABLE )); +if (ret) +return ret; + + ret =regmap_update_bits (regmap,TCPC_VENDOR_CC_CTRL1 ,CCCONNDRY ,0 ); +if (ret) +return ret; + + ret =max_tcpci_write8 (chip,TCPC_ROLE_CTRL ,TCPC_ROLE_CTRL_DRP | +FIELD_PREP (TCPC_ROLE_CTRL_CC1 , +TCPC_ROLE_CTRL_CC_RD ) | +FIELD_PREP (TCPC_ROLE_CTRL_CC2 , +TCPC_ROLE_CTRL_CC_RD )); +if (ret) +return ret; + + ret =regmap_update_bits (regmap,TCPC_TCPC_CTRL , +TCPC_TCPC_CTRL_EN_LK4CONN_ALRT , +TCPC_TCPC_CTRL_EN_LK4CONN_ALRT ); +if (ret) +return ret; + +return max_tcpci_write8 (chip,TCPC_COMMAND ,TCPC_CMD_LOOK4CONNECTION ); +} +bool max_contaminant_is_contaminant (struct max_tcpci_chip *chip,bool disconnect_while_debounce,bool *cc_handled) {
@@ -345,6 +378,12 @@ bool max_contaminant_is_contaminant(struif (ret <0 )return false; +if (cc_status &TCPC_CC_STATUS_TOGGLING ) { +if (chip->contaminant_state ==DETECTED ) +return true; +return false; + } +if (chip->contaminant_state ==NOT_DETECTED || chip->contaminant_state ==SINK ) {if (!disconnect_while_debounce)msleep (100 );
@@ -377,6 +416,12 @@ bool max_contaminant_is_contaminant(strumax_contaminant_enable_dry_detection (chip);return true; } + + ret =max_contaminant_enable_toggling (chip); +if (ret) +dev_err (chip->dev, +"Failed to enable toggling, ret=%d" , + ret); } }else if (chip->contaminant_state ==DETECTED ) {if (!(cc_status &TCPC_CC_STATUS_TOGGLING )) {
@@ -384,6 +429,14 @@ bool max_contaminant_is_contaminant(struif (chip->contaminant_state ==DETECTED ) {max_contaminant_enable_dry_detection (chip);return true; + }else { + ret =max_contaminant_enable_toggling (chip); +if (ret) { +dev_err (chip->dev, +"Failed to enable toggling, ret=%d" , + ret); +return true; + } } } }
Greg Kroah-Hartman
maintainerPATCH 321/457 usb: xhci: Fix slot_id resource race conflict
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Weitao Wang <[email protected]>
commit 2eb03376151bb8585caa23ed2673583107bb5193 upstream.
xHC controller may immediately reuse a slot_id after it's disabled, giving it to a new enumerating device before the xhci driver freed all resources related to the disabled device.
In such a scenario, device-A with slot_id equal to 1 is disconnecting while device-B is enumerating, device-B will fail to enumerate in the follow sequence.
1.[device-A] send disable slot command
2.[device-B] send enable slot command
3.[device-A] disable slot command completed and wakeup waiting thread 4.[device-B] enable slot command completed with slot_id equal to 1 and
wakeup waiting thread
5.[device-B] driver checks that slot_id is still in use (by device-A) in
xhci_alloc_virt_device, and fail to enumerate due to this conflict
6.[device-A] xhci->devs[slot_id] set to NULL in xhci_free_virt_device
To fix driver's slot_id resources conflict, clear xhci->devs[slot_id] and xhci->dcbba->dev_context_ptrs[slot_id] pointers in the interrupt context when disable slot command completes successfully. Simultaneously, adjust function xhci_free_virt_device to accurately handle device release.
[minor smatch warning and commit message fix -Mathias]
--- drivers/usb/host/xhci-hub.c | 3 +-- drivers/usb/host/xhci-mem.c | 22 +++++++++++----------- drivers/usb/host/xhci-ring.c | 9 +++++++-- drivers/usb/host/xhci.c | 21 ++++++++++++++------- drivers/usb/host/xhci.h | 3 ++- 5 files changed, 35 insertions(+), 23 deletions(-)
drivers/usb/host/xhci-hub.c +1 -2
@@ -704,8 +704,7 @@ static int xhci_enter_test_mode(struct xif (!xhci->devs[i])continue ; - retval =xhci_disable_slot (xhci, i); -xhci_free_virt_device (xhci, i); + retval =xhci_disable_and_free_slot (xhci, i);if (retval)xhci_err (xhci,"Failed to disable slot %d, %d. Enter test mode anyway\n" , i, retval);
drivers/usb/host/xhci-mem.c +11 -11
@@ -865,21 +865,20 @@ free_tts:* will be manipulated by the configure endpoint, allocate device, or update * hub functions while this function is removing the TT entries from the list. */ -void xhci_free_virt_device (struct xhci_hcd *xhci,int slot_id) +void xhci_free_virt_device (struct xhci_hcd *xhci,struct xhci_virt_device *dev, +int slot_id) { -struct xhci_virt_device *dev;int i;int old_active_eps =0 ;/* Slot ID 0 is reserved */ -if (slot_id ==0 || !xhci->devs[slot_id]) +if (slot_id ==0 || !dev)return ; - dev = xhci->devs[slot_id]; - - xhci->dcbaa->dev_context_ptrs[slot_id] =0 ; -if (!dev) -return ; +/* If device ctx array still points to _this_ device, clear it */ +if (dev->out_ctx && + xhci->dcbaa->dev_context_ptrs[slot_id] ==cpu_to_le64 (dev->out_ctx->dma)) + xhci->dcbaa->dev_context_ptrs[slot_id] =0 ;trace_xhci_free_virt_device (dev);
@@ -920,8 +919,9 @@ void xhci_free_virt_device(struct xhci_h dev->udev->slot_id =0 ;if (dev->rhub_port && dev->rhub_port->slot_id == slot_id) dev->rhub_port->slot_id =0 ; -kfree (xhci->devs[slot_id]); - xhci->devs[slot_id] =NULL ; +if (xhci->devs[slot_id] == dev) + xhci->devs[slot_id] =NULL ; +kfree (dev); }/*
@@ -962,7 +962,7 @@ static void xhci_free_virt_devices_depth out:/* we are now at a leaf device */ xhci_debugfs_remove_slot (xhci, slot_id); -xhci_free_virt_device (xhci, slot_id); +xhci_free_virt_device (xhci, vdev, slot_id); } int xhci_alloc_virt_device(struct xhci_hcd *xhci, int slot_id,
drivers/usb/host/xhci-ring.c +7 -2
@@ -1592,7 +1592,8 @@ static void xhci_handle_cmd_enable_slot( command->slot_id =0 ; } -static void xhci_handle_cmd_disable_slot (struct xhci_hcd *xhci,int slot_id) +static void xhci_handle_cmd_disable_slot (struct xhci_hcd *xhci,int slot_id, +u32 cmd_comp_code) {struct xhci_virt_device *virt_dev;struct xhci_slot_ctx *slot_ctx;
@@ -1607,6 +1608,10 @@ static void xhci_handle_cmd_disable_slotif (xhci->quirks &XHCI_EP_LIMIT_QUIRK )/* Delete default control endpoint resources */ xhci_free_device_endpoint_resources (xhci, virt_dev, true); +if (cmd_comp_code ==COMP_SUCCESS ) { + xhci->dcbaa->dev_context_ptrs[slot_id] =0 ; + xhci->devs[slot_id] =NULL ; + } }static void xhci_handle_cmd_config_ep (struct xhci_hcd *xhci,int slot_id)
@@ -1856,7 +1861,7 @@ static void handle_cmd_completion(structxhci_handle_cmd_enable_slot (slot_id, cmd, cmd_comp_code);break ;case TRB_DISABLE_SLOT : -xhci_handle_cmd_disable_slot (xhci, slot_id); +xhci_handle_cmd_disable_slot (xhci, slot_id, cmd_comp_code);break ;case TRB_CONFIG_EP :if (!cmd->completion)
drivers/usb/host/xhci.c +14 -7
@@ -3932,8 +3932,7 @@ static int xhci_discover_or_reset_device* Obtaining a new device slot to inform the xHCI host that * the USB device has been reset. */ - ret =xhci_disable_slot (xhci, udev->slot_id); -xhci_free_virt_device (xhci, udev->slot_id); + ret =xhci_disable_and_free_slot (xhci, udev->slot_id);if (!ret) { ret =xhci_alloc_dev (hcd, udev);if (ret ==1 )
@@ -4090,7 +4089,7 @@ static void xhci_free_dev(struct usb_hcdxhci_disable_slot (xhci, udev->slot_id);spin_lock_irqsave (&xhci->lock, flags); -xhci_free_virt_device (xhci, udev->slot_id); +xhci_free_virt_device (xhci, virt_dev, udev->slot_id);spin_unlock_irqrestore (&xhci->lock, flags); }
@@ -4139,6 +4138,16 @@ int xhci_disable_slot(struct xhci_hcd *xreturn 0 ; } +int xhci_disable_and_free_slot (struct xhci_hcd *xhci,u32 slot_id) +{ +struct xhci_virt_device *vdev = xhci->devs[slot_id]; +int ret; + + ret =xhci_disable_slot (xhci, slot_id); +xhci_free_virt_device (xhci, vdev, slot_id); +return ret; +} +/* * Checks if we have enough host controller resources for the default control * endpoint.
@@ -4245,8 +4254,7 @@ int xhci_alloc_dev(struct usb_hcd *hcd,return 1 ; disable_slot: -xhci_disable_slot (xhci, udev->slot_id); -xhci_free_virt_device (xhci, udev->slot_id); +xhci_disable_and_free_slot (xhci, udev->slot_id);return 0 ; }
@@ -4382,8 +4390,7 @@ static int xhci_setup_device(struct usb_dev_warn (&udev->dev,"Device not responding to setup %s.\n" , act);mutex_unlock (&xhci->mutex); - ret =xhci_disable_slot (xhci, udev->slot_id); -xhci_free_virt_device (xhci, udev->slot_id); + ret =xhci_disable_and_free_slot (xhci, udev->slot_id);if (!ret) {if (xhci_alloc_dev (hcd, udev) ==1 )xhci_setup_addressable_virt_dev (xhci, udev);
drivers/usb/host/xhci.h +2 -1
@@ -1791,7 +1791,7 @@ void xhci_dbg_trace(struct xhci_hcd *xhc/* xHCI memory management */ void xhci_mem_cleanup (struct xhci_hcd *xhci);int xhci_mem_init (struct xhci_hcd *xhci,gfp_t flags); -void xhci_free_virt_device (struct xhci_hcd *xhci,int slot_id); +void xhci_free_virt_device (struct xhci_hcd *xhci,struct xhci_virt_device *dev,int slot_id);int xhci_alloc_virt_device (struct xhci_hcd *xhci,int slot_id,struct usb_device *udev,gfp_t flags);int xhci_setup_addressable_virt_dev (struct xhci_hcd *xhci,struct usb_device *udev); void xhci_copy_ep0_dequeue_into_input_ctx(struct xhci_hcd *xhci,
@@ -1888,6 +1888,7 @@ void xhci_reset_bandwidth(struct usb_hcdint xhci_update_hub_device (struct usb_hcd *hcd,struct usb_device *hdev,struct usb_tt *tt,gfp_t mem_flags);int xhci_disable_slot (struct xhci_hcd *xhci,u32 slot_id); +int xhci_disable_and_free_slot (struct xhci_hcd *xhci,u32 slot_id);int xhci_ext_cap_init (struct xhci_hcd *xhci);int xhci_suspend (struct xhci_hcd *xhci,bool do_wakeup);
Greg Kroah-Hartman
maintainerPATCH 322/457 usb: xhci: fix host not responding after suspend and resume
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Neronin <[email protected]>
commit ff9a09b3e09c7b794b56f2f5858f5ce42ba46cb3 upstream.
Partially revert commit e1db856bd288 ("usb: xhci: remove '0' write to write-1-to-clear register") because the patch cleared the Interrupt Pending bit during interrupt enabling and disabling. The Interrupt Pending bit should only be cleared when the driver has handled the interrupt.
Ideally, all interrupts should be handled before disabling the interrupt; consequently, no interrupt should be pending when enabling the interrupt. For this reason, keep the debug message informing if an interrupt is still pending when an interrupt is disabled.
Because the Interrupt Pending bit is write-1-to-clear, writing '0' to it ensures that the state does not change.
--- drivers/usb/host/xhci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/host/xhci.c +2 -0
@@ -309,6 +309,7 @@ int xhci_enable_interrupter(struct xhci_interrupter *ir)return -EINVAL ; iman =readl (&ir->ir_set->iman); + iman &= ~IMAN_IP ; iman |=IMAN_IE ;writel (iman, &ir->ir_set->iman);
@@ -325,6 +326,7 @@ int xhci_disable_interrupter(struct xhci_hcd *xhci, struct xhci_interrupter *ir)return -EINVAL ; iman =readl (&ir->ir_set->iman); + iman &= ~IMAN_IP ; iman &= ~IMAN_IE ;writel (iman, &ir->ir_set->iman);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 323/457 usb: dwc3: Ignore late xferNotReady event to prevent halt timeout
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kuen-Han Tsai <[email protected]>
commit 58577118cc7cec9eb7c1836bf88f865ff2c5e3a3 upstream.
During a device-initiated disconnect, the End Transfer command resets the event filter, allowing a new xferNotReady event to be generated before the controller is fully halted. Processing this late event incorrectly triggers a Start Transfer, which prevents the controller from halting and results in a DSTS.DEVCTLHLT bit polling timeout.
Ignore the late xferNotReady event if the controller is already in a disconnected state.
--- drivers/usb/dwc3/gadget.c | 9 +++++++++ 1 file changed, 9 insertions(+)
drivers/usb/dwc3/gadget.c +9 -0
@@ -3779,6 +3779,15 @@ static void dwc3_gadget_endpoint_transfestatic void dwc3_gadget_endpoint_transfer_not_ready (struct dwc3_ep *dep,const struct dwc3_event_depevt *event) { +/* +* During a device-initiated disconnect, a late xferNotReady event can +* be generated after the End Transfer command resets the event filter, +* but before the controller is halted. Ignore it to prevent a new +* transfer from starting. +*/ +if (!dep->dwc->connected) +return ; +dwc3_gadget_endpoint_frame_from_event (dep, event);/*
Greg Kroah-Hartman
maintainerPATCH 324/457 usb: dwc3: Remove WARN_ON for device endpoint command timeouts
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Selvarasu Ganesan <[email protected]>
commit 45eae113dccaf8e502090ecf5b3d9e9b805add6f upstream.
This commit addresses a rarely observed endpoint command timeout which causes kernel panic due to warn when 'panic_on_warn' is enabled and unnecessary call trace prints when 'panic_on_warn' is disabled. It is seen during fast software-controlled connect/disconnect testcases. The following is one such endpoint command timeout that we observed:
1. Connect
=======
->dwc3_thread_interrupt
->dwc3_ep0_interrupt
->configfs_composite_setup
->composite_setup
->usb_ep_queue
->dwc3_gadget_ep0_queue
->__dwc3_gadget_ep0_queue
->__dwc3_ep0_do_control_data
->dwc3_send_gadget_ep_cmd2. Disconnect
==========
->dwc3_thread_interrupt
->dwc3_gadget_disconnect_interrupt
->dwc3_ep0_reset_state
->dwc3_ep0_end_control_data
->dwc3_send_gadget_ep_cmd
In the issue scenario, in Exynos platforms, we observed that control transfers for the previous connect have not yet been completed and end transfer command sent as a part of the disconnect sequence and processing of USB_ENDPOINT_HALT feature request from the host timeout. This maybe an expected scenario since the controller is processing EP commands sent as a part of the previous connect. It maybe better to remove WARN_ON in all places where device endpoint commands are sent to avoid unnecessary kernel panic due to warn.
--- drivers/usb/dwc3/ep0.c | 20 ++++++++++++++++---- drivers/usb/dwc3/gadget.c | 10 ++++++++-- 2 files changed, 24 insertions(+), 6 deletions(-)
drivers/usb/dwc3/ep0.c +16 -4
@@ -288,7 +288,9 @@ void dwc3_ep0_out_start(struct dwc3 *dwcdwc3_ep0_prepare_one_trb (dep, dwc->ep0_trb_addr,8 ,DWC3_TRBCTL_CONTROL_SETUP , false); ret =dwc3_ep0_start_trans (dep); -WARN_ON (ret <0 ); +if (ret <0 ) +dev_err (dwc->dev,"ep0 out start transfer failed: %d\n" , ret); +for (i =2 ; i <DWC3_ENDPOINTS_NUM ; i++) {struct dwc3_ep *dwc3_ep;
@@ -1061,7 +1063,9 @@ static void __dwc3_ep0_do_control_data(s ret =dwc3_ep0_start_trans (dep); } -WARN_ON (ret <0 ); +if (ret <0 ) +dev_err (dwc->dev, +"ep0 data phase start transfer failed: %d\n" , ret); }static int dwc3_ep0_start_control_status (struct dwc3_ep *dep)
@@ -1078,7 +1082,12 @@ static int dwc3_ep0_start_control_statusstatic void __dwc3_ep0_do_control_status (struct dwc3 *dwc,struct dwc3_ep *dep) { -WARN_ON (dwc3_ep0_start_control_status (dep)); +int ret; + + ret =dwc3_ep0_start_control_status (dep); +if (ret) +dev_err (dwc->dev, +"ep0 status phase start transfer failed: %d\n" , ret); } static void dwc3_ep0_do_control_status(struct dwc3 *dwc,
@@ -1121,7 +1130,10 @@ void dwc3_ep0_end_control_data(struct dw cmd |=DWC3_DEPCMD_PARAM (dep->resource_index);memset (¶ms,0 ,sizeof (params)); ret =dwc3_send_gadget_ep_cmd (dep, cmd, ¶ms); -WARN_ON_ONCE (ret); +if (ret) +dev_err_ratelimited (dwc->dev, +"ep0 data phase end transfer failed: %d\n" , ret); + dep->resource_index =0 ; }
drivers/usb/dwc3/gadget.c +8 -2
@@ -1774,7 +1774,11 @@ static int __dwc3_stop_active_transfer(s dep->flags |=DWC3_EP_DELAY_STOP ;return 0 ; } -WARN_ON_ONCE (ret); + +if (ret) +dev_err_ratelimited (dep->dwc->dev, +"end transfer failed: %d\n" , ret); + dep->resource_index =0 ;if (!interrupt)
@@ -4050,7 +4054,9 @@ static void dwc3_clear_stall_all_ep(stru dep->flags &= ~DWC3_EP_STALL ; ret =dwc3_send_clear_stall_ep_cmd (dep); -WARN_ON_ONCE (ret); +if (ret) +dev_err_ratelimited (dwc->dev, +"failed to clear STALL on %s\n" , dep->name); } }
Greg Kroah-Hartman
maintainerPATCH 325/457 usb: dwc3: pci: add support for the Intel Wildcat Lake
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Heikki Krogerus <[email protected]>
commit 86f390ba59cd8d5755bafe2b163c3e6b89d6bbd9 upstream.
This patch adds the necessary PCI ID for Intel Wildcat Lake devices.
--- drivers/usb/dwc3/dwc3-pci.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/usb/dwc3/dwc3-pci.c +2 -0
@@ -41,6 +41,7 @@#define PCI_DEVICE_ID_INTEL_TGPLP 0xa0ee#define PCI_DEVICE_ID_INTEL_TGPH 0x43ee#define PCI_DEVICE_ID_INTEL_JSP 0x4dee +#define PCI_DEVICE_ID_INTEL_WCL 0x4d7e#define PCI_DEVICE_ID_INTEL_ADL 0x460e#define PCI_DEVICE_ID_INTEL_ADL_PCH 0x51ee#define PCI_DEVICE_ID_INTEL_ADLN 0x465e
@@ -431,6 +432,7 @@ static const struct pci_device_id dwc3_p { PCI_DEVICE_DATA(INTEL, TGPLP, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, TGPH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, JSP, &dwc3_pci_intel_swnode) }, + { PCI_DEVICE_DATA(INTEL, WCL, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADL, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADL_PCH, &dwc3_pci_intel_swnode) }, { PCI_DEVICE_DATA(INTEL, ADLN, &dwc3_pci_intel_swnode) },
Greg Kroah-Hartman
maintainerPATCH 326/457 tracing: Remove unneeded goto out logic
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Steven Rostedt <[email protected]>
[ Upstream commit c89504a703fb779052213add0e8ed642f4a4f1c8 ]
Several places in the trace.c file there's a goto out where the out is simply a return. There's no reason to jump to the out label if it's not doing any more logic but simply returning from the function.
Replace the goto outs with a return and remove the out labels.
Stable-dep-of: 6a909ea83f22 ("tracing: Limit access to parser->buffer when trace_get_user failed")
--- kernel/trace/trace.c | 38 +++++++++++++++----------------------- 1 file changed, 15 insertions(+), 23 deletions(-)
kernel/trace/trace.c +15 -23
@@ -1846,7 +1846,7 @@ int trace_get_user(struct trace_parser * ret =get_user (ch, ubuf++);if (ret) - goto out; +return ret; read++; cnt--;
@@ -1860,7 +1860,7 @@ int trace_get_user(struct trace_parser *while (cnt &&isspace (ch)) { ret =get_user (ch, ubuf++);if (ret) - goto out; +return ret; read++; cnt--; }
@@ -1870,8 +1870,7 @@ int trace_get_user(struct trace_parser */* only spaces were written */ if (isspace (ch) || !ch) { *ppos += read; - ret = read; - goto out; +return read; } }
@@ -1879,13 +1878,12 @@ int trace_get_user(struct trace_parser *while (cnt && !isspace (ch) && ch) {if (parser->idx < parser->size -1 ) parser->buffer[parser->idx++] = ch; -else { - ret = -EINVAL ; - goto out; - } +else +return -EINVAL ; + ret =get_user (ch, ubuf++);if (ret) - goto out; +return ret; read++; cnt--; }
@@ -1900,15 +1898,11 @@ int trace_get_user(struct trace_parser */* Make sure the parsed string always terminates with '\0'. */ parser->buffer[parser->idx] =0 ; }else { - ret = -EINVAL ; - goto out; +return -EINVAL ; } *ppos += read; - ret = read; - -out: -return ret; +return read; }/* TODO add a seq_buf_to_buffer() */
@@ -2410,10 +2404,10 @@ int __init register_tracer(struct tracermutex_unlock (&trace_types_lock);if (ret || !default_bootup_tracer) - goto out_unlock; +return ret;if (strncmp (default_bootup_tracer, type->name,MAX_TRACER_SIZE )) - goto out_unlock; +return 0 ;printk (KERN_INFO "Starting tracer '%s'\n" , type->name);/* Do we want this tracer to start on bootup? */
@@ -2425,8 +2419,7 @@ int __init register_tracer(struct tracer/* disable other selftests, since this will break it. */ disable_tracing_selftest ("running a tracer" ); - out_unlock: -return ret; +return 0 ; }static void tracing_reset_cpu (struct array_buffer *buf,int cpu)
@@ -8954,12 +8947,12 @@ ftrace_trace_snapshot_callback(struct tr out_reg: ret =tracing_arm_snapshot (tr);if (ret <0 ) - goto out; +return ret; ret =register_ftrace_function_probe (glob, tr, ops, count);if (ret <0 )tracing_disarm_snapshot (tr); - out: +return ret <0 ? ret :0 ; }
@@ -11057,7 +11050,7 @@ __init static int tracer_alloc_buffers(vBUILD_BUG_ON (TRACE_ITER_LAST_BIT >TRACE_FLAGS_MAX_SIZE );if (!alloc_cpumask_var (&tracing_buffer_mask,GFP_KERNEL )) - goto out; +return -ENOMEM ;if (!alloc_cpumask_var (&global_trace.tracing_cpumask,GFP_KERNEL )) goto out_free_buffer_mask;
@@ -11175,7 +11168,6 @@ out_free_cpumask:free_cpumask_var (global_trace.tracing_cpumask); out_free_buffer_mask:free_cpumask_var (tracing_buffer_mask); -out:return ret; }
Greg Kroah-Hartman
maintainerPATCH 327/457 tracing: Limit access to parser->buffer when trace_get_user failed
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pu Lehui <[email protected]>
[ Upstream commit 6a909ea83f226803ea0e718f6e88613df9234d58 ]
When the length of the string written to set_ftrace_filter exceeds FTRACE_BUFF_MAX, the following KASAN alarm will be triggered:
BUG: KASAN: slab-out-of-bounds in strsep+0x18c/0x1b0 Read of size 1 at addr ffff0000d00bd5ba by task ash/165 CPU: 1 UID: 0 PID: 165 Comm: ash Not tainted 6.16.0-g6bcdbd62bd56-dirty Hardware name: linux,dummy-virt (DT) Call trace: show_stack+0x34/0x50 (C) dump_stack_lvl+0xa0/0x158 print_address_description.constprop.0+0x88/0x398 print_report+0xb0/0x280 kasan_report+0xa4/0xf0 __asan_report_load1_noabort+0x20/0x30 strsep+0x18c/0x1b0 ftrace_process_regex.isra.0+0x100/0x2d8 ftrace_regex_release+0x484/0x618 __fput+0x364/0xa58 ____fput+0x28/0x40 task_work_run+0x154/0x278 do_notify_resume+0x1f0/0x220 el0_svc+0xec/0xf0 el0t_64_sync_handler+0xa0/0xe8 el0t_64_sync+0x1ac/0x1b0
The reason is that trace_get_user will fail when processing a string longer than FTRACE_BUFF_MAX, but not set the end of parser->buffer to 0. Then an OOB access will be triggered in ftrace_regex_release-> ftrace_process_regex->strsep->strpbrk. We can solve this problem by limiting access to parser->buffer when trace_get_user failed.
--- kernel/trace/trace.c | 18 ++++++++++++------ kernel/trace/trace.h | 8 +++++++- 2 files changed, 19 insertions(+), 7 deletions(-)
kernel/trace/trace.c +12 -6
@@ -1846,7 +1846,7 @@ int trace_get_user(struct trace_parser * ret =get_user (ch, ubuf++);if (ret) -return ret; + goto fail; read++; cnt--;
@@ -1860,7 +1860,7 @@ int trace_get_user(struct trace_parser *while (cnt &&isspace (ch)) { ret =get_user (ch, ubuf++);if (ret) -return ret; + goto fail; read++; cnt--; }
@@ -1878,12 +1878,14 @@ int trace_get_user(struct trace_parser *while (cnt && !isspace (ch) && ch) {if (parser->idx < parser->size -1 ) parser->buffer[parser->idx++] = ch; -else -return -EINVAL ; +else { + ret = -EINVAL ; + goto fail; + } ret =get_user (ch, ubuf++);if (ret) -return ret; + goto fail; read++; cnt--; }
@@ -1898,11 +1900,15 @@ int trace_get_user(struct trace_parser */* Make sure the parsed string always terminates with '\0'. */ parser->buffer[parser->idx] =0 ; }else { -return -EINVAL ; + ret = -EINVAL ; + goto fail; } *ppos += read;return read; +fail: +trace_parser_fail (parser); +return ret; }/* TODO add a seq_buf_to_buffer() */
kernel/trace/trace.h +7 -1
@@ -1292,6 +1292,7 @@ bool ftrace_event_is_function(struct tra*/ struct trace_parser {bool cont; +bool fail;char *buffer;unsigned idx;unsigned size;
@@ -1299,7 +1300,7 @@ struct trace_parser {static inline bool trace_parser_loaded (struct trace_parser *parser) { -return (parser->idx !=0 ); +return !parser->fail && parser->idx !=0 ; }static inline bool trace_parser_cont (struct trace_parser *parser)
@@ -1313,6 +1314,11 @@ static inline void trace_parser_clear(st parser->idx =0 ; } +static inline void trace_parser_fail (struct trace_parser *parser) +{ + parser->fail = true; +} +extern int trace_parser_get_init (struct trace_parser *parser,int size);extern void trace_parser_put (struct trace_parser *parser); extern int trace_get_user(struct trace_parser *parser, const char __user *ubuf,
Greg Kroah-Hartman
maintainerPATCH 328/457 ovl: use I_MUTEX_PARENT when locking parent in ovl_create_temp()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: NeilBrown <[email protected]>
commit 5f1c8965e748c150d580a2ea8fbee1bd80d07a24 upstream.
ovl_create_temp() treats "workdir" as a parent in which it creates an object so it should use I_MUTEX_PARENT.
Prior to the commit identified below the lock was taken by the caller which sometimes used I_MUTEX_PARENT and sometimes used I_MUTEX_NORMAL. The use of I_MUTEX_NORMAL was incorrect but unfortunately copied into ovl_create_temp().
Note to backporters: This patch only applies after the last Fixes given below (post v6.16). To fix the bug in v6.7 and later the inode_lock() call in ovl_copy_up_workdir() needs to nest using I_MUTEX_PARENT.
--- fs/overlayfs/copy_up.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/overlayfs/copy_up.c +1 -1
@@ -779,7 +779,7 @@ static int ovl_copy_up_workdir(struct ovreturn err;ovl_start_write (c->dentry); -inode_lock (wdir); +inode_lock_nested (wdir,I_MUTEX_PARENT ); temp =ovl_create_temp (ofs, c->workdir, &cattr);inode_unlock (wdir);ovl_end_write (c->dentry);
Greg Kroah-Hartman
maintainerPATCH 329/457 PCI: dwc: Ensure that dw_pcie_wait_for_link() waits 100 ms after link up
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Niklas Cassel <[email protected]>
commit 80dc18a0cba8dea42614f021b20a04354b213d86 upstream.
As per PCIe r6.0, sec 6.6.1, a Downstream Port that supports Link speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms after Link training completes before sending a Configuration Request.
Add this delay in dw_pcie_wait_for_link(), after the link is reported as up. The delay will only be performed in the success case where the link came up.
DWC glue drivers that have a link up IRQ (drivers that set use_linkup_irq = true) do not call dw_pcie_wait_for_link(), instead they perform this delay in their threaded link up IRQ handler.
--- drivers/pci/controller/dwc/pcie-designware.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/pci/controller/dwc/pcie-designware.c +8 -0
@@ -714,6 +714,14 @@ int dw_pcie_wait_for_link(struct dw_pciereturn -ETIMEDOUT ; } +/* +* As per PCIe r6.0, sec 6.6.1, a Downstream Port that supports Link +* speeds greater than 5.0 GT/s, software must wait a minimum of 100 ms +* after Link training completes before sending a Configuration Request. +*/ +if (pci->max_link_speed >2 ) +msleep (PCIE_RESET_CONFIG_WAIT_MS ); + offset =dw_pcie_find_capability (pci,PCI_CAP_ID_EXP ); val =dw_pcie_readw_dbi (pci, offset +PCI_EXP_LNKSTA );
Greg Kroah-Hartman
maintainerPATCH 330/457 tls: fix handling of zero-length records on the rx_list
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Kicinski <[email protected]>
commit 62708b9452f8eb77513115b17c4f8d1a22ebf843 upstream.
Each recvmsg() call must process either
- only contiguous DATA records (any number of them)
- one non-DATA record
If the next record has different type than what has already been processed we break out of the main processing loop. If the record has already been decrypted (which may be the case for TLS 1.3 where we don't know type until decryption) we queue the pending record to the rx_list. Next recvmsg() will pick it up from there.
Queuing the skb to rx_list after zero-copy decrypt is not possible, since in that case we decrypted directly to the user space buffer, and we don't have an skb to queue (darg.skb points to the ciphertext skb for access to metadata like length).
Only data records are allowed zero-copy, and we break the processing loop after each non-data record. So we should never zero-copy and then find out that the record type has changed. The corner case we missed is when the initial record comes from rx_list, and it's zero length.
--- net/tls/tls_sw.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-)
net/tls/tls_sw.c +6 -1
@@ -1808,6 +1808,9 @@ int decrypt_skb(struct sock *sk, structreturn tls_decrypt_sg (sk,NULL , sgout, &darg); } +/* All records returned from a recvmsg() call must have the same type. +* 0 is not a valid content type. Use it as "no type reported, yet". +*/ static int tls_record_content_type (struct msghdr *msg,struct tls_msg *tlm,u8 *control) {
@@ -2051,8 +2054,10 @@ int tls_sw_recvmsg(struct sock *sk,if (err <0 ) goto end; +/* process_rx_list() will set @control if it processed any records */ copied = err; -if (len <= copied || (copied && control !=TLS_RECORD_TYPE_DATA ) || rx_more) +if (len <= copied || rx_more || + (control && control !=TLS_RECORD_TYPE_DATA )) goto end; target =sock_rcvlowat (sk, flags &MSG_WAITALL , len);
Greg Kroah-Hartman
maintainerPATCH 331/457 x86/CPU/AMD: Ignore invalid reset reason value
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yazen Ghannam <[email protected]>
commit e9576e078220c50ace9e9087355423de23e25fa5 upstream.
The reset reason value may be "all bits set", e.g. 0xFFFFFFFF. This is a commonly used error response from hardware. This may occur due to a real hardware issue or when running in a VM.
The user will see all reset reasons reported in this case.
Check for an error response value and return early to avoid decoding invalid data.
Also, adjust the data variable type to match the hardware register size.
--- arch/x86/kernel/cpu/amd.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
arch/x86/kernel/cpu/amd.c +6 -2
@@ -1324,8 +1324,8 @@ static const char * const s5_reset_reasostatic __init int print_s5_reset_status_mmio (void ) { -unsigned long value;void __iomem *addr; +u32 value;int i;if (!cpu_feature_enabled (X86_FEATURE_ZEN ))
@@ -1338,12 +1338,16 @@ static __init int print_s5_reset_status_ value =ioread32 (addr);iounmap (addr); +/* Value with "all bits set" is an error response and should be ignored. */ +if (value ==U32_MAX ) +return 0 ; +for (i =0 ; i <ARRAY_SIZE (s5_reset_reason_txt); i++) {if (!(value &BIT (i)))continue ;if (s5_reset_reason_txt[i]) { -pr_info ("x86/amd: Previous system reset reason [0x%08lx]: %s\n" , +pr_info ("x86/amd: Previous system reset reason [0x%08x]: %s\n" , value, s5_reset_reason_txt[i]); } }
Greg Kroah-Hartman
maintainerPATCH 332/457 x86/cpu/hygon: Add missing resctrl_cpu_detect() in bsp_init helper
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Tianxiang Peng <[email protected]>
commit d8df126349dad855cdfedd6bbf315bad2e901c2f upstream.
Since
923f3a2b48bd ("x86/resctrl: Query LLC monitoring properties once during boot")
resctrl_cpu_detect() has been moved from common CPU initialization code to the vendor-specific BSP init helper, while Hygon didn't put that call in their code.
This triggers a division by zero fault during early booting stage on our machines with X86_FEATURE_CQM* supported, where get_rdt_mon_resources() tries to calculate mon_l3_config with uninitialized boot_cpu_data.x86_cache_occ_scale.
Add the missing resctrl_cpu_detect() in the Hygon BSP init helper.
[ bp: Massage commit message. ]
--- arch/x86/kernel/cpu/hygon.c | 3 +++ 1 file changed, 3 insertions(+)
arch/x86/kernel/cpu/hygon.c +3 -0
@@ -16,6 +16,7 @@#include <asm/spec-ctrl.h> #include <asm/delay.h> #include <asm/msr.h> +#include <asm/resctrl.h> #include "cpu.h"
@@ -117,6 +118,8 @@ static void bsp_init_hygon(struct cpuinf x86_amd_ls_cfg_ssbd_mask =1ULL <<10 ; } } + +resctrl_cpu_detect (c); }static void early_init_hygon (struct cpuinfo_x86 *c)
Greg Kroah-Hartman
maintainerPATCH 333/457 i2c: rtl9300: Fix out-of-bounds bug in rtl9300_i2c_smbus_xfer
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Alex Guo <[email protected]>
commit 57f312b955938fc4663f430cb57a71f2414f601b upstream.
The data->block[0] variable comes from user. Without proper check, the variable may be very large to cause an out-of-bounds bug.
Fix this bug by checking the value of data->block[0] first.
1. commit 39244cc75482 ("i2c: ismt: Fix an out-of-bounds bug in ismt_access()")
2. commit 92fbb6d1296f ("i2c: xgene-slimpro: Fix out-of-bounds bug in xgene_slimpro_i2c_xfer()")
--- drivers/i2c/busses/i2c-rtl9300.c | 4 ++++ 1 file changed, 4 insertions(+)
drivers/i2c/busses/i2c-rtl9300.c +4 -0
@@ -281,6 +281,10 @@ static int rtl9300_i2c_smbus_xfer(struct ret =rtl9300_i2c_reg_addr_set (i2c, command,1 );if (ret) goto out_unlock; +if (data->block[0 ] <1 || data->block[0 ] >I2C_SMBUS_BLOCK_MAX ) { + ret = -EINVAL ; + goto out_unlock; + } ret =rtl9300_i2c_config_xfer (i2c, chan, addr, data->block[0 ]);if (ret) goto out_unlock;
Greg Kroah-Hartman
maintainerPATCH 334/457 i2c: rtl9300: Fix multi-byte I2C write
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Harshal Gohel <[email protected]>
commit d67b740b9edfa46310355e2b68050f79ebf05a4c upstream.
The RTL93xx I2C controller has 4 32 bit registers to store the bytes for the upcoming I2C transmission. The first byte is stored in the least-significant byte of the first register. And the last byte in the most significant byte of the last register. A map of the transferred bytes to their order in the registers is:
reg 0: 0x04_03_02_01
reg 1: 0x08_07_06_05
reg 2: 0x0c_0b_0a_09
reg 3: 0x10_0f_0e_0d
The i2c_read() function basically demonstrates how the hardware would pick up bytes from this register set. But the i2c_write() function was just pushing bytes one after another to the least significant byte of a register AFTER shifting the last one to the next more significant byte position.
If you would then have tried to send a buffer with numbers 1-11 using i2c_write(), you would have ended up with following register content:
reg 0: 0x01_02_03_04
reg 1: 0x05_06_07_08
reg 2: 0x00_09_0a_0b
reg 3: 0x00_00_00_00
On the wire, you would then have seen:
Sr Addr Wr [A] 04 A 03 A 02 A 01 A 08 A 07 A 06 A 05 A 0b A 0a A 09 A P
But the correct data transmission was expected to be
Sr Addr Wr [A] 01 A 02 A 03 A 04 A 05 A 06 A 07 A 08 A 09 A 0a A 0b A P
Because of this multi-byte ordering problem, only single byte i2c_write() operations were executed correctly (on the wire).
By shifting the byte directly to the correct end position in the register, it is possible to avoid this incorrect byte ordering and fix multi-byte transmissions.
The second initialization (to 0) of vals was also be dropped because this array is initialized to 0 on the stack by using = {};. This makes the fix a lot more readable.
--- drivers/i2c/busses/i2c-rtl9300.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
drivers/i2c/busses/i2c-rtl9300.c +4 -4
@@ -143,10 +143,10 @@ static int rtl9300_i2c_write(struct rtl9return -EIO ;for (i =0 ; i < len; i++) { -if (i %4 ==0 ) - vals[i/4 ] =0 ; - vals[i/4 ] <<=8 ; - vals[i/4 ] |= buf[i]; +unsigned int shift = (i %4 ) *8 ; +unsigned int reg = i /4 ; + + vals[reg] |= buf[i] << shift; } return regmap_bulk_write(i2c->regmap, i2c->reg_base + RTL9300_I2C_MST_DATA_WORD0,
Greg Kroah-Hartman
maintainerPATCH 335/457 i2c: rtl9300: Increase timeout for transfer polling
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit ceee7776c010c5f09d30985c9e5223b363a6172a upstream.
The timeout for transfers was only set to 2ms. Because of this relatively low limit, 12-byte read operations to the frontend MCU of a RTL8239 POE PSE chip cluster was consistently resulting in a timeout.
The original OpenWrt downstream driver [1] was not using any timeout limit at all. This is also possible by setting the timeout_us parameter of regmap_read_poll_timeout() to 0. But since the driver currently implements the ETIMEDOUT error, it is more sensible to increase the timeout in such a way that communication with the (quite common) Realtek I2C-connected POE management solution is possible.
--- drivers/i2c/busses/i2c-rtl9300.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/i2c/busses/i2c-rtl9300.c +1 -1
@@ -175,7 +175,7 @@ static int rtl9300_i2c_execute_xfer(struct rtl9300_i2c *i2c, char read_write,return ret; ret =regmap_read_poll_timeout (i2c->regmap, i2c->reg_base +RTL9300_I2C_MST_CTRL1 , - val, !(val &RTL9300_I2C_MST_CTRL1_I2C_TRIG ),100 ,2000 ); + val, !(val &RTL9300_I2C_MST_CTRL1_I2C_TRIG ),100 ,100000 );if (ret)return ret;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 336/457 i2c: rtl9300: Add missing count byte for SMBus Block Ops
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sven Eckelmann <[email protected]>
commit 82b350dd8185ce790e61555c436f90b6501af23c upstream.
The expected on-wire format of an SMBus Block Write is
S Addr Wr [A] Comm [A] Count [A] Data [A] Data [A] ... [A] Data [A] P
Everything starting from the Count byte is provided by the I2C subsystem in the array data->block. But the driver was skipping the Count byte (data->block[0]) when sending it to the RTL93xx I2C controller.
Only the actual data could be seen on the wire:
S Addr Wr [A] Comm [A] Data [A] Data [A] ... [A] Data [A] P
This wire format is not SMBus Block Write compatible but matches the format of an I2C Block Write. Simply adding the count byte to the buffer for the I2C controller is enough to fix the transmission.
This also affects read because the I2C controller must receive the count byte + $count * data bytes.
--- drivers/i2c/busses/i2c-rtl9300.c | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-)
drivers/i2c/busses/i2c-rtl9300.c +3 -3
@@ -285,15 +285,15 @@ static int rtl9300_i2c_smbus_xfer(struct ret = -EINVAL ; goto out_unlock; } - ret =rtl9300_i2c_config_xfer (i2c, chan, addr, data->block[0 ]); + ret =rtl9300_i2c_config_xfer (i2c, chan, addr, data->block[0 ] +1 );if (ret) goto out_unlock;if (read_write ==I2C_SMBUS_WRITE ) { - ret =rtl9300_i2c_write (i2c, &data->block[1 ], data->block[0 ]); + ret =rtl9300_i2c_write (i2c, &data->block[0 ], data->block[0 ] +1 );if (ret) goto out_unlock; } - len = data->block[0 ]; + len = data->block[0 ] +1 ;break ;default :
Greg Kroah-Hartman
maintainerPATCH 337/457 devlink: let driver opt out of automatic phys_port_name generation
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jedrzej Jagielski <[email protected]>
[ Upstream commit c5ec7f49b480db0dfc83f395755b1c2a7c979920 ]
Currently when adding devlink port, phys_port_name is automatically generated within devlink port initialization flow. As a result adding devlink port support to driver may result in forced changes of interface names, which breaks already existing network configs.
This is an expected behavior but in some scenarios it would not be preferable to provide such limitation for legacy driver not being able to keep 'pre-devlink' interface name.
Add flag no_phys_port_name to devlink_port_attrs struct which indicates if devlink should not alter name of interface.
--- include/net/devlink.h | 6 +++++- net/devlink/port.c | 2 +- 2 files changed, 6 insertions(+), 2 deletions(-)
include/net/devlink.h +5 -1
@@ -78,6 +78,9 @@ struct devlink_port_pci_sf_attrs {* @flavour: flavour of the port * @split: indicates if this is split port * @splittable: indicates if the port can be split. +* @no_phys_port_name: skip automatic phys_port_name generation; for +* compatibility only, newly added driver/port instance +* should never set this. * @lanes: maximum number of lanes the port supports. 0 value is not passed to netlink. * @switch_id: if the port is part of switch, this is buffer with ID, otherwise this is NULL * @phys: physical port attributes
@@ -87,7 +90,8 @@ struct devlink_port_pci_sf_attrs {*/ struct devlink_port_attrs {u8 split:1 , - splittable:1 ; + splittable:1 , + no_phys_port_name:1 ;u32 lanes;enum devlink_port_flavour flavour;struct netdev_phys_item_id switch_id;
net/devlink/port.c +1 -1
@@ -1519,7 +1519,7 @@ static int __devlink_port_phys_port_namestruct devlink_port_attrs *attrs = &devlink_port->attrs;int n =0 ; -if (!devlink_port->attrs_set) +if (!devlink_port->attrs_set || devlink_port->attrs.no_phys_port_name)return -EOPNOTSUPP ;switch (attrs->flavour) {
Greg Kroah-Hartman
maintainerPATCH 338/457 ixgbe: prevent from unwanted interface name changes
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jedrzej Jagielski <[email protected]>
[ upstream commit e67a0bc3ed4fd8ee1697cb6d937e2b294ec13b5e ]
Users of the ixgbe driver report that after adding devlink support by the commit a0285236ab93 ("ixgbe: add initial devlink support") their configs got broken due to unwanted changes of interface names. It's caused by automatic phys_port_name generation during devlink port initialization flow.
To prevent from that set no_phys_port_name flag for ixgbe devlink ports.
--- drivers/net/ethernet/intel/ixgbe/devlink/devlink.c | 1 + 1 file changed, 1 insertion(+)
drivers/net/ethernet/intel/ixgbe/devlink/devlink.c +1 -0
@@ -543,6 +543,7 @@ int ixgbe_devlink_register_port(struct i attrs.flavour =DEVLINK_PORT_FLAVOUR_PHYSICAL ; attrs.phys.port_number = adapter->hw.bus.func; + attrs.no_phys_port_name =1 ;ixgbe_devlink_set_switch_id (adapter, &attrs.switch_id);devlink_port_attrs_set (devlink_port, &attrs);
Greg Kroah-Hartman
maintainerPATCH 339/457 iio: imu: inv_icm42600: use = { } instead of memset()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Lechner <[email protected]>
[ Upstream commit 352112e2d9aab6a156c2803ae14eb89a9fd93b7d ]
Use { } instead of memset() to zero-initialize stack memory to simplify the code.
Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
--- drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 5 ++--- drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 5 ++--- 2 files changed, 4 insertions(+), 6 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +2 -3
@@ -902,7 +902,8 @@ int inv_icm42600_accel_parse_fifo(structconst int8_t *temp;unsigned int odr;int64_t ts_val; -struct inv_icm42600_accel_buffer buffer; +/* buffer is copied to userspace, zeroing it to avoid any data leak */ +struct inv_icm42600_accel_buffer buffer = { };/* parse all fifo packets */ for (i =0 , no =0 ; i < st->fifo.count; i += size, ++no) {
@@ -921,8 +922,6 @@ int inv_icm42600_accel_parse_fifo(structinv_sensors_timestamp_apply_odr (ts, st->fifo.period, st->fifo.nb.total, no); -/* buffer is copied to userspace, zeroing it to avoid any data leak */ -memset (&buffer,0 ,sizeof (buffer));memcpy (&buffer.accel, accel,sizeof (buffer.accel));/* convert 8 bits FIFO temperature in high resolution format */ buffer.temp = temp ? (*temp *64 ) :0 ;
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +2 -3
@@ -806,7 +806,8 @@ int inv_icm42600_gyro_parse_fifo(structconst int8_t *temp;unsigned int odr;int64_t ts_val; -struct inv_icm42600_gyro_buffer buffer; +/* buffer is copied to userspace, zeroing it to avoid any data leak */ +struct inv_icm42600_gyro_buffer buffer = { };/* parse all fifo packets */ for (i =0 , no =0 ; i < st->fifo.count; i += size, ++no) {
@@ -825,8 +826,6 @@ int inv_icm42600_gyro_parse_fifo(structinv_sensors_timestamp_apply_odr (ts, st->fifo.period, st->fifo.nb.total, no); -/* buffer is copied to userspace, zeroing it to avoid any data leak */ -memset (&buffer,0 ,sizeof (buffer));memcpy (&buffer.gyro, gyro,sizeof (buffer.gyro));/* convert 8 bits FIFO temperature in high resolution format */ buffer.temp = temp ? (*temp *64 ) :0 ;
Greg Kroah-Hartman
maintainerPATCH 340/457 iio: imu: inv_icm42600: Convert to uXX and sXX integer types
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Andy Shevchenko <[email protected]>
[ Upstream commit a4135386fa49c2a170b89296da12c4a3be2089d9 ]
The driver code is full of intXX_t and uintXX_t types which is not the pattern we use in the IIO subsystem. Switch the driver to use kernel internal types for that. No functional changes.
Stable-dep-of: dfdc31e7ccf3 ("iio: imu: inv_icm42600: change invalid data error to -EBUSY")
--- drivers/iio/imu/inv_icm42600/inv_icm42600.h | 8 ++-- drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c | 26 +++++++-------- drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c | 22 ++++++------ drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h | 10 ++--- drivers/iio/imu/inv_icm42600/inv_icm42600_core.c | 6 +-- drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c | 36 ++++++++++----------- drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c | 6 +-- 7 files changed, 57 insertions(+), 57 deletions(-)
drivers/iio/imu/inv_icm42600/inv_icm42600.h +4 -4
@@ -164,11 +164,11 @@ struct inv_icm42600_state {struct inv_icm42600_suspended suspended;struct iio_dev *indio_gyro;struct iio_dev *indio_accel; -uint8_t buffer[2 ]__aligned(IIO_DMA_MINALIGN) ; +u8 buffer[2 ]__aligned(IIO_DMA_MINALIGN) ;struct inv_icm42600_fifo fifo;struct { -int64_t gyro; -int64_t accel; +s64 gyro; +s64 accel; } timestamp; };
@@ -410,7 +410,7 @@ const struct iio_mount_matrix * inv_icm42600_get_mount_matrix(const struct iio_dev *indio_dev, const struct iio_chan_spec *chan); -uint32_t inv_icm42600_odr_to_period (enum inv_icm42600_odr odr); +u32 inv_icm42600_odr_to_period (enum inv_icm42600_odr odr); int inv_icm42600_set_accel_conf(struct inv_icm42600_state *st, struct inv_icm42600_sensor_conf *conf,
drivers/iio/imu/inv_icm42600/inv_icm42600_accel.c +13 -13
@@ -177,7 +177,7 @@ static const struct iio_chan_spec inv_ic*/ struct inv_icm42600_accel_buffer {struct inv_icm42600_fifo_sensor_data accel; -int16_t temp; +s16 temp;aligned_s64 timestamp; };
@@ -241,7 +241,7 @@ out_unlock:static int inv_icm42600_accel_read_sensor (struct iio_dev *indio_dev,struct iio_chan_spec const *chan, -int16_t *val) +s16 *val) {struct inv_icm42600_state *st =iio_device_get_drvdata (indio_dev);struct inv_icm42600_sensor_state *accel_st =iio_priv (indio_dev);
@@ -284,7 +284,7 @@ static int inv_icm42600_accel_read_sensoif (ret) goto exit; - *val = (int16_t )be16_to_cpup (data); + *val = (s16 )be16_to_cpup (data);if (*val ==INV_ICM42600_DATA_INVALID ) ret = -EINVAL ; exit:
@@ -492,11 +492,11 @@ static int inv_icm42600_accel_read_offse int *val, int *val2) { struct device *dev = regmap_get_device(st->map); -int64_t val64; -int32_t bias; +s64 val64; +s32 bias;unsigned int reg; -int16_t offset; -uint8_t data[2 ]; +s16 offset; +u8 data[2 ];int ret;if (chan->type !=IIO_ACCEL )
@@ -550,7 +550,7 @@ static int inv_icm42600_accel_read_offse* result in micro (1000000) * (offset * 5 * 9.806650 * 1000000) / 10000 */ - val64 = (int64_t )offset *5LL *9806650LL ; + val64 = (s64 )offset *5LL *9806650LL ;/* for rounding, add + or - divisor (10000) divided by 2 */ if (val64 >=0 ) val64 +=10000LL /2LL ;
@@ -568,10 +568,10 @@ static int inv_icm42600_accel_write_offs int val, int val2) {struct device *dev =regmap_get_device (st->map); -int64_t val64; -int32_t min, max; +s64 val64; +s32 min, max;unsigned int reg, regval; -int16_t offset; +s16 offset;int ret;if (chan->type !=IIO_ACCEL )
@@ -596,7 +596,7 @@ static int inv_icm42600_accel_write_offs inv_icm42600_accel_calibbias[1 ]; max = inv_icm42600_accel_calibbias[4 ] *1000000L + inv_icm42600_accel_calibbias[5 ]; - val64 = (int64_t )val *1000000LL + (int64_t )val2; + val64 = (s64 )val *1000000LL + (s64 )val2;if (val64 < min || val64 > max)return -EINVAL ;
@@ -671,7 +671,7 @@ static int inv_icm42600_accel_read_raw(s int *val, int *val2, long mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); -int16_t data; +s16 data;int ret;switch (chan->type) {
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.c +11 -11
@@ -26,28 +26,28 @@#define INV_ICM42600_FIFO_HEADER_ODR_GYRO BIT(0)struct inv_icm42600_fifo_1sensor_packet { -uint8_t header; +u8 header;struct inv_icm42600_fifo_sensor_data data; -int8_t temp; +s8 temp; } __packed;#define INV_ICM42600_FIFO_1SENSOR_PACKET_SIZE 8struct inv_icm42600_fifo_2sensors_packet { -uint8_t header; +u8 header;struct inv_icm42600_fifo_sensor_data accel;struct inv_icm42600_fifo_sensor_data gyro; -int8_t temp; +s8 temp;__be16 timestamp; } __packed;#define INV_ICM42600_FIFO_2SENSORS_PACKET_SIZE 16ssize_t inv_icm42600_fifo_decode_packet (const void *packet,const void **accel, -const void **gyro,const int8_t **temp, +const void **gyro,const s8 **temp,const void **timestamp,unsigned int *odr) {const struct inv_icm42600_fifo_1sensor_packet *pack1 = packet;const struct inv_icm42600_fifo_2sensors_packet *pack2 = packet; -uint8_t header = *((const uint8_t *)packet); +u8 header = *((const u8 *)packet);/* FIFO empty */ if (header &INV_ICM42600_FIFO_HEADER_MSG ) {
@@ -100,7 +100,7 @@ ssize_t inv_icm42600_fifo_decode_packet(void inv_icm42600_buffer_update_fifo_period (struct inv_icm42600_state *st) { -uint32_t period_gyro, period_accel, period; +u32 period_gyro, period_accel, period;if (st->fifo.en &INV_ICM42600_SENSOR_GYRO ) period_gyro =inv_icm42600_odr_to_period (st->conf.gyro.odr);
@@ -204,8 +204,8 @@ int inv_icm42600_buffer_update_watermark {size_t packet_size, wm_size;unsigned int wm_gyro, wm_accel, watermark; -uint32_t period_gyro, period_accel, period; -uint32_t latency_gyro, latency_accel, latency; +u32 period_gyro, period_accel, period; +u32 latency_gyro, latency_accel, latency;bool restore;__le16 raw_wm;int ret;
@@ -459,7 +459,7 @@ int inv_icm42600_buffer_fifo_read(struct__be16 *raw_fifo_count;ssize_t i, size;const void *accel, *gyro, *timestamp; -const int8_t *temp; +const s8 *temp;unsigned int odr;int ret;
@@ -550,7 +550,7 @@ int inv_icm42600_buffer_hwfifo_flush(strstruct inv_icm42600_sensor_state *gyro_st =iio_priv (st->indio_gyro);struct inv_icm42600_sensor_state *accel_st =iio_priv (st->indio_accel);struct inv_sensors_timestamp *ts; -int64_t gyro_ts, accel_ts; +s64 gyro_ts, accel_ts;int ret; gyro_ts =iio_get_time_ns (st->indio_gyro);
drivers/iio/imu/inv_icm42600/inv_icm42600_buffer.h +5 -5
@@ -28,7 +28,7 @@ struct inv_icm42600_state;struct inv_icm42600_fifo {unsigned int on;unsigned int en; -uint32_t period; +u32 period;struct {unsigned int gyro;unsigned int accel;
@@ -41,7 +41,7 @@ struct inv_icm42600_fifo {size_t accel;size_t total; } nb; -uint8_t data[2080 ]__aligned(IIO_DMA_MINALIGN) ; +u8 data[2080 ]__aligned(IIO_DMA_MINALIGN) ; };/* FIFO data packet */
@@ -52,7 +52,7 @@ struct inv_icm42600_fifo_sensor_data { } __packed;#define INV_ICM42600_FIFO_DATA_INVALID -32768 -static inline int16_t inv_icm42600_fifo_get_sensor_data (__be16 d) +static inline s16 inv_icm42600_fifo_get_sensor_data (__be16 d) {return be16_to_cpu (d); }
@@ -60,7 +60,7 @@ static inline int16_t inv_icm42600_fifo_static inline bool inv_icm42600_fifo_is_data_valid (const struct inv_icm42600_fifo_sensor_data *s) { -int16_t x, y, z; +s16 x, y, z; x =inv_icm42600_fifo_get_sensor_data (s->x); y =inv_icm42600_fifo_get_sensor_data (s->y);
@@ -75,7 +75,7 @@ inv_icm42600_fifo_is_data_valid(const st }ssize_t inv_icm42600_fifo_decode_packet (const void *packet,const void **accel, -const void **gyro,const int8_t **temp, +const void **gyro,const s8 **temp,const void **timestamp,unsigned int *odr);extern const struct iio_buffer_setup_ops inv_icm42600_buffer_ops;
drivers/iio/imu/inv_icm42600/inv_icm42600_core.c +3 -3
@@ -103,7 +103,7 @@ const struct regmap_config inv_icm42600_EXPORT_SYMBOL_NS_GPL (inv_icm42600_spi_regmap_config,"IIO_ICM42600" );struct inv_icm42600_hw { -uint8_t whoami; +u8 whoami;const char *name;const struct inv_icm42600_conf *conf; };
@@ -188,9 +188,9 @@ inv_icm42600_get_mount_matrix(const strureturn &st->orientation; } -uint32_t inv_icm42600_odr_to_period (enum inv_icm42600_odr odr) +u32 inv_icm42600_odr_to_period (enum inv_icm42600_odr odr) { -static uint32_t odr_periods[INV_ICM42600_ODR_NB ] = { +static u32 odr_periods[INV_ICM42600_ODR_NB ] = {/* reserved values */ 0 ,0 ,0 ,/* 8kHz */
drivers/iio/imu/inv_icm42600/inv_icm42600_gyro.c +18 -18
@@ -77,7 +77,7 @@ static const struct iio_chan_spec inv_ic*/ struct inv_icm42600_gyro_buffer {struct inv_icm42600_fifo_sensor_data gyro; -int16_t temp; +s16 temp;aligned_s64 timestamp; };
@@ -139,7 +139,7 @@ out_unlock:static int inv_icm42600_gyro_read_sensor (struct inv_icm42600_state *st,struct iio_chan_spec const *chan, -int16_t *val) +s16 *val) {struct device *dev =regmap_get_device (st->map);struct inv_icm42600_sensor_conf conf =INV_ICM42600_SENSOR_CONF_INIT ;
@@ -179,7 +179,7 @@ static int inv_icm42600_gyro_read_sensorif (ret) goto exit; - *val = (int16_t )be16_to_cpup (data); + *val = (s16 )be16_to_cpup (data);if (*val ==INV_ICM42600_DATA_INVALID ) ret = -EINVAL ; exit:
@@ -399,11 +399,11 @@ static int inv_icm42600_gyro_read_offset int *val, int *val2) { struct device *dev = regmap_get_device(st->map); -int64_t val64; -int32_t bias; +s64 val64; +s32 bias;unsigned int reg; -int16_t offset; -uint8_t data[2 ]; +s16 offset; +u8 data[2 ];int ret;if (chan->type !=IIO_ANGL_VEL )
@@ -457,7 +457,7 @@ static int inv_icm42600_gyro_read_offset* result in nano (1000000000) * (offset * 64 * Pi * 1000000000) / (2048 * 180) */ - val64 = (int64_t )offset *64LL *3141592653LL ; + val64 = (s64 )offset *64LL *3141592653LL ;/* for rounding, add + or - divisor (2048 * 180) divided by 2 */ if (val64 >=0 ) val64 +=2048 *180 /2 ;
@@ -475,9 +475,9 @@ static int inv_icm42600_gyro_write_offse int val, int val2) {struct device *dev =regmap_get_device (st->map); -int64_t val64, min, max; +s64 val64, min, max;unsigned int reg, regval; -int16_t offset; +s16 offset;int ret;if (chan->type !=IIO_ANGL_VEL )
@@ -498,11 +498,11 @@ static int inv_icm42600_gyro_write_offse }/* inv_icm42600_gyro_calibbias: min - step - max in nano */ - min = (int64_t )inv_icm42600_gyro_calibbias[0 ] *1000000000LL + - (int64_t )inv_icm42600_gyro_calibbias[1 ]; - max = (int64_t )inv_icm42600_gyro_calibbias[4 ] *1000000000LL + - (int64_t )inv_icm42600_gyro_calibbias[5 ]; - val64 = (int64_t )val *1000000000LL + (int64_t )val2; + min = (s64 )inv_icm42600_gyro_calibbias[0 ] *1000000000LL + + (s64 )inv_icm42600_gyro_calibbias[1 ]; + max = (s64 )inv_icm42600_gyro_calibbias[4 ] *1000000000LL + + (s64 )inv_icm42600_gyro_calibbias[5 ]; + val64 = (s64 )val *1000000000LL + (s64 )val2;if (val64 < min || val64 > max)return -EINVAL ;
@@ -577,7 +577,7 @@ static int inv_icm42600_gyro_read_raw(st int *val, int *val2, long mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); -int16_t data; +s16 data;int ret;switch (chan->type) {
@@ -803,9 +803,9 @@ int inv_icm42600_gyro_parse_fifo(structssize_t i, size;unsigned int no;const void *accel, *gyro, *timestamp; -const int8_t *temp; +const s8 *temp;unsigned int odr; -int64_t ts_val; +s64 ts_val;/* buffer is copied to userspace, zeroing it to avoid any data leak */ struct inv_icm42600_gyro_buffer buffer = { };
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +3 -3
@@ -13,7 +13,7 @@#include "inv_icm42600.h" #include "inv_icm42600_temp.h" -static int inv_icm42600_temp_read (struct inv_icm42600_state *st,int16_t *temp) +static int inv_icm42600_temp_read (struct inv_icm42600_state *st,s16 *temp) {struct device *dev =regmap_get_device (st->map);__be16 *raw;
@@ -31,7 +31,7 @@ static int inv_icm42600_temp_read(structif (ret) goto exit; - *temp = (int16_t )be16_to_cpup (raw); + *temp = (s16 )be16_to_cpup (raw);if (*temp ==INV_ICM42600_DATA_INVALID ) ret = -EINVAL ;
@@ -48,7 +48,7 @@ int inv_icm42600_temp_read_raw(struct ii int *val, int *val2, long mask) { struct inv_icm42600_state *st = iio_device_get_drvdata(indio_dev); -int16_t temp; +s16 temp;int ret;if (chan->type !=IIO_TEMP )
Greg Kroah-Hartman
maintainerPATCH 341/457 iio: imu: inv_icm42600: change invalid data error to -EBUSY
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jean-Baptiste Maneyrol <[email protected]>
[ Upstream commit dfdc31e7ccf3ac1d5ec01d5120c71e14745e3dd8 ]
Temperature sensor returns the temperature of the mechanical parts of the chip. If both accel and gyro are off, the temperature sensor is also automatically turned off and returns invalid data.
In this case, returning -EBUSY error code is better then -EINVAL and indicates userspace that it needs to retry reading temperature in another context.
--- drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-)
drivers/iio/imu/inv_icm42600/inv_icm42600_temp.c +5 -1
@@ -32,8 +32,12 @@ static int inv_icm42600_temp_read(struct goto exit; *temp = (s16 )be16_to_cpup (raw); +/* +* Temperature data is invalid if both accel and gyro are off. +* Return -EBUSY in this case. +*/ if (*temp ==INV_ICM42600_DATA_INVALID ) - ret = -EINVAL ; + ret = -EBUSY ; exit:mutex_unlock (&st->lock);
Greg Kroah-Hartman
maintainerPATCH 342/457 spi: spi-qpic-snand: use correct CW_PER_PAGE value for OOB write
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
[ Upstream commit 6bc829220b33da8522572cc50fdf5067c51d3bf3 ]
The qcom_spi_program_oob() function uses only the last codeword to write the OOB data into the flash, but it sets the CW_PER_PAGE field in the CFG0 register as it would use all codewords.
It seems that this confuses the hardware somehow, and any access to the flash fails with a timeout error after the function is called. The problem can be easily reproduced with the following commands:
# dd if=/dev/zero bs=2176 count=1 > /tmp/test.bin
1+0 records in
1+0 records out
# flash_erase /dev/mtd4 0 0
Erasing 128 Kibyte @ 0 -- 100 % complete
# nandwrite -O /dev/mtd4 /tmp/test.bin
Writing data to block 0 at offset 0x0
# nanddump -o /dev/mtd4 >/dev/null
ECC failed: 0
ECC corrected: 0
Number of bad blocks: 0
Number of bbt blocks: 0
Block size 131072, page size 2048, OOB size 128
Dumping data starting at 0x00000000 and ending at 0x00020000...
[ 33.197605] qcom_snand 79b0000.spi: failure to read oob
libmtd: error!: MEMREADOOB64 ioctl failed for mtd4, offset 0 (eraseblock 0)
error 110 (Operation timed out)
[ 35.277582] qcom_snand 79b0000.spi: failure in submitting cmd descriptor
libmtd: error!: cannot read 2048 bytes from mtd4 (eraseblock 0, offset 2048)
error 110 (Operation timed out)
nanddump: error!: mtd_readChange the code to use the correct CW_PER_PAGE value to avoid this.
--- drivers/spi/spi-qpic-snand.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/spi/spi-qpic-snand.c +1 -1
@@ -1185,7 +1185,7 @@ static int qcom_spi_program_oob(struct qcom_nand_controller *snandc,u32 cfg0, cfg1, ecc_bch_cfg, ecc_buf_cfg; cfg0 = (ecc_cfg->cfg0 & ~CW_PER_PAGE_MASK ) | -FIELD_PREP (CW_PER_PAGE_MASK , num_cw -1 ); +FIELD_PREP (CW_PER_PAGE_MASK ,0 ); cfg1 = ecc_cfg->cfg1; ecc_bch_cfg = ecc_cfg->ecc_bch_cfg; ecc_buf_cfg = ecc_cfg->ecc_buf_cfg;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 343/457 spi: spi-fsl-lpspi: Clamp too high speed_hz
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Stefan Wahren <[email protected]>
[ Upstream commit af357a6a3b7d685e7aa621c6fb1d4ed6c349ec9e ]
Currently the driver is not able to handle the case that a SPI device specifies a higher spi-max-frequency than half of per-clk:
per-clk should be at least two times of transfer speed
Fix this by clamping to the max possible value and use the minimum SCK period of 2 cycles.
--- drivers/spi/spi-fsl-lpspi.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/spi/spi-fsl-lpspi.c +3 -5
@@ -331,13 +331,11 @@ static int fsl_lpspi_set_bitrate(struct fsl_lpspi_data *fsl_lpspi) }if (config.speed_hz > perclk_rate /2 ) { -dev_err (fsl_lpspi->dev, -"per-clk should be at least two times of transfer speed" ); -return -EINVAL ; + div =2 ; + }else { + div =DIV_ROUND_UP (perclk_rate, config.speed_hz); } - div =DIV_ROUND_UP (perclk_rate, config.speed_hz); -for (prescale =0 ; prescale <= prescale_max; prescale++) { scldiv = div / (1 << prescale) -2 ;if (scldiv >=0 && scldiv <256 ) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 344/457 spi: spi-qpic-snand: fix calculating of ECC OOB regions properties
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Gabor Juhos <[email protected]>
[ Upstream commit 13d0fe84a214658254a7412b2b46ec1507dc51f0 ]
The OOB layout used by the driver has two distinct regions which contains hardware specific ECC data, yet the qcom_spi_ooblayout_ecc() function sets the same offset and length values for both regions which is clearly wrong.
Change the code to calculate the correct values for both regions.
For reference, the following table shows the computed offset and length values for various OOB size/ECC strength configurations:
+-----------------+-----------------+
|before the change| after the change|
+-------+----------+--------+--------+--------+--------+--------+
| OOB | ECC | region | region | region | region | region |
| size | strength | index | offset | length | offset | length |
+-------+----------+--------+--------+--------+--------+--------+
| 128 | 8 | 0 | 113 | 15 | 0 | 49 |
| | | 1 | 113 | 15 | 65 | 63 |
+-------+----------+--------+--------+--------+--------+--------+
| 128 | 4 | 0 | 117 | 11 | 0 | 37 |
| | | 1 | 117 | 11 | 53 | 75 |
+-------+----------+--------+--------+--------+--------+--------+
| 64 | 4 | 0 | 53 | 11 | 0 | 37 |
| | | 1 | 53 | 11 | 53 | 11 |
+-------+----------+--------+--------+--------+--------+--------+--- drivers/spi/spi-qpic-snand.c | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-)
drivers/spi/spi-qpic-snand.c +14 -6
@@ -216,13 +216,21 @@ static int qcom_spi_ooblayout_ecc(struct mtd_info *mtd, int section,struct qcom_nand_controller *snandc =nand_to_qcom_snand (nand);struct qpic_ecc *qecc = snandc->qspi->ecc; -if (section >1 ) -return -ERANGE ; - - oobregion->length = qecc->ecc_bytes_hw + qecc->spare_bytes; - oobregion->offset = mtd->oobsize - oobregion->length; +switch (section) { +case 0 : + oobregion->offset =0 ; + oobregion->length = qecc->bytes * (qecc->steps -1 ) + + qecc->bbm_size; +return 0 ; +case 1 : + oobregion->offset = qecc->bytes * (qecc->steps -1 ) + + qecc->bbm_size + + qecc->steps *4 ; + oobregion->length = mtd->oobsize - oobregion->offset; +return 0 ; + } -return 0 ; +return -ERANGE ; } static int qcom_spi_ooblayout_free(struct mtd_info *mtd, int section,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 345/457 drm/nouveau/nvif: Fix potential memory leak in nvif_vmm_ctor().
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Fanhua Li <[email protected]>
[ Upstream commit bb8aeaa3191b617c6faf8ae937252e059673b7ea ]
When the nvif_vmm_type is invalid, we will return error directly without freeing the args in nvif_vmm_ctor(), which leading a memory leak. Fix it by setting the ret -EINVAL and goto done.
--- drivers/gpu/drm/nouveau/nvif/vmm.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/nouveau/nvif/vmm.c +2 -1
@@ -219,7 +219,8 @@ nvif_vmm_ctor(struct nvif_mmu *mmu, const char *name, s32 oclass,case RAW : args->type =NVIF_VMM_V0_TYPE_RAW ;break ;default :WARN_ON (1 ); -return -EINVAL ; + ret = -EINVAL ; + goto done; }memcpy (args->data, argv, argc);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 346/457 cgroup/cpuset: Use static_branch_enable_cpuslocked() on cpusets_insane_config_key
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 65f97cc81b0adc5f49cf6cff5d874be0058e3f41 ]
The following lockdep splat was observed.
[ 812.359086] ============================================
[ 812.359089] WARNING: possible recursive locking detected
[ 812.359097] --------------------------------------------
[ 812.359100] runtest.sh/30042 is trying to acquire lock:
[ 812.359105] ffffffffa7f27420 (cpu_hotplug_lock){++++}-{0:0}, at: static_key_enable+0xe/0x20
[ 812.359131]
[ 812.359131] but task is already holding lock:
[ 812.359134] ffffffffa7f27420 (cpu_hotplug_lock){++++}-{0:0}, at: cpuset_write_resmask+0x98/0xa70
:
[ 812.359267] Call Trace:
[ 812.359272] <TASK>
[ 812.359367] cpus_read_lock+0x3c/0xe0
[ 812.359382] static_key_enable+0xe/0x20
[ 812.359389] check_insane_mems_config.part.0+0x11/0x30
[ 812.359398] cpuset_write_resmask+0x9f2/0xa70
[ 812.359411] cgroup_file_write+0x1c7/0x660
[ 812.359467] kernfs_fop_write_iter+0x358/0x530
[ 812.359479] vfs_write+0xabe/0x1250
[ 812.359529] ksys_write+0xf9/0x1d0
[ 812.359558] do_syscall_64+0x5f/0xe0Since commit d74b27d63a8b ("cgroup/cpuset: Change cpuset_rwsem and hotplug lock order"), the ordering of cpu hotplug lock and cpuset_mutex had been reversed. That patch correctly used the cpuslocked version of the static branch API to enable cpusets_pre_enable_key and cpusets_enabled_key, but it didn't do the same for cpusets_insane_config_key.
The cpusets_insane_config_key can be enabled in the check_insane_mems_config() which is called from update_nodemask() or cpuset_hotplug_update_tasks() with both cpu hotplug lock and cpuset_mutex held. Deadlock can happen with a pending hotplug event that tries to acquire the cpu hotplug write lock which will block further cpus_read_lock() attempt from check_insane_mems_config(). Fix that by switching to use static_branch_enable_cpuslocked().
--- kernel/cgroup/cpuset.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
kernel/cgroup/cpuset.c +1 -1
@@ -280,7 +280,7 @@ static inline void check_insane_mems_config(nodemask_t *nodes) {if (!cpusets_insane_config () &&movable_only_nodes (nodes)) { -static_branch_enable (&cpusets_insane_config_key); +static_branch_enable_cpuslocked (&cpusets_insane_config_key);pr_info ("Unsupported (movable nodes only) cpuset configuration detected (nmask=%*pbl)!\n" "Cpuset allocations might fail even with a lot of memory available.\n" ,nodemask_pr_args (nodes));
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 347/457 cgroup/cpuset: Fix a partition error with CPU hotplug
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Waiman Long <[email protected]>
[ Upstream commit 150e298ae0ccbecff2357a72fbabd80f8849ea6e ]
It was found during testing that an invalid leaf partition with an empty effective exclusive CPU list can become a valid empty partition with no CPU afer an offline/online operation of an unrelated CPU. An empty partition root is allowed in the special case that it has no task in its cgroup and has distributed out all its CPUs to its child partitions. That is certainly not the case here.
The problem is in the cpumask_subsets() test in the hotplug case (update with no new mask) of update_parent_effective_cpumask() as it also returns true if the effective exclusive CPU list is empty. Fix that by addding the cpumask_empty() test to root out this exception case. Also add the cpumask_empty() test in cpuset_hotplug_update_tasks() to avoid calling update_parent_effective_cpumask() for this special case.
--- kernel/cgroup/cpuset.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-)
kernel/cgroup/cpuset.c +4 -3
@@ -1843,7 +1843,7 @@ static int update_parent_effective_cpumask(struct cpuset *cs, int cmd,if (is_partition_valid (cs)) adding =cpumask_and (tmp->addmask, xcpus, parent->effective_xcpus); - }else if (is_partition_invalid (cs) && + }else if (is_partition_invalid (cs) && !cpumask_empty (xcpus) &&cpumask_subset (xcpus, parent->effective_xcpus)) {struct cgroup_subsys_state *css;struct cpuset *child;
@@ -3870,9 +3870,10 @@ static void cpuset_hotplug_update_tasks(struct cpuset *cs, struct tmpmasks *tmp) partcmd = partcmd_invalidate;/* * On the other hand, an invalid partition root may be transitioned -* back to a regular one. +* back to a regular one with a non-empty effective xcpus. */ - else if (is_partition_valid(parent) && is_partition_invalid(cs)) + else if (is_partition_valid(parent) && is_partition_invalid(cs) && + !cpumask_empty(cs->effective_xcpus)) partcmd = partcmd_update;if (partcmd >=0 ) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 348/457 drm/tests: Fix endian warning
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Expósito <[email protected]>
[ Upstream commit d28b9d2925b4f773adb21b1fc20260ddc370fb13 ]
When compiling with sparse enabled, this warning is thrown:
warning: incorrect type in argument 2 (different base types)
expected restricted __le32 const [usertype] *buf got unsigned int [usertype] *[assigned] buf
Add a cast to fix it.
--- drivers/gpu/drm/tests/drm_format_helper_test.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/gpu/drm/tests/drm_format_helper_test.c +1 -1
@@ -1071,7 +1071,7 @@ static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test) NULL : &result->dst_pitch;drm_fb_xrgb8888_to_xrgb2101010 (&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); - buf =le32buf_to_cpu (test, buf, dst_size /sizeof (u32)); + buf =le32buf_to_cpu (test, (__force const __le32 *)buf, dst_size /sizeof (u32));KUNIT_EXPECT_MEMEQ (test, buf, result->expected, dst_size); buf = dst.vaddr;/* restore original value of buf */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 349/457 drm/tests: Do not use drm_fb_blit() in format-helper tests
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Thomas Zimmermann <[email protected]>
[ Upstream commit 5a4856e0e38109ba994f369962f054ecb445c098 ]
Export additional helpers from the format-helper library and open-code drm_fb_blit() in tests. Prepares for the removal of drm_fb_blit(). Only sysfb drivers use drm_fb_blit(). The function will soon be removed from format helpers and be refactored within sysfb helpers.
Stable-dep-of: 05663d88fd0b ("drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian")
--- drivers/gpu/drm/drm_format_helper.c | 108 ++++++++++++++++-- drivers/gpu/drm/drm_format_internal.h | 8 ++ .../gpu/drm/tests/drm_format_helper_test.c | 108 +++--------------- include/drm/drm_format_helper.h | 9 ++ 4 files changed, 131 insertions(+), 102 deletions(-)
drivers/gpu/drm/drm_format_helper.c +98 -10
@@ -857,11 +857,33 @@ static void drm_fb_xrgb8888_to_abgr8888_line(void *dbuf, const void *sbuf, unsigdrm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_abgr8888); } -static void drm_fb_xrgb8888_to_abgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, -const struct iosys_map *src, -const struct drm_framebuffer *fb, -const struct drm_rect *clip, -struct drm_format_conv_state *state) +/** +* drm_fb_xrgb8888_to_abgr8888 - Convert XRGB8888 to ABGR8888 clip buffer +* @dst: Array of ABGR8888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffer +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. The parameters @dst, @dst_pitch and @src refer +* to arrays. Each array must have at least as many entries as there are planes in +* @fb's format. Each entry stores the value for the format's respective color plane +* at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for ABGR8888 devices that don't support XRGB8888 +* natively. It sets an opaque alpha channel as part of the conversion. +*/ +void drm_fb_xrgb8888_to_abgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src, +const struct drm_framebuffer *fb, +const struct drm_rect *clip, +struct drm_format_conv_state *state) {static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = {4 ,
@@ -870,17 +892,40 @@ static void drm_fb_xrgb8888_to_abgr8888(struct iosys_map *dst, const unsigned indrm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, drm_fb_xrgb8888_to_abgr8888_line); } +EXPORT_SYMBOL (drm_fb_xrgb8888_to_abgr8888);static void drm_fb_xrgb8888_to_xbgr8888_line (void *dbuf,const void *sbuf,unsigned int pixels) {drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_xbgr8888); } -static void drm_fb_xrgb8888_to_xbgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, -const struct iosys_map *src, -const struct drm_framebuffer *fb, -const struct drm_rect *clip, -struct drm_format_conv_state *state) +/** +* drm_fb_xrgb8888_to_xbgr8888 - Convert XRGB8888 to XBGR8888 clip buffer +* @dst: Array of XBGR8888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffer +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. The parameters @dst, @dst_pitch and @src refer +* to arrays. Each array must have at least as many entries as there are planes in +* @fb's format. Each entry stores the value for the format's respective color plane +* at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for XBGR8888 devices that don't support XRGB8888 +* natively. +*/ +void drm_fb_xrgb8888_to_xbgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src, +const struct drm_framebuffer *fb, +const struct drm_rect *clip, +struct drm_format_conv_state *state) {static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = {4 ,
@@ -889,6 +934,49 @@ static void drm_fb_xrgb8888_to_xbgr8888(struct iosys_map *dst, const unsigned indrm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, drm_fb_xrgb8888_to_xbgr8888_line); } +EXPORT_SYMBOL (drm_fb_xrgb8888_to_xbgr8888); + +static void drm_fb_xrgb8888_to_bgrx8888_line (void *dbuf,const void *sbuf,unsigned int pixels) +{ +drm_fb_xfrm_line_32to32 (dbuf, sbuf, pixels, drm_pixel_xrgb8888_to_bgrx8888); +} + +/** +* drm_fb_xrgb8888_to_bgrx8888 - Convert XRGB8888 to BGRX8888 clip buffer +* @dst: Array of BGRX8888 destination buffers +* @dst_pitch: Array of numbers of bytes between the start of two consecutive scanlines +* within @dst; can be NULL if scanlines are stored next to each other. +* @src: Array of XRGB8888 source buffer +* @fb: DRM framebuffer +* @clip: Clip rectangle area to copy +* @state: Transform and conversion state +* +* This function copies parts of a framebuffer to display memory and converts the +* color format during the process. The parameters @dst, @dst_pitch and @src refer +* to arrays. Each array must have at least as many entries as there are planes in +* @fb's format. Each entry stores the value for the format's respective color plane +* at the same index. +* +* This function does not apply clipping on @dst (i.e. the destination is at the +* top-left corner). +* +* Drivers can use this function for BGRX8888 devices that don't support XRGB8888 +* natively. +*/ +void drm_fb_xrgb8888_to_bgrx8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src, +const struct drm_framebuffer *fb, +const struct drm_rect *clip, +struct drm_format_conv_state *state) +{ +static const u8 dst_pixsize[DRM_FORMAT_MAX_PLANES ] = { +4 , + }; + +drm_fb_xfrm (dst, dst_pitch, dst_pixsize, src, fb, clip, false, state, + drm_fb_xrgb8888_to_bgrx8888_line); +} +EXPORT_SYMBOL (drm_fb_xrgb8888_to_bgrx8888);static void drm_fb_xrgb8888_to_xrgb2101010_line (void *dbuf,const void *sbuf,unsigned int pixels) {
drivers/gpu/drm/drm_format_internal.h +8 -0
@@ -111,6 +111,14 @@ static inline u32 drm_pixel_xrgb8888_to_xbgr8888(u32 pix) ((pix &0x000000ff ) <<16 ); } +static inline u32 drm_pixel_xrgb8888_to_bgrx8888 (u32 pix) +{ +return ((pix &0xff000000 ) >>24 ) |/* also copy filler bits */ + ((pix &0x00ff0000 ) >>8 ) | + ((pix &0x0000ff00 ) <<8 ) | + ((pix &0x000000ff ) <<24 ); +} +static inline u32 drm_pixel_xrgb8888_to_abgr8888 (u32 pix) { return GENMASK(31, 24) | /* fill alpha bits */
drivers/gpu/drm/tests/drm_format_helper_test.c +16 -92
210 lines not on this page · raw message
include/drm/drm_format_helper.h +9 -0
@@ -102,6 +102,15 @@ void drm_fb_xrgb8888_to_bgr888(struct iosys_map *dst, const unsigned int *dst_pivoid drm_fb_xrgb8888_to_argb8888 (struct iosys_map *dst,const unsigned int *dst_pitch,const struct iosys_map *src,const struct drm_framebuffer *fb,const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_abgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_xbgr8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state); +void drm_fb_xrgb8888_to_bgrx8888 (struct iosys_map *dst,const unsigned int *dst_pitch, +const struct iosys_map *src,const struct drm_framebuffer *fb, +const struct drm_rect *clip,struct drm_format_conv_state *state); void drm_fb_xrgb8888_to_xrgb2101010(struct iosys_map *dst, const unsigned int *dst_pitch, const struct iosys_map *src, const struct drm_framebuffer *fb, const struct drm_rect *clip,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 350/457 drm/tests: Fix drm_test_fb_xrgb8888_to_xrgb2101010() on big-endian
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: José Expósito <[email protected]>
[ Upstream commit 05663d88fd0b8ee1c54ab2d5fb36f9b6a3ed37f7 ]
Fix failures on big-endian architectures on tests cases single_pixel_source_buffer, single_pixel_clip_rectangle, well_known_colors and destination_pitch.
--- drivers/gpu/drm/tests/drm_format_helper_test.c | 1 + 1 file changed, 1 insertion(+)
drivers/gpu/drm/tests/drm_format_helper_test.c +1 -0
@@ -1040,6 +1040,7 @@ static void drm_test_fb_xrgb8888_to_xrgb2101010(struct kunit *test)memset (buf,0 , dst_size);drm_fb_xrgb8888_to_xrgb2101010 (&dst, dst_pitch, &src, &fb, ¶ms->clip, &fmtcnv_state); + buf =le32buf_to_cpu (test, (__force const __le32 *)buf, dst_size /sizeof (u32));KUNIT_EXPECT_MEMEQ (test, buf, result->expected, dst_size); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 351/457 iosys-map: Fix undefined behavior in iosys_map_clear()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Gote <[email protected]>
[ Upstream commit 5634c8cb298a7146b4e38873473e280b50e27a2c ]
The current iosys_map_clear() implementation reads the potentially uninitialized 'is_iomem' boolean field to decide which union member to clear. This causes undefined behavior when called on uninitialized structures, as 'is_iomem' may contain garbage values like 0xFF.
UBSAN detects this as:
UBSAN: invalid-load in include/linux/iosys-map.h:267
load of value 255 is not a valid value for type '_Bool'Fix by unconditionally clearing the entire structure with memset(), eliminating the need to read uninitialized data and ensuring all fields are set to known good values.
--- include/linux/iosys-map.h | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
include/linux/iosys-map.h +1 -6
@@ -264,12 +264,7 @@ static inline bool iosys_map_is_set(const struct iosys_map *map)*/ static inline void iosys_map_clear (struct iosys_map *map) { -if (map->is_iomem) { - map->vaddr_iomem =NULL ; - map->is_iomem = false; - }else { - map->vaddr =NULL ; - } +memset (map,0 ,sizeof (*map)); }/**
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 352/457 rust: alloc: replace aligned_size() with Kmalloc::aligned_layout()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
[ Upstream commit fde578c86281f27b182680c7642836a0dbbd0be7 ]
aligned_size() dates back to when Rust did support kmalloc() only, but is now used in ReallocFunc::call() and hence for all allocators.
However, the additional padding applied by aligned_size() is only required by the kmalloc() allocator backend.
Hence, replace aligned_size() with Kmalloc::aligned_layout() and use it for the affected allocators, i.e. kmalloc() and kvmalloc(), only.
While at it, make Kmalloc::aligned_layout() public, such that Rust abstractions, which have to call subsystem specific kmalloc() based allocation primitives directly, can make use of it.
--- rust/kernel/alloc/allocator.rs | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-)
rust/kernel/alloc/allocator.rs +18 -12
@@ -43,17 +43,6 @@ pub struct Vmalloc;/// For more details see [self]. pub struct KVmalloc ; -/// Returns a proper size to alloc a new object aligned to `new_layout`'s alignment. -fn aligned_size (new_layout:Layout ) ->usize { -// Customized layouts from `Layout::from_size_align()` can have size < align, so pad first. -let layout = new_layout.pad_to_align (); - -// Note that `layout.size()` (after padding) is guaranteed to be a multiple of `layout.align()` -// which together with the slab guarantees means the `krealloc` will return a properly aligned -// object (see comments in `kmalloc()` for more information). - layout.size () -} -/// # Invariants /// /// One of the following: `krealloc`, `vrealloc`, `kvrealloc`.
@@ -88,7 +77,7 @@ impl ReallocFunc { old_layout: Layout, flags: Flags, ) -> Result<NonNull<[u8]>, AllocError> { -let size =aligned_size (layout); +let size = layout.size ();let ptr =match ptr {Some (ptr) => {if old_layout.size () ==0 {
@@ -123,6 +112,17 @@ impl ReallocFunc { } } +impl Kmalloc { +/// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of +/// `layout`. +pub fn aligned_layout (layout:Layout ) ->Layout { +// Note that `layout.size()` (after padding) is guaranteed to be a multiple of +// `layout.align()` which together with the slab guarantees means that `Kmalloc` will return +// a properly aligned object (see comments in `kmalloc()` for more information). + layout.pad_to_align () + } +} +// SAFETY: `realloc` delegates to `ReallocFunc::call`, which guarantees that // - memory remains valid until it is explicitly freed, // - passing a pointer to a valid memory allocation is OK,
@@ -135,6 +135,8 @@ unsafe impl Allocator for Kmalloc { old_layout: Layout, flags: Flags, ) -> Result<NonNull<[u8]>, AllocError> { +let layout =Kmalloc ::aligned_layout (layout); +// SAFETY: `ReallocFunc::call` has the same safety requirements as `Allocator::realloc`. unsafe {ReallocFunc ::KREALLOC .call (ptr, layout, old_layout, flags) } }
@@ -176,6 +178,10 @@ unsafe impl Allocator for KVmalloc { old_layout: Layout, flags: Flags, ) -> Result<NonNull<[u8]>, AllocError> { +// `KVmalloc` may use the `Kmalloc` backend, hence we have to enforce a `Kmalloc` +// compatible layout. +let layout =Kmalloc ::aligned_layout (layout); +// TODO: Support alignments larger than PAGE_SIZE. if layout.align () > bindings::PAGE_SIZE {pr_warn! ("KVmalloc does not support alignments larger than PAGE_SIZE yet.\n" );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 353/457 rust: drm: ensure kmalloc() compatible Layout
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
[ Upstream commit 22ab0641b939967f630d108e33a3582841ad6846 ]
drm::Device is allocated through __drm_dev_alloc() (which uses kmalloc()) and the driver private data, <T as drm::Driver>::Data, is initialized in-place.
Due to the order of fields in drm::Device
pub struct Device<T: drm::Driver> {
dev: Opaque<bindings::drm_device>,
data: T::Data,
}even with an arbitrary large alignment requirement of T::Data it can't happen that the size of Device is smaller than its alignment requirement.
However, let's not rely on this subtle circumstance and create a proper kmalloc() compatible Layout.
--- rust/kernel/drm/device.rs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-)
rust/kernel/drm/device.rs +7 -2
@@ -5,6 +5,7 @@//! C header: [`include/linux/drm/drm_device.h`](srctree/include/linux/drm/drm_device.h) use crate ::{ + alloc::allocator::Kmalloc , bindings, device, drm, drm::driver::AllocImpl , error::from_err_ptr,
@@ -12,7 +13,7 @@ use crate::{ prelude::*, types::{ARef, AlwaysRefCounted, Opaque}, }; -use core::{mem, ops::Deref , ptr, ptr::NonNull }; +use core::{alloc::Layout , mem, ops::Deref , ptr, ptr::NonNull };#[cfg( CONFIG_DRM_LEGACY )] macro_rules! drm_legacy_fields {
@@ -96,6 +97,10 @@ impl<T: drm::Driver> Device<T> {/// Create a new `drm::Device` for a `drm::Driver`. pub fn new (dev: &device::Device , data:impl PinInit <T ::Data ,Error >) ->Result <ARef <Self >> { +// `__drm_dev_alloc` uses `kmalloc()` to allocate memory, hence ensure a `kmalloc()` +// compatible `Layout`. +let layout =Kmalloc ::aligned_layout (Layout ::new ::<Self >()); +// SAFETY: // - `VTABLE`, as a `const` is pinned to the read-only section of the compilation, // - `dev` is valid by its type invarants,
@@ -103,7 +108,7 @@ impl<T: drm::Driver> Device<T> { bindings::__drm_dev_alloc ( dev.as_raw (), &Self ::VTABLE , - mem::size_of ::<Self >(), + layout.size (), mem::offset_of!(Self , dev), ) }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 354/457 rust: drm: remove pin annotations from drm::Device
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
[ Upstream commit 0c04a81c1d0214d5b2025f805ccec1ac37c96b08 ]
The #[pin_data] and #[pin] annotations are not necessary for drm::Device, since we don't use any pin-init macros, but only __pinned_init() on the impl PinInit<T::Data, Error> argument of drm::Device::new().
--- rust/kernel/drm/device.rs | 2 -- 1 file changed, 2 deletions(-)
rust/kernel/drm/device.rs +0 -2
@@ -54,10 +54,8 @@ macro_rules! drm_legacy_fields {/// /// `self.dev` is a valid instance of a `struct device`. #[repr( C )] -#[pin_data] pub struct Device <T : drm::Driver > { dev:Opaque <bindings::drm_device >, -#[pin] data:T ::Data , }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 355/457 rust: drm: dont pass the address of drm::Device to drm_dev_put()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Danilo Krummrich <[email protected]>
[ Upstream commit 360077278ba62e81310080f075a1a3028e778ef9 ]
In drm_dev_put() call in AlwaysRefCounted::dec_ref() we rely on struct drm_device to be the first field in drm::Device, whereas everywhere else we correctly obtain the address of the actual struct drm_device.
Analogous to the from_drm_device() helper, provide the into_drm_device() helper in order to address this.
--- rust/kernel/drm/device.rs | 21 ++++++++++++++++++--- 1 file changed, 18 insertions(+), 3 deletions(-)
rust/kernel/drm/device.rs +18 -3
@@ -120,9 +120,13 @@ impl<T: drm::Driver> Device<T> {// - `raw_data` is a valid pointer to uninitialized memory. // - `raw_data` will not move until it is dropped. unsafe { data.__pinned_init (raw_data) }.inspect_err (|_| { -// SAFETY: `__drm_dev_alloc()` was successful, hence `raw_drm` must be valid and the +// SAFETY: `raw_drm` is a valid pointer to `Self`, given that `__drm_dev_alloc` was +// successful. +let drm_dev =unsafe {Self ::into_drm_device (raw_drm) }; + +// SAFETY: `__drm_dev_alloc()` was successful, hence `drm_dev` must be valid and the // refcount must be non-zero. -unsafe { bindings::drm_dev_put (ptr::addr_of_mut!((*raw_drm.as_ptr ()).dev).cast ()) }; +unsafe { bindings::drm_dev_put (drm_dev) }; })?;// SAFETY: The reference count is one, and now we take ownership of that reference as a
@@ -145,6 +149,14 @@ impl<T: drm::Driver> Device<T> {unsafe {crate ::container_of!(ptr,Self , dev) }.cast_mut () } +/// # Safety +/// +/// `ptr` must be a valid pointer to `Self`. +unsafe fn into_drm_device (ptr:NonNull <Self >) -> *mut bindings::drm_device { +// SAFETY: By the safety requirements of this function, `ptr` is a valid pointer to `Self`. +unsafe { &raw mut (*ptr.as_ptr ()).dev }.cast () + } +/// Not intended to be called externally, except via declare_drm_ioctls!() /// /// # Safety
@@ -194,8 +206,11 @@ unsafe impl<T: drm::Driver> AlwaysRefCounted for Device<T> { }unsafe fn dec_ref (obj:NonNull <Self >) { +// SAFETY: `obj` is a valid pointer to `Self`. +let drm_dev =unsafe {Self ::into_drm_device (obj) }; +// SAFETY: The safety requirements guarantee that the refcount is non-zero. -unsafe { bindings::drm_dev_put (obj.cast ().as_ptr ()) }; +unsafe { bindings::drm_dev_put (drm_dev) }; } }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 356/457 drm/panic: Add a u64 divide by 10 for arm32
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jocelyn Falempe <[email protected]>
[ Upstream commit 9af8f2b469c0438620832f3729a3c5c03853b56b ]
On 32bits ARM, u64 divided by a constant is not optimized to a multiply by inverse by the compiler [1].
So do the multiply by inverse explicitly for this architecture.
--- drivers/gpu/drm/drm_panic_qr.rs | 22 +++++++++++++++++++++- 1 file changed, 21 insertions(+), 1 deletion(-)
drivers/gpu/drm/drm_panic_qr.rs +21 -1
@@ -381,6 +381,26 @@ struct DecFifo { len: usize, } +// On arm32 architecture, dividing an `u64` by a constant will generate a call +// to `__aeabi_uldivmod` which is not present in the kernel. +// So use the multiply by inverse method for this architecture. +fn div10 (val:u64 ) ->u64 { +if cfg! (target_arch ="arm" ) { +let val_h = val >>32 ; +let val_l = val &0xFFFFFFFF ; +let b_h:u64 =0x66666666 ; +let b_l:u64 =0x66666667 ; + +let tmp1 = val_h * b_l + ((val_l * b_l) >>32 ); +let tmp2 = val_l * b_h + (tmp1 &0xffffffff ); +let tmp3 = val_h * b_h + (tmp1 >>32 ) + (tmp2 >>32 ); + + tmp3 >>2 + }else { + val /10 + } +} +impl DecFifo {fn push (&mut self, data:u64 , len:usize ) {let mut chunk = data;
@@ -389,7 +409,7 @@ impl DecFifo { }for iin 0 ..len { self.decimals[i] = (chunk %10 )as u8 ; - chunk /=10 ; + chunk =div10 (chunk); } self.len += len; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 357/457 platform/x86/amd/hsmp: Ensure sock->metric_tbl_addr is non-NULL
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suma Hegde <[email protected]>
[ Upstream commit 2c78fb287e1f430b929f2e49786518350d15605c ]
If metric table address is not allocated, accessing metrics_bin will result in a NULL pointer dereference, so add a check.
--- drivers/platform/x86/amd/hsmp/hsmp.c | 5 +++++ 1 file changed, 5 insertions(+)
drivers/platform/x86/amd/hsmp/hsmp.c +5 -0
@@ -356,6 +356,11 @@ ssize_t hsmp_metric_tbl_read(struct hsmp_socket *sock, char *buf, size_t size)if (!sock || !buf)return -EINVAL ; +if (!sock->metric_tbl_addr) { +dev_err (sock->dev,"Metrics table address not available\n" ); +return -ENOMEM ; + } +/* Do not support lseek(), also don't allow more than the size of metric table */ if (size !=sizeof (struct hsmp_metric_table )) {dev_err (sock->dev,"Wrong buffer size\n" );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 358/457 RDMA/erdma: Fix ignored return value of init_kernel_qp
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boshi Yu <[email protected]>
[ Upstream commit d5c74713f0117d07f91eb48b10bc2ad44e23c9b9 ]
The init_kernel_qp interface may fail. Check its return value and free related resources properly when it does.
--- drivers/infiniband/hw/erdma/erdma_verbs.c | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-)
drivers/infiniband/hw/erdma/erdma_verbs.c +3 -1
@@ -1031,7 +1031,9 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs,if (ret) goto err_out_cmd; }else { -init_kernel_qp (dev, qp, attrs); + ret =init_kernel_qp (dev, qp, attrs); +if (ret) + goto err_out_xa; } qp->attrs.max_send_sge = attrs->cap.max_send_sge;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 359/457 RDMA/erdma: Fix unset QPN of GSI QP
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Boshi Yu <[email protected]>
[ Upstream commit d4ac86b47563c7895dae28658abd1879d266b2b4 ]
The QPN of the GSI QP was not set, which may cause issues. Set the QPN to 1 when creating the GSI QP.
--- drivers/infiniband/hw/erdma/erdma_verbs.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/erdma/erdma_verbs.c +2 -0
@@ -994,6 +994,8 @@ int erdma_create_qp(struct ib_qp *ibqp, struct ib_qp_init_attr *attrs, old_entry =xa_store (&dev->qp_xa,1 , qp,GFP_KERNEL );if (xa_is_err (old_entry)) ret =xa_err (old_entry); +else + qp->ibqp.qp_num =1 ; }else { ret = xa_alloc_cyclic(&dev->qp_xa, &qp->ibqp.qp_num, qp, XA_LIMIT(1, dev->attrs.max_qp - 1),
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 360/457 RDMA/hns: Fix querying wrong SCC context for DIP algorithm
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: wenglianfa <[email protected]>
[ Upstream commit 085a1b42e52750769a3fa29d4da6c05ab56f18f8 ]
When using DIP algorithm, all QPs establishing connections with the same destination IP share the same SCC, which is indexed by dip_idx, but dip_idx isn't necessarily equal to qpn. Therefore, dip_idx should be used to query SCC context instead of qpn.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 4 ++-- drivers/infiniband/hw/hns/hns_roce_restrack.c | 9 ++++++++- 2 files changed, 10 insertions(+), 3 deletions(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +2 -2
@@ -5514,7 +5514,7 @@ static int hns_roce_v2_query_srqc(struct hns_roce_dev *hr_dev, u32 srqn,return ret; } -static int hns_roce_v2_query_sccc (struct hns_roce_dev *hr_dev,u32 qpn, +static int hns_roce_v2_query_sccc (struct hns_roce_dev *hr_dev,u32 sccn,void *buffer) {struct hns_roce_v2_scc_context *context;
@@ -5526,7 +5526,7 @@ static int hns_roce_v2_query_sccc(struct hns_roce_dev *hr_dev, u32 qpn,return PTR_ERR (mailbox); ret =hns_roce_cmd_mbox (hr_dev,0 , mailbox->dma,HNS_ROCE_CMD_QUERY_SCCC , - qpn); + sccn);if (ret) goto out;
drivers/infiniband/hw/hns/hns_roce_restrack.c +8 -1
@@ -100,6 +100,7 @@ int hns_roce_fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ib_qp)struct hns_roce_v2_qp_context qpc;struct hns_roce_v2_scc_context sccc; } context = {}; +u32 sccn = hr_qp->qpn;int ret;if (!hr_dev->hw->query_qpc)
@@ -116,7 +117,13 @@ int hns_roce_fill_res_qp_entry_raw(struct sk_buff *msg, struct ib_qp *ib_qp) !hr_dev->hw->query_sccc) goto out; - ret = hr_dev->hw->query_sccc (hr_dev, hr_qp->qpn, &context.sccc); +if (hr_qp->cong_type ==CONG_TYPE_DIP ) { +if (!hr_qp->dip) + goto out; + sccn = hr_qp->dip->dip_idx; + } + + ret = hr_dev->hw->query_sccc (hr_dev, sccn, &context.sccc);if (ret) ibdev_warn_ratelimited(&hr_dev->ib_dev, "failed to query SCCC, ret = %d.\n",
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 361/457 RDMA/bnxt_re: Fix to do SRQ armena by default
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 6296f9a5293ada28558f2867ac54c487e1e2b9f2 ]
Whenever SRQ is created, make sure SRQ arm enable is always set. Driver is always ready to receive SRQ ASYNC event.
Additional note -
There is no need to do srq arm enable conditionally. See bnxt_qplib_armen_db in bnxt_qplib_create_cq().
--- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/infiniband/hw/bnxt_re/qplib_fp.c +1 -2
@@ -705,8 +705,7 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, srq->dbinfo.db = srq->dpi->dbr; srq->dbinfo.max_slot =1 ; srq->dbinfo.priv_db = res->dpi_tbl.priv_db; -if (srq->threshold) -bnxt_qplib_armen_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ_ARMENA ); +bnxt_qplib_armen_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ_ARMENA ); srq->arm_req = false;return 0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 362/457 RDMA/bnxt_re: Fix to remove workload check in SRQ limit path
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kashyap Desai <[email protected]>
[ Upstream commit 666bce0bd7e771127cb0cda125cc9d32d9f9f15d ]
There should not be any checks of current workload to set srq_limit value to SRQ hw context.
Remove all such workload checks and make a direct call to set srq_limit via doorbell SRQ_ARM.
--- drivers/infiniband/hw/bnxt_re/ib_verbs.c | 8 ++----- drivers/infiniband/hw/bnxt_re/qplib_fp.c | 27 ------------------------ drivers/infiniband/hw/bnxt_re/qplib_fp.h | 2 -- 3 files changed, 2 insertions(+), 35 deletions(-)
drivers/infiniband/hw/bnxt_re/ib_verbs.c +2 -6
@@ -1921,7 +1921,6 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr, struct bnxt_re_srq *srq = container_of(ib_srq, struct bnxt_re_srq, ib_srq);struct bnxt_re_dev *rdev = srq->rdev; -int rc;switch (srq_attr_mask) {case IB_SRQ_MAX_WR :
@@ -1933,11 +1932,8 @@ int bnxt_re_modify_srq(struct ib_srq *ib_srq, struct ib_srq_attr *srq_attr,return -EINVAL ; srq->qplib_srq.threshold = srq_attr->srq_limit; - rc =bnxt_qplib_modify_srq (&rdev->qplib_res, &srq->qplib_srq); -if (rc) { -ibdev_err (&rdev->ibdev,"Modify HW SRQ failed!" ); -return rc; - } +bnxt_qplib_srq_arm_db (&srq->qplib_srq.dbinfo, srq->qplib_srq.threshold); +/* On success, update the shadow */ srq->srq_limit = srq_attr->srq_limit;/* No need to Build and send response back to udata */
drivers/infiniband/hw/bnxt_re/qplib_fp.c +0 -27
@@ -706,7 +706,6 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res, srq->dbinfo.max_slot =1 ; srq->dbinfo.priv_db = res->dpi_tbl.priv_db;bnxt_qplib_armen_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ_ARMENA ); - srq->arm_req = false;return 0 ; fail:
@@ -716,24 +715,6 @@ int bnxt_qplib_create_srq(struct bnxt_qplib_res *res,return rc; } -int bnxt_qplib_modify_srq (struct bnxt_qplib_res *res, -struct bnxt_qplib_srq *srq) -{ -struct bnxt_qplib_hwq *srq_hwq = &srq->hwq; -u32 count; - - count =__bnxt_qplib_get_avail (srq_hwq); -if (count > srq->threshold) { - srq->arm_req = false; -bnxt_qplib_srq_arm_db (&srq->dbinfo, srq->threshold); - }else { -/* Deferred arming */ - srq->arm_req = true; - } - -return 0 ; -} -int bnxt_qplib_query_srq (struct bnxt_qplib_res *res,struct bnxt_qplib_srq *srq) {
@@ -775,7 +756,6 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,struct bnxt_qplib_hwq *srq_hwq = &srq->hwq;struct rq_wqe *srqe;struct sq_sge *hw_sge; -u32 count =0 ;int i, next;spin_lock (&srq_hwq->lock);
@@ -807,15 +787,8 @@ int bnxt_qplib_post_srq_recv(struct bnxt_qplib_srq *srq,bnxt_qplib_hwq_incr_prod (&srq->dbinfo, srq_hwq, srq->dbinfo.max_slot); -spin_lock (&srq_hwq->lock); - count =__bnxt_qplib_get_avail (srq_hwq); -spin_unlock (&srq_hwq->lock);/* Ring DB */ bnxt_qplib_ring_prod_db (&srq->dbinfo,DBC_DBC_TYPE_SRQ ); -if (srq->arm_req == true && count > srq->threshold) { - srq->arm_req = false; -bnxt_qplib_srq_arm_db (&srq->dbinfo, srq->threshold); - }return 0 ; }
drivers/infiniband/hw/bnxt_re/qplib_fp.h +0 -2
@@ -543,8 +543,6 @@ int bnxt_qplib_enable_nq(struct pci_dev *pdev, struct bnxt_qplib_nq *nq, srqn_handler_t srq_handler);int bnxt_qplib_create_srq (struct bnxt_qplib_res *res,struct bnxt_qplib_srq *srq); -int bnxt_qplib_modify_srq (struct bnxt_qplib_res *res, -struct bnxt_qplib_srq *srq);int bnxt_qplib_query_srq (struct bnxt_qplib_res *res,struct bnxt_qplib_srq *srq); void bnxt_qplib_destroy_srq(struct bnxt_qplib_res *res,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 363/457 RDMA/bnxt_re: Fix a possible memory leak in the driver
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kalesh AP <[email protected]>
[ Upstream commit ba60a1e8cbbd396c69ff9c8bc3242f5ab133e38a ]
The GID context reuse logic requires the context memory to be not freed if and when DEL_GID firmware command fails. But, if there's no subsequent ADD_GID to reuse it, the context memory must be freed when the driver is unloaded. Otherwise it leads to a memory leak.
Below is the kmemleak trace reported:
unreferenced object 0xffff88817a4f34d0 (size 8):
comm "insmod", pid 1072504, jiffies 4402561550
hex dump (first 8 bytes):
01 00 00 00 00 00 00 00 ........
backtrace (crc ccaa009e):
__kmalloc_cache_noprof+0x33e/0x400 0xffffffffc2db9d48 add_modify_gid+0x5e0/0xb60 [ib_core] __ib_cache_gid_add+0x213/0x350 [ib_core] update_gid+0xf2/0x180 [ib_core] enum_netdev_ipv4_ips+0x3f3/0x690 [ib_core] enum_all_gids_of_dev_cb+0x125/0x1b0 [ib_core] ib_enum_roce_netdev+0x14b/0x250 [ib_core] ib_cache_setup_one+0x2e5/0x540 [ib_core] ib_register_device+0x82c/0xf10 [ib_core] 0xffffffffc2df5ad9 0xffffffffc2da8b07 0xffffffffc2db174d auxiliary_bus_probe+0xa5/0x120 really_probe+0x1e4/0x850 __driver_probe_device+0x18f/0x3d0
--- drivers/infiniband/hw/bnxt_re/main.c | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+)
drivers/infiniband/hw/bnxt_re/main.c +23 -0
@@ -2017,6 +2017,28 @@ static void bnxt_re_free_nqr_mem(struct bnxt_re_dev *rdev) rdev->nqr =NULL ; } +/* When DEL_GID fails, driver is not freeing GID ctx memory. +* To avoid the memory leak, free the memory during unload +*/ +static void bnxt_re_free_gid_ctx (struct bnxt_re_dev *rdev) +{ +struct bnxt_qplib_sgid_tbl *sgid_tbl = &rdev->qplib_res.sgid_tbl; +struct bnxt_re_gid_ctx *ctx, **ctx_tbl; +int i; + +if (!sgid_tbl->active) +return ; + + ctx_tbl = sgid_tbl->ctx; +for (i =0 ; i < sgid_tbl->max; i++) { +if (sgid_tbl->hw_id[i] ==0xFFFF ) +continue ; + + ctx = ctx_tbl[i]; +kfree (ctx); + } +} +static void bnxt_re_dev_uninit (struct bnxt_re_dev *rdev,u8 op_type) {u8 type;
@@ -2030,6 +2052,7 @@ static void bnxt_re_dev_uninit(struct bnxt_re_dev *rdev, u8 op_type)if (test_and_clear_bit (BNXT_RE_FLAG_QOS_WORK_REG , &rdev->flags))cancel_delayed_work_sync (&rdev->worker); +bnxt_re_free_gid_ctx (rdev);if (test_and_clear_bit (BNXT_RE_FLAG_RESOURCES_INITIALIZED , &rdev->flags))bnxt_re_cleanup_res (rdev);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 364/457 RDMA/bnxt_re: Fix to initialize the PBL array
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Anantha Prabhu <[email protected]>
[ Upstream commit 806b9f494f62791ee6d68f515a8056c615a0e7b2 ]
memset the PBL page pointer and page map arrays before populating the SGL addresses of the HWQ.
--- drivers/infiniband/hw/bnxt_re/qplib_res.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/infiniband/hw/bnxt_re/qplib_res.c +2 -0
@@ -121,6 +121,7 @@ static int __alloc_pbl(struct bnxt_qplib_res *res, pbl->pg_arr =vmalloc_array (pages,sizeof (void *));if (!pbl->pg_arr)return -ENOMEM ; +memset (pbl->pg_arr,0 , pages *sizeof (void *)); pbl->pg_map_arr =vmalloc_array (pages,sizeof (dma_addr_t));if (!pbl->pg_map_arr) {
@@ -128,6 +129,7 @@ static int __alloc_pbl(struct bnxt_qplib_res *res, pbl->pg_arr =NULL ;return -ENOMEM ; } +memset (pbl->pg_map_arr,0 , pages *sizeof (dma_addr_t)); pbl->pg_count =0 ; pbl->pg_size = sginfo->pgsize;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 365/457 RDMA/core: Free pfn_list with appropriate kvfree call
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Akhilesh Patil <[email protected]>
[ Upstream commit 111aea0464c20f3eb25a48d5ff6c036e6b416123 ]
Ensure that pfn_list allocated by kvcalloc() is freed using corresponding kvfree() function. Match memory allocation and free routines kvcalloc -> kvfree.
--- drivers/infiniband/core/umem_odp.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/infiniband/core/umem_odp.c +2 -2
@@ -115,7 +115,7 @@ static int ib_init_umem_odp(struct ib_umem_odp *umem_odp, out_free_map:if (ib_uses_virt_dma (dev)) -kfree (map->pfn_list); +kvfree (map->pfn_list);else hmm_dma_map_free (dev->dma_device, map);return ret;
@@ -287,7 +287,7 @@ static void ib_umem_odp_free(struct ib_umem_odp *umem_odp)mutex_unlock (&umem_odp->umem_mutex);mmu_interval_notifier_remove (&umem_odp->notifier);if (ib_uses_virt_dma (dev)) -kfree (umem_odp->map.pfn_list); +kvfree (umem_odp->map.pfn_list);else hmm_dma_map_free (dev->dma_device, &umem_odp->map); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 366/457 RDMA/hns: Fix dip entries leak on devices newer than hip09
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Junxian Huang <[email protected]>
[ Upstream commit fa2e2d31ee3b7212079323b4b09201ef68af3a97 ]
DIP algorithm is also supported on devices newer than hip09, so free dip entries too.
--- drivers/infiniband/hw/hns/hns_roce_hw_v2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/infiniband/hw/hns/hns_roce_hw_v2.c +1 -1
@@ -3043,7 +3043,7 @@ static void hns_roce_v2_exit(struct hns_roce_dev *hr_dev)if (!hr_dev->is_vf)hns_roce_free_link_table (hr_dev); -if (hr_dev->pci_dev->revision ==PCI_REVISION_ID_HIP09 ) +if (hr_dev->pci_dev->revision >=PCI_REVISION_ID_HIP09 )free_dip_entry (hr_dev); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 367/457 net: xilinx: axienet: Fix RX skb ring management in DMAengine mode
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Suraj Gupta <[email protected]>
[ Upstream commit fd980bf6e9cdae885105685259421164f843ca55 ]
Submit multiple descriptors in axienet_rx_cb() to fill Rx skb ring. This ensures the ring "catches up" on previously missed allocations.
Increment Rx skb ring head pointer after BD is successfully allocated. Previously, head pointer was incremented before verifying if descriptor is successfully allocated and has valid entries, which could lead to ring state inconsistency if descriptor setup failed.
These changes improve reliability by maintaining adequate descriptor availability and ensuring proper ring buffer state management.
--- drivers/net/ethernet/xilinx/xilinx_axienet_main.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-)
drivers/net/ethernet/xilinx/xilinx_axienet_main.c +6 -2
@@ -1160,6 +1160,7 @@ static void axienet_dma_rx_cb(void *data, const struct dmaengine_result *result)struct axienet_local *lp = data;struct sk_buff *skb;u32 *app_metadata; +int i; skbuf_dma =axienet_get_rx_desc (lp, lp->rx_ring_tail++); skb = skbuf_dma->skb;
@@ -1178,7 +1179,10 @@ static void axienet_dma_rx_cb(void *data, const struct dmaengine_result *result)u64_stats_add (&lp->rx_packets,1 );u64_stats_add (&lp->rx_bytes, rx_len);u64_stats_update_end (&lp->rx_stat_sync); -axienet_rx_submit_desc (lp->ndev); + +for (i =0 ; i <CIRC_SPACE (lp->rx_ring_head, lp->rx_ring_tail, +RX_BUF_NUM_DEFAULT ); i++) +axienet_rx_submit_desc (lp->ndev);dma_async_issue_pending (lp->rx_chan); }
@@ -1457,7 +1461,6 @@ static void axienet_rx_submit_desc(struct net_device *ndev)if (!skbuf_dma)return ; - lp->rx_ring_head++; skb =netdev_alloc_skb (ndev, lp->max_frm_size);if (!skb)return ;
@@ -1482,6 +1485,7 @@ static void axienet_rx_submit_desc(struct net_device *ndev) skbuf_dma->desc = dma_rx_desc; dma_rx_desc->callback_param = lp; dma_rx_desc->callback_result = axienet_dma_rx_cb; + lp->rx_ring_head++;dmaengine_submit (dma_rx_desc);return ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 368/457 net: bridge: fix soft lockup in br_multicast_query_expired()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Wang Liang <[email protected]>
[ Upstream commit d1547bf460baec718b3398365f8de33d25c5f36f ]
When set multicast_query_interval to a large value, the local variable 'time' in br_multicast_send_query() may overflow. If the time is smaller than jiffies, the timer will expire immediately, and then call mod_timer() again, which creates a loop and may trigger the following soft lockup issue.
watchdog: BUG: soft lockup - CPU#1 stuck for 221s! [rb_consumer:66] CPU: 1 UID: 0 PID: 66 Comm: rb_consumer Not tainted 6.16.0+ #259 PREEMPT(none) Call Trace: <IRQ> __netdev_alloc_skb+0x2e/0x3a0 br_ip6_multicast_alloc_query+0x212/0x1b70 __br_multicast_send_query+0x376/0xac0 br_multicast_send_query+0x299/0x510 br_multicast_query_expired.constprop.0+0x16d/0x1b0 call_timer_fn+0x3b/0x2a0 __run_timers+0x619/0x950 run_timer_softirq+0x11c/0x220 handle_softirqs+0x18e/0x560 __irq_exit_rcu+0x158/0x1a0 sysvec_apic_timer_interrupt+0x76/0x90 </IRQ>
This issue can be reproduced with:
ip link add br0 type bridge
echo 1 > /sys/class/net/br0/bridge/multicast_querier echo 0xffffffffffffffff >
/sys/class/net/br0/bridge/multicast_query_interval
ip link set dev br0 up
The multicast_startup_query_interval can also cause this issue. Similar to the commit 99b40610956a ("net: bridge: mcast: add and enforce query interval minimum"), add check for the query interval maximum to fix this issue.
--- net/bridge/br_multicast.c | 16 ++++++++++++++++ net/bridge/br_private.h | 2 ++ 2 files changed, 18 insertions(+)
net/bridge/br_multicast.c +16 -0
@@ -4818,6 +4818,14 @@ void br_multicast_set_query_intvl(struct net_bridge_mcast *brmctx, intvl_jiffies =BR_MULTICAST_QUERY_INTVL_MIN ; } +if (intvl_jiffies >BR_MULTICAST_QUERY_INTVL_MAX ) { +br_info (brmctx->br, +"trying to set multicast query interval above maximum, setting to %lu (%ums)\n" , +jiffies_to_clock_t (BR_MULTICAST_QUERY_INTVL_MAX ), +jiffies_to_msecs (BR_MULTICAST_QUERY_INTVL_MAX )); + intvl_jiffies =BR_MULTICAST_QUERY_INTVL_MAX ; + } + brmctx->multicast_query_interval = intvl_jiffies; }
@@ -4834,6 +4842,14 @@ void br_multicast_set_startup_query_intvl(struct net_bridge_mcast *brmctx, intvl_jiffies =BR_MULTICAST_STARTUP_QUERY_INTVL_MIN ; } +if (intvl_jiffies >BR_MULTICAST_STARTUP_QUERY_INTVL_MAX ) { +br_info (brmctx->br, +"trying to set multicast startup query interval above maximum, setting to %lu (%ums)\n" , +jiffies_to_clock_t (BR_MULTICAST_STARTUP_QUERY_INTVL_MAX ), +jiffies_to_msecs (BR_MULTICAST_STARTUP_QUERY_INTVL_MAX )); + intvl_jiffies =BR_MULTICAST_STARTUP_QUERY_INTVL_MAX ; + } + brmctx->multicast_startup_query_interval = intvl_jiffies; }
net/bridge/br_private.h +2 -0
@@ -31,6 +31,8 @@#define BR_MULTICAST_DEFAULT_HASH_MAX 4096#define BR_MULTICAST_QUERY_INTVL_MIN msecs_to_jiffies(1000)#define BR_MULTICAST_STARTUP_QUERY_INTVL_MIN BR_MULTICAST_QUERY_INTVL_MIN +#define BR_MULTICAST_QUERY_INTVL_MAX msecs_to_jiffies(86400000)/* 24 hours */ +#define BR_MULTICAST_STARTUP_QUERY_INTVL_MAX BR_MULTICAST_QUERY_INTVL_MAX#define BR_HWDOM_MAX BITS_PER_LONG
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 369/457 net/sched: Fix backlog accounting in qdisc_dequeue_internal
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: William Liu <[email protected]>
[ Upstream commit 52bf272636bda69587952b35ae97690b8dc89941 ]
This issue applies for the following qdiscs: hhf, fq, fq_codel, and fq_pie, and occurs in their change handlers when adjusting to the new limit. The problem is the following in the values passed to the subsequent qdisc_tree_reduce_backlog call given a tbf parent:
When the tbf parent runs out of tokens, skbs of these qdiscs will be placed in gso_skb. Their peek handlers are qdisc_peek_dequeued, which accounts for both qlen and backlog. However, in the case of qdisc_dequeue_internal, ONLY qlen is accounted for when pulling from gso_skb. This means that these qdiscs are missing a qdisc_qstats_backlog_dec when dropping packets to satisfy the new limit in their change handlers.
One can observe this issue with the following (with tc patched to support a limit of 0):
export TARGET=fq
tc qdisc del dev lo root
tc qdisc add dev lo root handle 1: tbf rate 8bit burst 100b latency 1ms tc qdisc replace dev lo handle 3: parent 1:1 $TARGET limit 1000 echo ''; echo 'add child'; tc -s -d qdisc show dev lo
ping -I lo -f -c2 -s32 -W0.001 127.0.0.1 2>&1 >/dev/null echo ''; echo 'after ping'; tc -s -d qdisc show dev lo
tc qdisc change dev lo handle 3: parent 1:1 $TARGET limit 0 echo ''; echo 'after limit drop'; tc -s -d qdisc show dev lo tc qdisc replace dev lo handle 2: parent 1:1 sfq
echo ''; echo 'post graft'; tc -s -d qdisc show dev lo
The second to last show command shows 0 packets but a positive number (74) of backlog bytes. The problem becomes clearer in the last show command, where qdisc_purge_queue triggers qdisc_tree_reduce_backlog with the positive backlog and causes an underflow in the tbf parent's backlog (4096 Mb instead of 0).
To fix this issue, the codepath for all clients of qdisc_dequeue_internal has been simplified: codel, pie, hhf, fq, fq_pie, and fq_codel. qdisc_dequeue_internal handles the backlog adjustments for all cases that do not directly use the dequeue handler.
The old fq_codel_change limit adjustment loop accumulated the arguments to the subsequent qdisc_tree_reduce_backlog call through the cstats field. However, this is confusing and error prone as fq_codel_dequeue could also potentially mutate this field (which qdisc_dequeue_internal calls in the non gso_skb case), so we have unified the code here with other qdiscs.
--- include/net/sch_generic.h | 11 ++++++++--- net/sched/sch_codel.c | 12 +++++++----- net/sched/sch_fq.c | 12 +++++++----- net/sched/sch_fq_codel.c | 12 +++++++----- net/sched/sch_fq_pie.c | 12 +++++++----- net/sched/sch_hhf.c | 12 +++++++----- net/sched/sch_pie.c | 12 +++++++----- 7 files changed, 50 insertions(+), 33 deletions(-)
include/net/sch_generic.h +8 -3
@@ -1038,12 +1038,17 @@ static inline struct sk_buff *qdisc_dequeue_internal(struct Qdisc *sch, bool dir skb =__skb_dequeue (&sch->gso_skb);if (skb) { sch->q.qlen--; +qdisc_qstats_backlog_dec (sch, skb);return skb; } -if (direct) -return __qdisc_dequeue_head (&sch->q); -else +if (direct) { + skb =__qdisc_dequeue_head (&sch->q); +if (skb) +qdisc_qstats_backlog_dec (sch, skb); +return skb; + }else {return sch->dequeue (sch); + } }static inline struct sk_buff *qdisc_dequeue_head (struct Qdisc *sch)
net/sched/sch_codel.c +7 -5
@@ -101,9 +101,9 @@ static const struct nla_policy codel_policy[TCA_CODEL_MAX + 1] = {static int codel_change (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) { +unsigned int dropped_pkts =0 , dropped_bytes =0 ;struct codel_sched_data *q =qdisc_priv (sch);struct nlattr *tb[TCA_CODEL_MAX +1 ]; -unsigned int qlen, dropped =0 ;int err; err = nla_parse_nested_deprecated(tb, TCA_CODEL_MAX, opt,
@@ -142,15 +142,17 @@ static int codel_change(struct Qdisc *sch, struct nlattr *opt,WRITE_ONCE (q->params.ecn, !!nla_get_u32 (tb[TCA_CODEL_ECN ])); - qlen = sch->q.qlen;while (sch->q.qlen > sch->limit) {struct sk_buff *skb =qdisc_dequeue_internal (sch, true); - dropped +=qdisc_pkt_len (skb); -qdisc_qstats_backlog_dec (sch, skb); +if (!skb) +break ; + + dropped_pkts++; + dropped_bytes +=qdisc_pkt_len (skb);rtnl_qdisc_drop (skb, sch); } -qdisc_tree_reduce_backlog (sch, qlen - sch->q.qlen, dropped); +qdisc_tree_reduce_backlog (sch, dropped_pkts, dropped_bytes);sch_tree_unlock (sch);return 0 ;
net/sched/sch_fq.c +7 -5
@@ -1013,11 +1013,11 @@ static int fq_load_priomap(struct fq_sched_data *q,static int fq_change (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) { +unsigned int dropped_pkts =0 , dropped_bytes =0 ;struct fq_sched_data *q =qdisc_priv (sch);struct nlattr *tb[TCA_FQ_MAX +1 ]; -int err, drop_count =0 ; -unsigned drop_len =0 ;u32 fq_log; +int err; err =nla_parse_nested_deprecated (tb,TCA_FQ_MAX , opt, fq_policy,NULL );
@@ -1135,16 +1135,18 @@ static int fq_change(struct Qdisc *sch, struct nlattr *opt, err =fq_resize (sch, fq_log);sch_tree_lock (sch); } +while (sch->q.qlen > sch->limit) {struct sk_buff *skb =qdisc_dequeue_internal (sch, false);if (!skb)break ; - drop_len +=qdisc_pkt_len (skb); + + dropped_pkts++; + dropped_bytes +=qdisc_pkt_len (skb);rtnl_kfree_skbs (skb, skb); - drop_count++; } -qdisc_tree_reduce_backlog (sch, drop_count, drop_len); +qdisc_tree_reduce_backlog (sch, dropped_pkts, dropped_bytes);sch_tree_unlock (sch);return err;
net/sched/sch_fq_codel.c +7 -5
@@ -366,6 +366,7 @@ static const struct nla_policy fq_codel_policy[TCA_FQ_CODEL_MAX + 1] = {static int fq_codel_change (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) { +unsigned int dropped_pkts =0 , dropped_bytes =0 ;struct fq_codel_sched_data *q =qdisc_priv (sch);struct nlattr *tb[TCA_FQ_CODEL_MAX +1 ];u32 quantum =0 ;
@@ -443,13 +444,14 @@ static int fq_codel_change(struct Qdisc *sch, struct nlattr *opt, q->memory_usage > q->memory_limit) {struct sk_buff *skb =qdisc_dequeue_internal (sch, false); - q->cstats.drop_len +=qdisc_pkt_len (skb); +if (!skb) +break ; + + dropped_pkts++; + dropped_bytes +=qdisc_pkt_len (skb);rtnl_kfree_skbs (skb, skb); - q->cstats.drop_count++; } -qdisc_tree_reduce_backlog (sch, q->cstats.drop_count, q->cstats.drop_len); - q->cstats.drop_count =0 ; - q->cstats.drop_len =0 ; +qdisc_tree_reduce_backlog (sch, dropped_pkts, dropped_bytes);sch_tree_unlock (sch);return 0 ;
net/sched/sch_fq_pie.c +7 -5
@@ -287,10 +287,9 @@ static struct sk_buff *fq_pie_qdisc_dequeue(struct Qdisc *sch)static int fq_pie_change (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) { +unsigned int dropped_pkts =0 , dropped_bytes =0 ;struct fq_pie_sched_data *q =qdisc_priv (sch);struct nlattr *tb[TCA_FQ_PIE_MAX +1 ]; -unsigned int len_dropped =0 ; -unsigned int num_dropped =0 ;int err; err =nla_parse_nested (tb,TCA_FQ_PIE_MAX , opt, fq_pie_policy, extack);
@@ -368,11 +367,14 @@ static int fq_pie_change(struct Qdisc *sch, struct nlattr *opt,while (sch->q.qlen > sch->limit) {struct sk_buff *skb =qdisc_dequeue_internal (sch, false); - len_dropped +=qdisc_pkt_len (skb); - num_dropped +=1 ; +if (!skb) +break ; + + dropped_pkts++; + dropped_bytes +=qdisc_pkt_len (skb);rtnl_kfree_skbs (skb, skb); } -qdisc_tree_reduce_backlog (sch, num_dropped, len_dropped); +qdisc_tree_reduce_backlog (sch, dropped_pkts, dropped_bytes);sch_tree_unlock (sch);return 0 ;
net/sched/sch_hhf.c +7 -5
@@ -508,9 +508,9 @@ static const struct nla_policy hhf_policy[TCA_HHF_MAX + 1] = {static int hhf_change (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) { +unsigned int dropped_pkts =0 , dropped_bytes =0 ;struct hhf_sched_data *q =qdisc_priv (sch);struct nlattr *tb[TCA_HHF_MAX +1 ]; -unsigned int qlen, prev_backlog;int err;u64 non_hh_quantum;u32 new_quantum = q->quantum;
@@ -561,15 +561,17 @@ static int hhf_change(struct Qdisc *sch, struct nlattr *opt, usecs_to_jiffies(us)); } - qlen = sch->q.qlen; - prev_backlog = sch->qstats.backlog;while (sch->q.qlen > sch->limit) {struct sk_buff *skb =qdisc_dequeue_internal (sch, false); +if (!skb) +break ; + + dropped_pkts++; + dropped_bytes +=qdisc_pkt_len (skb);rtnl_kfree_skbs (skb, skb); } -qdisc_tree_reduce_backlog (sch, qlen - sch->q.qlen, - prev_backlog - sch->qstats.backlog); +qdisc_tree_reduce_backlog (sch, dropped_pkts, dropped_bytes);sch_tree_unlock (sch);return 0 ;
net/sched/sch_pie.c +7 -5
@@ -141,9 +141,9 @@ static const struct nla_policy pie_policy[TCA_PIE_MAX + 1] = {static int pie_change (struct Qdisc *sch,struct nlattr *opt,struct netlink_ext_ack *extack) { +unsigned int dropped_pkts =0 , dropped_bytes =0 ;struct pie_sched_data *q =qdisc_priv (sch);struct nlattr *tb[TCA_PIE_MAX +1 ]; -unsigned int qlen, dropped =0 ;int err; err = nla_parse_nested_deprecated(tb, TCA_PIE_MAX, opt, pie_policy,
@@ -193,15 +193,17 @@ static int pie_change(struct Qdisc *sch, struct nlattr *opt, nla_get_u32(tb[TCA_PIE_DQ_RATE_ESTIMATOR]));/* Drop excess packets if new limit is lower */ - qlen = sch->q.qlen;while (sch->q.qlen > sch->limit) {struct sk_buff *skb =qdisc_dequeue_internal (sch, true); - dropped +=qdisc_pkt_len (skb); -qdisc_qstats_backlog_dec (sch, skb); +if (!skb) +break ; + + dropped_pkts++; + dropped_bytes +=qdisc_pkt_len (skb);rtnl_qdisc_drop (skb, sch); } -qdisc_tree_reduce_backlog (sch, qlen - sch->q.qlen, dropped); +qdisc_tree_reduce_backlog (sch, dropped_pkts, dropped_bytes);sch_tree_unlock (sch);return 0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 370/457 rtase: Fix Rx descriptor CRC error bit definition
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Justin Lai <[email protected]>
[ Upstream commit 065c31f2c6915b38f45b1c817b31f41f62eaa774 ]
The CRC error bit is located at bit 17 in the Rx descriptor, but the driver was incorrectly using bit 16. Fix it.
--- drivers/net/ethernet/realtek/rtase/rtase.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/realtek/rtase/rtase.h +1 -1
@@ -241,7 +241,7 @@ union rtase_rx_desc {#define RTASE_RX_RES BIT(20)#define RTASE_RX_RUNT BIT(19)#define RTASE_RX_RWT BIT(18) -#define RTASE_RX_CRC BIT(16) +#define RTASE_RX_CRC BIT(17)#define RTASE_RX_V6F BIT(31)#define RTASE_RX_V4F BIT(30)#define RTASE_RX_UDPT BIT(29)
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 371/457 scsi: qla4xxx: Prevent a potential error pointer dereference
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 9dcf111dd3e7ed5fce82bb108e3a3fc001c07225 ]
The qla4xxx_get_ep_fwdb() function is supposed to return NULL on error, but qla4xxx_ep_connect() returns error pointers. Propagating the error pointers will lead to an Oops in the caller, so change the error pointers to NULL.
--- drivers/scsi/qla4xxx/ql4_os.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/scsi/qla4xxx/ql4_os.c +2 -0
@@ -6606,6 +6606,8 @@ static struct iscsi_endpoint *qla4xxx_get_ep_fwdb(struct scsi_qla_host *ha, ep =qla4xxx_ep_connect (ha->host, (struct sockaddr *)dst_addr,0 );vfree (dst_addr); +if (IS_ERR (ep)) +return NULL ;return ep; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 372/457 iommu/amd: Avoid stack buffer overflow from kernel cmdline
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Kees Cook <[email protected]>
[ Upstream commit 8503d0fcb1086a7cfe26df67ca4bd9bd9e99bdec ]
While the kernel command line is considered trusted in most environments, avoid writing 1 byte past the end of "acpiid" if the "str" argument is maximum length.
--- drivers/iommu/amd/init.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/iommu/amd/init.c +2 -2
@@ -3596,7 +3596,7 @@ static int __init parse_ivrs_acpihid(char *str) {u32 seg =0 , bus, dev, fn;char *hid, *uid, *p, *addr; -char acpiid[ACPIID_LEN ] = {0 }; +char acpiid[ACPIID_LEN +1 ] = { };/* size with NULL terminator */ int i; addr =strchr (str,'@' );
@@ -3622,7 +3622,7 @@ static int __init parse_ivrs_acpihid(char *str)/* We have the '@', make it the terminator to get just the acpiid */ *addr++ =0 ; -if (strlen (str) >ACPIID_LEN +1 ) +if (strlen (str) >ACPIID_LEN ) goto not_found;if (sscanf (str,"=%s" , acpiid) !=1 )
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 373/457 Bluetooth: hci_sync: Fix scan state after PA Sync has been established
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit ca88be1a2725a42f8dbad579181611d9dcca8e88 ]
Passive scanning is used to program the address of the peer to be synchronized, so once HCI_EV_LE_PA_SYNC_ESTABLISHED is received it needs to be updated after clearing HCI_PA_SYNC then call hci_update_passive_scan_sync to return it to its original state.
--- net/bluetooth/hci_sync.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-)
net/bluetooth/hci_sync.c +5 -2
@@ -6985,8 +6985,6 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err)hci_dev_lock (hdev); -hci_dev_clear_flag (hdev,HCI_PA_SYNC ); -if (!hci_conn_valid (hdev, conn))clear_bit (HCI_CONN_CREATE_PA_SYNC , &conn->flags);
@@ -7080,6 +7078,11 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)__hci_cmd_sync_status (hdev,HCI_OP_LE_PA_CREATE_SYNC_CANCEL ,0 ,NULL ,HCI_CMD_TIMEOUT ); +hci_dev_clear_flag (hdev,HCI_PA_SYNC ); + +/* Update passive scan since HCI_PA_SYNC flag has been cleared */ +hci_update_passive_scan_sync (hdev); +return err; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 374/457 Bluetooth: btmtk: Fix wait_on_bit_timeout interruption during shutdown
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jiande Lu <[email protected]>
[ Upstream commit 099799fa9b76c5c02b49e07005a85117a25b01ea ]
During the shutdown process, an interrupt occurs that prematurely terminates the wait for the expected event. This change replaces TASK_INTERRUPTIBLE with TASK_UNINTERRUPTIBLE in the wait_on_bit_timeout call to ensure the shutdown process completes as intended without being interrupted by signals.
--- drivers/bluetooth/btmtk.c | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-)
drivers/bluetooth/btmtk.c +1 -6
@@ -642,12 +642,7 @@ static int btmtk_usb_hci_wmt_sync(struct hci_dev *hdev,* WMT command. */ err =wait_on_bit_timeout (&data->flags,BTMTK_TX_WAIT_VND_EVT , -TASK_INTERRUPTIBLE ,HCI_INIT_TIMEOUT ); -if (err == -EINTR ) { -bt_dev_err (hdev,"Execution of wmt command interrupted" ); -clear_bit (BTMTK_TX_WAIT_VND_EVT , &data->flags); - goto err_free_wc; - } +TASK_UNINTERRUPTIBLE ,HCI_INIT_TIMEOUT );if (err) {bt_dev_err (hdev,"Execution of wmt command timed out" );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 375/457 Bluetooth: hci_core: Fix using {cis,bis}_capable for current settings
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 709788b154caf042874d765628ffa860f0bb0d1e ]
{cis,bis}_capable only indicates the controller supports the feature since it doesn't check that LE is enabled so it shall not be used for current setting, instead this introduces {cis,bis}_enabled macros that can be used to indicate that these features are currently enabled.
--- include/net/bluetooth/bluetooth.h | 4 ++-- include/net/bluetooth/hci_core.h | 13 ++++++++++++- net/bluetooth/hci_sync.c | 4 ++-- net/bluetooth/iso.c | 14 +++++++------- net/bluetooth/mgmt.c | 10 +++++----- 5 files changed, 28 insertions(+), 17 deletions(-)
include/net/bluetooth/bluetooth.h +2 -2
@@ -638,7 +638,7 @@ static inline void sco_exit(void)#if IS_ENABLED (CONFIG_BT_LE )int iso_init (void );int iso_exit (void ); -bool iso_enabled (void ); +bool iso_inited (void );#else static inline int iso_init (void ) {
@@ -650,7 +650,7 @@ static inline int iso_exit(void)return 0 ; } -static inline bool iso_enabled (void ) +static inline bool iso_inited (void ) {return false; }
include/net/bluetooth/hci_core.h +12 -1
@@ -1932,6 +1932,8 @@ void hci_conn_del_sysfs(struct hci_conn *conn); !hci_dev_test_flag(dev, HCI_RPA_EXPIRED))#define adv_rpa_valid (adv) (bacmp(&adv->random_addr, BDADDR_ANY) && \ !adv->rpa_expired) +#define le_enabled (dev) (lmp_le_capable(dev) && \ + hci_dev_test_flag(dev, HCI_LE_ENABLED))#define scan_1m (dev) (((dev)->le_tx_def_phys & HCI_LE_SET_PHY_1M) || \ ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_1M))
@@ -1998,14 +2000,23 @@ void hci_conn_del_sysfs(struct hci_conn *conn);/* CIS Master/Slave and BIS support */ #define iso_capable (dev) (cis_capable(dev) || bis_capable(dev)) +#define iso_enabled (dev) (le_enabled(dev) && iso_capable(dev))#define cis_capable (dev) \ (cis_central_capable(dev) || cis_peripheral_capable(dev)) +#define cis_enabled (dev) (le_enabled(dev) && cis_capable(dev))#define cis_central_capable (dev) \ ((dev)->le_features[3] & HCI_LE_CIS_CENTRAL) +#define cis_central_enabled (dev) \ + (le_enabled(dev) && cis_central_capable(dev))#define cis_peripheral_capable (dev) \ ((dev)->le_features[3] & HCI_LE_CIS_PERIPHERAL) +#define cis_peripheral_enabled (dev) \ + (le_enabled(dev) && cis_peripheral_capable(dev))#define bis_capable (dev) ((dev)->le_features[3] & HCI_LE_ISO_BROADCASTER) -#define sync_recv_capable (dev) ((dev)->le_features[3] & HCI_LE_ISO_SYNC_RECEIVER) +#define bis_enabled (dev) (le_enabled(dev) && bis_capable(dev)) +#define sync_recv_capable (dev) \ + ((dev)->le_features[3] & HCI_LE_ISO_SYNC_RECEIVER) +#define sync_recv_enabled (dev) (le_enabled(dev) && sync_recv_capable(dev))#define mws_transport_config_capable (dev) (((dev)->commands[30] & 0x08) && \ (!hci_test_quirk((dev), HCI_QUIRK_BROKEN_MWS_TRANSPORT_CONFIG)))
net/bluetooth/hci_sync.c +2 -2
@@ -4531,14 +4531,14 @@ static int hci_le_set_host_feature_sync(struct hci_dev *hdev) {struct hci_cp_le_set_host_feature cp; -if (!cis_capable (hdev)) +if (!iso_capable (hdev))return 0 ;memset (&cp,0 ,sizeof (cp));/* Connected Isochronous Channels (Host Support) */ cp.bit_number =32 ; - cp.bit_value =1 ; + cp.bit_value =iso_enabled (hdev) ?0x01 :0x00 ;return __hci_cmd_sync_status (hdev,HCI_OP_LE_SET_HOST_FEATURE ,sizeof (cp), &cp,HCI_CMD_TIMEOUT );
net/bluetooth/iso.c +7 -7
@@ -2455,11 +2455,11 @@ static const struct net_proto_family iso_sock_family_ops = { .create = iso_sock_create, }; -static bool iso_inited; +static bool inited; -bool iso_enabled (void ) +bool iso_inited (void ) { -return iso_inited; +return inited; }int iso_init (void )
@@ -2468,7 +2468,7 @@ int iso_init(void)BUILD_BUG_ON (sizeof (struct sockaddr_iso ) >sizeof (struct sockaddr )); -if (iso_inited) +if (inited)return -EALREADY ; err =proto_register (&iso_proto,0 );
@@ -2496,7 +2496,7 @@ int iso_init(void) iso_debugfs =debugfs_create_file ("iso" ,0444 , bt_debugfs,NULL , &iso_debugfs_fops); - iso_inited = true; + inited = true;return 0 ;
@@ -2507,7 +2507,7 @@ int iso_init(void)int iso_exit (void ) { -if (!iso_inited) +if (!inited)return -EALREADY ;bt_procfs_cleanup (&init_net,"iso" );
@@ -2521,7 +2521,7 @@ int iso_exit(void)proto_unregister (&iso_proto); - iso_inited = false; + inited = false;return 0 ; }
net/bluetooth/mgmt.c +5 -5
@@ -922,16 +922,16 @@ static u32 get_current_settings(struct hci_dev *hdev)if (hci_dev_test_flag (hdev,HCI_WIDEBAND_SPEECH_ENABLED )) settings |=MGMT_SETTING_WIDEBAND_SPEECH ; -if (cis_central_capable (hdev)) +if (cis_central_enabled (hdev)) settings |=MGMT_SETTING_CIS_CENTRAL ; -if (cis_peripheral_capable (hdev)) +if (cis_peripheral_enabled (hdev)) settings |=MGMT_SETTING_CIS_PERIPHERAL ; -if (bis_capable (hdev)) +if (bis_enabled (hdev)) settings |=MGMT_SETTING_ISO_BROADCASTER ; -if (sync_recv_capable (hdev)) +if (sync_recv_enabled (hdev)) settings |=MGMT_SETTING_ISO_SYNC_RECEIVER ;if (ll_privacy_capable (hdev))
@@ -4512,7 +4512,7 @@ static int read_exp_features_info(struct sock *sk, struct hci_dev *hdev, }if (IS_ENABLED (CONFIG_BT_LE )) { - flags =iso_enabled () ?BIT (0 ) :0 ; + flags =iso_inited () ?BIT (0 ) :0 ;memcpy (rp->features[idx].uuid, iso_socket_uuid,16 ); rp->features[idx].flags =cpu_to_le32 (flags); idx++;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 376/457 Bluetooth: hci_core: Fix using ll_privacy_capable for current settings
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 3dcf7175f2c04bd3a7d50db3fa42a0bd933b6e23 ]
ll_privacy_capable only indicates that the controller supports the feature but it doesnt' check that LE is enabled so it end up being marked as active in the current settings when it shouldn't.
--- include/net/bluetooth/hci_core.h | 1 + net/bluetooth/mgmt.c | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-)
include/net/bluetooth/hci_core.h +1 -0
@@ -1951,6 +1951,7 @@ void hci_conn_del_sysfs(struct hci_conn *conn); ((dev)->le_rx_def_phys & HCI_LE_SET_PHY_CODED))#define ll_privacy_capable (dev) ((dev)->le_features[0] & HCI_LE_LL_PRIVACY) +#define ll_privacy_enabled (dev) (le_enabled(dev) && ll_privacy_capable(dev))#define privacy_mode_capable (dev) (ll_privacy_capable(dev) && \ ((dev)->commands[39] & 0x04))
net/bluetooth/mgmt.c +1 -1
@@ -934,7 +934,7 @@ static u32 get_current_settings(struct hci_dev *hdev)if (sync_recv_enabled (hdev)) settings |=MGMT_SETTING_ISO_SYNC_RECEIVER ; -if (ll_privacy_capable (hdev)) +if (ll_privacy_enabled (hdev)) settings |=MGMT_SETTING_LL_PRIVACY ;return settings;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 377/457 Bluetooth: hci_sync: Prevent unintended PA sync when SID is 0xFF
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Li <[email protected]>
[ Upstream commit 4d19cd228bbe8ff84a63fe7b11bc756b4b4370c7 ]
After LE Extended Scan times out, conn->sid remains 0xFF, so the PA sync creation process should be aborted.
Btmon snippet from PA sync with SID=0xFF:
< HCI Command: LE Set Extended.. (0x08|0x0042) plen 6 #74726 [hci0] 863.107927
Extended scan: Enabled (0x01)
Filter duplicates: Enabled (0x01)
Duration: 0 msec (0x0000)
Period: 0.00 sec (0x0000)Quoted 1 line
HCI Event: Command Complete (
0x0e) plen 4 #74727 [hci0] 863.109389
LE Set Extended Scan Enable (0x08|0x0042) ncmd 1
Status: Success (0x00)
< HCI Command: LE Periodic Ad.. (0x08|0x0044) plen 14 #74728 [hci0] 865.141168
Options: 0x0000
Use advertising SID, Advertiser Address Type and address
Reporting initially enabled
SID: 0xff
Adv address type: Random (0x01)
Adv address: 0D:D7:2C:E7:42:46 (Non-Resolvable)
Skip: 0x0000
Sync timeout: 20000 msec (0x07d0)
Sync CTE type: 0x0000Quoted 1 line
HCI Event: Command Status (
0x0f) plen 4 #74729 [hci0] 865.143223
LE Periodic Advertising Create Sync (0x08|0x0044) ncmd 1
Status: Success (0x00)--- net/bluetooth/hci_sync.c | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-)
net/bluetooth/hci_sync.c +8 -4
@@ -7045,10 +7045,13 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)/* SID has not been set listen for HCI_EV_LE_EXT_ADV_REPORT to update * it. */ -if (conn->sid ==HCI_SID_INVALID ) -__hci_cmd_sync_status_sk (hdev,HCI_OP_NOP ,0 ,NULL , -HCI_EV_LE_EXT_ADV_REPORT , - conn->conn_timeout,NULL ); +if (conn->sid ==HCI_SID_INVALID ) { + err =__hci_cmd_sync_status_sk (hdev,HCI_OP_NOP ,0 ,NULL , +HCI_EV_LE_EXT_ADV_REPORT , + conn->conn_timeout,NULL ); +if (err == -ETIMEDOUT ) + goto done; + }memset (&cp,0 ,sizeof (cp)); cp.options = qos->bcast.options;
@@ -7078,6 +7081,7 @@ static int hci_le_pa_create_sync(struct hci_dev *hdev, void *data)__hci_cmd_sync_status (hdev,HCI_OP_LE_PA_CREATE_SYNC_CANCEL ,0 ,NULL ,HCI_CMD_TIMEOUT ); +done:hci_dev_clear_flag (hdev,HCI_PA_SYNC );/* Update passive scan since HCI_PA_SYNC flag has been cleared */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 378/457 Bluetooth: hci_event: fix MTU for BN == 0 in CIS Established
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Pauli Virtanen <[email protected]>
[ Upstream commit 0b3725dbf61b51e7c663834811b3691157ae17d6 ]
BN == 0x00 in CIS Established means no isochronous data for the corresponding direction (Core v6.1 pp. 2394). In this case SDU MTU should be 0.
However, the specification does not say the Max_PDU_C_To_P or P_To_C are then zero. Intel AX210 in Framed CIS mode sets nonzero Max_PDU for direction with zero BN. This causes failure later when we try to LE Setup ISO Data Path for disabled direction, which is disallowed (Core v6.1 pp. 2750).
Fix by setting SDU MTU to 0 if BN == 0.
--- net/bluetooth/hci_event.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-)
net/bluetooth/hci_event.c +4 -4
@@ -6744,8 +6744,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, qos->ucast.out.latency =DIV_ROUND_CLOSEST (get_unaligned_le24 (ev->p_latency),1000 ); - qos->ucast.in.sdu =le16_to_cpu (ev->c_mtu); - qos->ucast.out.sdu =le16_to_cpu (ev->p_mtu); + qos->ucast.in.sdu = ev->c_bn ?le16_to_cpu (ev->c_mtu) :0 ; + qos->ucast.out.sdu = ev->p_bn ?le16_to_cpu (ev->p_mtu) :0 ; qos->ucast.in.phy = ev->c_phy; qos->ucast.out.phy = ev->p_phy;break ;
@@ -6759,8 +6759,8 @@ static void hci_le_cis_estabilished_evt(struct hci_dev *hdev, void *data, qos->ucast.in.latency =DIV_ROUND_CLOSEST (get_unaligned_le24 (ev->p_latency),1000 ); - qos->ucast.out.sdu =le16_to_cpu (ev->c_mtu); - qos->ucast.in.sdu =le16_to_cpu (ev->p_mtu); + qos->ucast.out.sdu = ev->c_bn ?le16_to_cpu (ev->c_mtu) :0 ; + qos->ucast.in.sdu = ev->p_bn ?le16_to_cpu (ev->p_mtu) :0 ; qos->ucast.out.phy = ev->c_phy; qos->ucast.in.phy = ev->p_phy;break ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 379/457 Bluetooth: hci_conn: do return error from hci_enhanced_setup_sync()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Sergey Shtylyov <[email protected]>
[ Upstream commit 0eaf7c7e85da7495c0e03a99375707fc954f5e7b ]
The commit e07a06b4eb41 ("Bluetooth: Convert SCO configure_datapath to hci_sync") missed to update the *return* statement under the *case* of BT_CODEC_TRANSPARENT in hci_enhanced_setup_sync(), which led to returning success (0) instead of the negative error code (-EINVAL). However, the result of hci_enhanced_setup_sync() seems to be ignored anyway, since NULL gets passed to hci_cmd_sync_queue() as the last argument in that case and the only function interested in that result is specified by that argument.
--- net/bluetooth/hci_conn.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/bluetooth/hci_conn.c +2 -1
@@ -339,7 +339,8 @@ static int hci_enhanced_setup_sync(struct hci_dev *hdev, void *data)case BT_CODEC_TRANSPARENT :if (!find_next_esco_param (conn, esco_param_msbc,ARRAY_SIZE (esco_param_msbc))) -return false; +return -EINVAL ; + param = &esco_param_msbc[conn->attempt -1 ]; cp.tx_coding_format.id =0x03 ; cp.rx_coding_format.id =0x03 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 380/457 Bluetooth: Add PA_LINK to distinguish BIG sync and PA sync connections
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yang Li <[email protected]>
[ Upstream commit a7bcffc673de219af2698fbb90627016233de67b ]
Currently, BIS_LINK is used for both BIG sync and PA sync connections, which makes it impossible to distinguish them when searching for a PA sync connection.
Adding PA_LINK will make the distinction clearer and simplify future extensions for PA-related features.
Stable-dep-of: 9d4b01a0bf8d ("Bluetooth: hci_core: Fix not accounting for BIS/CIS/PA links separately")
--- include/net/bluetooth/hci.h | 1 + include/net/bluetooth/hci_core.h | 10 +++++++--- net/bluetooth/hci_conn.c | 14 +++++++++----- net/bluetooth/hci_core.c | 27 +++++++++++++++------------ net/bluetooth/hci_event.c | 7 ++++--- net/bluetooth/hci_sync.c | 10 +++++----- net/bluetooth/iso.c | 6 ++++-- net/bluetooth/mgmt.c | 1 + 8 files changed, 46 insertions(+), 30 deletions(-)
include/net/bluetooth/hci.h +1 -0
@@ -562,6 +562,7 @@ enum {#define LE_LINK 0x80#define CIS_LINK 0x82#define BIS_LINK 0x83 +#define PA_LINK 0x84#define INVALID_LINK 0xff/* LMP features */
include/net/bluetooth/hci_core.h +7 -3
@@ -1015,6 +1015,7 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c)break ;case CIS_LINK :case BIS_LINK : +case PA_LINK : h->iso_num++;break ; }
@@ -1042,6 +1043,7 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c)break ;case CIS_LINK :case BIS_LINK : +case PA_LINK : h->iso_num--;break ; }
@@ -1060,6 +1062,7 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)return h->sco_num;case CIS_LINK :case BIS_LINK : +case PA_LINK :return h->iso_num;default :return 0 ;
@@ -1142,7 +1145,7 @@ hci_conn_hash_lookup_create_pa_sync(struct hci_dev *hdev)rcu_read_lock ();list_for_each_entry_rcu (c, &h->list, list) { -if (c->type !=BIS_LINK ) +if (c->type !=PA_LINK )continue ;if (!test_bit (HCI_CONN_CREATE_PA_SYNC , &c->flags))
@@ -1337,7 +1340,7 @@ hci_conn_hash_lookup_big_sync_pend(struct hci_dev *hdev,rcu_read_lock ();list_for_each_entry_rcu (c, &h->list, list) { -if (c->type !=BIS_LINK ) +if (c->type !=PA_LINK )continue ;if (handle == c->iso_qos.bcast.big && num_bis == c->num_bis) {
@@ -1407,7 +1410,7 @@ hci_conn_hash_lookup_pa_sync_handle(struct hci_dev *hdev, __u16 sync_handle)rcu_read_lock ();list_for_each_entry_rcu (c, &h->list, list) { -if (c->type !=BIS_LINK ) +if (c->type !=PA_LINK )continue ;/* Ignore the listen hcon, we are looking
@@ -2038,6 +2041,7 @@ static inline int hci_proto_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr,case CIS_LINK :case BIS_LINK : +case PA_LINK :return iso_connect_ind (hdev, bdaddr, flags);default :
net/bluetooth/hci_conn.c +9 -5
@@ -786,7 +786,7 @@ static int hci_le_big_terminate(struct hci_dev *hdev, u8 big, struct hci_conn *c d->sync_handle = conn->sync_handle;if (test_and_clear_bit (HCI_CONN_PA_SYNC , &conn->flags)) { -hci_conn_hash_list_flag (hdev, find_bis,BIS_LINK , +hci_conn_hash_list_flag (hdev, find_bis,PA_LINK ,HCI_CONN_PA_SYNC , d);if (!d->count)
@@ -915,6 +915,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_tbreak ;case CIS_LINK :case BIS_LINK : +case PA_LINK :if (hdev->iso_mtu)/* Dedicated ISO Buffer exists */ break ;
@@ -980,6 +981,7 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_tbreak ;case CIS_LINK :case BIS_LINK : +case PA_LINK :/* conn->src should reflect the local identity address */ hci_copy_identity_address (hdev, &conn->src, &conn->src_type);
@@ -1034,7 +1036,6 @@ static struct hci_conn *__hci_conn_add(struct hci_dev *hdev, int type, bdaddr_t }hci_conn_init_sysfs (conn); -return conn; }
@@ -1078,6 +1079,7 @@ static void hci_conn_cleanup_child(struct hci_conn *conn, u8 reason)break ;case CIS_LINK :case BIS_LINK : +case PA_LINK :if ((conn->state !=BT_CONNECTED && !test_bit (HCI_CONN_CREATE_CIS , &conn->flags)) ||test_bit (HCI_CONN_BIG_CREATED , &conn->flags))
@@ -1153,7 +1155,8 @@ void hci_conn_del(struct hci_conn *conn) }else {/* Unacked ISO frames */ if (conn->type ==CIS_LINK || - conn->type ==BIS_LINK ) { + conn->type ==BIS_LINK || + conn->type ==PA_LINK ) {if (hdev->iso_pkts) hdev->iso_cnt += conn->sent;else if (hdev->le_pkts)
@@ -2082,7 +2085,7 @@ struct hci_conn *hci_pa_create_sync(struct hci_dev *hdev, bdaddr_t *dst,bt_dev_dbg (hdev,"dst %pMR type %d sid %d" , dst, dst_type, sid); - conn =hci_conn_add_unset (hdev,BIS_LINK , dst,HCI_ROLE_SLAVE ); + conn =hci_conn_add_unset (hdev,PA_LINK , dst,HCI_ROLE_SLAVE );if (IS_ERR (conn))return conn;
@@ -2247,7 +2250,7 @@ struct hci_conn *hci_connect_bis(struct hci_dev *hdev, bdaddr_t *dst,* the start periodic advertising and create BIG commands have * been queued */ -hci_conn_hash_list_state (hdev, bis_mark_per_adv,BIS_LINK , +hci_conn_hash_list_state (hdev, bis_mark_per_adv,PA_LINK ,BT_BOUND , &data);/* Queue start periodic advertising and create BIG */
@@ -2981,6 +2984,7 @@ void hci_conn_tx_queue(struct hci_conn *conn, struct sk_buff *skb)switch (conn->type) {case CIS_LINK :case BIS_LINK : +case PA_LINK :case ACL_LINK :case LE_LINK :break ;
net/bluetooth/hci_core.c +15 -12
@@ -2938,12 +2938,14 @@ int hci_recv_frame(struct hci_dev *hdev, struct sk_buff *skb)case HCI_ACLDATA_PKT :/* Detect if ISO packet has been sent as ACL */ if (hci_conn_num (hdev,CIS_LINK ) || -hci_conn_num (hdev,BIS_LINK )) { +hci_conn_num (hdev,BIS_LINK ) || +hci_conn_num (hdev,PA_LINK )) {__u16 handle =__le16_to_cpu (hci_acl_hdr (skb)->handle);__u8 type; type =hci_conn_lookup_type (hdev,hci_handle (handle)); -if (type ==CIS_LINK || type ==BIS_LINK ) +if (type ==CIS_LINK || type ==BIS_LINK || + type ==PA_LINK )hci_skb_pkt_type (skb) =HCI_ISODATA_PKT ; }break ;
@@ -3398,6 +3400,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote)break ;case CIS_LINK :case BIS_LINK : +case PA_LINK : cnt = hdev->iso_mtu ? hdev->iso_cnt : hdev->le_mtu ? hdev->le_cnt : hdev->acl_cnt;break ;
@@ -3411,7 +3414,7 @@ static inline void hci_quote_sent(struct hci_conn *conn, int num, int *quote) }static struct hci_conn *hci_low_sent (struct hci_dev *hdev,__u8 type, -__u8 type2,int *quote) +int *quote) {struct hci_conn_hash *h = &hdev->conn_hash;struct hci_conn *conn =NULL , *c;
@@ -3423,7 +3426,7 @@ static struct hci_conn *hci_low_sent(struct hci_dev *hdev, __u8 type,rcu_read_lock ();list_for_each_entry_rcu (c, &h->list, list) { -if ((c->type != type && c->type != type2) || +if (c->type != type ||skb_queue_empty (&c->data_q))continue ;
@@ -3627,7 +3630,7 @@ static void hci_sched_sco(struct hci_dev *hdev, __u8 type)else cnt = &hdev->sco_cnt; -while (*cnt && (conn =hci_low_sent (hdev, type, type, "e))) { +while (*cnt && (conn =hci_low_sent (hdev, type, "e))) {while (quote-- && (skb =skb_dequeue (&conn->data_q))) {BT_DBG ("skb %p len %d" , skb, skb->len);hci_send_conn_frame (hdev, conn, skb);
@@ -3746,8 +3749,8 @@ static void hci_sched_le(struct hci_dev *hdev)hci_prio_recalculate (hdev,LE_LINK ); } -/* Schedule CIS */ -static void hci_sched_iso (struct hci_dev *hdev) +/* Schedule iso */ +static void hci_sched_iso (struct hci_dev *hdev,__u8 type) {struct hci_conn *conn;struct sk_buff *skb;
@@ -3755,14 +3758,12 @@ static void hci_sched_iso(struct hci_dev *hdev)BT_DBG ("%s" , hdev->name); -if (!hci_conn_num (hdev,CIS_LINK ) && - !hci_conn_num (hdev,BIS_LINK )) +if (!hci_conn_num (hdev, type))return ; cnt = hdev->iso_pkts ? &hdev->iso_cnt : hdev->le_pkts ? &hdev->le_cnt : &hdev->acl_cnt; -while (*cnt && (conn =hci_low_sent (hdev,CIS_LINK ,BIS_LINK , - "e))) { +while (*cnt && (conn =hci_low_sent (hdev, type, "e))) {while (quote-- && (skb =skb_dequeue (&conn->data_q))) {BT_DBG ("skb %p len %d" , skb, skb->len);hci_send_conn_frame (hdev, conn, skb);
@@ -3787,7 +3788,9 @@ static void hci_tx_work(struct work_struct *work)/* Schedule queues and send stuff to HCI driver */ hci_sched_sco (hdev,SCO_LINK );hci_sched_sco (hdev,ESCO_LINK ); -hci_sched_iso (hdev); +hci_sched_iso (hdev,CIS_LINK ); +hci_sched_iso (hdev,BIS_LINK ); +hci_sched_iso (hdev,PA_LINK );hci_sched_acl (hdev);hci_sched_le (hdev); }
net/bluetooth/hci_event.c +4 -3
@@ -4432,6 +4432,7 @@ static void hci_num_comp_pkts_evt(struct hci_dev *hdev, void *data,case CIS_LINK :case BIS_LINK : +case PA_LINK :if (hdev->iso_pkts) { hdev->iso_cnt += count;if (hdev->iso_cnt > hdev->iso_pkts)
@@ -6381,7 +6382,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, conn->sync_handle =le16_to_cpu (ev->handle); conn->sid =HCI_SID_INVALID ; - mask |=hci_proto_connect_ind (hdev, &ev->bdaddr,BIS_LINK , + mask |=hci_proto_connect_ind (hdev, &ev->bdaddr,PA_LINK , &flags);if (!(mask &HCI_LM_ACCEPT )) {hci_le_pa_term_sync (hdev, ev->handle);
@@ -6392,7 +6393,7 @@ static void hci_le_pa_sync_estabilished_evt(struct hci_dev *hdev, void *data, goto unlock;/* Add connection to indicate PA sync event */ - pa_sync =hci_conn_add_unset (hdev,BIS_LINK ,BDADDR_ANY , + pa_sync =hci_conn_add_unset (hdev,PA_LINK ,BDADDR_ANY ,HCI_ROLE_SLAVE );if (IS_ERR (pa_sync))
@@ -6423,7 +6424,7 @@ static void hci_le_per_adv_report_evt(struct hci_dev *hdev, void *data,hci_dev_lock (hdev); - mask |=hci_proto_connect_ind (hdev,BDADDR_ANY ,BIS_LINK , &flags); + mask |=hci_proto_connect_ind (hdev,BDADDR_ANY ,PA_LINK , &flags);if (!(mask &HCI_LM_ACCEPT )) goto unlock;
net/bluetooth/hci_sync.c +5 -5
@@ -2929,7 +2929,7 @@ static int hci_le_set_ext_scan_param_sync(struct hci_dev *hdev, u8 type,if (sent) {struct hci_conn *conn; - conn =hci_conn_hash_lookup_ba (hdev,BIS_LINK , + conn =hci_conn_hash_lookup_ba (hdev,PA_LINK , &sent->bdaddr);if (conn) {struct bt_iso_qos *qos = &conn->iso_qos;
@@ -5493,7 +5493,7 @@ static int hci_disconnect_sync(struct hci_dev *hdev, struct hci_conn *conn, {struct hci_cp_disconnect cp; -if (conn->type ==BIS_LINK ) { +if (conn->type ==BIS_LINK || conn->type ==PA_LINK ) {/* This is a BIS connection, hci_conn_del will * do the necessary cleanup. */
@@ -5562,7 +5562,7 @@ static int hci_connect_cancel_sync(struct hci_dev *hdev, struct hci_conn *conn,return HCI_ERROR_LOCAL_HOST_TERM ; } -if (conn->type ==BIS_LINK ) { +if (conn->type ==BIS_LINK || conn->type ==PA_LINK ) {/* There is no way to cancel a BIS without terminating the BIG * which is done later on connection cleanup. */
@@ -5627,7 +5627,7 @@ static int hci_reject_conn_sync(struct hci_dev *hdev, struct hci_conn *conn,if (conn->type ==CIS_LINK )return hci_le_reject_cis_sync (hdev, conn, reason); -if (conn->type ==BIS_LINK ) +if (conn->type ==BIS_LINK || conn->type ==PA_LINK )return -EINVAL ;if (conn->type ==SCO_LINK || conn->type ==ESCO_LINK )
@@ -6992,7 +6992,7 @@ static void create_pa_complete(struct hci_dev *hdev, void *data, int err) goto unlock;/* Add connection to indicate PA sync error */ - pa_sync =hci_conn_add_unset (hdev,BIS_LINK ,BDADDR_ANY , + pa_sync =hci_conn_add_unset (hdev,PA_LINK ,BDADDR_ANY ,HCI_ROLE_SLAVE );if (IS_ERR (pa_sync))
net/bluetooth/iso.c +4 -2
@@ -2226,7 +2226,8 @@ int iso_connect_ind(struct hci_dev *hdev, bdaddr_t *bdaddr, __u8 *flags)static void iso_connect_cfm (struct hci_conn *hcon,__u8 status) { -if (hcon->type !=CIS_LINK && hcon->type !=BIS_LINK ) { +if (hcon->type !=CIS_LINK && hcon->type !=BIS_LINK && + hcon->type !=PA_LINK ) {if (hcon->type !=LE_LINK )return ;
@@ -2267,7 +2268,8 @@ static void iso_connect_cfm(struct hci_conn *hcon, __u8 status)static void iso_disconn_cfm (struct hci_conn *hcon,__u8 reason) { -if (hcon->type !=CIS_LINK && hcon->type !=BIS_LINK ) +if (hcon->type !=CIS_LINK && hcon->type !=BIS_LINK && + hcon->type !=PA_LINK )return ;BT_DBG ("hcon %p reason %d" , hcon, reason);
net/bluetooth/mgmt.c +1 -0
@@ -3237,6 +3237,7 @@ static u8 link_to_bdaddr(u8 link_type, u8 addr_type)switch (link_type) {case CIS_LINK :case BIS_LINK : +case PA_LINK :case LE_LINK :switch (addr_type) {case ADDR_LE_DEV_PUBLIC :
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 381/457 Bluetooth: hci_core: Fix not accounting for BIS/CIS/PA links separately
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Luiz Augusto von Dentz <[email protected]>
[ Upstream commit 9d4b01a0bf8d2163ae129c9c537cb0753ad5a2aa ]
This fixes the likes of hci_conn_num(CIS_LINK) returning the total of ISO connection which includes BIS_LINK as well, so this splits the iso_num into each link type and introduces hci_iso_num that can be used in places where the total number of ISO connection still needs to be used.
--- include/net/bluetooth/hci_core.h | 30 +++++++++++++++++++++++++----- 1 file changed, 25 insertions(+), 5 deletions(-)
include/net/bluetooth/hci_core.h +25 -5
@@ -129,7 +129,9 @@ struct hci_conn_hash {struct list_head list;unsigned int acl_num;unsigned int sco_num; -unsigned int iso_num; +unsigned int cis_num; +unsigned int bis_num; +unsigned int pa_num;unsigned int le_num;unsigned int le_num_peripheral; };
@@ -1014,9 +1016,13 @@ static inline void hci_conn_hash_add(struct hci_dev *hdev, struct hci_conn *c) h->sco_num++;break ;case CIS_LINK : + h->cis_num++; +break ;case BIS_LINK : + h->bis_num++; +break ;case PA_LINK : - h->iso_num++; + h->pa_num++;break ; } }
@@ -1042,9 +1048,13 @@ static inline void hci_conn_hash_del(struct hci_dev *hdev, struct hci_conn *c) h->sco_num--;break ;case CIS_LINK : + h->cis_num--; +break ;case BIS_LINK : + h->bis_num--; +break ;case PA_LINK : - h->iso_num--; + h->pa_num--;break ; } }
@@ -1061,9 +1071,11 @@ static inline unsigned int hci_conn_num(struct hci_dev *hdev, __u8 type)case ESCO_LINK :return h->sco_num;case CIS_LINK : +return h->cis_num;case BIS_LINK : +return h->bis_num;case PA_LINK : -return h->iso_num; +return h->pa_num;default :return 0 ; }
@@ -1073,7 +1085,15 @@ static inline unsigned int hci_conn_count(struct hci_dev *hdev) {struct hci_conn_hash *c = &hdev->conn_hash; -return c->acl_num + c->sco_num + c->le_num + c->iso_num; +return c->acl_num + c->sco_num + c->le_num + c->cis_num + c->bis_num + + c->pa_num; +} + +static inline unsigned int hci_iso_count (struct hci_dev *hdev) +{ +struct hci_conn_hash *c = &hdev->conn_hash; + +return c->cis_num + c->bis_num; }static inline bool hci_conn_valid (struct hci_dev *hdev,struct hci_conn *conn)
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 382/457 mlxsw: spectrum: Forward packets with an IPv4 link-local source IP
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Ido Schimmel <[email protected]>
[ Upstream commit f604d3aaf64ff0d90cc875295474d3abf4155629 ]
By default, the device does not forward IPv4 packets with a link-local source IP (i.e., 169.254.0.0/16). This behavior does not align with the kernel which does forward them.
Fix by instructing the device to forward such packets instead of dropping them.
--- drivers/net/ethernet/mellanox/mlxsw/spectrum.c | 2 ++ drivers/net/ethernet/mellanox/mlxsw/trap.h | 1 + 2 files changed, 3 insertions(+)
drivers/net/ethernet/mellanox/mlxsw/spectrum.c +2 -0
@@ -2375,6 +2375,8 @@ static const struct mlxsw_listener mlxsw_sp_listener[] = { ROUTER_EXP, false),MLXSW_SP_RXL_NO_MARK (DISCARD_ING_ROUTER_DIP_LINK_LOCAL ,FORWARD ,ROUTER_EXP , false), +MLXSW_SP_RXL_NO_MARK (DISCARD_ING_ROUTER_SIP_LINK_LOCAL ,FORWARD , +ROUTER_EXP , false),/* Multicast Router Traps */ MLXSW_SP_RXL_MARK (ACL1 ,TRAP_TO_CPU ,MULTICAST , false), MLXSW_SP_RXL_L3_MARK(ACL2, TRAP_TO_CPU, MULTICAST, false),
drivers/net/ethernet/mellanox/mlxsw/trap.h +1 -0
@@ -94,6 +94,7 @@ enum {MLXSW_TRAP_ID_DISCARD_ING_ROUTER_IPV4_SIP_BC =0x16A ,MLXSW_TRAP_ID_DISCARD_ING_ROUTER_IPV4_DIP_LOCAL_NET =0x16B ,MLXSW_TRAP_ID_DISCARD_ING_ROUTER_DIP_LINK_LOCAL =0x16C , +MLXSW_TRAP_ID_DISCARD_ING_ROUTER_SIP_LINK_LOCAL =0x16D ,MLXSW_TRAP_ID_DISCARD_ROUTER_IRIF_EN =0x178 ,MLXSW_TRAP_ID_DISCARD_ROUTER_ERIF_EN =0x179 , MLXSW_TRAP_ID_DISCARD_ROUTER_LPM4 = 0x17B,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 383/457 drm: nova-drm: fix 32-bit arm build
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
[ Upstream commit db2e7bcee11cd57f95fef3c6cbb562d0577eb84a ]
In 32-bit arm, the build fails with:
error[E0308]: mismatched types
--> drivers/gpu/drm/nova/file.rs:42:28
|
42 | getparam.set_value(value);
| --------- ^^^^^ expected `u64`, found `u32`
| |
| arguments to this method are incorrect
|
note: method defined here
--> drivers/gpu/drm/nova/uapi.rs:29:12
|
29 | pub fn set_value(&self, v: u64) {
| ^^^^^^^^^ ------
help: you can convert a `u32` to a `u64`
|
42 | getparam.set_value(value.into());
| +++++++The reason is that Getparam::set_value takes a u64 (from the UAPI), but pci::Device::resource_len() returns a resource_size_t, which is a phys_addr_t, which may be 32- or 64-bit.
Thus add an into() call to support the 32-bit case, while allowing the Clippy lint that complains in the 64-bit case where the type is the same.
--- drivers/gpu/drm/nova/file.rs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
drivers/gpu/drm/nova/file.rs +2 -1
@@ -39,7 +39,8 @@ impl File { _ => return Err(EINVAL), }; - getparam.set_value (value); +#[allow(clippy::useless_conversion)] + getparam.set_value (value.into ());Ok (0 ) }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 384/457 md: rename recovery_cp to resync_offset
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Li Nan <[email protected]>
[ Upstream commit 907a99c314a5a695e35acff78ac61f4ec950a6d3 ]
'recovery_cp' was used to represent the progress of sync, but its name contains recovery, which can cause confusion. Replaces 'recovery_cp' with 'resync_offset' for clarity.
Stable-dep-of: b7ee30f0efd1 ("md: fix sync_action incorrect display during resync")
--- drivers/md/dm-raid.c | 42 ++++++++++++++-------------- drivers/md/md-bitmap.c | 8 +++--- drivers/md/md-cluster.c | 16 +++++------ drivers/md/md.c | 50 +++++++++++++++++----------------- drivers/md/md.h | 2 +- drivers/md/raid0.c | 6 ++-- drivers/md/raid1-10.c | 2 +- drivers/md/raid1.c | 10 +++---- drivers/md/raid10.c | 16 +++++------ drivers/md/raid5-ppl.c | 6 ++-- drivers/md/raid5.c | 30 ++++++++++---------- include/uapi/linux/raid/md_p.h | 2 +- 12 files changed, 95 insertions(+), 95 deletions(-)
drivers/md/dm-raid.c +21 -21
@@ -439,7 +439,7 @@ static bool rs_is_reshapable(struct raid_set *rs)/* Return true, if raid set in @rs is recovering */ static bool rs_is_recovering (struct raid_set *rs) { -return rs->md.recovery_cp < rs->md.dev_sectors; +return rs->md.resync_offset < rs->md.dev_sectors; }/* Return true, if raid set in @rs is reshaping */
@@ -769,7 +769,7 @@ static struct raid_set *raid_set_alloc(struct dm_target *ti, struct raid_type *r rs->md.layout = raid_type->algorithm; rs->md.new_layout = rs->md.layout; rs->md.delta_disks =0 ; - rs->md.recovery_cp = MaxSector; + rs->md.resync_offset = MaxSector;for (i =0 ; i < raid_devs; i++)md_rdev_init (&rs->dev[i].rdev);
@@ -913,7 +913,7 @@ static int parse_dev_params(struct raid_set *rs, struct dm_arg_set *as) rs->md.external =0 ; rs->md.persistent =1 ; rs->md.major_version =2 ; - }else if (rebuild && !rs->md.recovery_cp) { + }else if (rebuild && !rs->md.resync_offset) {/* * Without metadata, we will not be able to tell if the array * is in-sync or not - we must assume it is not. Therefore,
@@ -1696,20 +1696,20 @@ static void rs_setup_recovery(struct raid_set *rs, sector_t dev_sectors) {/* raid0 does not recover */ if (rs_is_raid0 (rs)) - rs->md.recovery_cp = MaxSector; + rs->md.resync_offset = MaxSector;/* * A raid6 set has to be recovered either * completely or for the grown part to * ensure proper parity and Q-Syndrome */ else if (rs_is_raid6 (rs)) - rs->md.recovery_cp = dev_sectors; + rs->md.resync_offset = dev_sectors;/* * Other raid set types may skip recovery * depending on the 'nosync' flag. */ else - rs->md.recovery_cp =test_bit (__CTR_FLAG_NOSYNC, &rs->ctr_flags) + rs->md.resync_offset =test_bit (__CTR_FLAG_NOSYNC, &rs->ctr_flags) ? MaxSector : dev_sectors; }
@@ -2144,7 +2144,7 @@ static void super_sync(struct mddev *mddev, struct md_rdev *rdev) sb->events =cpu_to_le64 (mddev->events); sb->disk_recovery_offset =cpu_to_le64 (rdev->recovery_offset); - sb->array_resync_offset =cpu_to_le64 (mddev->recovery_cp); + sb->array_resync_offset =cpu_to_le64 (mddev->resync_offset); sb->level =cpu_to_le32 (mddev->level); sb->layout =cpu_to_le32 (mddev->layout);
@@ -2335,18 +2335,18 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) }if (!test_bit (__CTR_FLAG_NOSYNC, &rs->ctr_flags)) - mddev->recovery_cp =le64_to_cpu (sb->array_resync_offset); + mddev->resync_offset =le64_to_cpu (sb->array_resync_offset);/* * During load, we set FirstUse if a new superblock was written. * There are two reasons we might not have a superblock: * 1) The raid set is brand new - in which case, all of the * devices must have their In_sync bit set. Also, -* recovery_cp must be 0, unless forced. +* resync_offset must be 0, unless forced. * 2) This is a new device being added to an old raid set * and the new device needs to be rebuilt - in which * case the In_sync bit will /not/ be set and -* recovery_cp must be MaxSector. +* resync_offset must be MaxSector. * 3) This is/are a new device(s) being added to an old * raid set during takeover to a higher raid level * to provide capacity for redundancy or during reshape
@@ -2391,8 +2391,8 @@ static int super_init_validation(struct raid_set *rs, struct md_rdev *rdev) new_devs > 1 ? "s" : "");return -EINVAL ; }else if (!test_bit (__CTR_FLAG_REBUILD, &rs->ctr_flags) &&rs_is_recovering (rs)) { -DMERR ("'rebuild' specified while raid set is not in-sync (recovery_cp=%llu)" , - (unsigned long long ) mddev->recovery_cp); +DMERR ("'rebuild' specified while raid set is not in-sync (resync_offset=%llu)" , + (unsigned long long ) mddev->resync_offset);return -EINVAL ; }else if (rs_is_reshaping (rs)) { DMERR("'rebuild' specified while raid set is being reshaped (reshape_position=%llu)",
@@ -2697,11 +2697,11 @@ static int rs_adjust_data_offsets(struct raid_set *rs) } out:/* -* Raise recovery_cp in case data_offset != 0 to +* Raise resync_offset in case data_offset != 0 to * avoid false recovery positives in the constructor. */ -if (rs->md.recovery_cp < rs->md.dev_sectors) - rs->md.recovery_cp += rs->dev[0 ].rdev.data_offset; +if (rs->md.resync_offset < rs->md.dev_sectors) + rs->md.resync_offset += rs->dev[0 ].rdev.data_offset;/* Adjust data offsets on all rdevs but on any raid4/5/6 journal device */ rdev_for_each (rdev, &rs->md) {
@@ -2756,7 +2756,7 @@ static int rs_setup_takeover(struct raid_set *rs) }clear_bit (MD_ARRAY_FIRST_USE , &mddev->flags); - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector;while (d--) { rdev = &rs->dev[d].rdev;
@@ -2764,7 +2764,7 @@ static int rs_setup_takeover(struct raid_set *rs)if (test_bit (d, (void *) rs->rebuild_disks)) {clear_bit (In_sync, &rdev->flags);clear_bit (Faulty, &rdev->flags); - mddev->recovery_cp = rdev->recovery_offset =0 ; + mddev->resync_offset = rdev->recovery_offset =0 ;/* Bitmap has to be created when we do an "up" takeover */ set_bit (MD_ARRAY_FIRST_USE , &mddev->flags); }
@@ -3222,7 +3222,7 @@ static int raid_ctr(struct dm_target *ti, unsigned int argc, char **argv)if (r) goto bad; -rs_setup_recovery (rs, rs->md.recovery_cp < rs->md.dev_sectors ? rs->md.recovery_cp : rs->md.dev_sectors); +rs_setup_recovery (rs, rs->md.resync_offset < rs->md.dev_sectors ? rs->md.resync_offset : rs->md.dev_sectors); }else {/* This is no size change or it is shrinking, update size and record in superblocks */ r =rs_set_dev_and_array_sectors (rs, rs->ti->len, false);
@@ -3446,7 +3446,7 @@ static sector_t rs_get_progress(struct raid_set *rs, unsigned long recovery, }else {if (state == st_idle && !test_bit (MD_RECOVERY_INTR , &recovery)) - r = mddev->recovery_cp; + r = mddev->resync_offset;else r = mddev->curr_resync_completed;
@@ -4074,9 +4074,9 @@ static int raid_preresume(struct dm_target *ti) }/* Check for any resize/reshape on @rs and adjust/initiate */ -if (mddev->recovery_cp && mddev->recovery_cp < MaxSector) { +if (mddev->resync_offset && mddev->resync_offset < MaxSector) {set_bit (MD_RECOVERY_REQUESTED , &mddev->recovery); - mddev->resync_min = mddev->recovery_cp; + mddev->resync_min = mddev->resync_offset;if (test_bit (RT_FLAG_RS_GROW , &rs->runtime_flags)) mddev->resync_max_sectors = mddev->dev_sectors; }
drivers/md/md-bitmap.c +4 -4
@@ -1987,12 +1987,12 @@ static void bitmap_dirty_bits(struct mddev *mddev, unsigned long s,md_bitmap_set_memory_bits (bitmap, sec,1 );md_bitmap_file_set_bit (bitmap, sec); -if (sec < bitmap->mddev->recovery_cp) +if (sec < bitmap->mddev->resync_offset)/* We are asserting that the array is dirty, -* so move the recovery_cp address back so +* so move the resync_offset address back so * that it is obvious that it is dirty */ - bitmap->mddev->recovery_cp = sec; + bitmap->mddev->resync_offset = sec; } }
@@ -2258,7 +2258,7 @@ static int bitmap_load(struct mddev *mddev) || bitmap->events_cleared == mddev->events)/* no need to keep dirty bits to optimise a * re-add of a missing device */ - start = mddev->recovery_cp; + start = mddev->resync_offset;mutex_lock (&mddev->bitmap_info.mutex); err =md_bitmap_init_from_disk (bitmap, start);
drivers/md/md-cluster.c +8 -8
@@ -337,11 +337,11 @@ static void recover_bitmaps(struct md_thread *thread)md_wakeup_thread (mddev->sync_thread);if (hi >0 ) { -if (lo < mddev->recovery_cp) - mddev->recovery_cp = lo; +if (lo < mddev->resync_offset) + mddev->resync_offset = lo;/* wake up thread to continue resync in case resync * is not finished */ -if (mddev->recovery_cp != MaxSector) { +if (mddev->resync_offset != MaxSector) {/* * clear the REMOTE flag since we will launch * resync thread in current node.
@@ -863,9 +863,9 @@ static int gather_all_resync_info(struct mddev *mddev, int total_slots)lockres_free (bm_lockres);continue ; } -if ((hi >0 ) && (lo < mddev->recovery_cp)) { +if ((hi >0 ) && (lo < mddev->resync_offset)) {set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); - mddev->recovery_cp = lo; + mddev->resync_offset = lo;md_check_recovery (mddev); }
@@ -1027,7 +1027,7 @@ static int leave(struct mddev *mddev)* Also, we should send BITMAP_NEEDS_SYNC message in * case reshaping is interrupted. */ -if ((cinfo->slot_number >0 && mddev->recovery_cp != MaxSector) || +if ((cinfo->slot_number >0 && mddev->resync_offset != MaxSector) || (mddev->reshape_position != MaxSector &&test_bit (MD_CLOSING , &mddev->flags)))resync_bitmap (mddev);
@@ -1605,8 +1605,8 @@ static int gather_bitmaps(struct md_rdev *rdev)pr_warn ("md-cluster: Could not gather bitmaps from slot %d" , sn); goto out; } -if ((hi >0 ) && (lo < mddev->recovery_cp)) - mddev->recovery_cp = lo; +if ((hi >0 ) && (lo < mddev->resync_offset)) + mddev->resync_offset = lo; } out:return err;
drivers/md/md.c +25 -25
159 lines not on this page · raw message
drivers/md/md.h +1 -1
@@ -523,7 +523,7 @@ struct mddev {unsigned long normal_io_events;/* IO event timestamp */ atomic_t recovery_active;/* blocks scheduled, but not written */ wait_queue_head_t recovery_wait; -sector_t recovery_cp; +sector_t resync_offset;sector_t resync_min;/* user requested sync * starts here */ sector_t resync_max;/* resync should pause
drivers/md/raid0.c +3 -3
@@ -673,7 +673,7 @@ static void *raid0_takeover_raid45(struct mddev *mddev) mddev->raid_disks--; mddev->delta_disks =-1 ;/* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector;mddev_clear_unsupported_flags (mddev,UNSUPPORTED_MDDEV_FLAGS );create_strip_zones (mddev, &priv_conf);
@@ -716,7 +716,7 @@ static void *raid0_takeover_raid10(struct mddev *mddev) mddev->raid_disks += mddev->delta_disks; mddev->degraded =0 ;/* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector;mddev_clear_unsupported_flags (mddev,UNSUPPORTED_MDDEV_FLAGS );create_strip_zones (mddev, &priv_conf);
@@ -759,7 +759,7 @@ static void *raid0_takeover_raid1(struct mddev *mddev) mddev->delta_disks =1 - mddev->raid_disks; mddev->raid_disks =1 ;/* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector;mddev_clear_unsupported_flags (mddev,UNSUPPORTED_MDDEV_FLAGS );create_strip_zones (mddev, &priv_conf);
drivers/md/raid1-10.c +1 -1
@@ -283,7 +283,7 @@ static inline int raid1_check_read_range(struct md_rdev *rdev,static inline bool raid1_should_read_first (struct mddev *mddev,sector_t this_sector,int len) { -if ((mddev->recovery_cp < this_sector + len)) +if ((mddev->resync_offset < this_sector + len))return true; if (mddev_is_clustered(mddev) &&
drivers/md/raid1.c +5 -5
@@ -2822,7 +2822,7 @@ static sector_t raid1_sync_request(struct mddev *mddev, sector_t sector_nr, }if (mddev->bitmap ==NULL && - mddev->recovery_cp == MaxSector && + mddev->resync_offset == MaxSector && !test_bit (MD_RECOVERY_REQUESTED , &mddev->recovery) && conf->fullsync ==0 ) { *skipped =1 ;
@@ -3282,9 +3282,9 @@ static int raid1_run(struct mddev *mddev) }if (conf->raid_disks - mddev->degraded ==1 ) - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; -if (mddev->recovery_cp != MaxSector) +if (mddev->resync_offset != MaxSector)pr_info ("md/raid1:%s: not clean -- starting background reconstruction\n" ,mdname (mddev)); pr_info("md/raid1:%s: active with %d out of %d mirrors\n",
@@ -3345,8 +3345,8 @@ static int raid1_resize(struct mddev *mddev, sector_t sectors)md_set_array_sectors (mddev, newsize);if (sectors > mddev->dev_sectors && - mddev->recovery_cp > mddev->dev_sectors) { - mddev->recovery_cp = mddev->dev_sectors; + mddev->resync_offset > mddev->dev_sectors) { + mddev->resync_offset = mddev->dev_sectors;set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); } mddev->dev_sectors = sectors;
drivers/md/raid10.c +8 -8
@@ -2117,7 +2117,7 @@ static int raid10_add_disk(struct mddev *mddev, struct md_rdev *rdev)int last = conf->geo.raid_disks -1 ;struct raid10_info *p; -if (mddev->recovery_cp < MaxSector) +if (mddev->resync_offset < MaxSector)/* only hot-add to in-sync arrays, as recovery is * very different from resync */
@@ -3185,7 +3185,7 @@ static sector_t raid10_sync_request(struct mddev *mddev, sector_t sector_nr,* of a clean array, like RAID1 does. */ if (mddev->bitmap == NULL && - mddev->recovery_cp == MaxSector && + mddev->resync_offset == MaxSector && mddev->reshape_position == MaxSector && !test_bit(MD_RECOVERY_SYNC, &mddev->recovery) && !test_bit(MD_RECOVERY_REQUESTED, &mddev->recovery) &&
@@ -4145,7 +4145,7 @@ static int raid10_run(struct mddev *mddev) disk->recovery_disabled = mddev->recovery_disabled -1 ; } -if (mddev->recovery_cp != MaxSector) +if (mddev->resync_offset != MaxSector)pr_notice ("md/raid10:%s: not clean -- starting background reconstruction\n" ,mdname (mddev)); pr_info("md/raid10:%s: active with %d out of %d devices\n",
@@ -4245,8 +4245,8 @@ static int raid10_resize(struct mddev *mddev, sector_t sectors)md_set_array_sectors (mddev, size);if (sectors > mddev->dev_sectors && - mddev->recovery_cp > oldsize) { - mddev->recovery_cp = oldsize; + mddev->resync_offset > oldsize) { + mddev->resync_offset = oldsize;set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); }calc_sectors (conf, sectors);
@@ -4275,7 +4275,7 @@ static void *raid10_takeover_raid0(struct mddev *mddev, sector_t size, int devs) mddev->delta_disks = mddev->raid_disks; mddev->raid_disks *=2 ;/* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector; mddev->dev_sectors = size; conf =setup_conf (mddev);
@@ -5087,8 +5087,8 @@ static void raid10_finish_reshape(struct mddev *mddev)return ;if (mddev->delta_disks >0 ) { -if (mddev->recovery_cp > mddev->resync_max_sectors) { - mddev->recovery_cp = mddev->resync_max_sectors; +if (mddev->resync_offset > mddev->resync_max_sectors) { + mddev->resync_offset = mddev->resync_max_sectors;set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); } mddev->resync_max_sectors = mddev->array_sectors;
drivers/md/raid5-ppl.c +3 -3
@@ -1163,7 +1163,7 @@ static int ppl_load_distributed(struct ppl_log *log) le64_to_cpu(pplhdr->generation));/* attempt to recover from log if we are starting a dirty array */ -if (pplhdr && !mddev->pers && mddev->recovery_cp != MaxSector) +if (pplhdr && !mddev->pers && mddev->resync_offset != MaxSector) ret =ppl_recover (log, pplhdr, pplhdr_offset);/* write empty header if we are starting the array */
@@ -1422,14 +1422,14 @@ int ppl_init_log(struct r5conf *conf)if (ret) { goto err; - }else if (!mddev->pers && mddev->recovery_cp ==0 && + }else if (!mddev->pers && mddev->resync_offset ==0 && ppl_conf->recovered_entries >0 && ppl_conf->mismatch_count ==0 ) {/* * If we are starting a dirty array and the recovery succeeds * without any issues, set the array as clean. */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector;set_bit (MD_SB_CHANGE_CLEAN , &mddev->sb_flags); }else if (mddev->pers && ppl_conf->mismatch_count >0 ) {/* no mismatch allowed when enabling PPL for a running array */
drivers/md/raid5.c +15 -15
@@ -3740,7 +3740,7 @@ static int want_replace(struct stripe_head *sh, int disk_idx) && !test_bit (Faulty, &rdev->flags) && !test_bit (In_sync, &rdev->flags) && (rdev->recovery_offset <= sh->sector - || rdev->mddev->recovery_cp <= sh->sector)) + || rdev->mddev->resync_offset <= sh->sector)) rv = 1;return rv; }
@@ -3832,7 +3832,7 @@ static int need_this_block(struct stripe_head *sh, struct stripe_head_state *s,* is missing/faulty, then we need to read everything we can. */ if (!force_rcw && - sh->sector < sh->raid_conf->mddev->recovery_cp) + sh->sector < sh->raid_conf->mddev->resync_offset)/* reconstruct-write isn't being forced */ return 0 ;for (i =0 ; i < s->failed && i <2 ; i++) {
@@ -4097,7 +4097,7 @@ static int handle_stripe_dirtying(struct r5conf *conf, int disks) {int rmw =0 , rcw =0 , i; -sector_t recovery_cp = conf->mddev->recovery_cp; +sector_t resync_offset = conf->mddev->resync_offset;/* Check whether resync is now happening or should start. * If yes, then the array is dirty (after unclean shutdown or
@@ -4107,14 +4107,14 @@ static int handle_stripe_dirtying(struct r5conf *conf,* generate correct data from the parity. */ if (conf->rmw_level ==PARITY_DISABLE_RMW || - (recovery_cp < MaxSector && sh->sector >= recovery_cp && + (resync_offset < MaxSector && sh->sector >= resync_offset && s->failed ==0 )) {/* Calculate the real rcw later - for now make it * look like rcw is cheaper */ rcw =1 ; rmw =2 ; -pr_debug ("force RCW rmw_level=%u, recovery_cp=%llu sh->sector=%llu\n" , - conf->rmw_level, (unsigned long long )recovery_cp, +pr_debug ("force RCW rmw_level=%u, resync_offset=%llu sh->sector=%llu\n" , + conf->rmw_level, (unsigned long long )resync_offset, (unsigned long long )sh->sector); }else for (i = disks; i--; ) {/* would I have to read this buffer for read_modify_write */
@@ -4770,14 +4770,14 @@ static void analyse_stripe(struct stripe_head *sh, struct stripe_head_state *s)if (test_bit (STRIPE_SYNCING , &sh->state)) {/* If there is a failed device being replaced, * we must be recovering. -* else if we are after recovery_cp, we must be syncing +* else if we are after resync_offset, we must be syncing * else if MD_RECOVERY_REQUESTED is set, we also are syncing. * else we can only be replacing * sync and recovery both need to read all devices, and so * use the same flag. */ if (do_recovery || - sh->sector >= conf->mddev->recovery_cp || + sh->sector >= conf->mddev->resync_offset ||test_bit (MD_RECOVERY_REQUESTED , &(conf->mddev->recovery))) s->syncing =1 ;else
@@ -7780,7 +7780,7 @@ static int raid5_run(struct mddev *mddev)int first =1 ;int ret = -EIO ; -if (mddev->recovery_cp != MaxSector) +if (mddev->resync_offset != MaxSector)pr_notice ("md/raid:%s: not clean -- starting background reconstruction\n" ,mdname (mddev));
@@ -7921,7 +7921,7 @@ static int raid5_run(struct mddev *mddev) mdname(mddev)); mddev->ro =1 ;set_disk_ro (mddev->gendisk,1 ); - }else if (mddev->recovery_cp == MaxSector) + }else if (mddev->resync_offset == MaxSector)set_bit (MD_JOURNAL_CLEAN , &mddev->flags); }
@@ -7988,7 +7988,7 @@ static int raid5_run(struct mddev *mddev) mddev->resync_max_sectors = mddev->dev_sectors;if (mddev->degraded > dirty_parity_disks && - mddev->recovery_cp != MaxSector) { + mddev->resync_offset != MaxSector) {if (test_bit (MD_HAS_PPL , &mddev->flags))pr_crit ("md/raid:%s: starting dirty degraded array with PPL.\n" ,mdname (mddev));
@@ -8328,8 +8328,8 @@ static int raid5_resize(struct mddev *mddev, sector_t sectors)md_set_array_sectors (mddev, newsize);if (sectors > mddev->dev_sectors && - mddev->recovery_cp > mddev->dev_sectors) { - mddev->recovery_cp = mddev->dev_sectors; + mddev->resync_offset > mddev->dev_sectors) { + mddev->resync_offset = mddev->dev_sectors;set_bit (MD_RECOVERY_NEEDED , &mddev->recovery); } mddev->dev_sectors = sectors;
@@ -8423,7 +8423,7 @@ static int raid5_start_reshape(struct mddev *mddev)return -EINVAL ;/* raid5 can't handle concurrent reshape and recovery */ -if (mddev->recovery_cp < MaxSector) +if (mddev->resync_offset < MaxSector)return -EBUSY ;for (i =0 ; i < conf->raid_disks; i++)if (conf->disks[i].replacement)
@@ -8648,7 +8648,7 @@ static void *raid45_takeover_raid0(struct mddev *mddev, int level) mddev->raid_disks +=1 ; mddev->delta_disks =1 ;/* make sure it will be not marked as dirty */ - mddev->recovery_cp = MaxSector; + mddev->resync_offset = MaxSector;return setup_conf (mddev); }
include/uapi/linux/raid/md_p.h +1 -1
@@ -173,7 +173,7 @@ typedef struct mdp_superblock_s {#else #error unspecified endianness#endif -__u32 recovery_cp;/* 11 recovery checkpoint sector count */ +__u32 resync_offset;/* 11 resync checkpoint sector count */ /* There are only valid for minor_version > 90 */ __u64 reshape_position;/* 12,13 next address in array-space for reshape */ __u32 new_level;/* 14 new level we are reshaping to */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 385/457 md: add helper rdev_needs_recovery()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Qixing <[email protected]>
[ Upstream commit cb0780ad4333040a98e10f014b593ef738a3f31e ]
Add a helper for checking if an rdev needs recovery.
Stable-dep-of: b7ee30f0efd1 ("md: fix sync_action incorrect display during resync")
--- drivers/md/md.c | 23 ++++++++++++----------- 1 file changed, 12 insertions(+), 11 deletions(-)
drivers/md/md.c +12 -11
@@ -4822,6 +4822,15 @@ metadata_store(struct mddev *mddev, const char *buf, size_t len)static struct md_sysfs_entry md_metadata =__ATTR_PREALLOC (metadata_version,S_IRUGO |S_IWUSR , metadata_show, metadata_store); +static bool rdev_needs_recovery (struct md_rdev *rdev,sector_t sectors) +{ +return rdev->raid_disk >=0 && + !test_bit (Journal, &rdev->flags) && + !test_bit (Faulty, &rdev->flags) && + !test_bit (In_sync, &rdev->flags) && + rdev->recovery_offset < sectors; +} +enum sync_action md_sync_action (struct mddev *mddev) {unsigned long recovery = mddev->recovery;
@@ -8959,11 +8968,7 @@ static sector_t md_sync_position(struct mddev *mddev, enum sync_action action) start = MaxSector;rcu_read_lock ();rdev_for_each_rcu (rdev, mddev) -if (rdev->raid_disk >=0 && - !test_bit (Journal, &rdev->flags) && - !test_bit (Faulty, &rdev->flags) && - !test_bit (In_sync, &rdev->flags) && - rdev->recovery_offset < start) +if (rdev_needs_recovery (rdev, start)) start = rdev->recovery_offset;rcu_read_unlock ();
@@ -9322,12 +9327,8 @@ void md_do_sync(struct md_thread *thread) test_bit(MD_RECOVERY_RECOVER, &mddev->recovery)) {rcu_read_lock ();rdev_for_each_rcu (rdev, mddev) -if (rdev->raid_disk >=0 && - mddev->delta_disks >=0 && - !test_bit (Journal, &rdev->flags) && - !test_bit (Faulty, &rdev->flags) && - !test_bit (In_sync, &rdev->flags) && - rdev->recovery_offset < mddev->curr_resync) +if (mddev->delta_disks >=0 && +rdev_needs_recovery (rdev, mddev->curr_resync)) rdev->recovery_offset = mddev->curr_resync;rcu_read_unlock (); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 386/457 md: fix sync_action incorrect display during resync
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Zheng Qixing <[email protected]>
[ Upstream commit b7ee30f0efd12f42735ae233071015389407966c ]
During raid resync, if a disk becomes faulty, the operation is briefly interrupted. The MD_RECOVERY_RECOVER flag triggered by the disk failure causes sync_action to incorrectly show "recover" instead of "resync". The same issue affects reshape operations.
Reproduction steps:
mdadm -Cv /dev/md1 -l1 -n4 -e1.2 /dev/sd{a..d} // -> resync happened
mdadm -f /dev/md1 /dev/sda // -> resync interrupted
cat sync_action
-> recover
Add progress checks in md_sync_action() for resync/recover/reshape to ensure the interface correctly reports the actual operation type.
--- drivers/md/md.c | 37 +++++++++++++++++++++++++++++++++++-- 1 file changed, 35 insertions(+), 2 deletions(-)
drivers/md/md.c +35 -2
@@ -4831,9 +4831,33 @@ static bool rdev_needs_recovery(struct md_rdev *rdev, sector_t sectors) rdev->recovery_offset < sectors; } +static enum sync_action md_get_active_sync_action (struct mddev *mddev) +{ +struct md_rdev *rdev; +bool is_recover = false; + +if (mddev->resync_offset < MaxSector) +return ACTION_RESYNC ; + +if (mddev->reshape_position != MaxSector) +return ACTION_RESHAPE ; + +rcu_read_lock (); +rdev_for_each_rcu (rdev, mddev) { +if (rdev_needs_recovery (rdev, MaxSector)) { + is_recover = true; +break ; + } + } +rcu_read_unlock (); + +return is_recover ?ACTION_RECOVER :ACTION_IDLE ; +} +enum sync_action md_sync_action (struct mddev *mddev) {unsigned long recovery = mddev->recovery; +enum sync_action active_action;/* * frozen has the highest priority, means running sync_thread will be
@@ -4857,8 +4881,17 @@ enum sync_action md_sync_action(struct mddev *mddev) !test_bit(MD_RECOVERY_NEEDED, &recovery))return ACTION_IDLE ; -if (test_bit (MD_RECOVERY_RESHAPE , &recovery) || - mddev->reshape_position != MaxSector) +/* +* Check if any sync operation (resync/recover/reshape) is +* currently active. This ensures that only one sync operation +* can run at a time. Returns the type of active operation, or +* ACTION_IDLE if none are active. +*/ + active_action =md_get_active_sync_action (mddev); +if (active_action !=ACTION_IDLE ) +return active_action; + +if (test_bit (MD_RECOVERY_RESHAPE , &recovery))return ACTION_RESHAPE ;if (test_bit (MD_RECOVERY_RECOVER , &recovery))
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 387/457 rust: alloc: fix `rusttest` by providing `Cmalloc::aligned_layout` too
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Miguel Ojeda <[email protected]>
[ Upstream commit 0f580d5d3d9d9cd0953695cd32e43aac3a946338 ]
Commit fde578c86281 ("rust: alloc: replace aligned_size() with Kmalloc::aligned_layout()") provides a public aligned_layout function in Kamlloc, but not in Cmalloc, and thus uses of it will trigger an error in rusttest.
Such a user appeared in the following commit 22ab0641b939 ("rust: drm:
ensure kmalloc() compatible Layout"):
error[E0599]: no function or associated item named `aligned_layout` found for struct `alloc::allocator_test::Cmalloc` in the current scope
--> rust/kernel/drm/device.rs:100:31
|
100 | let layout = Kmalloc::aligned_layout(Layout::new::<Self>());
| ^^^^^^^^^^^^^^ function or associated item not found in `Cmalloc`
|
::: rust/kernel/alloc/allocator_test.rs:19:1
|
19 | pub struct Cmalloc;
| ------------------ function or associated item `aligned_layout` not found for this structThus add an equivalent one for Cmalloc.
--- rust/kernel/alloc/allocator_test.rs | 11 +++++++++++ 1 file changed, 11 insertions(+)
rust/kernel/alloc/allocator_test.rs +11 -0
@@ -22,6 +22,17 @@ pub type Kmalloc = Cmalloc;pub type Vmalloc =Kmalloc ;pub type KVmalloc =Kmalloc ; +impl Cmalloc { +/// Returns a [`Layout`] that makes [`Kmalloc`] fulfill the requested size and alignment of +/// `layout`. +pub fn aligned_layout (layout:Layout ) ->Layout { +// Note that `layout.size()` (after padding) is guaranteed to be a multiple of +// `layout.align()` which together with the slab guarantees means that `Kmalloc` will return +// a properly aligned object (see comments in `kmalloc()` for more information). + layout.pad_to_align () + } +} +extern "C" {#[link_name = "aligned_alloc" ] fn libc_aligned_alloc (align:usize , size:usize ) -> *mut crate ::ffi::c_void ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 388/457 drm/hisilicon/hibmc: fix the i2c device resource leak when vdac init failed
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit e5f48bfa2ae0806d5f51fb8061afc619a73599a7 ]
Currently the driver missed to clean the i2c adapter when vdac init failed. It may cause resource leak.
--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h | 1 + drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c | 5 +++++ drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c | 11 ++++++++--- 3 files changed, 14 insertions(+), 3 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.h +1 -0
@@ -69,6 +69,7 @@ int hibmc_de_init(struct hibmc_drm_private *priv);int hibmc_vdac_init (struct hibmc_drm_private *priv);int hibmc_ddc_create (struct drm_device *drm_dev,struct hibmc_vdac *connector); +void hibmc_ddc_del (struct hibmc_vdac *vdac);int hibmc_dp_init (struct hibmc_drm_private *priv);
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_i2c.c +5 -0
@@ -95,3 +95,8 @@ int hibmc_ddc_create(struct drm_device *drm_dev, struct hibmc_vdac *vdac)return i2c_bit_add_bus (&vdac->adapter); } + +void hibmc_ddc_del (struct hibmc_vdac *vdac) +{ +i2c_del_adapter (&vdac->adapter); +}
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_vdac.c +8 -3
@@ -53,7 +53,7 @@ static void hibmc_connector_destroy(struct drm_connector *connector) {struct hibmc_vdac *vdac =to_hibmc_vdac (connector); -i2c_del_adapter (&vdac->adapter); +hibmc_ddc_del (vdac);drm_connector_cleanup (connector); }
@@ -110,7 +110,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) ret =drmm_encoder_init (dev, encoder,NULL ,DRM_MODE_ENCODER_DAC ,NULL );if (ret) {drm_err (dev,"failed to init encoder: %d\n" , ret); -return ret; + goto err; }drm_encoder_helper_add (encoder, &hibmc_encoder_helper_funcs);
@@ -121,7 +121,7 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) &vdac->adapter);if (ret) {drm_err (dev,"failed to init connector: %d\n" , ret); -return ret; + goto err; }drm_connector_helper_add (connector, &hibmc_connector_helper_funcs);
@@ -131,4 +131,9 @@ int hibmc_vdac_init(struct hibmc_drm_private *priv) connector->polled =DRM_CONNECTOR_POLL_CONNECT |DRM_CONNECTOR_POLL_DISCONNECT ;return 0 ; + +err: +hibmc_ddc_del (vdac); + +return ret; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 389/457 drm/hisilicon/hibmc: fix irq_request()s irq name variable is local
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit 8bed4ec42a4e0dc8113172696ff076d1eb6d8bcb ]
The local variable is passed in request_irq (), and there will be use after free problem, which will make request_irq failed. Using the global irq name instead of it to fix.
--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 10 +++------- 1 file changed, 3 insertions(+), 7 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +3 -7
@@ -32,7 +32,7 @@DEFINE_DRM_GEM_FOPS (hibmc_fops); -static const char *g_irqs_names_map[HIBMC_MAX_VECTORS ] = {"vblank" ,"hpd" }; +static const char *g_irqs_names_map[HIBMC_MAX_VECTORS ] = {"hibmc-vblank" ,"hibmc-hpd" };static irqreturn_t hibmc_interrupt (int irq,void *arg) {
@@ -277,7 +277,6 @@ static void hibmc_unload(struct drm_device *dev)static int hibmc_msi_init (struct drm_device *dev) {struct pci_dev *pdev =to_pci_dev (dev->dev); -char name[32 ] = {0 };int valid_irq_num;int irq;int ret;
@@ -292,9 +291,6 @@ static int hibmc_msi_init(struct drm_device *dev) valid_irq_num = ret;for (int i =0 ; i < valid_irq_num; i++) { -snprintf (name,ARRAY_SIZE (name) -1 ,"%s-%s-%s" , - dev->driver->name,pci_name (pdev), g_irqs_names_map[i]); - irq =pci_irq_vector (pdev, i);if (i)
@@ -302,10 +298,10 @@ static int hibmc_msi_init(struct drm_device *dev) ret =devm_request_threaded_irq (&pdev->dev, irq, hibmc_dp_interrupt, hibmc_dp_hpd_isr, -IRQF_SHARED , name, dev); +IRQF_SHARED , g_irqs_names_map[i], dev); else ret =devm_request_irq (&pdev->dev, irq, hibmc_interrupt, -IRQF_SHARED , name, dev); +IRQF_SHARED , g_irqs_names_map[i], dev);if (ret) {drm_err (dev,"install irq failed: %d\n" , ret);return ret;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 390/457 drm/hisilicon/hibmc: fix the hibmc loaded failed bug
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit 93a08f856fcc5aaeeecad01f71bef3088588216a ]
When hibmc loaded failed, the driver use hibmc_unload to free the resource, but the mutexes in mode.config are not init, which will access an NULL pointer. Just change goto statement to return, because hibnc_hw_init() doesn't need to free anything.
--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +2 -2
@@ -319,13 +319,13 @@ static int hibmc_load(struct drm_device *dev) ret =hibmc_hw_init (priv);if (ret) - goto err; +return ret; ret =drmm_vram_helper_init (dev,pci_resource_start (pdev,0 ),pci_resource_len (pdev,0 ));if (ret) {drm_err (dev,"Error initializing VRAM MM; %d\n" , ret); - goto err; +return ret; } ret =hibmc_kms_init (priv);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 391/457 drm/hisilicon/hibmc: fix rare monitors cannot display problem
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit 9f98b429ba67d430b873e06bcfb90afa22888978 ]
In some case, the dp link training success at 8.1Gbps, but the sink's maximum supported rate is less than 8.1G. So change the default 8.1Gbps link rate to the rate that reads from devices' capabilities.
--- drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-)
drivers/gpu/drm/hisilicon/hibmc/dp/dp_link.c +12 -2
@@ -325,6 +325,17 @@ static int hibmc_dp_link_downgrade_training_eq(struct hibmc_dp_dev *dp)return hibmc_dp_link_reduce_rate (dp); } +static void hibmc_dp_update_caps (struct hibmc_dp_dev *dp) +{ + dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE ]; +if (dp->link.cap.link_rate >DP_LINK_BW_8_1 || !dp->link.cap.link_rate) + dp->link.cap.link_rate =DP_LINK_BW_8_1 ; + + dp->link.cap.lanes = dp->dpcd[DP_MAX_LANE_COUNT ] &DP_MAX_LANE_COUNT_MASK ; +if (dp->link.cap.lanes >HIBMC_DP_LANE_NUM_MAX ) + dp->link.cap.lanes =HIBMC_DP_LANE_NUM_MAX ; +} +int hibmc_dp_link_training (struct hibmc_dp_dev *dp) {struct hibmc_dp_link *link = &dp->link;
@@ -334,8 +345,7 @@ int hibmc_dp_link_training(struct hibmc_dp_dev *dp)if (ret)drm_err (dp->dev,"dp aux read dpcd failed, ret: %d\n" , ret); - dp->link.cap.link_rate = dp->dpcd[DP_MAX_LINK_RATE ]; - dp->link.cap.lanes =0x2 ; +hibmc_dp_update_caps (dp); ret =hibmc_dp_get_serdes_rate_cfg (dp);if (ret <0 )
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 392/457 drm/hisilicon/hibmc: fix dp and vga cannot show together
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Baihan Li <[email protected]>
[ Upstream commit 3271faf42d135bcf569c3ff6af55c21858eec212 ]
If VGA and DP connected together, there will be only one can get crtc. Add encoder possible_clones to support two connectors enable.
--- drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c | 8 ++++++++ 1 file changed, 8 insertions(+)
drivers/gpu/drm/hisilicon/hibmc/hibmc_drm_drv.c +8 -0
@@ -115,6 +115,8 @@ static const struct drm_mode_config_funcs hibmc_mode_funcs = {static int hibmc_kms_init (struct hibmc_drm_private *priv) {struct drm_device *dev = &priv->dev; +struct drm_encoder *encoder; +u32 clone_mask =0 ;int ret; ret =drmm_mode_config_init (dev);
@@ -154,6 +156,12 @@ static int hibmc_kms_init(struct hibmc_drm_private *priv)return ret; } +drm_for_each_encoder (encoder, dev) + clone_mask |=drm_encoder_mask (encoder); + +drm_for_each_encoder (encoder, dev) + encoder->possible_clones = clone_mask; +return 0 ; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 393/457 ALSA: usb-audio: Fix size validation in convert_chmap_v3()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 89f0addeee3cb2dc49837599330ed9c4612f05b0 ]
The "p" pointer is void so sizeof(*p) is 1. The intent was to check sizeof(*cs_desc), which is 3, instead.
--- sound/usb/stream.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
sound/usb/stream.c +1 -1
@@ -349,7 +349,7 @@ snd_pcm_chmap_elem *convert_chmap_v3(struct uac3_cluster_header_descriptoru16 cs_len;u8 cs_type; -if (len <sizeof (*p)) +if (len <sizeof (*cs_desc))break ; cs_len =le16_to_cpu (cs_desc->wLength);if (len < cs_len)
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 394/457 regulator: pca9450: Use devm_register_sys_off_handler
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Peng Fan <[email protected]>
[ Upstream commit 447be50598c05499f7ccc2b1f6ddb3da30f8099a ]
With module test, there is error dump:
------------[ cut here ]------------ notifier callback pca9450_i2c_restart_handler already registered WARNING: kernel/notifier.c:23 at notifier_chain_register+0x5c/0x88, CPU#0: kworker/u16:3/50 Call trace: notifier_chain_register+0x5c/0x88 (P) atomic_notifier_chain_register+0x30/0x58 register_restart_handler+0x1c/0x28 pca9450_i2c_probe+0x418/0x538 i2c_device_probe+0x220/0x3d0 really_probe+0x114/0x410 __driver_probe_device+0xa0/0x150 driver_probe_device+0x40/0x114 __device_attach_driver+0xd4/0x12c
So use devm_register_sys_off_handler to let kernel handle the resource free to avoid kernel dump.
--- drivers/regulator/pca9450-regulator.c | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-)
drivers/regulator/pca9450-regulator.c +5 -8
@@ -34,7 +34,6 @@ struct pca9450 {struct device *dev;struct regmap *regmap;struct gpio_desc *sd_vsel_gpio; -struct notifier_block restart_nb;enum pca9450_chip_type type;unsigned int rcnt;int irq;
@@ -967,10 +966,9 @@ static irqreturn_t pca9450_irq_handler(int irq, void *data)return IRQ_HANDLED ; } -static int pca9450_i2c_restart_handler (struct notifier_block *nb, -unsigned long action,void *data) +static int pca9450_i2c_restart_handler (struct sys_off_data *data) { - struct pca9450 *pca9450 = container_of(nb, struct pca9450, restart_nb); +struct pca9450 *pca9450 = data->cb_data; struct i2c_client *i2c = container_of(pca9450->dev, struct i2c_client, dev);dev_dbg (&i2c->dev,"Restarting device..\n" );
@@ -1128,10 +1126,9 @@ static int pca9450_i2c_probe(struct i2c_client *i2c) pca9450->sd_vsel_fixed_low =of_property_read_bool (ldo5->dev.of_node,"nxp,sd-vsel-fixed-low" ); - pca9450->restart_nb.notifier_call = pca9450_i2c_restart_handler; - pca9450->restart_nb.priority =PCA9450_RESTART_HANDLER_PRIORITY ; - -if (register_restart_handler (&pca9450->restart_nb)) +if (devm_register_sys_off_handler (&i2c->dev,SYS_OFF_MODE_RESTART , +PCA9450_RESTART_HANDLER_PRIORITY , + pca9450_i2c_restart_handler, pca9450))dev_warn (&i2c->dev,"Failed to register restart handler\n" ); dev_info(&i2c->dev, "%s probed.\n",
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 395/457 drm/amd/display: Add null pointer check in mod_hdcp_hdcp1_create_session()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Chenyuan Yang <[email protected]>
[ Upstream commit 7a2ca2ea64b1b63c8baa94a8f5deb70b2248d119 ]
The function mod_hdcp_hdcp1_create_session() calls the function get_first_active_display(), but does not check its return value. The return value is a null pointer if the display list is empty. This will lead to a null pointer dereference.
Add a null pointer check for get_first_active_display() and return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND if the function return null.
This is similar to the commit c3e9826a2202
("drm/amd/display: Add null pointer check for get_first_active_display()").
--- drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c | 3 +++ 1 file changed, 3 insertions(+)
drivers/gpu/drm/amd/display/modules/hdcp/hdcp_psp.c +3 -0
@@ -260,6 +260,9 @@ enum mod_hdcp_status mod_hdcp_hdcp1_create_session(struct mod_hdcp *hdcp)return MOD_HDCP_STATUS_FAILURE ; } +if (!display) +return MOD_HDCP_STATUS_DISPLAY_NOT_FOUND ; + hdcp_cmd = (struct ta_hdcp_shared_memory *)psp->hdcp_context.context.mem_context.shared_buf;mutex_lock (&psp->hdcp_context.mutex);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 396/457 drm/amd/display: Adjust DCE 8-10 clock, dont overclock by 15%
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit 1fc931be2f47fde23ca5aff6f19421375c312fb2 ]
Adjust the nominal (and performance) clocks for DCE 8-10, and set them to 625 MHz, which is the value used by the legacy display code in amdgpu_atombios_get_clock_info.
This was tested with Hawaii, Tonga and Fiji. These GPUs can output 4K 60Hz (10-bit depth) at 625 MHz.
The extra 15% clock was added as a workaround for a Polaris issue which uses DCE 11, and should not have been used on DCE 8-10 which are already hardcoded to the highest possible display clock. Unfortunately, the extra 15% was mistakenly copied and kept even on code paths which don't affect Polaris.
This commit fixes that and also adds a check to make sure
not to exceed the maximum DCE 8-10 display clock.
--- .../drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c | 12 +++++------- 1 file changed, 5 insertions(+), 7 deletions(-)
drivers/gpu/drm/amd/display/dc/clk_mgr/dce100/dce_clk_mgr.c +5 -7
@@ -72,9 +72,9 @@ static const struct state_dependent_clocks dce80_max_clks_by_state[] = {/* ClocksStateLow */ { .display_clk_khz = 352000, .pixel_clk_khz = 330000}, /* ClocksStateNominal */ -{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 }, +{ .display_clk_khz = 625000, .pixel_clk_khz = 400000 }, /* ClocksStatePerformance */ -{ .display_clk_khz = 600000, .pixel_clk_khz = 400000 } }; +{ .display_clk_khz = 625000, .pixel_clk_khz = 400000 } };int dentist_get_divider_from_did (int did) {
@@ -403,11 +403,9 @@ static void dce_update_clocks(struct clk_mgr *clk_mgr_base, {struct clk_mgr_internal *clk_mgr_dce =TO_CLK_MGR_INTERNAL (clk_mgr_base);struct dm_pp_power_level_change_request level_change_req; -int patched_disp_clk = context->bw_ctx.bw.dce.dispclk_khz; - -/*TODO: W/A for dal3 linux, investigate why this works */ -if (!clk_mgr_dce->dfs_bypass_active) - patched_disp_clk = patched_disp_clk *115 /100 ; +const int max_disp_clk = + clk_mgr_dce->max_clks_by_state[DM_PP_CLOCKS_STATE_PERFORMANCE ].display_clk_khz; +int patched_disp_clk =MIN (max_disp_clk, context->bw_ctx.bw.dce.dispclk_khz); level_change_req.power_level =dce_get_required_clocks_state (clk_mgr_base, context);/* get max clock state from PPLIB */
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 397/457 drm/amd/display: Dont print errors for nonexistent connectors
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Timur Kristóf <[email protected]>
[ Upstream commit f14ee2e7a86c5e57295b48b8e198cae7189b3b93 ]
When getting the number of connectors, the VBIOS reports the number of valid indices, but it doesn't say which indices are valid, and not every valid index has an actual connector. If we don't find a connector on an index, that is not an error.
Considering these are not actual errors, don't litter the logs.
--- drivers/gpu/drm/amd/display/dc/bios/bios_parser.c | 5 +---- drivers/gpu/drm/amd/display/dc/core/dc.c | 15 ++++++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-)
drivers/gpu/drm/amd/display/dc/bios/bios_parser.c +1 -4
@@ -174,11 +174,8 @@ static struct graphics_object_id bios_parser_get_connector_id(return object_id; } -if (tbl->ucNumberOfObjects <= i) { -dm_error ("Can't find connector id %d in connector table of size %d.\n" , - i, tbl->ucNumberOfObjects); +if (tbl->ucNumberOfObjects <= i)return object_id; - } id =le16_to_cpu (tbl->asObjects[i].usObjectID); object_id =object_id_from_bios_object_id (id);
drivers/gpu/drm/amd/display/dc/core/dc.c +14 -1
@@ -217,11 +217,24 @@ static bool create_links( connectors_num, num_virtual_links); -// condition loop on link_count to allow skipping invalid indices +/* When getting the number of connectors, the VBIOS reports the number of valid indices, +* but it doesn't say which indices are valid, and not every index has an actual connector. +* So, if we don't find a connector on an index, that is not an error. +* +* - There is no guarantee that the first N indices will be valid +* - VBIOS may report a higher amount of valid indices than there are actual connectors +* - Some VBIOS have valid configurations for more connectors than there actually are +* on the card. This may be because the manufacturer used the same VBIOS for different +* variants of the same card. +*/ for (i =0 ; dc->link_count < connectors_num && i <MAX_LINKS ; i++) { +struct graphics_object_id connector_id = bios->funcs->get_connector_id (bios, i);struct link_init_data link_init_params = {0 };struct dc_link *link; +if (connector_id.id ==CONNECTOR_ID_UNKNOWN ) +continue ; +DC_LOG_DC ("BIOS object table - printing link object info for connector number: %d, link_index: %d" , i, dc->link_count); link_init_params.ctx = dc->ctx;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 398/457 net: gso: Forbid IPv6 TSO with extensions on devices with only IPV6_CSUM
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jakub Ramaseuski <[email protected]>
[ Upstream commit 864e3396976ef41de6cc7bc366276bf4e084fff2 ]
When performing Generic Segmentation Offload (GSO) on an IPv6 packet that contains extension headers, the kernel incorrectly requests checksum offload if the egress device only advertises NETIF_F_IPV6_CSUM feature, which has a strict contract: it supports checksum offload only for plain TCP or UDP over IPv6 and explicitly does not support packets with extension headers. The current GSO logic violates this contract by failing to disable the feature for packets with extension headers, such as those used in GREoIPv6 tunnels.
This violation results in the device being asked to perform an operation it cannot support, leading to a skb_warn_bad_offload warning and a collapse of network throughput. While device TSO/USO is correctly bypassed in favor of software GSO for these packets, the GSO stack must be explicitly told not to request checksum offload.
Mask NETIF_F_IPV6_CSUM, NETIF_F_TSO6 and NETIF_F_GSO_UDP_L4
in gso_features_check if the IPv6 header contains extension headers to compute checksum in software.
The exception is a BIG TCP extension, which, as stated in commit 68e068cabd2c6c53 ("net: reenable NETIF_F_IPV6_CSUM offload for BIG TCP packets"):
"The feature is only enabled on devices that support BIG TCP TSO. The header is only present for PF_PACKET taps like tcpdump,
and not transmitted by physical devices."
kernel log output (truncated):
WARNING: CPU: 1 PID: 5273 at net/core/dev.c:3535 skb_warn_bad_offload+0x81/0x140 ... Call Trace: <TASK> skb_checksum_help+0x12a/0x1f0 validate_xmit_skb+0x1a3/0x2d0 validate_xmit_skb_list+0x4f/0x80 sch_direct_xmit+0x1a2/0x380 __dev_xmit_skb+0x242/0x670 __dev_queue_xmit+0x3fc/0x7f0 ip6_finish_output2+0x25e/0x5d0 ip6_finish_output+0x1fc/0x3f0 ip6_tnl_xmit+0x608/0xc00 [ip6_tunnel] ip6gre_tunnel_xmit+0x1c0/0x390 [ip6_gre] dev_hard_start_xmit+0x63/0x1c0 __dev_queue_xmit+0x6d0/0x7f0 ip6_finish_output2+0x214/0x5d0 ip6_finish_output+0x1fc/0x3f0 ip6_xmit+0x2ca/0x6f0 ip6_finish_output+0x1fc/0x3f0 ip6_xmit+0x2ca/0x6f0 inet6_csk_xmit+0xeb/0x150 __tcp_transmit_skb+0x555/0xa80 tcp_write_xmit+0x32a/0xe90 tcp_sendmsg_locked+0x437/0x1110 tcp_sendmsg+0x2f/0x50 ... skb linear: 00000000: e4 3d 1a 7d ec 30 e4 3d 1a 7e 5d 90 86 dd 60 0e skb linear: 00000010: 00 0a 1b 34 3c 40 20 11 00 00 00 00 00 00 00 00 skb linear: 00000020: 00 00 00 00 00 12 20 11 00 00 00 00 00 00 00 00 skb linear: 00000030: 00 00 00 00 00 11 2f 00 04 01 04 01 01 00 00 00 skb linear: 00000040: 86 dd 60 0e 00 0a 1b 00 06 40 20 23 00 00 00 00 skb linear: 00000050: 00 00 00 00 00 00 00 00 00 12 20 23 00 00 00 00 skb linear: 00000060: 00 00 00 00 00 00 00 00 00 11 bf 96 14 51 13 f9 skb linear: 00000070: ae 27 a0 a8 2b e3 80 18 00 40 5b 6f 00 00 01 01 skb linear: 00000080: 08 0a 42 d4 50 d5 4b 70 f8 1a
--- net/core/dev.c | 12 ++++++++++++ 1 file changed, 12 insertions(+)
net/core/dev.c +12 -0
@@ -3782,6 +3782,18 @@ static netdev_features_t gso_features_check(const struct sk_buff *skb, features &= ~NETIF_F_TSO_MANGLEID ; } +/* NETIF_F_IPV6_CSUM does not support IPv6 extension headers, +* so neither does TSO that depends on it. +*/ +if (features &NETIF_F_IPV6_CSUM && + (skb_shinfo (skb)->gso_type &SKB_GSO_TCPV6 || + (skb_shinfo (skb)->gso_type &SKB_GSO_UDP_L4 && +vlan_get_protocol (skb) ==htons (ETH_P_IPV6 ))) && +skb_transport_header_was_set (skb) && +skb_network_header_len (skb) !=sizeof (struct ipv6hdr ) && + !ipv6_has_hopopt_jumbo (skb)) + features &= ~(NETIF_F_IPV6_CSUM |NETIF_F_TSO6 |NETIF_F_GSO_UDP_L4 ); +return features; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 399/457 ipv6: sr: validate HMAC algorithm ID in seg6_hmac_info_add
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Minhong He <[email protected]>
[ Upstream commit 84967deee9d9870b15bc4c3acb50f1d401807902 ]
The seg6_genl_sethmac() directly uses the algorithm ID provided by the userspace without verifying whether it is an HMAC algorithm supported by the system.
If an unsupported HMAC algorithm ID is configured, packets using SRv6 HMAC will be dropped during encapsulation or decapsulation.
--- net/ipv6/seg6_hmac.c | 3 +++ 1 file changed, 3 insertions(+)
net/ipv6/seg6_hmac.c +3 -0
@@ -305,6 +305,9 @@ int seg6_hmac_info_add(struct net *net, u32 key, struct seg6_hmac_info *hinfo)struct seg6_pernet_data *sdata =seg6_pernet (net);int err; +if (!__hmac_get_algo (hinfo->alg_id)) +return -EINVAL ; + err =rhashtable_lookup_insert_fast (&sdata->hmac_infos, &hinfo->node, rht_params);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 400/457 bnxt_en: Fix lockdep warning during rmmod
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Michael Chan <[email protected]>
[ Upstream commit 4611d88a37cfc18cbabc6978aaf7325d1ae3f53a ]
The commit under the Fixes tag added a netdev_assert_locked() in bnxt_free_ntp_fltrs(). The lock should be held during normal run-time but the assert will be triggered (see below) during bnxt_remove_one() which should not need the lock. The netdev is already unregistered by then. Fix it by calling netdev_assert_locked_or_invisible() which will not assert if the netdev is unregistered.
WARNING: CPU: 5 PID: 2241 at ./include/net/netdev_lock.h:17 bnxt_free_ntp_fltrs+0xf8/0x100 [bnxt_en] Modules linked in: rpcrdma rdma_cm iw_cm ib_cm configfs ib_core bnxt_en(-) bridge stp llc x86_pkg_temp_thermal xfs tg3 [last unloaded: bnxt_re] CPU: 5 UID: 0 PID: 2241 Comm: rmmod Tainted: G S W 6.16.0 #2 PREEMPT(voluntary) Tainted: [S]=CPU_OUT_OF_SPEC, [W]=WARN Hardware name: Dell Inc. PowerEdge R730/072T6D, BIOS 2.4.3 01/17/2017 RIP: 0010:bnxt_free_ntp_fltrs+0xf8/0x100 [bnxt_en] Code: 41 5c 41 5d 41 5e 41 5f c3 cc cc cc cc 48 8b 47 60 be ff ff ff ff 48 8d b8 28 0c 00 00 e8 d0 cf 41 c3 85 c0 0f 85 2e ff ff ff <0f> 0b e9 27 ff ff ff 90 90 90 90 90 90 90 90 90 90 90 90 90 90 90 RSP: 0018:ffffa92082387da0 EFLAGS: 00010246 RAX: 0000000000000000 RBX: ffff9e5b593d8000 RCX: 0000000000000001 RDX: 0000000000000001 RSI: ffffffff83dc9a70 RDI: ffffffff83e1a1cf RBP: ffff9e5b593d8c80 R08: 0000000000000000 R09: ffffffff8373a2b3 R10: 000000008100009f R11: 0000000000000001 R12: 0000000000000001 R13: ffffffffc01c4478 R14: dead000000000122 R15: dead000000000100 FS: 00007f3a8a52c740(0000) GS:ffff9e631ad1c000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 0000000080050033 CR2: 000055bb289419c8 CR3: 000000011274e001 CR4: 00000000003706f0 Call Trace: <TASK> bnxt_remove_one+0x57/0x180 [bnxt_en] pci_device_remove+0x39/0xc0 device_release_driver_internal+0xa5/0x130 driver_detach+0x42/0x90 bus_remove_driver+0x61/0xc0 pci_unregister_driver+0x38/0x90 bnxt_exit+0xc/0x7d0 [bnxt_en]
--- drivers/net/ethernet/broadcom/bnxt/bnxt.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/ethernet/broadcom/bnxt/bnxt.c +1 -1
@@ -5325,7 +5325,7 @@ static void bnxt_free_ntp_fltrs(struct bnxt *bp, bool all) {int i; -netdev_assert_locked (bp->dev); +netdev_assert_locked_or_invisible (bp->dev);/* Under netdev instance lock and all our NAPIs have been disabled. * It's safe to delete the hash table.
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 401/457 scsi: ufs: core: Fix IRQ lock inversion for the SCSI host lock
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit eabcac808ca3ee9878223d4b49b750979029016b ]
Commit 3c7ac40d7322 ("scsi: ufs: core: Delegate the interrupt service routine to a threaded IRQ handler") introduced an IRQ lock inversion issue. Fix this lock inversion by changing the spin_lock_irq() calls into spin_lock_irqsave() calls in code that can be called either from interrupt context or from thread context. This patch fixes the following lockdep complaint:
WARNING: possible irq lock inversion dependency detected
6.12.30-android16-5-maybe-dirty-4k #1 Tainted: G W OE
--------------------------------------------------------
kworker/u28:0/12 just changed the state of lock:ffffff881e29dd60 (&hba->clk_gating.lock){-...}-{2:2}, at: ufshcd_release_scsi_cmd+0x60/0x110 but this lock took another, HARDIRQ-unsafe lock in the past:
(shost->host_lock){+.+.}-{2:2}
and interrupts could create inverse lock ordering between them.
other info that might help us debug this:
Possible interrupt unsafe locking scenario:
CPU0 CPU1
---- ----
lock(shost->host_lock);
local_irq_disable();
lock(&hba->clk_gating.lock);
lock(shost->host_lock);
<Interrupt>
lock(&hba->clk_gating.lock);*** DEADLOCK ***
4 locks held by kworker/u28:0/12:
#0: ffffff8800ac6158 ((wq_completion)async){+.+.}-{0:0}, at: process_one_work+0x1bc/0x65c #1: ffffffc085c93d70 ((work_completion)(&entry->work)){+.+.}-{0:0}, at: process_one_work+0x1e4/0x65c #2: ffffff881e29c0e0 (&shost->scan_mutex){+.+.}-{3:3}, at: __scsi_add_device+0x74/0x120 #3: ffffff881960ea00 (&hwq->cq_lock){-...}-{2:2}, at: ufshcd_mcq_poll_cqe_lock+0x28/0x104
the shortest dependencies between 2nd lock and 1st lock:
-> (shost->host_lock){+.+.}-{2:2} {
HARDIRQ-ON-W at:
lock_acquire+0x134/0x2b4
_raw_spin_lock+0x48/0x64
ufshcd_sl_intr+0x4c/0xa08
ufshcd_threaded_intr+0x70/0x12c
irq_thread_fn+0x48/0xa8
irq_thread+0x130/0x1ec
kthread+0x110/0x134
ret_from_fork+0x10/0x20
SOFTIRQ-ON-W at:
lock_acquire+0x134/0x2b4
_raw_spin_lock+0x48/0x64
ufshcd_sl_intr+0x4c/0xa08
ufshcd_threaded_intr+0x70/0x12c
irq_thread_fn+0x48/0xa8
irq_thread+0x130/0x1ec
kthread+0x110/0x134
ret_from_fork+0x10/0x20
INITIAL USE at:
lock_acquire+0x134/0x2b4
_raw_spin_lock+0x48/0x64
ufshcd_sl_intr+0x4c/0xa08
ufshcd_threaded_intr+0x70/0x12c
irq_thread_fn+0x48/0xa8
irq_thread+0x130/0x1ec
kthread+0x110/0x134
ret_from_fork+0x10/0x20
}
... key at: [<ffffffc085ba1a98>] scsi_host_alloc.__key+0x0/0x10
... acquired at:
_raw_spin_lock_irqsave+0x5c/0x80
__ufshcd_release+0x78/0x118
ufshcd_send_uic_cmd+0xe4/0x118
ufshcd_dme_set_attr+0x88/0x1c8
ufs_google_phy_initialization+0x68/0x418 [ufs]
ufs_google_link_startup_notify+0x78/0x27c [ufs]
ufshcd_link_startup+0x84/0x720
ufshcd_init+0xf3c/0x1330
ufshcd_pltfrm_init+0x728/0x7d8
ufs_google_probe+0x30/0x84 [ufs]
platform_probe+0xa0/0xe0
really_probe+0x114/0x454
__driver_probe_device+0xa4/0x160
driver_probe_device+0x44/0x23c
__driver_attach_async_helper+0x60/0xd4
async_run_entry_fn+0x4c/0x17c
process_one_work+0x26c/0x65c
worker_thread+0x33c/0x498
kthread+0x110/0x134
ret_from_fork+0x10/0x20-> (&hba->clk_gating.lock){-...}-{2:2} {
IN-HARDIRQ-W at:
lock_acquire+0x134/0x2b4
_raw_spin_lock_irqsave+0x5c/0x80
ufshcd_release_scsi_cmd+0x60/0x110
ufshcd_compl_one_cqe+0x2c0/0x3f4
ufshcd_mcq_poll_cqe_lock+0xb0/0x104
ufs_google_mcq_intr+0x80/0xa0 [ufs]
__handle_irq_event_percpu+0x104/0x32c
handle_irq_event+0x40/0x9c
handle_fasteoi_irq+0x170/0x2e8
generic_handle_domain_irq+0x58/0x80
gic_handle_irq+0x48/0x104
call_on_irq_stack+0x3c/0x50
do_interrupt_handler+0x7c/0xd8
el1_interrupt+0x34/0x58
el1h_64_irq_handler+0x18/0x24
el1h_64_irq+0x68/0x6c
_raw_spin_unlock_irqrestore+0x3c/0x6c
debug_object_assert_init+0x16c/0x21c
__mod_timer+0x4c/0x48c
schedule_timeout+0xd4/0x16c
io_schedule_timeout+0x48/0x70
do_wait_for_common+0x100/0x194
wait_for_completion_io_timeout+0x48/0x6c
blk_execute_rq+0x124/0x17c
scsi_execute_cmd+0x18c/0x3f8
scsi_probe_and_add_lun+0x204/0xd74
__scsi_add_device+0xbc/0x120
ufshcd_async_scan+0x80/0x3c0
async_run_entry_fn+0x4c/0x17c
process_one_work+0x26c/0x65c
worker_thread+0x33c/0x498
kthread+0x110/0x134
ret_from_fork+0x10/0x20
INITIAL USE at:
lock_acquire+0x134/0x2b4
_raw_spin_lock_irqsave+0x5c/0x80
ufshcd_hold+0x34/0x14c
ufshcd_send_uic_cmd+0x28/0x118
ufshcd_dme_set_attr+0x88/0x1c8
ufs_google_phy_initialization+0x68/0x418 [ufs]
ufs_google_link_startup_notify+0x78/0x27c [ufs]
ufshcd_link_startup+0x84/0x720
ufshcd_init+0xf3c/0x1330
ufshcd_pltfrm_init+0x728/0x7d8
ufs_google_probe+0x30/0x84 [ufs]
platform_probe+0xa0/0xe0
really_probe+0x114/0x454
__driver_probe_device+0xa4/0x160
driver_probe_device+0x44/0x23c
__driver_attach_async_helper+0x60/0xd4
async_run_entry_fn+0x4c/0x17c
process_one_work+0x26c/0x65c
worker_thread+0x33c/0x498
kthread+0x110/0x134
ret_from_fork+0x10/0x20
}
... key at: [<ffffffc085ba6fe8>] ufshcd_init.__key+0x0/0x10
... acquired at:
mark_lock+0x1c4/0x224
__lock_acquire+0x438/0x2e1c
lock_acquire+0x134/0x2b4
_raw_spin_lock_irqsave+0x5c/0x80
ufshcd_release_scsi_cmd+0x60/0x110
ufshcd_compl_one_cqe+0x2c0/0x3f4
ufshcd_mcq_poll_cqe_lock+0xb0/0x104
ufs_google_mcq_intr+0x80/0xa0 [ufs]
__handle_irq_event_percpu+0x104/0x32c
handle_irq_event+0x40/0x9c
handle_fasteoi_irq+0x170/0x2e8
generic_handle_domain_irq+0x58/0x80
gic_handle_irq+0x48/0x104
call_on_irq_stack+0x3c/0x50
do_interrupt_handler+0x7c/0xd8
el1_interrupt+0x34/0x58
el1h_64_irq_handler+0x18/0x24
el1h_64_irq+0x68/0x6c
_raw_spin_unlock_irqrestore+0x3c/0x6c
debug_object_assert_init+0x16c/0x21c
__mod_timer+0x4c/0x48c
schedule_timeout+0xd4/0x16c
io_schedule_timeout+0x48/0x70
do_wait_for_common+0x100/0x194
wait_for_completion_io_timeout+0x48/0x6c
blk_execute_rq+0x124/0x17c
scsi_execute_cmd+0x18c/0x3f8
scsi_probe_and_add_lun+0x204/0xd74
__scsi_add_device+0xbc/0x120
ufshcd_async_scan+0x80/0x3c0
async_run_entry_fn+0x4c/0x17c
process_one_work+0x26c/0x65c
worker_thread+0x33c/0x498
kthread+0x110/0x134
ret_from_fork+0x10/0x20
stack backtrace:
CPU: 6 UID: 0 PID: 12 Comm: kworker/u28:0 Tainted: G W OE 6.12.30-android16-5-maybe-dirty-4k #1 ccd4020fe444bdf629efc3b86df6be920b8df7d0
Tainted: [W]=WARN, [O]=OOT_MODULE, [E]=UNSIGNED_MODULE
Hardware name: Spacecraft board based on MALIBU (DT)
Workqueue: async async_run_entry_fn
Call trace:
dump_backtrace+0xfc/0x17c
show_stack+0x18/0x28
dump_stack_lvl+0x40/0xa0
dump_stack+0x18/0x24
print_irq_inversion_bug+0x2fc/0x304
mark_lock_irq+0x388/0x4fc
mark_lock+0x1c4/0x224
__lock_acquire+0x438/0x2e1c
lock_acquire+0x134/0x2b4
_raw_spin_lock_irqsave+0x5c/0x80
ufshcd_release_scsi_cmd+0x60/0x110
ufshcd_compl_one_cqe+0x2c0/0x3f4
ufshcd_mcq_poll_cqe_lock+0xb0/0x104
ufs_google_mcq_intr+0x80/0xa0 [ufs dd6f385554e109da094ab91d5f7be18625a2222a]
__handle_irq_event_percpu+0x104/0x32c
handle_irq_event+0x40/0x9c
handle_fasteoi_irq+0x170/0x2e8
generic_handle_domain_irq+0x58/0x80
gic_handle_irq+0x48/0x104
call_on_irq_stack+0x3c/0x50
do_interrupt_handler+0x7c/0xd8
el1_interrupt+0x34/0x58
el1h_64_irq_handler+0x18/0x24
el1h_64_irq+0x68/0x6c
_raw_spin_unlock_irqrestore+0x3c/0x6c
debug_object_assert_init+0x16c/0x21c
__mod_timer+0x4c/0x48c
schedule_timeout+0xd4/0x16c
io_schedule_timeout+0x48/0x70
do_wait_for_common+0x100/0x194
wait_for_completion_io_timeout+0x48/0x6c
blk_execute_rq+0x124/0x17c
scsi_execute_cmd+0x18c/0x3f8
scsi_probe_and_add_lun+0x204/0xd74
__scsi_add_device+0xbc/0x120
ufshcd_async_scan+0x80/0x3c0
async_run_entry_fn+0x4c/0x17c
process_one_work+0x26c/0x65c
worker_thread+0x33c/0x498
kthread+0x110/0x134
ret_from_fork+0x10/0x20--- drivers/ufs/core/ufshcd.c | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-)
drivers/ufs/core/ufshcd.c +3 -5
@@ -5531,7 +5531,7 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)irqreturn_t retval =IRQ_NONE ;struct uic_command *cmd; -spin_lock (hba->host->host_lock); +guard (spinlock_irqsave)(hba->host->host_lock); cmd = hba->active_uic_cmd;if (WARN_ON_ONCE (!cmd)) goto unlock;
@@ -5558,8 +5558,6 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)ufshcd_add_uic_command_trace (hba, cmd,UFS_CMD_COMP ); unlock: -spin_unlock (hba->host->host_lock); -return retval; }
@@ -6892,7 +6890,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)bool queue_eh_work = false;irqreturn_t retval =IRQ_NONE ; -spin_lock (hba->host->host_lock); +guard (spinlock_irqsave)(hba->host->host_lock); hba->errors |=UFSHCD_ERROR_MASK & intr_status;if (hba->errors &INT_FATAL_ERRORS ) {
@@ -6951,7 +6949,7 @@ static irqreturn_t ufshcd_check_errors(struct ufs_hba *hba, u32 intr_status)*/ hba->errors =0 ; hba->uic_error =0 ; -spin_unlock (hba->host->host_lock); +return retval; }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 402/457 scsi: ufs: core: Remove WARN_ON_ONCE() call from ufshcd_uic_cmd_compl()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bart Van Assche <[email protected]>
[ Upstream commit e5203d89d59bfcbe1f348aa0d2dc4449a8ba644c ]
The UIC completion interrupt may be disabled while an UIC command is being processed. When the UIC completion interrupt is reenabled, an UIC interrupt is triggered and the WARN_ON_ONCE(!cmd) statement is hit. Hence this patch that removes this kernel warning.
--- drivers/ufs/core/ufshcd.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/ufs/core/ufshcd.c +1 -1
@@ -5533,7 +5533,7 @@ static irqreturn_t ufshcd_uic_cmd_compl(struct ufs_hba *hba, u32 intr_status)guard (spinlock_irqsave)(hba->host->host_lock); cmd = hba->active_uic_cmd; -if (WARN_ON_ONCE (!cmd)) +if (!cmd) goto unlock;if (ufshcd_is_auto_hibern8_error (hba, intr_status))
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 403/457 scsi: ufs: ufs-qcom: Update esi_vec_mask for HW major version >= 6
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Bao D. Nguyen <[email protected]>
[ Upstream commit 7a9d5195a7f5871a4ad4e55fc567a2b3bee49a59 ]
The MCQ feature and ESI are supported by all Qualcomm UFS controller versions 6 and above.
Therefore, update the ESI vector mask in the UFS_MEM_CFG3 register for platforms with major version number of 6 or higher.
Stable-dep-of: 6300d5c54387 ("scsi: ufs: ufs-qcom: Fix ESI null pointer dereference")
--- drivers/ufs/host/ufs-qcom.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-)
drivers/ufs/host/ufs-qcom.c +1 -2
@@ -2109,8 +2109,7 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)retain_and_null_ptr (qi); -if (host->hw_ver.major ==6 && host->hw_ver.minor ==0 && - host->hw_ver.step ==0 ) { +if (host->hw_ver.major >=6 ) {ufshcd_rmwl (hba,ESI_VEC_MASK ,FIELD_PREP (ESI_VEC_MASK ,MAX_ESI_VEC -1 ),REG_UFS_CFG3 ); }
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 404/457 scsi: ufs: ufs-qcom: Fix ESI null pointer dereference
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Nitin Rawat <[email protected]>
[ Upstream commit 6300d5c5438724c0876828da2f6e2c1a661871fc ]
ESI/MSI is a performance optimization feature that provides dedicated interrupts per MCQ hardware queue. This is optional feature and UFS MCQ should work with and without ESI feature.
Commit e46a28cea29a ("scsi: ufs: qcom: Remove the MSI descriptor abuse") brings a regression in ESI (Enhanced System Interrupt) configuration that causes a null pointer dereference when Platform MSI allocation fails.
The issue occurs in when platform_device_msi_init_and_alloc_irqs() in ufs_qcom_config_esi() fails (returns -EINVAL) but the current code uses __free() macro for automatic cleanup free MSI resources that were never successfully allocated.
Unable to handle kernel NULL pointer dereference at virtual
address 0000000000000008
Call trace: mutex_lock+0xc/0x54 (P) platform_device_msi_free_irqs_all+0x1c/0x40 ufs_qcom_config_esi+0x1d0/0x220 [ufs_qcom] ufshcd_config_mcq+0x28/0x104 ufshcd_init+0xa3c/0xf40 ufshcd_pltfrm_init+0x504/0x7d4 ufs_qcom_probe+0x20/0x58 [ufs_qcom]
Fix by restructuring the ESI configuration to try MSI allocation first, before any other resource allocation and instead use explicit cleanup instead of __free() macro to avoid cleanup of unallocated resources.
Tested on SM8750 platform with MCQ enabled, both with and without Platform ESI support.
--- drivers/ufs/host/ufs-qcom.c | 39 ++++++++++++++----------------------- 1 file changed, 15 insertions(+), 24 deletions(-)
drivers/ufs/host/ufs-qcom.c +15 -24
@@ -2053,17 +2053,6 @@ static irqreturn_t ufs_qcom_mcq_esi_handler(int irq, void *data)return IRQ_HANDLED ; } -static void ufs_qcom_irq_free (struct ufs_qcom_irq *uqi) -{ -for (struct ufs_qcom_irq *q = uqi; q->irq; q++) -devm_free_irq (q->hba->dev, q->irq, q->hba); - -platform_device_msi_free_irqs_all (uqi->hba->dev); -devm_kfree (uqi->hba->dev, uqi); -} - -DEFINE_FREE(ufs_qcom_irq, struct ufs_qcom_irq *, if (_T) ufs_qcom_irq_free(_T)) -static int ufs_qcom_config_esi (struct ufs_hba *hba) {struct ufs_qcom_host *host =ufshcd_get_variant (hba);
@@ -2078,18 +2067,18 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba)*/ nr_irqs = hba->nr_hw_queues - hba->nr_queues[HCTX_TYPE_POLL ]; - struct ufs_qcom_irq *qi __free(ufs_qcom_irq) = -devm_kcalloc (hba->dev, nr_irqs,sizeof (*qi),GFP_KERNEL ); -if (!qi) -return -ENOMEM ; -/* Preset so __free() has a pointer to hba in all error paths */ - qi[0 ].hba = hba; - ret =platform_device_msi_init_and_alloc_irqs (hba->dev, nr_irqs, ufs_qcom_write_msi_msg);if (ret) { -dev_err (hba->dev,"Failed to request Platform MSI %d\n" , ret); -return ret; +dev_warn (hba->dev,"Platform MSI not supported or failed, continuing without ESI\n" ); +return ret;/* Continue without ESI */ + } + +struct ufs_qcom_irq *qi =devm_kcalloc (hba->dev, nr_irqs,sizeof (*qi),GFP_KERNEL ); + +if (!qi) { +platform_device_msi_free_irqs_all (hba->dev); +return -ENOMEM ; }for (int idx =0 ; idx < nr_irqs; idx++) {
@@ -2100,15 +2089,17 @@ static int ufs_qcom_config_esi(struct ufs_hba *hba) ret =devm_request_irq (hba->dev, qi[idx].irq, ufs_qcom_mcq_esi_handler,IRQF_SHARED ,"qcom-mcq-esi" , qi + idx);if (ret) { -dev_err (hba->dev,"%s: Fail to request IRQ for %d, err = %d\n" , +dev_err (hba->dev,"%s: Failed to request IRQ for %d, err = %d\n" , __func__, qi[idx].irq, ret); - qi[idx].irq =0 ; +/* Free previously allocated IRQs */ +for (int j =0 ; j < idx; j++) +devm_free_irq (hba->dev, qi[j].irq, qi + j); +platform_device_msi_free_irqs_all (hba->dev); +devm_kfree (hba->dev, qi);return ret; } } -retain_and_null_ptr (qi); -if (host->hw_ver.major >=6 ) {ufshcd_rmwl (hba,ESI_VEC_MASK ,FIELD_PREP (ESI_VEC_MASK ,MAX_ESI_VEC -1 ),REG_UFS_CFG3 );
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 405/457 net: ethernet: mtk_ppe: add RCU lock around dev_fill_forward_path
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <[email protected]>
[ Upstream commit 62c30c544359aa18b8fb2734166467a07d435c2d ]
Ensure ndo_fill_forward_path() is called with RCU lock held.
--- drivers/net/ethernet/mediatek/mtk_ppe_offload.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/mediatek/mtk_ppe_offload.c +2 -0
@@ -101,7 +101,9 @@ mtk_flow_get_wdma_info(struct net_device *dev, const u8 *addr, struct mtk_wdma_iif (!IS_ENABLED (CONFIG_NET_MEDIATEK_SOC_WED ))return -1 ; +rcu_read_lock (); err =dev_fill_forward_path (dev, addr, &stack); +rcu_read_unlock ();if (err)return err;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 406/457 ppp: fix race conditions in ppp_fill_forward_path
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Qingfang Deng <[email protected]>
[ Upstream commit 0417adf367a0af11adf7ace849af4638cfb573f7 ]
ppp_fill_forward_path() has two race conditions:
1. The ppp->channels list can change between list_empty() and list_first_entry(), as ppp_lock() is not held. If the only channel is deleted in ppp_disconnect_channel(), list_first_entry() may access an empty head or a freed entry, and trigger a panic.
2. pch->chan can be NULL. When ppp_unregister_channel() is called, pch->chan is set to NULL before pch is removed from ppp->channels.
Fix these by using a lockless RCU approach:
- Use list_first_or_null_rcu() to safely test and access the first list entry.
- Convert list modifications on ppp->channels to their RCU variants and add synchronize_net() after removal.
- Check for a NULL pch->chan before dereferencing it.
--- drivers/net/ppp/ppp_generic.c | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-)
drivers/net/ppp/ppp_generic.c +11 -6
@@ -33,6 +33,7 @@#include <linux/ppp_channel.h> #include <linux/ppp-comp.h> #include <linux/skbuff.h> +#include <linux/rculist.h> #include <linux/rtnetlink.h> #include <linux/if_arp.h> #include <linux/ip.h>
@@ -1612,11 +1613,14 @@ static int ppp_fill_forward_path(struct net_device_path_ctx *ctx,if (ppp->flags &SC_MULTILINK )return -EOPNOTSUPP ; -if (list_empty (&ppp->channels)) + pch = list_first_or_null_rcu(&ppp->channels, struct channel, clist); +if (!pch) +return -ENODEV ; + + chan =READ_ONCE (pch->chan); +if (!chan)return -ENODEV ; - pch = list_first_entry(&ppp->channels, struct channel, clist); - chan = pch->chan;if (!chan->ops->fill_forward_path)return -EOPNOTSUPP ;
@@ -2999,7 +3003,7 @@ ppp_unregister_channel(struct ppp_channel *chan)*/ down_write (&pch->chan_sem);spin_lock_bh (&pch->downl); - pch->chan =NULL ; +WRITE_ONCE (pch->chan,NULL );spin_unlock_bh (&pch->downl);up_write (&pch->chan_sem);ppp_disconnect_channel (pch);
@@ -3509,7 +3513,7 @@ ppp_connect_channel(struct channel *pch, int unit) hdrlen = pch->file.hdrlen +2 ;/* for protocol bytes */ if (hdrlen > ppp->dev->hard_header_len) ppp->dev->hard_header_len = hdrlen; -list_add_tail (&pch->clist, &ppp->channels); +list_add_tail_rcu (&pch->clist, &ppp->channels); ++ppp->n_channels; pch->ppp = ppp;refcount_inc (&ppp->file.refcnt);
@@ -3539,10 +3543,11 @@ ppp_disconnect_channel(struct channel *pch)if (ppp) {/* remove it from the ppp unit's list */ ppp_lock (ppp); -list_del (&pch->clist); +list_del_rcu (&pch->clist);if (--ppp->n_channels ==0 )wake_up_interruptible (&ppp->file.rwait);ppp_unlock (ppp); +synchronize_net ();if (refcount_dec_and_test (&ppp->file.refcnt))ppp_destroy_interface (ppp); err =0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 407/457 net: ti: icssg-prueth: Fix HSR and switch offload Enablement during firwmare reload.
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: MD Danish Anwar <[email protected]>
[ Upstream commit 01792bc3e5bdafa171dd83c7073f00e7de93a653 ]
To enable HSR / Switch offload, certain configurations are needed. Currently they are done inside icssg_change_mode(). This function only gets called if we move from one mode to another without bringing the links up / down.
Once in HSR / Switch mode, if we bring the links down and bring it back up again. The callback sequence is,
- emac_ndo_stop()
Firmwares are stopped
- emac_ndo_open()
Firmwares are loaded
In this path icssg_change_mode() doesn't get called and as a result the configurations needed for HSR / Switch is not done.
To fix this, put all these configurations in a separate function icssg_enable_fw_offload() and call this from both icssg_change_mode() and emac_ndo_open()
--- drivers/net/ethernet/ti/icssg/icssg_prueth.c | 72 +++++++++++--------- 1 file changed, 41 insertions(+), 31 deletions(-)
drivers/net/ethernet/ti/icssg/icssg_prueth.c +41 -31
@@ -240,6 +240,44 @@ static void prueth_emac_stop(struct prueth *prueth) } } +static void icssg_enable_fw_offload (struct prueth *prueth) +{ +struct prueth_emac *emac; +int mac; + +for (mac =PRUETH_MAC0 ; mac <PRUETH_NUM_MACS ; mac++) { + emac = prueth->emac[mac]; +if (prueth->is_hsr_offload_mode) { +if (emac->ndev->features &NETIF_F_HW_HSR_TAG_RM ) +icssg_set_port_state (emac,ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE ); +else +icssg_set_port_state (emac,ICSSG_EMAC_HSR_RX_OFFLOAD_DISABLE ); + } + +if (prueth->is_switch_mode || prueth->is_hsr_offload_mode) { +if (netif_running (emac->ndev)) { +icssg_fdb_add_del (emac, eth_stp_addr, prueth->default_vlan, +ICSSG_FDB_ENTRY_P0_MEMBERSHIP | +ICSSG_FDB_ENTRY_P1_MEMBERSHIP | +ICSSG_FDB_ENTRY_P2_MEMBERSHIP | +ICSSG_FDB_ENTRY_BLOCK , + true); +icssg_vtbl_modify (emac, emac->port_vlan |DEFAULT_VID , +BIT (emac->port_id) |DEFAULT_PORT_MASK , +BIT (emac->port_id) |DEFAULT_UNTAG_MASK , + true); +if (prueth->is_hsr_offload_mode) +icssg_vtbl_modify (emac,DEFAULT_VID , +DEFAULT_PORT_MASK , +DEFAULT_UNTAG_MASK , true); +icssg_set_pvid (prueth, emac->port_vlan, emac->port_id); +if (prueth->is_switch_mode) +icssg_set_port_state (emac,ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE ); + } + } + } +} +static int prueth_emac_common_start (struct prueth *prueth) {struct prueth_emac *emac;
@@ -790,6 +828,7 @@ static int emac_ndo_open(struct net_device *ndev) ret =prueth_emac_common_start (prueth);if (ret) goto free_rx_irq; +icssg_enable_fw_offload (prueth); } flow_cfg = emac->dram.va +ICSSG_CONFIG_OFFSET +PSI_L_REGULAR_FLOW_ID_BASE_OFFSET ;
@@ -1397,8 +1436,7 @@ static int prueth_emac_restart(struct prueth *prueth)static void icssg_change_mode (struct prueth *prueth) { -struct prueth_emac *emac; -int mac, ret; +int ret; ret =prueth_emac_restart (prueth);if (ret) {
@@ -1406,35 +1444,7 @@ static void icssg_change_mode(struct prueth *prueth)return ; } -for (mac =PRUETH_MAC0 ; mac <PRUETH_NUM_MACS ; mac++) { - emac = prueth->emac[mac]; -if (prueth->is_hsr_offload_mode) { -if (emac->ndev->features &NETIF_F_HW_HSR_TAG_RM ) -icssg_set_port_state (emac,ICSSG_EMAC_HSR_RX_OFFLOAD_ENABLE ); -else -icssg_set_port_state (emac,ICSSG_EMAC_HSR_RX_OFFLOAD_DISABLE ); - } - -if (netif_running (emac->ndev)) { -icssg_fdb_add_del (emac, eth_stp_addr, prueth->default_vlan, -ICSSG_FDB_ENTRY_P0_MEMBERSHIP | -ICSSG_FDB_ENTRY_P1_MEMBERSHIP | -ICSSG_FDB_ENTRY_P2_MEMBERSHIP | -ICSSG_FDB_ENTRY_BLOCK , - true); -icssg_vtbl_modify (emac, emac->port_vlan |DEFAULT_VID , -BIT (emac->port_id) |DEFAULT_PORT_MASK , -BIT (emac->port_id) |DEFAULT_UNTAG_MASK , - true); -if (prueth->is_hsr_offload_mode) -icssg_vtbl_modify (emac,DEFAULT_VID , -DEFAULT_PORT_MASK , -DEFAULT_UNTAG_MASK , true); -icssg_set_pvid (prueth, emac->port_vlan, emac->port_id); -if (prueth->is_switch_mode) -icssg_set_port_state (emac,ICSSG_EMAC_PORT_VLAN_AWARE_ENABLE ); - } - } +icssg_enable_fw_offload (prueth); } static int prueth_netdevice_port_link(struct net_device *ndev,
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 408/457 drm/xe: Assign ioctl xe file handler to vm in xe_vm_create
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Piotr Piórkowski <[email protected]>
[ Upstream commit 658a1c8e0a66d0777e0e37a11ba19f27a81e77f4 ]
In several code paths, such as xe_pt_create(), the vm->xef field is used to determine whether a VM originates from userspace or the kernel.
Previously, this handler was only assigned in xe_vm_create_ioctl(), after the VM was created by xe_vm_create(). However, xe_vm_create() triggers page table creation, and that function assumes vm->xef should be already set. This could lead to incorrect origin detection.
To fix this problem and ensure consistency in the initialization of the VM object, let's move the assignment of this handler to xe_vm_create.
v2:
- take reference to the xe file object only when xef is not NULL
- release the reference to the xe file object on the error path (Matthew)
--- drivers/gpu/drm/xe/xe_migrate.c | 2 +- drivers/gpu/drm/xe/xe_pxp_submit.c | 2 +- drivers/gpu/drm/xe/xe_vm.c | 11 ++++++----- drivers/gpu/drm/xe/xe_vm.h | 2 +- 4 files changed, 9 insertions(+), 8 deletions(-)
drivers/gpu/drm/xe/xe_migrate.c +1 -1
@@ -408,7 +408,7 @@ struct xe_migrate *xe_migrate_init(struct xe_tile *tile)/* Special layout, prepared below.. */ vm =xe_vm_create (xe,XE_VM_FLAG_MIGRATION | -XE_VM_FLAG_SET_TILE_ID (tile)); +XE_VM_FLAG_SET_TILE_ID (tile),NULL );if (IS_ERR (vm))return ERR_CAST (vm);
drivers/gpu/drm/xe/xe_pxp_submit.c +1 -1
@@ -101,7 +101,7 @@ static int allocate_gsc_client_resources(struct xe_gt *gt,xe_assert (xe, hwe);/* PXP instructions must be issued from PPGTT */ - vm =xe_vm_create (xe,XE_VM_FLAG_GSC ); + vm =xe_vm_create (xe,XE_VM_FLAG_GSC ,NULL );if (IS_ERR (vm))return PTR_ERR (vm);
drivers/gpu/drm/xe/xe_vm.c +6 -5
@@ -1612,7 +1612,7 @@ static void xe_vm_free_scratch(struct xe_vm *vm) } } -struct xe_vm *xe_vm_create (struct xe_device *xe,u32 flags) +struct xe_vm *xe_vm_create (struct xe_device *xe,u32 flags,struct xe_file *xef) {struct drm_gem_object *vm_resv_obj;struct xe_vm *vm;
@@ -1633,9 +1633,10 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags) vm->xe = xe; vm->size =1ull << xe->info.va_bits; - vm->flags = flags; +if (xef) + vm->xef =xe_file_get (xef);/** * GSC VMs are kernel-owned, only used for PXP ops and can sometimes be * manipulated under the PXP mutex. However, the PXP mutex can be taken
@@ -1786,6 +1787,8 @@ struct xe_vm *xe_vm_create(struct xe_device *xe, u32 flags)for_each_tile (tile, xe, id)xe_range_fence_tree_fini (&vm->rftree[id]);ttm_lru_bulk_move_fini (&xe->ttm, &vm->lru_bulk_move); +if (vm->xef) +xe_file_put (vm->xef);kfree (vm);if (flags &XE_VM_FLAG_LR_MODE )xe_pm_runtime_put (xe);
@@ -2069,7 +2072,7 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data,if (args->flags &DRM_XE_VM_CREATE_FLAG_FAULT_MODE ) flags |=XE_VM_FLAG_FAULT_MODE ; - vm =xe_vm_create (xe, flags); + vm =xe_vm_create (xe, flags, xef);if (IS_ERR (vm))return PTR_ERR (vm);
@@ -2085,8 +2088,6 @@ int xe_vm_create_ioctl(struct drm_device *dev, void *data, vm->usm.asid = asid; } - vm->xef =xe_file_get (xef); -/* Record BO memory for VM pagetable created against client */ for_each_tile (tile, xe, id)if (vm->pt_root[id])
drivers/gpu/drm/xe/xe_vm.h +1 -1
@@ -26,7 +26,7 @@ struct xe_sync_entry;struct xe_svm_range ;struct drm_exec ; -struct xe_vm *xe_vm_create (struct xe_device *xe,u32 flags); +struct xe_vm *xe_vm_create (struct xe_device *xe,u32 flags,struct xe_file *xef);struct xe_vm *xe_vm_lookup (struct xe_file *xef,u32 id);int xe_vma_cmp_vma_cb (const void *key,const struct rb_node *node);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 409/457 regulator: tps65219: regulator: tps65219: Fix error codes in probe()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Dan Carpenter <[email protected]>
[ Upstream commit 11cd7a5c21db020b8001aedcae27bd3fa9e1e901 ]
There is a copy and paste error and we accidentally use "PTR_ERR(rdev)" instead of "error". The "rdev" pointer is valid at this point.
Also there is no need to print the error code in the error message because dev_err_probe() already prints that. So clean up the error message a bit.
--- drivers/regulator/tps65219-regulator.c | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-)
drivers/regulator/tps65219-regulator.c +6 -6
@@ -454,9 +454,9 @@ static int tps65219_regulator_probe(struct platform_device *pdev) irq_type->irq_name, irq_data);if (error) -return dev_err_probe (tps->dev,PTR_ERR (rdev), -"Failed to request %s IRQ %d: %d\n" , - irq_type->irq_name, irq, error); +return dev_err_probe (tps->dev, error, +"Failed to request %s IRQ %d\n" , + irq_type->irq_name, irq); }for (i =0 ; i < pmic->dev_irq_size; ++i) {
@@ -477,9 +477,9 @@ static int tps65219_regulator_probe(struct platform_device *pdev) irq_type->irq_name, irq_data);if (error) -return dev_err_probe (tps->dev,PTR_ERR (rdev), -"Failed to request %s IRQ %d: %d\n" , - irq_type->irq_name, irq, error); +return dev_err_probe (tps->dev, error, +"Failed to request %s IRQ %d\n" , + irq_type->irq_name, irq); }return 0 ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 410/457 cifs: Fix oops due to uninitialised variable
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: David Howells <[email protected]>
[ Upstream commit 453a6d2a68e54a483d67233c6e1e24c4095ee4be ]
Fix smb3_init_transform_rq() to initialise buffer to NULL before calling netfs_alloc_folioq_buffer() as netfs assumes it can append to the buffer it is given. Setting it to NULL means it should start a fresh buffer, but the value is currently undefined.
--- fs/smb/client/smb2ops.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
fs/smb/client/smb2ops.c +1 -1
@@ -4496,7 +4496,7 @@ smb3_init_transform_rq(struct TCP_Server_Info *server, int num_rqst,for (int i =1 ; i < num_rqst; i++) {struct smb_rqst *old = &old_rq[i -1 ];struct smb_rqst *new = &new_rq[i]; -struct folio_queue *buffer; +struct folio_queue *buffer =NULL ;size_t size =iov_iter_count (&old->rq_iter); orig_len +=smb_rqst_len (server, old);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 411/457 phy: mscc: Fix timestamping for vsc8584
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Horatiu Vultur <[email protected]>
[ Upstream commit bc1a59cff9f797bfbf8f3104507584d89e9ecf2e ]
There was a problem when we received frames and the frames were timestamped. The driver is configured to store the nanosecond part of the timestmap in the ptp reserved bits and it would take the second part by reading the LTC. The problem is that when reading the LTC we are in atomic context and to read the second part will go over mdio bus which might sleep, so we get an error.
The fix consists in actually put all the frames in a queue and start the aux work and in that work to read the LTC and then calculate the full received time.
--- drivers/net/phy/mscc/mscc.h | 12 ++++++++ drivers/net/phy/mscc/mscc_main.c | 12 ++++++++ drivers/net/phy/mscc/mscc_ptp.c | 49 ++++++++++++++++++++++++-------- 3 files changed, 61 insertions(+), 12 deletions(-)
drivers/net/phy/mscc/mscc.h +12 -0
@@ -362,6 +362,13 @@ struct vsc85xx_hw_stat {u16 mask; }; +struct vsc8531_skb_cb { +u32 ns; +}; + +#define VSC8531_SKB_CB (skb) \ + ((struct vsc8531_skb_cb *)((skb)->cb)) +struct vsc8531_private {int rate_magic;u16 supp_led_modes;
@@ -410,6 +417,11 @@ struct vsc8531_private {*/ struct mutex ts_lock;struct mutex phc_lock; + +/* list of skbs that were received and need timestamp information but it +* didn't received it yet +*/ +struct sk_buff_head rx_skbs_list; };/* Shared structure between the PHYs of the same package.
drivers/net/phy/mscc/mscc_main.c +12 -0
@@ -2336,6 +2336,13 @@ static int vsc85xx_probe(struct phy_device *phydev)return vsc85xx_dt_led_modes_get (phydev, default_mode); } +static void vsc85xx_remove (struct phy_device *phydev) +{ +struct vsc8531_private *priv = phydev->priv; + +skb_queue_purge (&priv->rx_skbs_list); +} +/* Microsemi VSC85xx PHYs */ static struct phy_driver vsc85xx_driver[] = { {
@@ -2590,6 +2597,7 @@ static struct phy_driver vsc85xx_driver[] = { .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, + .remove = &vsc85xx_remove, .probe = &vsc8574_probe, .set_wol = &vsc85xx_wol_set, .get_wol = &vsc85xx_wol_get,
@@ -2615,6 +2623,7 @@ static struct phy_driver vsc85xx_driver[] = { .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, + .remove = &vsc85xx_remove, .probe = &vsc8574_probe, .set_wol = &vsc85xx_wol_set, .get_wol = &vsc85xx_wol_get,
@@ -2640,6 +2649,7 @@ static struct phy_driver vsc85xx_driver[] = { .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, + .remove = &vsc85xx_remove, .probe = &vsc8584_probe, .get_tunable = &vsc85xx_get_tunable, .set_tunable = &vsc85xx_set_tunable,
@@ -2663,6 +2673,7 @@ static struct phy_driver vsc85xx_driver[] = { .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, + .remove = &vsc85xx_remove, .probe = &vsc8584_probe, .get_tunable = &vsc85xx_get_tunable, .set_tunable = &vsc85xx_set_tunable,
@@ -2686,6 +2697,7 @@ static struct phy_driver vsc85xx_driver[] = { .config_intr = &vsc85xx_config_intr, .suspend = &genphy_suspend, .resume = &genphy_resume, + .remove = &vsc85xx_remove, .probe = &vsc8584_probe, .get_tunable = &vsc85xx_get_tunable, .set_tunable = &vsc85xx_set_tunable,
drivers/net/phy/mscc/mscc_ptp.c +37 -12
85 lines not on this page · raw message
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 412/457 net: usb: asix_devices: Fix PHY address mask in MDIO bus initialization
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yuichiro Tsuji <[email protected]>
[ Upstream commit 24ef2f53c07f273bad99173e27ee88d44d135b1c ]
Syzbot reported shift-out-of-bounds exception on MDIO bus initialization.
The PHY address should be masked to 5 bits (0-31). Without this mask, invalid PHY addresses could be used, potentially causing issues with MDIO bus operations.
Fix this by masking the PHY address with 0x1f (31 decimal) to ensure it stays within the valid range.
--- drivers/net/usb/asix_devices.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-)
drivers/net/usb/asix_devices.c +1 -1
@@ -676,7 +676,7 @@ static int ax88772_init_mdio(struct usbnet *dev) priv->mdio->read = &asix_mdio_bus_read; priv->mdio->write = &asix_mdio_bus_write; priv->mdio->name ="Asix MDIO Bus" ; - priv->mdio->phy_mask = ~(BIT (priv->phy_addr) |BIT (AX_EMBD_PHY_ADDR )); + priv->mdio->phy_mask = ~(BIT (priv->phy_addr &0x1f ) |BIT (AX_EMBD_PHY_ADDR ));/* mii bus name is usb-<usb bus number>-<usb device number> */ snprintf (priv->mdio->id,MII_BUS_ID_SIZE ,"usb-%03d:%03d" , dev->udev->bus->busnum, dev->udev->devnum);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 413/457 gve: prevent ethtool ops after shutdown
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Jordan Rhee <[email protected]>
[ Upstream commit 75a9a46d67f46d608205888f9b34e315c1786345 ]
A crash can occur if an ethtool operation is invoked after shutdown() is called.
shutdown() is invoked during system shutdown to stop DMA operations without performing expensive deallocations. It is discouraged to unregister the netdev in this path, so the device may still be visible to userspace and kernel helpers.
In gve, shutdown() tears down most internal data structures. If an ethtool operation is dispatched after shutdown(), it will dereference freed or NULL pointers, leading to a kernel panic. While graceful shutdown normally quiesces userspace before invoking the reboot syscall, forced shutdowns (as observed on GCP VMs) can still trigger this path.
Fix by calling netif_device_detach() in shutdown(). This marks the device as detached so the ethtool ioctl handler will skip dispatching operations to the driver.
--- drivers/net/ethernet/google/gve/gve_main.c | 2 ++ 1 file changed, 2 insertions(+)
drivers/net/ethernet/google/gve/gve_main.c +2 -0
@@ -2726,6 +2726,8 @@ static void gve_shutdown(struct pci_dev *pdev)struct gve_priv *priv =netdev_priv (netdev);bool was_up =netif_running (priv->dev); +netif_device_detach (netdev); +rtnl_lock ();netdev_lock (netdev);if (was_up &&gve_close (priv->dev)) {
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 414/457 net: stmmac: thead: Enable TX clock before MAC initialization
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yao Zi <[email protected]>
[ Upstream commit 6d6714bf0c4e8eb2274081b4b023dfa01581c123 ]
The clk_tx_i clock must be supplied to the MAC for successful initialization. On TH1520 SoC, the clock is provided by an internal divider configured through GMAC_PLLCLK_DIV register when using RGMII interface. However, currently we don't setup the divider before initialization of the MAC, resulting in DMA reset failures if the bootloader/firmware doesn't enable the divider,
[ 7.839601] thead-dwmac ffe7060000.ethernet eth0: Register MEM_TYPE_PAGE_POOL RxQ-0 [ 7.938338] thead-dwmac ffe7060000.ethernet eth0: PHY [stmmac-0:02] driver [RTL8211F Gigabit Ethernet] (irq=POLL) [ 8.160746] thead-dwmac ffe7060000.ethernet eth0: Failed to reset the dma [ 8.170118] thead-dwmac ffe7060000.ethernet eth0: stmmac_hw_setup: DMA engine initialization failed [ 8.179384] thead-dwmac ffe7060000.ethernet eth0: __stmmac_open: Hw setup failed
Let's simply write GMAC_PLLCLK_DIV_EN to GMAC_PLLCLK_DIV to enable the divider before MAC initialization. Note that for reconfiguring the divisor, the divider must be disabled first and re-enabled later to make sure the new divisor take effect.
The exact clock rate doesn't affect MAC's initialization according to my test. It's set to the speed required by RGMII when the linkspeed is 1Gbps and could be reclocked later after link is up if necessary.
--- drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-)
drivers/net/ethernet/stmicro/stmmac/dwmac-thead.c +8 -1
@@ -152,7 +152,7 @@ static int thead_set_clk_tx_rate(void *bsp_priv, struct clk *clk_tx_i,static int thead_dwmac_enable_clk (struct plat_stmmacenet_data *plat) {struct thead_dwmac *dwmac = plat->bsp_priv; -u32 reg; +u32 reg, div;switch (plat->mac_interface) {case PHY_INTERFACE_MODE_MII :
@@ -164,6 +164,13 @@ static int thead_dwmac_enable_clk(struct plat_stmmacenet_data *plat)case PHY_INTERFACE_MODE_RGMII_RXID :case PHY_INTERFACE_MODE_RGMII_TXID :/* use pll */ + div =clk_get_rate (plat->stmmac_clk) /rgmii_clock (SPEED_1000 ); + reg =FIELD_PREP (GMAC_PLLCLK_DIV_EN ,1 ) | +FIELD_PREP (GMAC_PLLCLK_DIV_NUM , div); + +writel (0 , dwmac->apb_base +GMAC_PLLCLK_DIV ); +writel (reg, dwmac->apb_base +GMAC_PLLCLK_DIV ); +writel (GMAC_GTXCLK_SEL_PLL , dwmac->apb_base +GMAC_GTXCLK_SEL ); reg =GMAC_TX_CLK_EN |GMAC_TX_CLK_N_EN |GMAC_TX_CLK_OUT_EN |GMAC_RX_CLK_EN |GMAC_RX_CLK_N_EN ;
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 415/457 net/smc: fix UAF on smcsk after smc_listen_out()
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: D. Wythe <[email protected]>
[ Upstream commit d9cef55ed49117bd63695446fb84b4b91815c0b4 ]
BPF CI testing report a UAF issue:
[ 16.446633] BUG: kernel NULL pointer dereference, address: 000000000000003 0 [ 16.447134] #PF: supervisor read access in kernel mod e [ 16.447516] #PF: error_code(0x0000) - not-present pag e [ 16.447878] PGD 0 P4D 0 [ 16.448063] Oops: Oops: 0000 [#1] PREEMPT SMP NOPT I [ 16.448409] CPU: 0 UID: 0 PID: 9 Comm: kworker/0:1 Tainted: G OE 6.13.0-rc3-g89e8a75fda73-dirty #4 2 [ 16.449124] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODUL E [ 16.449502] Hardware name: QEMU Ubuntu 24.04 PC (i440FX + PIIX, 1996), BIOS 1.16.3-debian-1.16.3-2 04/01/201 4 [ 16.450201] Workqueue: smc_hs_wq smc_listen_wor k [ 16.450531] RIP: 0010:smc_listen_work+0xc02/0x159 0 [ 16.452158] RSP: 0018:ffffb5ab40053d98 EFLAGS: 0001024 6 [ 16.452526] RAX: 0000000000000001 RBX: 0000000000000002 RCX: 000000000000030 0 [ 16.452994] RDX: 0000000000000280 RSI: 00003513840053f0 RDI: 000000000000000 0 [ 16.453492] RBP: ffffa097808e3800 R08: ffffa09782dba1e0 R09: 000000000000000 5 [ 16.453987] R10: 0000000000000000 R11: 0000000000000000 R12: ffffa0978274640 0 [ 16.454497] R13: 0000000000000000 R14: 0000000000000000 R15: ffffa09782d4092 0 [ 16.454996] FS: 0000000000000000(0000) GS:ffffa097bbc00000(0000) knlGS:000000000000000 0 [ 16.455557] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003 3 [ 16.455961] CR2: 0000000000000030 CR3: 0000000102788004 CR4: 0000000000770ef 0 [ 16.456459] PKRU: 5555555 4 [ 16.456654] Call Trace : [ 16.456832] <TASK > [ 16.456989] ? __die+0x23/0x7 0 [ 16.457215] ? page_fault_oops+0x180/0x4c 0 [ 16.457508] ? __lock_acquire+0x3e6/0x249 0 [ 16.457801] ? exc_page_fault+0x68/0x20 0 [ 16.458080] ? asm_exc_page_fault+0x26/0x3 0 [ 16.458389] ? smc_listen_work+0xc02/0x159 0 [ 16.458689] ? smc_listen_work+0xc02/0x159 0 [ 16.458987] ? lock_is_held_type+0x8f/0x10 0 [ 16.459284] process_one_work+0x1ea/0x6d 0 [ 16.459570] worker_thread+0x1c3/0x38 0 [ 16.459839] ? __pfx_worker_thread+0x10/0x1 0 [ 16.460144] kthread+0xe0/0x11 0 [ 16.460372] ? __pfx_kthread+0x10/0x1 0 [ 16.460640] ret_from_fork+0x31/0x5 0 [ 16.460896] ? __pfx_kthread+0x10/0x1 0 [ 16.461166] ret_from_fork_asm+0x1a/0x3 0 [ 16.461453] </TASK > [ 16.461616] Modules linked in: bpf_testmod(OE) [last unloaded: bpf_testmod(OE) ] [ 16.462134] CR2: 000000000000003 0 [ 16.462380] ---[ end trace 0000000000000000 ]--- [ 16.462710] RIP: 0010:smc_listen_work+0xc02/0x1590
The direct cause of this issue is that after smc_listen_out_connected(), newclcsock->sk may be NULL since it will releases the smcsk. Therefore, if the application closes the socket immediately after accept, newclcsock->sk can be NULL. A possible execution order could be as follows:
smc_listen_work | userspace
-----------------------------------------------------------------
lock_sock(sk) |
smc_listen_out_connected() |
| \- smc_listen_out |
| | \- release_sock |
| |- sk->sk_data_ready() |
| fd = accept();
| close(fd);
| \- socket->sk = NULL;/* newclcsock->sk is NULL now */
SMC_STAT_SERV_SUCC_INC(sock_net(newclcsock->sk))
Since smc_listen_out_connected() will not fail, simply swapping the order of the code can easily fix this issue.
--- net/smc/af_smc.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-)
net/smc/af_smc.c +2 -1
@@ -2568,8 +2568,9 @@ static void smc_listen_work(struct work_struct *work) goto out_decl; } -smc_listen_out_connected (new_smc);SMC_STAT_SERV_SUCC_INC (sock_net (newclcsock->sk), ini); +/* smc_listen_out() will release smcsk */ +smc_listen_out_connected (new_smc); goto out_free; out_unlock:
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 416/457 net/mlx5: HWS, fix bad parameter in CQ creation
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yevgeny Kliteynik <[email protected]>
[ Upstream commit 2462c1b9217246a889ec318b3894d84e4dd709c6 ]
'cqe_sz' valid value should be 0 for 64-byte CQE.
--- drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c | 1 - 1 file changed, 1 deletion(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/send.c +0 -1
@@ -964,7 +964,6 @@ static int hws_send_ring_open_cq(struct mlx5_core_dev *mdev,return -ENOMEM ;MLX5_SET (cqc, cqc_data, uar_page, mdev->priv.uar->index); -MLX5_SET (cqc, cqc_data, cqe_sz, queue->num_entries);MLX5_SET (cqc, cqc_data, log_cq_size,ilog2 (queue->num_entries)); err =hws_send_ring_alloc_cq (mdev, numa_node, queue, cqc_data, cq);
Signature · 1 line
2.50.1
Greg Kroah-Hartman
maintainerPATCH 417/457 net/mlx5: HWS, fix complex rules rehash error flow
In reply to Greg Kroah-Hartman6.16-stable review patch. If anyone has any objections, please let me know.
------------------
From: Yevgeny Kliteynik <[email protected]>
[ Upstream commit 4a842b1bf18a32ee0c25dd6dd98728b786a76fe4 ]
Moving rules from matcher to matcher should not fail. However, if it does fail due to various reasons, the error flow should allow the kernel to continue functioning (albeit with broken steering rules) instead of going into series of soft lock-ups or some other problematic behaviour.
Similar to the simple rules, complex rules rehash logic suffers from the same problems. This patch fixes the error flow for moving complex rules:
- If new rule creation fails before it was even enqeued, do not poll for completion
- If TIMEOUT happened while moving the rule, no point trying to poll for completions for other rules. Something is broken, completion won't come, just abort the rehash sequence.
- If some other completion with error received, don't give up. Continue handling rest of the rules to minimize the damage.
- Make sure that the first error code that was received will be actually returned to the caller instead of replacing it with the generic error code.
All the aforementioned issues stem from the same bad error flow, so no point fixing them one by one and leaving partially broken code - fixing them in one patch.
--- .../mlx5/core/steering/hws/bwc_complex.c | 41 +++++++++++++------ 1 file changed, 28 insertions(+), 13 deletions(-)
drivers/net/ethernet/mellanox/mlx5/core/steering/hws/bwc_complex.c +28 -13
@@ -1328,11 +1328,11 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher) {struct mlx5hws_context *ctx = bwc_matcher->matcher->tbl->ctx;struct mlx5hws_matcher *matcher = bwc_matcher->matcher; -bool move_error = false, poll_error = false;u16 bwc_queues =mlx5hws_bwc_queues (ctx);struct mlx5hws_bwc_rule *tmp_bwc_rule;struct mlx5hws_rule_attr rule_attr;struct mlx5hws_table *isolated_tbl; +int move_error =0 , poll_error =0 ;struct mlx5hws_rule *tmp_rule;struct list_head *rules_list;u32 expected_completions =1 ;
@@ -1391,11 +1391,15 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher) ret =mlx5hws_matcher_resize_rule_move (matcher, tmp_rule, &rule_attr); -if (unlikely (ret && !move_error)) { -mlx5hws_err (ctx, -"Moving complex BWC rule failed (%d), attempting to move rest of the rules\n" , - ret); - move_error = true; +if (unlikely (ret)) { +if (!move_error) { +mlx5hws_err (ctx, +"Moving complex BWC rule: move failed (%d), attempting to move rest of the rules\n" , + ret); + move_error = ret; + } +/* Rule wasn't queued, no need to poll */ +continue ; } expected_completions =1 ;
@@ -1403,11 +1407,19 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher) rule_attr.queue_id, &expected_completions, true); -if (unlikely (ret && !poll_error)) { -mlx5hws_err (ctx, -"Moving complex BWC rule: poll failed (%d), attempting to move rest of the rules\n" , - ret); - poll_error = true; +if (unlikely (ret)) { +if (ret == -ETIMEDOUT ) { +mlx5hws_err (ctx, +"Moving complex BWC rule: timeout polling for completions (%d), aborting rehash\n" , + ret); +return ret; + } +if (!poll_error) { +mlx5hws_err (ctx, +"Moving complex BWC rule: polling for completions failed (%d), attempting to move rest of the rules\n" , + ret); + poll_error = ret; + } }/* Done moving the rule to the new matcher,
@@ -1422,8 +1434,11 @@ mlx5hws_bwc_matcher_move_all_complex(struct mlx5hws_bwc_matcher *bwc_matcher) } } -if (move_error || poll_error) - ret = -EINVAL ; +/* Return the first error that happened */ +if (unlikely (move_error)) +return move_error; +if (unlikely (poll_error)) +return poll_error;return ret; }
Signature · 1 line
2.50.1