From 27841b2fbe53b41308a9828f8e55ca79b73bf494 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:16 -0400 Subject: [PATCH 01/21] wifi: cfg80211: sme: cap SSID length in __cfg80211_connect_result() jira LE-4613 cve CVE-2025-39849 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Dan Carpenter commit 62b635dcd69c4fde7ce1de4992d71420a37e51e3 If the ssid->datalen is more than IEEE80211_MAX_SSID_LEN (32) it would lead to memory corruption so add some bounds checking. Fixes: c38c70185101 ("wifi: cfg80211: Set SSID if it is not already set") Signed-off-by: Dan Carpenter Link: https://patch.msgid.link/0aaaae4a3ed37c6252363c34ae4904b1604e8e32.1756456951.git.dan.carpenter@linaro.org Signed-off-by: Johannes Berg (cherry picked from commit 62b635dcd69c4fde7ce1de4992d71420a37e51e3) Signed-off-by: Jonathan Maple --- net/wireless/sme.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/net/wireless/sme.c b/net/wireless/sme.c index 2681716000876..e0d3c713538b5 100644 --- a/net/wireless/sme.c +++ b/net/wireless/sme.c @@ -903,13 +903,16 @@ void __cfg80211_connect_result(struct net_device *dev, if (!wdev->u.client.ssid_len) { rcu_read_lock(); for_each_valid_link(cr, link) { + u32 ssid_len; + ssid = ieee80211_bss_get_elem(cr->links[link].bss, WLAN_EID_SSID); if (!ssid || !ssid->datalen) continue; - memcpy(wdev->u.client.ssid, ssid->data, ssid->datalen); + ssid_len = min(ssid->datalen, IEEE80211_MAX_SSID_LEN); + memcpy(wdev->u.client.ssid, ssid->data, ssid_len); wdev->u.client.ssid_len = ssid->datalen; break; } From f22b0ba8906c0083bba87ffbe0323d2bb7088be5 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:17 -0400 Subject: [PATCH 02/21] mm: swap: fix potential buffer overflow in setup_clusters() jira LE-4613 cve CVE-2025-39727 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Kemeng Shi commit 152c1339dc13ad46f1b136e8693de15980750835 In setup_swap_map(), we only ensure badpages are in range (0, last_page]. As maxpages might be < last_page, setup_clusters() will encounter a buffer overflow when a badpage is >= maxpages. Only call inc_cluster_info_page() for badpage which is < maxpages to fix the issue. Link: https://lkml.kernel.org/r/20250522122554.12209-4-shikemeng@huaweicloud.com Fixes: b843786b0bd0 ("mm: swapfile: fix SSD detection with swapfile on btrfs") Signed-off-by: Kemeng Shi Reviewed-by: Baoquan He Cc: Johannes Weiner Cc: Kairui Song Cc: Signed-off-by: Andrew Morton (cherry picked from commit 152c1339dc13ad46f1b136e8693de15980750835) Signed-off-by: Jonathan Maple --- mm/swapfile.c | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/mm/swapfile.c b/mm/swapfile.c index b0a9071cfe1da..602099367b45a 100644 --- a/mm/swapfile.c +++ b/mm/swapfile.c @@ -3322,9 +3322,13 @@ static struct swap_cluster_info *setup_clusters(struct swap_info_struct *si, * and the EOF part of the last cluster. */ inc_cluster_info_page(si, cluster_info, 0); - for (i = 0; i < swap_header->info.nr_badpages; i++) - inc_cluster_info_page(si, cluster_info, - swap_header->info.badpages[i]); + for (i = 0; i < swap_header->info.nr_badpages; i++) { + unsigned int page_nr = swap_header->info.badpages[i]; + + if (page_nr >= maxpages) + continue; + inc_cluster_info_page(si, cluster_info, page_nr); + } for (i = maxpages; i < round_up(maxpages, SWAPFILE_CLUSTER); i++) inc_cluster_info_page(si, cluster_info, i); From 7bcdb8ceda6d9a2f235f95612d302c2a0b89ac6a Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:17 -0400 Subject: [PATCH 03/21] vsock/virtio: Validate length in packet header before skb_put() jira LE-4613 cve CVE-2025-39718 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Will Deacon commit 0dab92484474587b82e8e0455839eaf5ac7bf894 When receiving a vsock packet in the guest, only the virtqueue buffer size is validated prior to virtio_vsock_skb_rx_put(). Unfortunately, virtio_vsock_skb_rx_put() uses the length from the packet header as the length argument to skb_put(), potentially resulting in SKB overflow if the host has gone wonky. Validate the length as advertised by the packet header before calling virtio_vsock_skb_rx_put(). Cc: Fixes: 71dc9ec9ac7d ("virtio/vsock: replace virtio_vsock_pkt with sk_buff") Signed-off-by: Will Deacon Message-Id: <20250717090116.11987-3-will@kernel.org> Signed-off-by: Michael S. Tsirkin Reviewed-by: Stefano Garzarella (cherry picked from commit 0dab92484474587b82e8e0455839eaf5ac7bf894) Signed-off-by: Jonathan Maple --- net/vmw_vsock/virtio_transport.c | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/net/vmw_vsock/virtio_transport.c b/net/vmw_vsock/virtio_transport.c index b58c3818f284f..90eb5cb82525e 100644 --- a/net/vmw_vsock/virtio_transport.c +++ b/net/vmw_vsock/virtio_transport.c @@ -624,8 +624,9 @@ static void virtio_transport_rx_work(struct work_struct *work) do { virtqueue_disable_cb(vq); for (;;) { + unsigned int len, payload_len; + struct virtio_vsock_hdr *hdr; struct sk_buff *skb; - unsigned int len; if (!virtio_transport_more_replies(vsock)) { /* Stop rx until the device processes already @@ -642,12 +643,19 @@ static void virtio_transport_rx_work(struct work_struct *work) vsock->rx_buf_nr--; /* Drop short/long packets */ - if (unlikely(len < sizeof(struct virtio_vsock_hdr) || + if (unlikely(len < sizeof(*hdr) || len > virtio_vsock_skb_len(skb))) { kfree_skb(skb); continue; } + hdr = virtio_vsock_hdr(skb); + payload_len = le32_to_cpu(hdr->len); + if (unlikely(payload_len > len - sizeof(*hdr))) { + kfree_skb(skb); + continue; + } + virtio_vsock_skb_rx_put(skb); virtio_transport_deliver_tap_pkt(skb); virtio_transport_recv_pkt(&virtio_transport, skb); From 4de0b8ad0b2f1ecbcd04a09c80194bc1345ca185 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:17 -0400 Subject: [PATCH 04/21] NFS: Fix a race when updating an existing write jira LE-4613 cve CVE-2025-39697 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Trond Myklebust commit 76d2e3890fb169168c73f2e4f8375c7cc24a765e After nfs_lock_and_join_requests() tests for whether the request is still attached to the mapping, nothing prevents a call to nfs_inode_remove_request() from succeeding until we actually lock the page group. The reason is that whoever called nfs_inode_remove_request() doesn't necessarily have a lock on the page group head. So in order to avoid races, let's take the page group lock earlier in nfs_lock_and_join_requests(), and hold it across the removal of the request in nfs_inode_remove_request(). Reported-by: Jeff Layton Tested-by: Joe Quanaim Tested-by: Andrew Steffen Reviewed-by: Jeff Layton Fixes: bd37d6fce184 ("NFSv4: Convert nfs_lock_and_join_requests() to use nfs_page_find_head_request()") Cc: stable@vger.kernel.org Signed-off-by: Trond Myklebust (cherry picked from commit 76d2e3890fb169168c73f2e4f8375c7cc24a765e) Signed-off-by: Jonathan Maple --- fs/nfs/pagelist.c | 9 +++++---- fs/nfs/write.c | 29 ++++++++++------------------- include/linux/nfs_page.h | 1 + 3 files changed, 16 insertions(+), 23 deletions(-) diff --git a/fs/nfs/pagelist.c b/fs/nfs/pagelist.c index 11968dcb72431..6e69ce43a13ff 100644 --- a/fs/nfs/pagelist.c +++ b/fs/nfs/pagelist.c @@ -253,13 +253,14 @@ nfs_page_group_unlock(struct nfs_page *req) nfs_page_clear_headlock(req); } -/* - * nfs_page_group_sync_on_bit_locked +/** + * nfs_page_group_sync_on_bit_locked - Test if all requests have @bit set + * @req: request in page group + * @bit: PG_* bit that is used to sync page group * * must be called with page group lock held */ -static bool -nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit) +bool nfs_page_group_sync_on_bit_locked(struct nfs_page *req, unsigned int bit) { struct nfs_page *head = req->wb_head; struct nfs_page *tmp; diff --git a/fs/nfs/write.c b/fs/nfs/write.c index aa3d8bea3ec06..06551c5ad75d1 100644 --- a/fs/nfs/write.c +++ b/fs/nfs/write.c @@ -153,20 +153,10 @@ nfs_page_set_inode_ref(struct nfs_page *req, struct inode *inode) } } -static int -nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode) +static void nfs_cancel_remove_inode(struct nfs_page *req, struct inode *inode) { - int ret; - - if (!test_bit(PG_REMOVE, &req->wb_flags)) - return 0; - ret = nfs_page_group_lock(req); - if (ret) - return ret; if (test_and_clear_bit(PG_REMOVE, &req->wb_flags)) nfs_page_set_inode_ref(req, inode); - nfs_page_group_unlock(req); - return 0; } /** @@ -583,19 +573,18 @@ static struct nfs_page *nfs_lock_and_join_requests(struct folio *folio) return ERR_PTR(ret); } + ret = nfs_page_group_lock(head); + if (ret < 0) + goto out_unlock; + /* Ensure that nobody removed the request before we locked it */ if (head != folio->private) { + nfs_page_group_unlock(head); nfs_unlock_and_release_request(head); goto retry; } - ret = nfs_cancel_remove_inode(head, inode); - if (ret < 0) - goto out_unlock; - - ret = nfs_page_group_lock(head); - if (ret < 0) - goto out_unlock; + nfs_cancel_remove_inode(head, inode); /* lock each request in the page group */ for (subreq = head->wb_this_page; @@ -800,7 +789,8 @@ static void nfs_inode_remove_request(struct nfs_page *req) { struct nfs_inode *nfsi = NFS_I(nfs_page_to_inode(req)); - if (nfs_page_group_sync_on_bit(req, PG_REMOVE)) { + nfs_page_group_lock(req); + if (nfs_page_group_sync_on_bit_locked(req, PG_REMOVE)) { struct folio *folio = nfs_page_to_folio(req->wb_head); struct address_space *mapping = folio->mapping; @@ -812,6 +802,7 @@ static void nfs_inode_remove_request(struct nfs_page *req) } spin_unlock(&mapping->i_private_lock); } + nfs_page_group_unlock(req); if (test_and_clear_bit(PG_INODE_REF, &req->wb_flags)) { atomic_long_dec(&nfsi->nrequests); diff --git a/include/linux/nfs_page.h b/include/linux/nfs_page.h index 169b4ae30ff47..9aed39abc94bc 100644 --- a/include/linux/nfs_page.h +++ b/include/linux/nfs_page.h @@ -160,6 +160,7 @@ extern void nfs_join_page_group(struct nfs_page *head, extern int nfs_page_group_lock(struct nfs_page *); extern void nfs_page_group_unlock(struct nfs_page *); extern bool nfs_page_group_sync_on_bit(struct nfs_page *, unsigned int); +extern bool nfs_page_group_sync_on_bit_locked(struct nfs_page *, unsigned int); extern int nfs_page_set_headlock(struct nfs_page *req); extern void nfs_page_clear_headlock(struct nfs_page *req); extern bool nfs_async_iocounter_wait(struct rpc_task *, struct nfs_lock_context *); From ceeea2b49d49419004af76181b9737a9626e825e Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:17 -0400 Subject: [PATCH 05/21] mlx5_en: use read sequence for gettimex64 jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Vadim Fedorenko commit 0452a2d8b8b98a5b1a9139c1a9ed98bccee356cc The gettimex64() doesn't modify values in timecounter, that's why there is no need to update sequence counter. Reduce the contention on sequence lock for multi-thread PHC reading use-case. Signed-off-by: Vadim Fedorenko Reviewed-by: Rahul Rameshbabu Acked-by: Tariq Toukan Link: https://patch.msgid.link/20241014170103.2473580-1-vadfed@meta.com Signed-off-by: Jakub Kicinski (cherry picked from commit 0452a2d8b8b98a5b1a9139c1a9ed98bccee356cc) Signed-off-by: Jonathan Maple --- drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index b306ae79bf97a..4822d01123b45 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -402,9 +402,7 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, struct ptp_system_timestamp *sts) { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); - struct mlx5_timer *timer = &clock->timer; struct mlx5_core_dev *mdev; - unsigned long flags; u64 cycles, ns; mdev = container_of(clock, struct mlx5_core_dev, clock); @@ -413,10 +411,8 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, goto out; } - write_seqlock_irqsave(&clock->lock, flags); cycles = mlx5_read_time(mdev, sts, false); - ns = timecounter_cyc2time(&timer->tc, cycles); - write_sequnlock_irqrestore(&clock->lock, flags); + ns = mlx5_timecounter_cyc2time(clock, cycles); *ts = ns_to_timespec64(ns); out: return 0; From 1e248aee197a2d2277486c5904643b0fe4d0dd76 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:18 -0400 Subject: [PATCH 06/21] net/mlx5: use do_aux_work for PHC overflow checks jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Vadim Fedorenko commit e61e6c415ba9ff2b32bb6780ce1b17d1d76238f1 The overflow_work is using system wq to do overflow checks and updates for PHC device timecounter, which might be overhelmed by other tasks. But there is dedicated kthread in PTP subsystem designed for such things. This patch changes the work queue to proper align with PTP subsystem and to avoid overloading system work queue. The adjfine() function acts the same way as overflow check worker, we can postpone ptp aux worker till the next overflow period after adjfine() was called. Reviewed-by: Dragos Tatulea Signed-off-by: Vadim Fedorenko Acked-by: Tariq Toukan Link: https://patch.msgid.link/20250107104812.380225-1-vadfed@meta.com Signed-off-by: Paolo Abeni (cherry picked from commit e61e6c415ba9ff2b32bb6780ce1b17d1d76238f1) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 24 ++++++++++--------- include/linux/mlx5/driver.h | 1 - 2 files changed, 13 insertions(+), 12 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 4822d01123b45..d61a1a9297c90 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -322,17 +322,16 @@ static void mlx5_pps_out(struct work_struct *work) } } -static void mlx5_timestamp_overflow(struct work_struct *work) +static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) { - struct delayed_work *dwork = to_delayed_work(work); struct mlx5_core_dev *mdev; struct mlx5_timer *timer; struct mlx5_clock *clock; unsigned long flags; - timer = container_of(dwork, struct mlx5_timer, overflow_work); - clock = container_of(timer, struct mlx5_clock, timer); + clock = container_of(ptp_info, struct mlx5_clock, ptp_info); mdev = container_of(clock, struct mlx5_core_dev, clock); + timer = &clock->timer; if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) goto out; @@ -343,7 +342,7 @@ static void mlx5_timestamp_overflow(struct work_struct *work) write_sequnlock_irqrestore(&clock->lock, flags); out: - schedule_delayed_work(&timer->overflow_work, timer->overflow_period); + return timer->overflow_period; } static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev, @@ -517,6 +516,7 @@ static int mlx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) timer->cycles.mult = mult; mlx5_update_clock_info_page(mdev); write_sequnlock_irqrestore(&clock->lock, flags); + ptp_schedule_worker(clock->ptp, timer->overflow_period); return 0; } @@ -852,6 +852,7 @@ static const struct ptp_clock_info mlx5_ptp_clock_info = { .settime64 = mlx5_ptp_settime, .enable = NULL, .verify = NULL, + .do_aux_work = mlx5_timestamp_overflow, }; static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin, @@ -1052,12 +1053,11 @@ static void mlx5_init_overflow_period(struct mlx5_clock *clock) do_div(ns, NSEC_PER_SEC / HZ); timer->overflow_period = ns; - INIT_DELAYED_WORK(&timer->overflow_work, mlx5_timestamp_overflow); - if (timer->overflow_period) - schedule_delayed_work(&timer->overflow_work, 0); - else + if (!timer->overflow_period) { + timer->overflow_period = HZ; mlx5_core_warn(mdev, - "invalid overflow period, overflow_work is not scheduled\n"); + "invalid overflow period, overflow_work is scheduled once per second\n"); + } if (clock_info) clock_info->overflow_period = timer->overflow_period; @@ -1172,6 +1172,9 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); mlx5_eq_notifier_register(mdev, &clock->pps_nb); + + if (clock->ptp) + ptp_schedule_worker(clock->ptp, 0); } void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) @@ -1188,7 +1191,6 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) } cancel_work_sync(&clock->pps_info.out_work); - cancel_delayed_work_sync(&clock->timer.overflow_work); if (mdev->clock_info) { free_page((unsigned long)mdev->clock_info); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index e23c692a34c70..0fcf26e1b1f5f 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -721,7 +721,6 @@ struct mlx5_timer { struct timecounter tc; u32 nominal_c_mult; unsigned long overflow_period; - struct delayed_work overflow_work; }; struct mlx5_clock { From ce9a839585b80aa568daedadb1990077375272ca Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:18 -0400 Subject: [PATCH 07/21] net/mlx5: Add support for MRTCQ register jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit e2685ef5f56295249bf98bc6603d3c092fe0ce56 Management Real Time Clock Query (MRTCQ) register is used to query hardware clock identity. Signed-off-by: Jianbo Liu Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Link: https://patch.msgid.link/20250109204231.1809851-3-tariqt@nvidia.com Reviewed-by: Jacob Keller Reviewed-by: Kalesh AP Signed-off-by: Leon Romanovsky (cherry picked from commit e2685ef5f56295249bf98bc6603d3c092fe0ce56) Signed-off-by: Jonathan Maple --- include/linux/mlx5/driver.h | 1 + include/linux/mlx5/mlx5_ifc.h | 11 ++++++++++- 2 files changed, 11 insertions(+), 1 deletion(-) diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 0fcf26e1b1f5f..f79f9fd92fb42 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -161,6 +161,7 @@ enum { MLX5_REG_MIRC = 0x9162, MLX5_REG_MTPTM = 0x9180, MLX5_REG_MTCTR = 0x9181, + MLX5_REG_MRTCQ = 0x9182, MLX5_REG_SBCAM = 0xB01F, MLX5_REG_RESOURCE_DUMP = 0xC000, MLX5_REG_DTOR = 0xC00E, diff --git a/include/linux/mlx5/mlx5_ifc.h b/include/linux/mlx5/mlx5_ifc.h index 96d369112bfa0..e0fc881d8b594 100644 --- a/include/linux/mlx5/mlx5_ifc.h +++ b/include/linux/mlx5/mlx5_ifc.h @@ -10627,7 +10627,8 @@ struct mlx5_ifc_mcam_access_reg_bits3 { u8 regs_63_to_32[0x20]; - u8 regs_31_to_2[0x1e]; + u8 regs_31_to_3[0x1d]; + u8 mrtcq[0x1]; u8 mtctr[0x1]; u8 mtptm[0x1]; }; @@ -13118,4 +13119,12 @@ struct mlx5_ifc_msees_reg_bits { u8 reserved_at_80[0x180]; }; +struct mlx5_ifc_mrtcq_reg_bits { + u8 reserved_at_0[0x40]; + + u8 rt_clock_identity[0x40]; + + u8 reserved_at_80[0x180]; +}; + #endif /* MLX5_IFC_H */ From 39d250b4b107381ca50a511bacfb14f5a0cbeb7d Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:18 -0400 Subject: [PATCH 08/21] net/mlx5: Add helper functions for PTP callbacks jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit e3ad54f5bdb9432bf34673f1050e8c28eee7908a The PTP callback functions should not be used directly by internal callers. Add helpers that can be used internally and externally. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Reviewed-by: Mateusz Polchlopek Signed-off-by: Paolo Abeni (cherry picked from commit e3ad54f5bdb9432bf34673f1050e8c28eee7908a) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 32 +++++++++++++------ 1 file changed, 22 insertions(+), 10 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index d61a1a9297c90..eaf3437560267 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -119,6 +119,13 @@ static u32 mlx5_ptp_shift_constant(u32 dev_freq_khz) ilog2((U32_MAX / NSEC_PER_MSEC) * dev_freq_khz)); } +static s32 mlx5_clock_getmaxphase(struct mlx5_core_dev *mdev) +{ + return MLX5_CAP_MCAM_FEATURE(mdev, mtutc_time_adjustment_extended_range) ? + MLX5_MTUTC_OPERATION_ADJUST_TIME_EXTENDED_MAX : + MLX5_MTUTC_OPERATION_ADJUST_TIME_MAX; +} + static s32 mlx5_ptp_getmaxphase(struct ptp_clock_info *ptp) { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); @@ -126,14 +133,12 @@ static s32 mlx5_ptp_getmaxphase(struct ptp_clock_info *ptp) mdev = container_of(clock, struct mlx5_core_dev, clock); - return MLX5_CAP_MCAM_FEATURE(mdev, mtutc_time_adjustment_extended_range) ? - MLX5_MTUTC_OPERATION_ADJUST_TIME_EXTENDED_MAX : - MLX5_MTUTC_OPERATION_ADJUST_TIME_MAX; + return mlx5_clock_getmaxphase(mdev); } static bool mlx5_is_mtutc_time_adj_cap(struct mlx5_core_dev *mdev, s64 delta) { - s64 max = mlx5_ptp_getmaxphase(&mdev->clock.ptp_info); + s64 max = mlx5_clock_getmaxphase(mdev); if (delta < -max || delta > max) return false; @@ -361,15 +366,12 @@ static int mlx5_ptp_settime_real_time(struct mlx5_core_dev *mdev, return mlx5_set_mtutc(mdev, in, sizeof(in)); } -static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts) +static int mlx5_clock_settime(struct mlx5_core_dev *mdev, struct mlx5_clock *clock, + const struct timespec64 *ts) { - struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_timer *timer = &clock->timer; - struct mlx5_core_dev *mdev; unsigned long flags; - mdev = container_of(clock, struct mlx5_core_dev, clock); - if (mlx5_modify_mtutc_allowed(mdev)) { int err = mlx5_ptp_settime_real_time(mdev, ts); @@ -385,6 +387,16 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 return 0; } +static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 *ts) +{ + struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); + struct mlx5_core_dev *mdev; + + mdev = container_of(clock, struct mlx5_core_dev, clock); + + return mlx5_clock_settime(mdev, clock, ts); +} + static struct timespec64 mlx5_ptp_gettimex_real_time(struct mlx5_core_dev *mdev, struct ptp_system_timestamp *sts) @@ -1129,7 +1141,7 @@ static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev) struct timespec64 ts; ktime_get_real_ts64(&ts); - mlx5_ptp_settime(&clock->ptp_info, &ts); + mlx5_clock_settime(mdev, clock, &ts); } } From 80658f82c577f7f0e522405eb4fce9a9366ff894 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:19 -0400 Subject: [PATCH 09/21] net/mlx5: Change parameters for PTP internal functions jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit 9f722fb105216771f3a494a83dfad445de8a7f2b In later patch, the mlx5_clock will be allocated dynamically, its address can be obtained from mlx5_core_dev struct, but mdev can't be obtained from mlx5_clock because it can be shared by multiple interfaces. So change the parameter for such internal functions, only mdev is passed down from the callers. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit 9f722fb105216771f3a494a83dfad445de8a7f2b) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 19 ++++++++----------- 1 file changed, 8 insertions(+), 11 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index eaf3437560267..e7e4bdba02a3a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -878,10 +878,8 @@ static int mlx5_query_mtpps_pin_mode(struct mlx5_core_dev *mdev, u8 pin, mtpps_size, MLX5_REG_MTPPS, 0, 0); } -static int mlx5_get_pps_pin_mode(struct mlx5_clock *clock, u8 pin) +static int mlx5_get_pps_pin_mode(struct mlx5_core_dev *mdev, u8 pin) { - struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, clock); - u32 out[MLX5_ST_SZ_DW(mtpps_reg)] = {}; u8 mode; int err; @@ -900,8 +898,9 @@ static int mlx5_get_pps_pin_mode(struct mlx5_clock *clock, u8 pin) return PTP_PF_NONE; } -static void mlx5_init_pin_config(struct mlx5_clock *clock) +static void mlx5_init_pin_config(struct mlx5_core_dev *mdev) { + struct mlx5_clock *clock = &mdev->clock; int i; if (!clock->ptp_info.n_pins) @@ -922,7 +921,7 @@ static void mlx5_init_pin_config(struct mlx5_clock *clock) sizeof(clock->ptp_info.pin_config[i].name), "mlx5_pps%d", i); clock->ptp_info.pin_config[i].index = i; - clock->ptp_info.pin_config[i].func = mlx5_get_pps_pin_mode(clock, i); + clock->ptp_info.pin_config[i].func = mlx5_get_pps_pin_mode(mdev, i); clock->ptp_info.pin_config[i].chan = 0; } } @@ -1041,10 +1040,10 @@ static void mlx5_timecounter_init(struct mlx5_core_dev *mdev) ktime_to_ns(ktime_get_real())); } -static void mlx5_init_overflow_period(struct mlx5_clock *clock) +static void mlx5_init_overflow_period(struct mlx5_core_dev *mdev) { - struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, clock); struct mlx5_ib_clock_info *clock_info = mdev->clock_info; + struct mlx5_clock *clock = &mdev->clock; struct mlx5_timer *timer = &clock->timer; u64 overflow_cycles; u64 frac = 0; @@ -1135,7 +1134,7 @@ static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev) mlx5_timecounter_init(mdev); mlx5_init_clock_info(mdev); - mlx5_init_overflow_period(clock); + mlx5_init_overflow_period(mdev); if (mlx5_real_time_mode(mdev)) { struct timespec64 ts; @@ -1147,13 +1146,11 @@ static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev) static void mlx5_init_pps(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; - if (!MLX5_PPS_CAP(mdev)) return; mlx5_get_pps_caps(mdev); - mlx5_init_pin_config(clock); + mlx5_init_pin_config(mdev); } void mlx5_init_clock(struct mlx5_core_dev *mdev) From d2a2b9d3bd3350cc5c00d8673e4daca8145e7506 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:19 -0400 Subject: [PATCH 10/21] net/mlx5: Add init and destruction functions for a single HW clock jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit ccb717a88b2ed57e464c3099d2e8b0c9db7cef21 Move hardware clock initialization and destruction to the functions, which will be used for dynamically allocated clock. Such clock is shared by all the devices if the queried clock identities are same. The out_work is for PPS out event, which can't be triggered when clock is shared, so INIT_WORK is not moved to the initialization function. Besides, we still need to register notifier for each device. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit ccb717a88b2ed57e464c3099d2e8b0c9db7cef21) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 48 ++++++++++++------- 1 file changed, 31 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index e7e4bdba02a3a..cc0a491bf6173 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -1153,17 +1153,11 @@ static void mlx5_init_pps(struct mlx5_core_dev *mdev) mlx5_init_pin_config(mdev); } -void mlx5_init_clock(struct mlx5_core_dev *mdev) +static void mlx5_init_clock_dev(struct mlx5_core_dev *mdev) { struct mlx5_clock *clock = &mdev->clock; - if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) { - mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n"); - return; - } - seqlock_init(&clock->lock); - INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out); /* Initialize the device clock */ mlx5_init_timer_clock(mdev); @@ -1179,28 +1173,19 @@ void mlx5_init_clock(struct mlx5_core_dev *mdev) clock->ptp = NULL; } - MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); - mlx5_eq_notifier_register(mdev, &clock->pps_nb); - if (clock->ptp) ptp_schedule_worker(clock->ptp, 0); } -void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) +static void mlx5_destroy_clock_dev(struct mlx5_core_dev *mdev) { struct mlx5_clock *clock = &mdev->clock; - if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) - return; - - mlx5_eq_notifier_unregister(mdev, &clock->pps_nb); if (clock->ptp) { ptp_clock_unregister(clock->ptp); clock->ptp = NULL; } - cancel_work_sync(&clock->pps_info.out_work); - if (mdev->clock_info) { free_page((unsigned long)mdev->clock_info); mdev->clock_info = NULL; @@ -1208,3 +1193,32 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) kfree(clock->ptp_info.pin_config); } + +void mlx5_init_clock(struct mlx5_core_dev *mdev) +{ + struct mlx5_clock *clock = &mdev->clock; + + if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) { + mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n"); + return; + } + + mlx5_init_clock_dev(mdev); + + INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out); + MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); + mlx5_eq_notifier_register(mdev, &clock->pps_nb); +} + +void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) +{ + struct mlx5_clock *clock = &mdev->clock; + + if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) + return; + + mlx5_eq_notifier_unregister(mdev, &clock->pps_nb); + cancel_work_sync(&clock->pps_info.out_work); + + mlx5_destroy_clock_dev(mdev); +} From 19185fcf1ad6374acb448f338fd998db3c3e286a Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:19 -0400 Subject: [PATCH 11/21] net/mlx5: Add API to get mlx5_core_dev from mlx5_clock jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit 355f58f10911f9654d42dcba3cbe127238b4fd94 The mdev is calculated directly from mlx5_clock, as it's one of the fields in mlx5_core_dev. Move to a function so it can be easily changed in next patch. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit 355f58f10911f9654d42dcba3cbe127238b4fd94) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 35 ++++++++++--------- 1 file changed, 18 insertions(+), 17 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index cc0a491bf6173..b2c88050ba36b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -77,6 +77,11 @@ enum { MLX5_MTUTC_OPERATION_ADJUST_TIME_EXTENDED_MAX = 200000, }; +static struct mlx5_core_dev *mlx5_clock_mdev_get(struct mlx5_clock *clock) +{ + return container_of(clock, struct mlx5_core_dev, clock); +} + static bool mlx5_real_time_mode(struct mlx5_core_dev *mdev) { return (mlx5_is_real_time_rq(mdev) || mlx5_is_real_time_sq(mdev)); @@ -131,7 +136,7 @@ static s32 mlx5_ptp_getmaxphase(struct ptp_clock_info *ptp) struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_core_dev *mdev; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); return mlx5_clock_getmaxphase(mdev); } @@ -226,7 +231,7 @@ static int mlx5_ptp_getcrosststamp(struct ptp_clock_info *ptp, struct system_time_snapshot history_begin = {0}; struct mlx5_core_dev *mdev; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); if (!mlx5_is_ptm_source_time_available(mdev)) return -EBUSY; @@ -268,8 +273,7 @@ static u64 read_internal_timer(const struct cyclecounter *cc) { struct mlx5_timer *timer = container_of(cc, struct mlx5_timer, cycles); struct mlx5_clock *clock = container_of(timer, struct mlx5_clock, timer); - struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, - clock); + struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); return mlx5_read_time(mdev, NULL, false) & cc->mask; } @@ -304,8 +308,7 @@ static void mlx5_pps_out(struct work_struct *work) out_work); struct mlx5_clock *clock = container_of(pps_info, struct mlx5_clock, pps_info); - struct mlx5_core_dev *mdev = container_of(clock, struct mlx5_core_dev, - clock); + struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; unsigned long flags; int i; @@ -335,7 +338,7 @@ static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) unsigned long flags; clock = container_of(ptp_info, struct mlx5_clock, ptp_info); - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); timer = &clock->timer; if (mdev->state == MLX5_DEVICE_STATE_INTERNAL_ERROR) @@ -392,7 +395,7 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_core_dev *mdev; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); return mlx5_clock_settime(mdev, clock, ts); } @@ -416,7 +419,7 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, struct mlx5_core_dev *mdev; u64 cycles, ns; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); if (mlx5_real_time_mode(mdev)) { *ts = mlx5_ptp_gettimex_real_time(mdev, sts); goto out; @@ -457,7 +460,7 @@ static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) struct mlx5_core_dev *mdev; unsigned long flags; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); if (mlx5_modify_mtutc_allowed(mdev)) { int err = mlx5_ptp_adjtime_real_time(mdev, delta); @@ -479,7 +482,7 @@ static int mlx5_ptp_adjphase(struct ptp_clock_info *ptp, s32 delta) struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_core_dev *mdev; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); return mlx5_ptp_adjtime_real_time(mdev, delta); } @@ -512,7 +515,7 @@ static int mlx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) unsigned long flags; u32 mult; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); if (mlx5_modify_mtutc_allowed(mdev)) { int err = mlx5_ptp_freq_adj_real_time(mdev, scaled_ppm); @@ -539,8 +542,7 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp, { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); - struct mlx5_core_dev *mdev = - container_of(clock, struct mlx5_core_dev, clock); + struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; u32 field_select = 0; u8 pin_mode = 0; @@ -724,8 +726,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); - struct mlx5_core_dev *mdev = - container_of(clock, struct mlx5_core_dev, clock); + struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); bool rt_mode = mlx5_real_time_mode(mdev); u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; u32 out_pulse_duration_ns = 0; @@ -987,7 +988,7 @@ static int mlx5_pps_event(struct notifier_block *nb, unsigned long flags; u64 ns; - mdev = container_of(clock, struct mlx5_core_dev, clock); + mdev = mlx5_clock_mdev_get(clock); switch (clock->ptp_info.pin_config[pin].func) { case PTP_PF_EXTTS: From a75ce40585bd984e7b09a1c6c324609be945cddf Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:19 -0400 Subject: [PATCH 12/21] net/mlx5: Change clock in mlx5_core_dev to mlx5_clock pointer jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit f9beaf4fac64c84631ba9a2eb864cea6b52032a2 Change clock member in mlx5_core_dev to a pointer, so it can point to a clock shared by multiple functions in later patch. For now, each function has its own clock, so mdev in mlx5_clock_priv is the back pointer to the function. Later it points to one (normally the first one) of the multiple functions sharing the same clock. Change mlx5_init_clock() to return error if mlx5_clock is not allocated. Besides, a null clock is defined and used when hardware clock is not supported. So, the clock pointer is always pointing to something valid. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit f9beaf4fac64c84631ba9a2eb864cea6b52032a2) Signed-off-by: Jonathan Maple --- .../net/ethernet/mellanox/mlx5/core/en/ptp.c | 4 +- .../net/ethernet/mellanox/mlx5/core/en/trap.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en/xdp.c | 4 +- .../mellanox/mlx5/core/en/xsk/setup.c | 2 +- .../net/ethernet/mellanox/mlx5/core/en_main.c | 4 +- .../ethernet/mellanox/mlx5/core/lib/clock.c | 87 ++++++++++++++----- .../ethernet/mellanox/mlx5/core/lib/clock.h | 35 +++++++- .../net/ethernet/mellanox/mlx5/core/main.c | 11 ++- include/linux/mlx5/driver.h | 31 +------ 9 files changed, 116 insertions(+), 64 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c index afd654583b6b1..131ed97ca997d 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/ptp.c @@ -326,7 +326,7 @@ static int mlx5e_ptp_alloc_txqsq(struct mlx5e_ptp *c, int txq_ix, int node; sq->pdev = c->pdev; - sq->clock = &mdev->clock; + sq->clock = mdev->clock; sq->mkey_be = c->mkey_be; sq->netdev = c->netdev; sq->priv = c->priv; @@ -696,7 +696,7 @@ static int mlx5e_init_ptp_rq(struct mlx5e_ptp *c, struct mlx5e_params *params, rq->pdev = c->pdev; rq->netdev = priv->netdev; rq->priv = priv; - rq->clock = &mdev->clock; + rq->clock = mdev->clock; rq->tstamp = &priv->tstamp; rq->mdev = mdev; rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/trap.c b/drivers/net/ethernet/mellanox/mlx5/core/en/trap.c index 53ca16cb9c41a..140606fcd23b1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/trap.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/trap.c @@ -46,7 +46,7 @@ static void mlx5e_init_trap_rq(struct mlx5e_trap *t, struct mlx5e_params *params rq->pdev = t->pdev; rq->netdev = priv->netdev; rq->priv = priv; - rq->clock = &mdev->clock; + rq->clock = mdev->clock; rq->tstamp = &priv->tstamp; rq->mdev = mdev; rq->hw_mtu = MLX5E_SW2HW_MTU(params, params->sw_mtu); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c index fdb5e5c3a5e79..78318af0db476 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xdp.c @@ -289,9 +289,9 @@ static u64 mlx5e_xsk_fill_timestamp(void *_priv) ts = get_cqe_ts(priv->cqe); if (mlx5_is_real_time_rq(priv->cq->mdev) || mlx5_is_real_time_sq(priv->cq->mdev)) - return mlx5_real_time_cyc2time(&priv->cq->mdev->clock, ts); + return mlx5_real_time_cyc2time(priv->cq->mdev->clock, ts); - return mlx5_timecounter_cyc2time(&priv->cq->mdev->clock, ts); + return mlx5_timecounter_cyc2time(priv->cq->mdev->clock, ts); } static void mlx5e_xsk_request_checksum(u16 csum_start, u16 csum_offset, void *priv) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c index 9240cfe25d102..d743e823362ae 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en/xsk/setup.c @@ -72,7 +72,7 @@ static int mlx5e_init_xsk_rq(struct mlx5e_channel *c, rq->netdev = c->netdev; rq->priv = c->priv; rq->tstamp = c->tstamp; - rq->clock = &mdev->clock; + rq->clock = mdev->clock; rq->icosq = &c->icosq; rq->ix = c->ix; rq->channel = c; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c index 13a3fa8dc0cb0..117bc1bb02e33 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/en_main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/en_main.c @@ -742,7 +742,7 @@ static int mlx5e_init_rxq_rq(struct mlx5e_channel *c, struct mlx5e_params *param rq->netdev = c->netdev; rq->priv = c->priv; rq->tstamp = c->tstamp; - rq->clock = &mdev->clock; + rq->clock = mdev->clock; rq->icosq = &c->icosq; rq->ix = c->ix; rq->channel = c; @@ -1621,7 +1621,7 @@ static int mlx5e_alloc_txqsq(struct mlx5e_channel *c, int err; sq->pdev = c->pdev; - sq->clock = &mdev->clock; + sq->clock = mdev->clock; sq->mkey_be = c->mkey_be; sq->netdev = c->netdev; sq->mdev = c->mdev; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index b2c88050ba36b..da2a21ce8060a 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -77,9 +77,19 @@ enum { MLX5_MTUTC_OPERATION_ADJUST_TIME_EXTENDED_MAX = 200000, }; +struct mlx5_clock_priv { + struct mlx5_clock clock; + struct mlx5_core_dev *mdev; +}; + +static struct mlx5_clock_priv *clock_priv(struct mlx5_clock *clock) +{ + return container_of(clock, struct mlx5_clock_priv, clock); +} + static struct mlx5_core_dev *mlx5_clock_mdev_get(struct mlx5_clock *clock) { - return container_of(clock, struct mlx5_core_dev, clock); + return clock_priv(clock)->mdev; } static bool mlx5_real_time_mode(struct mlx5_core_dev *mdev) @@ -219,7 +229,7 @@ static int mlx5_mtctr_syncdevicetime(ktime_t *device_time, if (real_time_mode) *device_time = ns_to_ktime(REAL_TIME_TO_NS(device >> 32, device & U32_MAX)); else - *device_time = mlx5_timecounter_cyc2time(&mdev->clock, device); + *device_time = mlx5_timecounter_cyc2time(mdev->clock, device); return 0; } @@ -281,7 +291,7 @@ static u64 read_internal_timer(const struct cyclecounter *cc) static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev) { struct mlx5_ib_clock_info *clock_info = mdev->clock_info; - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; struct mlx5_timer *timer; u32 sign; @@ -599,7 +609,7 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp, static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; u64 cycles_now, cycles_delta; u64 nsec_now, nsec_delta; struct mlx5_timer *timer; @@ -658,7 +668,7 @@ static int mlx5_perout_conf_out_pulse_duration(struct mlx5_core_dev *mdev, struct ptp_clock_request *rq, u32 *out_pulse_duration_ns) { - struct mlx5_pps *pps_info = &mdev->clock.pps_info; + struct mlx5_pps *pps_info = &mdev->clock->pps_info; u32 out_pulse_duration; struct timespec64 ts; @@ -691,7 +701,7 @@ static int perout_conf_npps_real_time(struct mlx5_core_dev *mdev, struct ptp_clo u32 *field_select, u32 *out_pulse_duration_ns, u64 *period, u64 *time_stamp) { - struct mlx5_pps *pps_info = &mdev->clock.pps_info; + struct mlx5_pps *pps_info = &mdev->clock->pps_info; struct ptp_clock_time *time = &rq->perout.start; struct timespec64 ts; @@ -901,7 +911,7 @@ static int mlx5_get_pps_pin_mode(struct mlx5_core_dev *mdev, u8 pin) static void mlx5_init_pin_config(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; int i; if (!clock->ptp_info.n_pins) @@ -929,8 +939,8 @@ static void mlx5_init_pin_config(struct mlx5_core_dev *mdev) static void mlx5_get_pps_caps(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; u32 out[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; + struct mlx5_clock *clock = mdev->clock; mlx5_query_mtpps(mdev, out, sizeof(out)); @@ -1025,7 +1035,7 @@ static int mlx5_pps_event(struct notifier_block *nb, static void mlx5_timecounter_init(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; struct mlx5_timer *timer = &clock->timer; u32 dev_freq; @@ -1044,7 +1054,7 @@ static void mlx5_timecounter_init(struct mlx5_core_dev *mdev) static void mlx5_init_overflow_period(struct mlx5_core_dev *mdev) { struct mlx5_ib_clock_info *clock_info = mdev->clock_info; - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; struct mlx5_timer *timer = &clock->timer; u64 overflow_cycles; u64 frac = 0; @@ -1077,7 +1087,7 @@ static void mlx5_init_overflow_period(struct mlx5_core_dev *mdev) static void mlx5_init_clock_info(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; struct mlx5_ib_clock_info *info; struct mlx5_timer *timer; @@ -1100,7 +1110,7 @@ static void mlx5_init_clock_info(struct mlx5_core_dev *mdev) static void mlx5_init_timer_max_freq_adjustment(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; u32 out[MLX5_ST_SZ_DW(mtutc_reg)] = {}; u32 in[MLX5_ST_SZ_DW(mtutc_reg)] = {}; u8 log_max_freq_adjustment = 0; @@ -1119,7 +1129,7 @@ static void mlx5_init_timer_max_freq_adjustment(struct mlx5_core_dev *mdev) static void mlx5_init_timer_clock(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; /* Configure the PHC */ clock->ptp_info = mlx5_ptp_clock_info; @@ -1156,7 +1166,7 @@ static void mlx5_init_pps(struct mlx5_core_dev *mdev) static void mlx5_init_clock_dev(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; seqlock_init(&clock->lock); @@ -1180,7 +1190,7 @@ static void mlx5_init_clock_dev(struct mlx5_core_dev *mdev) static void mlx5_destroy_clock_dev(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; if (clock->ptp) { ptp_clock_unregister(clock->ptp); @@ -1195,25 +1205,60 @@ static void mlx5_destroy_clock_dev(struct mlx5_core_dev *mdev) kfree(clock->ptp_info.pin_config); } -void mlx5_init_clock(struct mlx5_core_dev *mdev) +static void mlx5_clock_free(struct mlx5_core_dev *mdev) +{ + struct mlx5_clock_priv *cpriv = clock_priv(mdev->clock); + + mlx5_destroy_clock_dev(mdev); + kfree(cpriv); + mdev->clock = NULL; +} + +static int mlx5_clock_alloc(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock_priv *cpriv; + struct mlx5_clock *clock; + + cpriv = kzalloc(sizeof(*cpriv), GFP_KERNEL); + if (!cpriv) + return -ENOMEM; + + cpriv->mdev = mdev; + clock = &cpriv->clock; + mdev->clock = clock; + mlx5_init_clock_dev(mdev); + + return 0; +} + +static struct mlx5_clock null_clock; + +int mlx5_init_clock(struct mlx5_core_dev *mdev) +{ + struct mlx5_clock *clock; + int err; if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) { + mdev->clock = &null_clock; mlx5_core_warn(mdev, "invalid device_frequency_khz, aborting HW clock init\n"); - return; + return 0; } - mlx5_init_clock_dev(mdev); + err = mlx5_clock_alloc(mdev); + if (err) + return err; + clock = mdev->clock; INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out); MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); mlx5_eq_notifier_register(mdev, &clock->pps_nb); + + return 0; } void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = &mdev->clock; + struct mlx5_clock *clock = mdev->clock; if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) return; @@ -1221,5 +1266,5 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) mlx5_eq_notifier_unregister(mdev, &clock->pps_nb); cancel_work_sync(&clock->pps_info.out_work); - mlx5_destroy_clock_dev(mdev); + mlx5_clock_free(mdev); } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h index bd95b9f8d1439..eca1dd9039be6 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h @@ -33,6 +33,35 @@ #ifndef __LIB_CLOCK_H__ #define __LIB_CLOCK_H__ +#include + +#define MAX_PIN_NUM 8 +struct mlx5_pps { + u8 pin_caps[MAX_PIN_NUM]; + struct work_struct out_work; + u64 start[MAX_PIN_NUM]; + u8 enabled; + u64 min_npps_period; + u64 min_out_pulse_duration_ns; +}; + +struct mlx5_timer { + struct cyclecounter cycles; + struct timecounter tc; + u32 nominal_c_mult; + unsigned long overflow_period; +}; + +struct mlx5_clock { + struct mlx5_nb pps_nb; + seqlock_t lock; + struct hwtstamp_config hwtstamp_config; + struct ptp_clock *ptp; + struct ptp_clock_info ptp_info; + struct mlx5_pps pps_info; + struct mlx5_timer timer; +}; + static inline bool mlx5_is_real_time_rq(struct mlx5_core_dev *mdev) { u8 rq_ts_format_cap = MLX5_CAP_GEN(mdev, rq_ts_format); @@ -54,12 +83,12 @@ static inline bool mlx5_is_real_time_sq(struct mlx5_core_dev *mdev) typedef ktime_t (*cqe_ts_to_ns)(struct mlx5_clock *, u64); #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) -void mlx5_init_clock(struct mlx5_core_dev *mdev); +int mlx5_init_clock(struct mlx5_core_dev *mdev); void mlx5_cleanup_clock(struct mlx5_core_dev *mdev); static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev) { - return mdev->clock.ptp ? ptp_clock_index(mdev->clock.ptp) : -1; + return mdev->clock->ptp ? ptp_clock_index(mdev->clock->ptp) : -1; } static inline ktime_t mlx5_timecounter_cyc2time(struct mlx5_clock *clock, @@ -87,7 +116,7 @@ static inline ktime_t mlx5_real_time_cyc2time(struct mlx5_clock *clock, return ns_to_ktime(time); } #else -static inline void mlx5_init_clock(struct mlx5_core_dev *mdev) {} +static inline int mlx5_init_clock(struct mlx5_core_dev *mdev) { return 0; } static inline void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) {} static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev) { diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 220a9ac75c8ba..37b67ba01e17f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1032,7 +1032,11 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) mlx5_init_reserved_gids(dev); - mlx5_init_clock(dev); + err = mlx5_init_clock(dev); + if (err) { + mlx5_core_err(dev, "failed to initialize hardware clock\n"); + goto err_tables_cleanup; + } dev->vxlan = mlx5_vxlan_create(dev); dev->geneve = mlx5_geneve_create(dev); @@ -1040,7 +1044,7 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) err = mlx5_init_rl_table(dev); if (err) { mlx5_core_err(dev, "Failed to init rate limiting\n"); - goto err_tables_cleanup; + goto err_clock_cleanup; } err = mlx5_mpfs_init(dev); @@ -1117,10 +1121,11 @@ static int mlx5_init_once(struct mlx5_core_dev *dev) mlx5_mpfs_cleanup(dev); err_rl_cleanup: mlx5_cleanup_rl_table(dev); -err_tables_cleanup: +err_clock_cleanup: mlx5_geneve_destroy(dev->geneve); mlx5_vxlan_destroy(dev->vxlan); mlx5_cleanup_clock(dev); +err_tables_cleanup: mlx5_cleanup_reserved_gids(dev); mlx5_cq_debugfs_cleanup(dev); mlx5_fw_reset_cleanup(dev); diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index f79f9fd92fb42..fe527eeb3191a 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -55,7 +55,6 @@ #include #include #include -#include #include #define MLX5_ADEV_NAME "mlx5_core" @@ -707,33 +706,7 @@ struct mlx5_rsvd_gids { struct ida ida; }; -#define MAX_PIN_NUM 8 -struct mlx5_pps { - u8 pin_caps[MAX_PIN_NUM]; - struct work_struct out_work; - u64 start[MAX_PIN_NUM]; - u8 enabled; - u64 min_npps_period; - u64 min_out_pulse_duration_ns; -}; - -struct mlx5_timer { - struct cyclecounter cycles; - struct timecounter tc; - u32 nominal_c_mult; - unsigned long overflow_period; -}; - -struct mlx5_clock { - struct mlx5_nb pps_nb; - seqlock_t lock; - struct hwtstamp_config hwtstamp_config; - struct ptp_clock *ptp; - struct ptp_clock_info ptp_info; - struct mlx5_pps pps_info; - struct mlx5_timer timer; -}; - +struct mlx5_clock; struct mlx5_dm; struct mlx5_fw_tracer; struct mlx5_vxlan; @@ -817,7 +790,7 @@ struct mlx5_core_dev { #ifdef CONFIG_MLX5_FPGA struct mlx5_fpga_device *fpga; #endif - struct mlx5_clock clock; + struct mlx5_clock *clock; struct mlx5_ib_clock_info *clock_info; struct mlx5_fw_tracer *tracer; struct mlx5_rsc_dump *rsc_dump; From 743214f0fcbed761596724183dbc8293c3fc4d00 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:20 -0400 Subject: [PATCH 13/21] net/mlx5: Add devcom component for the clock shared by functions jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit 574998cf3b3f59afa9e3a6bbb609d9d4eb2023b4 Add new devcom component for hardware clock. When it is running in real time mode, the functions are grouped by the identify they query. According to firmware document, the clock identify size is 64 bits, so it's safe to memcpy to component key, as the key size is also 64 bits. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit 574998cf3b3f59afa9e3a6bbb609d9d4eb2023b4) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 59 ++++++++++++++++++- .../ethernet/mellanox/mlx5/core/lib/devcom.h | 1 + include/linux/mlx5/driver.h | 2 + 3 files changed, 61 insertions(+), 1 deletion(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index da2a21ce8060a..7e5882ea19e05 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -43,6 +43,8 @@ #include #endif /* CONFIG_X86 */ +#define MLX5_RT_CLOCK_IDENTITY_SIZE MLX5_FLD_SZ_BYTES(mrtcq_reg, rt_clock_identity) + enum { MLX5_PIN_MODE_IN = 0x0, MLX5_PIN_MODE_OUT = 0x1, @@ -77,6 +79,10 @@ enum { MLX5_MTUTC_OPERATION_ADJUST_TIME_EXTENDED_MAX = 200000, }; +struct mlx5_clock_dev_state { + struct mlx5_devcom_comp_dev *compdev; +}; + struct mlx5_clock_priv { struct mlx5_clock clock; struct mlx5_core_dev *mdev; @@ -109,6 +115,22 @@ static bool mlx5_modify_mtutc_allowed(struct mlx5_core_dev *mdev) return MLX5_CAP_MCAM_FEATURE(mdev, ptpcyc2realtime_modify); } +static int mlx5_clock_identity_get(struct mlx5_core_dev *mdev, + u8 identify[MLX5_RT_CLOCK_IDENTITY_SIZE]) +{ + u32 out[MLX5_ST_SZ_DW(mrtcq_reg)] = {}; + u32 in[MLX5_ST_SZ_DW(mrtcq_reg)] = {}; + int err; + + err = mlx5_core_access_reg(mdev, in, sizeof(in), + out, sizeof(out), MLX5_REG_MRTCQ, 0, 0); + if (!err) + memcpy(identify, MLX5_ADDR_OF(mrtcq_reg, out, rt_clock_identity), + MLX5_RT_CLOCK_IDENTITY_SIZE); + + return err; +} + static u32 mlx5_ptp_shift_constant(u32 dev_freq_khz) { /* Optimal shift constant leads to corrections above just 1 scaled ppm. @@ -1231,11 +1253,26 @@ static int mlx5_clock_alloc(struct mlx5_core_dev *mdev) return 0; } +static void mlx5_shared_clock_register(struct mlx5_core_dev *mdev, u64 key) +{ + mdev->clock_state->compdev = mlx5_devcom_register_component(mdev->priv.devc, + MLX5_DEVCOM_SHARED_CLOCK, + key, NULL, mdev); +} + +static void mlx5_shared_clock_unregister(struct mlx5_core_dev *mdev) +{ + mlx5_devcom_unregister_component(mdev->clock_state->compdev); +} + static struct mlx5_clock null_clock; int mlx5_init_clock(struct mlx5_core_dev *mdev) { + u8 identity[MLX5_RT_CLOCK_IDENTITY_SIZE]; + struct mlx5_clock_dev_state *clock_state; struct mlx5_clock *clock; + u64 key; int err; if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) { @@ -1244,9 +1281,26 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) return 0; } + clock_state = kzalloc(sizeof(*clock_state), GFP_KERNEL); + if (!clock_state) + return -ENOMEM; + mdev->clock_state = clock_state; + + if (MLX5_CAP_MCAM_REG3(mdev, mrtcq) && mlx5_real_time_mode(mdev)) { + if (mlx5_clock_identity_get(mdev, identity)) { + mlx5_core_warn(mdev, "failed to get rt clock identity, create ptp dev per function\n"); + } else { + memcpy(&key, &identity, sizeof(key)); + mlx5_shared_clock_register(mdev, key); + } + } + err = mlx5_clock_alloc(mdev); - if (err) + if (err) { + kfree(clock_state); + mdev->clock_state = NULL; return err; + } clock = mdev->clock; INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out); @@ -1267,4 +1321,7 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) cancel_work_sync(&clock->pps_info.out_work); mlx5_clock_free(mdev); + mlx5_shared_clock_unregister(mdev); + kfree(mdev->clock_state); + mdev->clock_state = NULL; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h index d58032dd0df74..c79699b94a025 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/devcom.h @@ -11,6 +11,7 @@ enum mlx5_devcom_component { MLX5_DEVCOM_MPV, MLX5_DEVCOM_HCA_PORTS, MLX5_DEVCOM_SD_GROUP, + MLX5_DEVCOM_SHARED_CLOCK, MLX5_DEVCOM_NUM_COMPONENTS, }; diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index fe527eeb3191a..2c1e83033612d 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -707,6 +707,7 @@ struct mlx5_rsvd_gids { }; struct mlx5_clock; +struct mlx5_clock_dev_state; struct mlx5_dm; struct mlx5_fw_tracer; struct mlx5_vxlan; @@ -791,6 +792,7 @@ struct mlx5_core_dev { struct mlx5_fpga_device *fpga; #endif struct mlx5_clock *clock; + struct mlx5_clock_dev_state *clock_state; struct mlx5_ib_clock_info *clock_info; struct mlx5_fw_tracer *tracer; struct mlx5_rsc_dump *rsc_dump; From 411b8f3280ae2992ff21f429f0e47927830df6c1 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:20 -0400 Subject: [PATCH 14/21] net/mlx5: Move PPS notifier and out_work to clock_state jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit 79faf9d76d66a1f846b61008ddf1596bd7944a08 The PPS notifier is currently in mlx5_clock, and mlx5_clock can be shared in later patch, so the notifier should be registered for each device to avoid any event miss. Besides, the out_work is scheduled by PPS out event which is triggered only when the device is in free running mode. So, both are moved to mlx5_core_dev's clock_state. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit 79faf9d76d66a1f846b61008ddf1596bd7944a08) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 37 +++++++++---------- .../ethernet/mellanox/mlx5/core/lib/clock.h | 2 - 2 files changed, 18 insertions(+), 21 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 7e5882ea19e05..2586b0788b40f 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -80,7 +80,10 @@ enum { }; struct mlx5_clock_dev_state { + struct mlx5_core_dev *mdev; struct mlx5_devcom_comp_dev *compdev; + struct mlx5_nb pps_nb; + struct work_struct out_work; }; struct mlx5_clock_priv { @@ -336,11 +339,10 @@ static void mlx5_update_clock_info_page(struct mlx5_core_dev *mdev) static void mlx5_pps_out(struct work_struct *work) { - struct mlx5_pps *pps_info = container_of(work, struct mlx5_pps, - out_work); - struct mlx5_clock *clock = container_of(pps_info, struct mlx5_clock, - pps_info); - struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); + struct mlx5_clock_dev_state *clock_state = container_of(work, struct mlx5_clock_dev_state, + out_work); + struct mlx5_core_dev *mdev = clock_state->mdev; + struct mlx5_clock *clock = mdev->clock; u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; unsigned long flags; int i; @@ -1012,16 +1014,16 @@ static u64 perout_conf_next_event_timer(struct mlx5_core_dev *mdev, static int mlx5_pps_event(struct notifier_block *nb, unsigned long type, void *data) { - struct mlx5_clock *clock = mlx5_nb_cof(nb, struct mlx5_clock, pps_nb); + struct mlx5_clock_dev_state *clock_state = mlx5_nb_cof(nb, struct mlx5_clock_dev_state, + pps_nb); + struct mlx5_core_dev *mdev = clock_state->mdev; + struct mlx5_clock *clock = mdev->clock; struct ptp_clock_event ptp_event; struct mlx5_eqe *eqe = data; int pin = eqe->data.pps.pin; - struct mlx5_core_dev *mdev; unsigned long flags; u64 ns; - mdev = mlx5_clock_mdev_get(clock); - switch (clock->ptp_info.pin_config[pin].func) { case PTP_PF_EXTTS: ptp_event.index = pin; @@ -1045,7 +1047,7 @@ static int mlx5_pps_event(struct notifier_block *nb, write_seqlock_irqsave(&clock->lock, flags); clock->pps_info.start[pin] = ns; write_sequnlock_irqrestore(&clock->lock, flags); - schedule_work(&clock->pps_info.out_work); + schedule_work(&clock_state->out_work); break; default: mlx5_core_err(mdev, " Unhandled clock PPS event, func %d\n", @@ -1271,7 +1273,6 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) { u8 identity[MLX5_RT_CLOCK_IDENTITY_SIZE]; struct mlx5_clock_dev_state *clock_state; - struct mlx5_clock *clock; u64 key; int err; @@ -1284,6 +1285,7 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) clock_state = kzalloc(sizeof(*clock_state), GFP_KERNEL); if (!clock_state) return -ENOMEM; + clock_state->mdev = mdev; mdev->clock_state = clock_state; if (MLX5_CAP_MCAM_REG3(mdev, mrtcq) && mlx5_real_time_mode(mdev)) { @@ -1301,24 +1303,21 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) mdev->clock_state = NULL; return err; } - clock = mdev->clock; - INIT_WORK(&clock->pps_info.out_work, mlx5_pps_out); - MLX5_NB_INIT(&clock->pps_nb, mlx5_pps_event, PPS_EVENT); - mlx5_eq_notifier_register(mdev, &clock->pps_nb); + INIT_WORK(&mdev->clock_state->out_work, mlx5_pps_out); + MLX5_NB_INIT(&mdev->clock_state->pps_nb, mlx5_pps_event, PPS_EVENT); + mlx5_eq_notifier_register(mdev, &mdev->clock_state->pps_nb); return 0; } void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) { - struct mlx5_clock *clock = mdev->clock; - if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) return; - mlx5_eq_notifier_unregister(mdev, &clock->pps_nb); - cancel_work_sync(&clock->pps_info.out_work); + mlx5_eq_notifier_unregister(mdev, &mdev->clock_state->pps_nb); + cancel_work_sync(&mdev->clock_state->out_work); mlx5_clock_free(mdev); mlx5_shared_clock_unregister(mdev); diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h index eca1dd9039be6..3c5fee2465822 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h @@ -38,7 +38,6 @@ #define MAX_PIN_NUM 8 struct mlx5_pps { u8 pin_caps[MAX_PIN_NUM]; - struct work_struct out_work; u64 start[MAX_PIN_NUM]; u8 enabled; u64 min_npps_period; @@ -53,7 +52,6 @@ struct mlx5_timer { }; struct mlx5_clock { - struct mlx5_nb pps_nb; seqlock_t lock; struct hwtstamp_config hwtstamp_config; struct ptp_clock *ptp; From b1e0259ec2dc6b062d7146fc1941eb2e8b5169e1 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:20 -0400 Subject: [PATCH 15/21] net/mlx5: Support one PTP device per hardware clock jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit f538ffb7a22d092a8301440bc5d59488c311ea8b Currently, mlx5 driver exposes a PTP device for each network interface, resulting in multiple device nodes representing the same underlying PHC (PTP hardware clock). This causes problem if it is trying to synchronize to itself. For instance, when ptp4l operates on multiple interfaces following different masters, phc2sys attempts to synchronize them in automatic mode. PHC can be configured to work as free running mode or real time mode. All functions can access it directly. In this patch, we create one PTP device for each PHC when it's running in real time mode. All the functions share the same PTP device if the clock identifies they query are same, and they are already grouped by devcom in previous commit. The first mdev in the peer list is chosen when sending MTPPS/MTUTC/MTPPSE/MRTCQ to firmware. Since the function can be unloaded at any time, we need to use a mutex lock to protect the mdev pointer used in PTP and PPS callbacks. Besides, new one should be picked from the peer list when the current is not available. The clock info, which is used by IB, is shared by all the interfaces using the same hardware clock. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit f538ffb7a22d092a8301440bc5d59488c311ea8b) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 250 ++++++++++++++---- .../ethernet/mellanox/mlx5/core/lib/clock.h | 1 + 2 files changed, 203 insertions(+), 48 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 2586b0788b40f..42df3a6fda93e 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -89,6 +89,7 @@ struct mlx5_clock_dev_state { struct mlx5_clock_priv { struct mlx5_clock clock; struct mlx5_core_dev *mdev; + struct mutex lock; /* protect mdev and used in PTP callbacks */ }; static struct mlx5_clock_priv *clock_priv(struct mlx5_clock *clock) @@ -96,11 +97,37 @@ static struct mlx5_clock_priv *clock_priv(struct mlx5_clock *clock) return container_of(clock, struct mlx5_clock_priv, clock); } +static void mlx5_clock_lockdep_assert(struct mlx5_clock *clock) +{ + if (!clock->shared) + return; + + lockdep_assert(lockdep_is_held(&clock_priv(clock)->lock)); +} + static struct mlx5_core_dev *mlx5_clock_mdev_get(struct mlx5_clock *clock) { + mlx5_clock_lockdep_assert(clock); + return clock_priv(clock)->mdev; } +static void mlx5_clock_lock(struct mlx5_clock *clock) +{ + if (!clock->shared) + return; + + mutex_lock(&clock_priv(clock)->lock); +} + +static void mlx5_clock_unlock(struct mlx5_clock *clock) +{ + if (!clock->shared) + return; + + mutex_unlock(&clock_priv(clock)->lock); +} + static bool mlx5_real_time_mode(struct mlx5_core_dev *mdev) { return (mlx5_is_real_time_rq(mdev) || mlx5_is_real_time_sq(mdev)); @@ -170,10 +197,14 @@ static s32 mlx5_ptp_getmaxphase(struct ptp_clock_info *ptp) { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_core_dev *mdev; + s32 ret; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); + ret = mlx5_clock_getmaxphase(mdev); + mlx5_clock_unlock(clock); - return mlx5_clock_getmaxphase(mdev); + return ret; } static bool mlx5_is_mtutc_time_adj_cap(struct mlx5_core_dev *mdev, s64 delta) @@ -265,16 +296,23 @@ static int mlx5_ptp_getcrosststamp(struct ptp_clock_info *ptp, struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct system_time_snapshot history_begin = {0}; struct mlx5_core_dev *mdev; + int err; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); - if (!mlx5_is_ptm_source_time_available(mdev)) - return -EBUSY; + if (!mlx5_is_ptm_source_time_available(mdev)) { + err = -EBUSY; + goto unlock; + } ktime_get_snapshot(&history_begin); - return get_device_system_crosststamp(mlx5_mtctr_syncdevicetime, mdev, - &history_begin, cts); + err = get_device_system_crosststamp(mlx5_mtctr_syncdevicetime, mdev, + &history_begin, cts); +unlock: + mlx5_clock_unlock(clock); + return err; } #endif /* CONFIG_X86 */ @@ -372,6 +410,7 @@ static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) unsigned long flags; clock = container_of(ptp_info, struct mlx5_clock, ptp_info); + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); timer = &clock->timer; @@ -384,6 +423,7 @@ static long mlx5_timestamp_overflow(struct ptp_clock_info *ptp_info) write_sequnlock_irqrestore(&clock->lock, flags); out: + mlx5_clock_unlock(clock); return timer->overflow_period; } @@ -428,10 +468,14 @@ static int mlx5_ptp_settime(struct ptp_clock_info *ptp, const struct timespec64 { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_core_dev *mdev; + int err; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); + err = mlx5_clock_settime(mdev, clock, ts); + mlx5_clock_unlock(clock); - return mlx5_clock_settime(mdev, clock, ts); + return err; } static @@ -453,6 +497,7 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, struct mlx5_core_dev *mdev; u64 cycles, ns; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); if (mlx5_real_time_mode(mdev)) { *ts = mlx5_ptp_gettimex_real_time(mdev, sts); @@ -463,6 +508,7 @@ static int mlx5_ptp_gettimex(struct ptp_clock_info *ptp, struct timespec64 *ts, ns = mlx5_timecounter_cyc2time(clock, cycles); *ts = ns_to_timespec64(ns); out: + mlx5_clock_unlock(clock); return 0; } @@ -493,14 +539,16 @@ static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) struct mlx5_timer *timer = &clock->timer; struct mlx5_core_dev *mdev; unsigned long flags; + int err = 0; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); if (mlx5_modify_mtutc_allowed(mdev)) { - int err = mlx5_ptp_adjtime_real_time(mdev, delta); + err = mlx5_ptp_adjtime_real_time(mdev, delta); if (err) - return err; + goto unlock; } write_seqlock_irqsave(&clock->lock, flags); @@ -508,17 +556,23 @@ static int mlx5_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta) mlx5_update_clock_info_page(mdev); write_sequnlock_irqrestore(&clock->lock, flags); - return 0; +unlock: + mlx5_clock_unlock(clock); + return err; } static int mlx5_ptp_adjphase(struct ptp_clock_info *ptp, s32 delta) { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); struct mlx5_core_dev *mdev; + int err; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); + err = mlx5_ptp_adjtime_real_time(mdev, delta); + mlx5_clock_unlock(clock); - return mlx5_ptp_adjtime_real_time(mdev, delta); + return err; } static int mlx5_ptp_freq_adj_real_time(struct mlx5_core_dev *mdev, long scaled_ppm) @@ -547,15 +601,17 @@ static int mlx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) struct mlx5_timer *timer = &clock->timer; struct mlx5_core_dev *mdev; unsigned long flags; + int err = 0; u32 mult; + mlx5_clock_lock(clock); mdev = mlx5_clock_mdev_get(clock); if (mlx5_modify_mtutc_allowed(mdev)) { - int err = mlx5_ptp_freq_adj_real_time(mdev, scaled_ppm); + err = mlx5_ptp_freq_adj_real_time(mdev, scaled_ppm); if (err) - return err; + goto unlock; } mult = (u32)adjust_by_scaled_ppm(timer->nominal_c_mult, scaled_ppm); @@ -567,7 +623,9 @@ static int mlx5_ptp_adjfine(struct ptp_clock_info *ptp, long scaled_ppm) write_sequnlock_irqrestore(&clock->lock, flags); ptp_schedule_worker(clock->ptp, timer->overflow_period); - return 0; +unlock: + mlx5_clock_unlock(clock); + return err; } static int mlx5_extts_configure(struct ptp_clock_info *ptp, @@ -576,17 +634,14 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp, { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); - struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; + struct mlx5_core_dev *mdev; u32 field_select = 0; u8 pin_mode = 0; u8 pattern = 0; int pin = -1; int err = 0; - if (!MLX5_PPS_CAP(mdev)) - return -EOPNOTSUPP; - /* Reject requests with unsupported flags */ if (rq->extts.flags & ~(PTP_ENABLE_FEATURE | PTP_RISING_EDGE | @@ -617,6 +672,14 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp, field_select = MLX5_MTPPS_FS_ENABLE; } + mlx5_clock_lock(clock); + mdev = mlx5_clock_mdev_get(clock); + + if (!MLX5_PPS_CAP(mdev)) { + err = -EOPNOTSUPP; + goto unlock; + } + MLX5_SET(mtpps_reg, in, pin, pin); MLX5_SET(mtpps_reg, in, pin_mode, pin_mode); MLX5_SET(mtpps_reg, in, pattern, pattern); @@ -625,10 +688,13 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp, err = mlx5_set_mtpps(mdev, in, sizeof(in)); if (err) - return err; + goto unlock; + + err = mlx5_set_mtppse(mdev, pin, 0, MLX5_EVENT_MODE_REPETETIVE & on); - return mlx5_set_mtppse(mdev, pin, 0, - MLX5_EVENT_MODE_REPETETIVE & on); +unlock: + mlx5_clock_unlock(clock); + return err; } static u64 find_target_cycles(struct mlx5_core_dev *mdev, s64 target_ns) @@ -760,25 +826,18 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, { struct mlx5_clock *clock = container_of(ptp, struct mlx5_clock, ptp_info); - struct mlx5_core_dev *mdev = mlx5_clock_mdev_get(clock); - bool rt_mode = mlx5_real_time_mode(mdev); u32 in[MLX5_ST_SZ_DW(mtpps_reg)] = {0}; u32 out_pulse_duration_ns = 0; + struct mlx5_core_dev *mdev; u32 field_select = 0; u64 npps_period = 0; u64 time_stamp = 0; u8 pin_mode = 0; u8 pattern = 0; + bool rt_mode; int pin = -1; int err = 0; - if (!MLX5_PPS_CAP(mdev)) - return -EOPNOTSUPP; - - /* Reject requests with unsupported flags */ - if (mlx5_perout_verify_flags(mdev, rq->perout.flags)) - return -EOPNOTSUPP; - if (rq->perout.index >= clock->ptp_info.n_pins) return -EINVAL; @@ -787,14 +846,29 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, if (pin < 0) return -EBUSY; - if (on) { - bool rt_mode = mlx5_real_time_mode(mdev); + mlx5_clock_lock(clock); + mdev = mlx5_clock_mdev_get(clock); + rt_mode = mlx5_real_time_mode(mdev); + + if (!MLX5_PPS_CAP(mdev)) { + err = -EOPNOTSUPP; + goto unlock; + } + + /* Reject requests with unsupported flags */ + if (mlx5_perout_verify_flags(mdev, rq->perout.flags)) { + err = -EOPNOTSUPP; + goto unlock; + } + if (on) { pin_mode = MLX5_PIN_MODE_OUT; pattern = MLX5_OUT_PATTERN_PERIODIC; - if (rt_mode && rq->perout.start.sec > U32_MAX) - return -EINVAL; + if (rt_mode && rq->perout.start.sec > U32_MAX) { + err = -EINVAL; + goto unlock; + } field_select |= MLX5_MTPPS_FS_PIN_MODE | MLX5_MTPPS_FS_PATTERN | @@ -807,7 +881,7 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, else err = perout_conf_1pps(mdev, rq, &time_stamp, rt_mode); if (err) - return err; + goto unlock; } MLX5_SET(mtpps_reg, in, pin, pin); @@ -820,13 +894,16 @@ static int mlx5_perout_configure(struct ptp_clock_info *ptp, MLX5_SET(mtpps_reg, in, out_pulse_duration_ns, out_pulse_duration_ns); err = mlx5_set_mtpps(mdev, in, sizeof(in)); if (err) - return err; + goto unlock; if (rt_mode) - return 0; + goto unlock; - return mlx5_set_mtppse(mdev, pin, 0, - MLX5_EVENT_MODE_REPETETIVE & on); + err = mlx5_set_mtppse(mdev, pin, 0, MLX5_EVENT_MODE_REPETETIVE & on); + +unlock: + mlx5_clock_unlock(clock); + return err; } static int mlx5_pps_configure(struct ptp_clock_info *ptp, @@ -1043,6 +1120,10 @@ static int mlx5_pps_event(struct notifier_block *nb, ptp_clock_event(clock->ptp, &ptp_event); break; case PTP_PF_PEROUT: + if (clock->shared) { + mlx5_core_warn(mdev, " Received unexpected PPS out event\n"); + break; + } ns = perout_conf_next_event_timer(mdev, clock); write_seqlock_irqsave(&clock->lock, flags); clock->pps_info.start[pin] = ns; @@ -1201,9 +1282,10 @@ static void mlx5_init_clock_dev(struct mlx5_core_dev *mdev) mlx5_init_pps(mdev); clock->ptp = ptp_clock_register(&clock->ptp_info, - &mdev->pdev->dev); + clock->shared ? NULL : &mdev->pdev->dev); if (IS_ERR(clock->ptp)) { - mlx5_core_warn(mdev, "ptp_clock_register failed %ld\n", + mlx5_core_warn(mdev, "%sptp_clock_register failed %ld\n", + clock->shared ? "shared clock " : "", PTR_ERR(clock->ptp)); clock->ptp = NULL; } @@ -1234,11 +1316,12 @@ static void mlx5_clock_free(struct mlx5_core_dev *mdev) struct mlx5_clock_priv *cpriv = clock_priv(mdev->clock); mlx5_destroy_clock_dev(mdev); + mutex_destroy(&cpriv->lock); kfree(cpriv); mdev->clock = NULL; } -static int mlx5_clock_alloc(struct mlx5_core_dev *mdev) +static int mlx5_clock_alloc(struct mlx5_core_dev *mdev, bool shared) { struct mlx5_clock_priv *cpriv; struct mlx5_clock *clock; @@ -1247,23 +1330,90 @@ static int mlx5_clock_alloc(struct mlx5_core_dev *mdev) if (!cpriv) return -ENOMEM; + mutex_init(&cpriv->lock); cpriv->mdev = mdev; clock = &cpriv->clock; + clock->shared = shared; mdev->clock = clock; + mlx5_clock_lock(clock); mlx5_init_clock_dev(mdev); + mlx5_clock_unlock(clock); + + if (!clock->shared) + return 0; + + if (!clock->ptp) { + mlx5_core_warn(mdev, "failed to create ptp dev shared by multiple functions"); + mlx5_clock_free(mdev); + return -EINVAL; + } return 0; } static void mlx5_shared_clock_register(struct mlx5_core_dev *mdev, u64 key) { + struct mlx5_core_dev *peer_dev, *next = NULL; + struct mlx5_devcom_comp_dev *pos; + mdev->clock_state->compdev = mlx5_devcom_register_component(mdev->priv.devc, MLX5_DEVCOM_SHARED_CLOCK, key, NULL, mdev); + if (IS_ERR(mdev->clock_state->compdev)) + return; + + mlx5_devcom_comp_lock(mdev->clock_state->compdev); + mlx5_devcom_for_each_peer_entry(mdev->clock_state->compdev, peer_dev, pos) { + if (peer_dev->clock) { + next = peer_dev; + break; + } + } + + if (next) { + mdev->clock = next->clock; + /* clock info is shared among all the functions using the same clock */ + mdev->clock_info = next->clock_info; + } else { + mlx5_clock_alloc(mdev, true); + } + mlx5_devcom_comp_unlock(mdev->clock_state->compdev); + + if (!mdev->clock) { + mlx5_devcom_unregister_component(mdev->clock_state->compdev); + mdev->clock_state->compdev = NULL; + } } static void mlx5_shared_clock_unregister(struct mlx5_core_dev *mdev) { + struct mlx5_core_dev *peer_dev, *next = NULL; + struct mlx5_clock *clock = mdev->clock; + struct mlx5_devcom_comp_dev *pos; + + mlx5_devcom_comp_lock(mdev->clock_state->compdev); + mlx5_devcom_for_each_peer_entry(mdev->clock_state->compdev, peer_dev, pos) { + if (peer_dev->clock && peer_dev != mdev) { + next = peer_dev; + break; + } + } + + if (next) { + struct mlx5_clock_priv *cpriv = clock_priv(clock); + + mlx5_clock_lock(clock); + if (mdev == cpriv->mdev) + cpriv->mdev = next; + mlx5_clock_unlock(clock); + } else { + mlx5_clock_free(mdev); + } + + mdev->clock = NULL; + mdev->clock_info = NULL; + mlx5_devcom_comp_unlock(mdev->clock_state->compdev); + mlx5_devcom_unregister_component(mdev->clock_state->compdev); } @@ -1297,11 +1447,13 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) } } - err = mlx5_clock_alloc(mdev); - if (err) { - kfree(clock_state); - mdev->clock_state = NULL; - return err; + if (!mdev->clock) { + err = mlx5_clock_alloc(mdev, false); + if (err) { + kfree(clock_state); + mdev->clock_state = NULL; + return err; + } } INIT_WORK(&mdev->clock_state->out_work, mlx5_pps_out); @@ -1319,8 +1471,10 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) mlx5_eq_notifier_unregister(mdev, &mdev->clock_state->pps_nb); cancel_work_sync(&mdev->clock_state->out_work); - mlx5_clock_free(mdev); - mlx5_shared_clock_unregister(mdev); + if (mdev->clock->shared) + mlx5_shared_clock_unregister(mdev); + else + mlx5_clock_free(mdev); kfree(mdev->clock_state); mdev->clock_state = NULL; } diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h index 3c5fee2465822..093fa131014a4 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h @@ -58,6 +58,7 @@ struct mlx5_clock { struct ptp_clock_info ptp_info; struct mlx5_pps pps_info; struct mlx5_timer timer; + bool shared; }; static inline bool mlx5_is_real_time_rq(struct mlx5_core_dev *mdev) From 3c9b109240dcb6c3c5ded1db488dbf242a50c107 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:20 -0400 Subject: [PATCH 16/21] net/mlx5: Generate PPS IN event on new function for shared clock jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Jianbo Liu commit 39c1202fa9428bcb8d1242ee12f81cbcb298c020 As a specific function (mdev) is chosen to send MTPPSE command to firmware, the event is generated only on that function. When that function is unloaded, the PPS event can't be forward to PTP device, even when there are other functions in the group, and PTP device is not destroyed. To resolve this problem, need to send MTPPSE again from new function, and dis-arm the event on old function after that. PPS events are handled by EQ notifier. The async EQs and notifiers are destroyed in mlx5_eq_table_destroy() which is called before mlx5_cleanup_clock(). During the period between mlx5_eq_table_destroy() and mlx5_cleanup_clock(), the events can't be handled. To avoid event loss, add mlx5_clock_unload() in mlx5_unload() to arm the event on other available function, and mlx5_clock_load in mlx5_load() for symmetry. Signed-off-by: Jianbo Liu Reviewed-by: Carolina Jubran Reviewed-by: Dragos Tatulea Signed-off-by: Tariq Toukan Signed-off-by: Paolo Abeni (cherry picked from commit 39c1202fa9428bcb8d1242ee12f81cbcb298c020) Signed-off-by: Jonathan Maple --- .../ethernet/mellanox/mlx5/core/lib/clock.c | 97 +++++++++++++++++-- .../ethernet/mellanox/mlx5/core/lib/clock.h | 5 + .../net/ethernet/mellanox/mlx5/core/main.c | 4 + 3 files changed, 99 insertions(+), 7 deletions(-) diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c index 42df3a6fda93e..65a94e46edcf1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.c @@ -90,6 +90,7 @@ struct mlx5_clock_priv { struct mlx5_clock clock; struct mlx5_core_dev *mdev; struct mutex lock; /* protect mdev and used in PTP callbacks */ + struct mlx5_core_dev *event_mdev; }; static struct mlx5_clock_priv *clock_priv(struct mlx5_clock *clock) @@ -691,6 +692,11 @@ static int mlx5_extts_configure(struct ptp_clock_info *ptp, goto unlock; err = mlx5_set_mtppse(mdev, pin, 0, MLX5_EVENT_MODE_REPETETIVE & on); + if (err) + goto unlock; + + clock->pps_info.pin_armed[pin] = on; + clock_priv(clock)->event_mdev = mdev; unlock: mlx5_clock_unlock(clock); @@ -1417,6 +1423,90 @@ static void mlx5_shared_clock_unregister(struct mlx5_core_dev *mdev) mlx5_devcom_unregister_component(mdev->clock_state->compdev); } +static void mlx5_clock_arm_pps_in_event(struct mlx5_clock *clock, + struct mlx5_core_dev *new_mdev, + struct mlx5_core_dev *old_mdev) +{ + struct ptp_clock_info *ptp_info = &clock->ptp_info; + struct mlx5_clock_priv *cpriv = clock_priv(clock); + int i; + + for (i = 0; i < ptp_info->n_pins; i++) { + if (ptp_info->pin_config[i].func != PTP_PF_EXTTS || + !clock->pps_info.pin_armed[i]) + continue; + + if (new_mdev) { + mlx5_set_mtppse(new_mdev, i, 0, MLX5_EVENT_MODE_REPETETIVE); + cpriv->event_mdev = new_mdev; + } else { + cpriv->event_mdev = NULL; + } + + if (old_mdev) + mlx5_set_mtppse(old_mdev, i, 0, MLX5_EVENT_MODE_DISABLE); + } +} + +void mlx5_clock_load(struct mlx5_core_dev *mdev) +{ + struct mlx5_clock *clock = mdev->clock; + struct mlx5_clock_priv *cpriv; + + if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) + return; + + INIT_WORK(&mdev->clock_state->out_work, mlx5_pps_out); + MLX5_NB_INIT(&mdev->clock_state->pps_nb, mlx5_pps_event, PPS_EVENT); + mlx5_eq_notifier_register(mdev, &mdev->clock_state->pps_nb); + + if (!clock->shared) { + mlx5_clock_arm_pps_in_event(clock, mdev, NULL); + return; + } + + cpriv = clock_priv(clock); + mlx5_devcom_comp_lock(mdev->clock_state->compdev); + mlx5_clock_lock(clock); + if (mdev == cpriv->mdev && mdev != cpriv->event_mdev) + mlx5_clock_arm_pps_in_event(clock, mdev, cpriv->event_mdev); + mlx5_clock_unlock(clock); + mlx5_devcom_comp_unlock(mdev->clock_state->compdev); +} + +void mlx5_clock_unload(struct mlx5_core_dev *mdev) +{ + struct mlx5_core_dev *peer_dev, *next = NULL; + struct mlx5_clock *clock = mdev->clock; + struct mlx5_devcom_comp_dev *pos; + + if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) + return; + + if (!clock->shared) { + mlx5_clock_arm_pps_in_event(clock, NULL, mdev); + goto out; + } + + mlx5_devcom_comp_lock(mdev->clock_state->compdev); + mlx5_devcom_for_each_peer_entry(mdev->clock_state->compdev, peer_dev, pos) { + if (peer_dev->clock && peer_dev != mdev) { + next = peer_dev; + break; + } + } + + mlx5_clock_lock(clock); + if (mdev == clock_priv(clock)->event_mdev) + mlx5_clock_arm_pps_in_event(clock, next, mdev); + mlx5_clock_unlock(clock); + mlx5_devcom_comp_unlock(mdev->clock_state->compdev); + +out: + mlx5_eq_notifier_unregister(mdev, &mdev->clock_state->pps_nb); + cancel_work_sync(&mdev->clock_state->out_work); +} + static struct mlx5_clock null_clock; int mlx5_init_clock(struct mlx5_core_dev *mdev) @@ -1456,10 +1546,6 @@ int mlx5_init_clock(struct mlx5_core_dev *mdev) } } - INIT_WORK(&mdev->clock_state->out_work, mlx5_pps_out); - MLX5_NB_INIT(&mdev->clock_state->pps_nb, mlx5_pps_event, PPS_EVENT); - mlx5_eq_notifier_register(mdev, &mdev->clock_state->pps_nb); - return 0; } @@ -1468,9 +1554,6 @@ void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) if (!MLX5_CAP_GEN(mdev, device_frequency_khz)) return; - mlx5_eq_notifier_unregister(mdev, &mdev->clock_state->pps_nb); - cancel_work_sync(&mdev->clock_state->out_work); - if (mdev->clock->shared) mlx5_shared_clock_unregister(mdev); else diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h index 093fa131014a4..c18a652c0faa1 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h @@ -42,6 +42,7 @@ struct mlx5_pps { u8 enabled; u64 min_npps_period; u64 min_out_pulse_duration_ns; + bool pin_armed[MAX_PIN_NUM]; }; struct mlx5_timer { @@ -84,6 +85,8 @@ typedef ktime_t (*cqe_ts_to_ns)(struct mlx5_clock *, u64); #if IS_ENABLED(CONFIG_PTP_1588_CLOCK) int mlx5_init_clock(struct mlx5_core_dev *mdev); void mlx5_cleanup_clock(struct mlx5_core_dev *mdev); +void mlx5_clock_load(struct mlx5_core_dev *mdev); +void mlx5_clock_unload(struct mlx5_core_dev *mdev); static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev) { @@ -117,6 +120,8 @@ static inline ktime_t mlx5_real_time_cyc2time(struct mlx5_clock *clock, #else static inline int mlx5_init_clock(struct mlx5_core_dev *mdev) { return 0; } static inline void mlx5_cleanup_clock(struct mlx5_core_dev *mdev) {} +static inline void mlx5_clock_load(struct mlx5_core_dev *mdev) {} +static inline void mlx5_clock_unload(struct mlx5_core_dev *mdev) {} static inline int mlx5_clock_get_ptp_index(struct mlx5_core_dev *mdev) { return -1; diff --git a/drivers/net/ethernet/mellanox/mlx5/core/main.c b/drivers/net/ethernet/mellanox/mlx5/core/main.c index 37b67ba01e17f..636cd780d8e4b 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/main.c +++ b/drivers/net/ethernet/mellanox/mlx5/core/main.c @@ -1358,6 +1358,8 @@ static int mlx5_load(struct mlx5_core_dev *dev) goto err_eq_table; } + mlx5_clock_load(dev); + err = mlx5_fw_tracer_init(dev->tracer); if (err) { mlx5_core_err(dev, "Failed to init FW tracer %d\n", err); @@ -1441,6 +1443,7 @@ static int mlx5_load(struct mlx5_core_dev *dev) mlx5_hv_vhca_cleanup(dev->hv_vhca); mlx5_fw_reset_events_stop(dev); mlx5_fw_tracer_cleanup(dev->tracer); + mlx5_clock_unload(dev); mlx5_eq_table_destroy(dev); err_eq_table: mlx5_irq_table_destroy(dev); @@ -1467,6 +1470,7 @@ static void mlx5_unload(struct mlx5_core_dev *dev) mlx5_hv_vhca_cleanup(dev->hv_vhca); mlx5_fw_reset_events_stop(dev); mlx5_fw_tracer_cleanup(dev->tracer); + mlx5_clock_unload(dev); mlx5_eq_table_destroy(dev); mlx5_irq_table_destroy(dev); mlx5_pagealloc_stop(dev); From 17251fc08c37525004e2f4b2c5e501af6d97e8cc Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:21 -0400 Subject: [PATCH 17/21] NFS: Fix filehandle bounds checking in nfs_fh_to_dentry() jira LE-4613 cve CVE-2025-39730 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Trond Myklebust commit ef93a685e01a281b5e2a25ce4e3428cf9371a205 The function needs to check the minimal filehandle length before it can access the embedded filehandle. Reported-by: zhangjian Fixes: 20fa19027286 ("nfs: add export operations") Signed-off-by: Trond Myklebust (cherry picked from commit ef93a685e01a281b5e2a25ce4e3428cf9371a205) Signed-off-by: Jonathan Maple --- fs/nfs/export.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/fs/nfs/export.c b/fs/nfs/export.c index be686b8e0c546..aeb17adcb2b64 100644 --- a/fs/nfs/export.c +++ b/fs/nfs/export.c @@ -66,14 +66,21 @@ nfs_fh_to_dentry(struct super_block *sb, struct fid *fid, { struct nfs_fattr *fattr = NULL; struct nfs_fh *server_fh = nfs_exp_embedfh(fid->raw); - size_t fh_size = offsetof(struct nfs_fh, data) + server_fh->size; + size_t fh_size = offsetof(struct nfs_fh, data); const struct nfs_rpc_ops *rpc_ops; struct dentry *dentry; struct inode *inode; - int len = EMBED_FH_OFF + XDR_QUADLEN(fh_size); + int len = EMBED_FH_OFF; u32 *p = fid->raw; int ret; + /* Initial check of bounds */ + if (fh_len < len + XDR_QUADLEN(fh_size) || + fh_len > XDR_QUADLEN(NFS_MAXFHSIZE)) + return NULL; + /* Calculate embedded filehandle size */ + fh_size += server_fh->size; + len += XDR_QUADLEN(fh_size); /* NULL translates to ESTALE */ if (fh_len < len || fh_type != len) return NULL; From 1692af94275dfe6743add6d31db563564029323f Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:21 -0400 Subject: [PATCH 18/21] s390/ism: fix concurrency management in ism_cmd() jira LE-4613 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Halil Pasic commit 897e8601b9cff1d054cdd53047f568b0e1995726 The s390x ISM device data sheet clearly states that only one request-response sequence is allowable per ISM function at any point in time. Unfortunately as of today the s390/ism driver in Linux does not honor that requirement. This patch aims to rectify that. This problem was discovered based on Aliaksei's bug report which states that for certain workloads the ISM functions end up entering error state (with PEC 2 as seen from the logs) after a while and as a consequence connections handled by the respective function break, and for future connection requests the ISM device is not considered -- given it is in a dysfunctional state. During further debugging PEC 3A was observed as well. A kernel message like [ 1211.244319] zpci: 061a:00:00.0: Event 0x2 reports an error for PCI function 0x61a is a reliable indicator of the stated function entering error state with PEC 2. Let me also point out that a kernel message like [ 1211.244325] zpci: 061a:00:00.0: The ism driver bound to the device does not support error recovery is a reliable indicator that the ISM function won't be auto-recovered because the ISM driver currently lacks support for it. On a technical level, without this synchronization, commands (inputs to the FW) may be partially or fully overwritten (corrupted) by another CPU trying to issue commands on the same function. There is hard evidence that this can lead to DMB token values being used as DMB IOVAs, leading to PEC 2 PCI events indicating invalid DMA. But this is only one of the failure modes imaginable. In theory even completely losing one command and executing another one twice and then trying to interpret the outputs as if the command we intended to execute was actually executed and not the other one is also possible. Frankly, I don't feel confident about providing an exhaustive list of possible consequences. Fixes: 684b89bc39ce ("s390/ism: add device driver for internal shared memory") Reported-by: Aliaksei Makarau Tested-by: Mahanta Jambigi Tested-by: Aliaksei Makarau Signed-off-by: Halil Pasic Reviewed-by: Alexandra Winter Signed-off-by: Alexandra Winter Reviewed-by: Simon Horman Link: https://patch.msgid.link/20250722161817.1298473-1-wintera@linux.ibm.com Signed-off-by: Paolo Abeni (cherry picked from commit 897e8601b9cff1d054cdd53047f568b0e1995726) Signed-off-by: Jonathan Maple --- drivers/s390/net/ism_drv.c | 3 +++ include/linux/ism.h | 1 + 2 files changed, 4 insertions(+) diff --git a/drivers/s390/net/ism_drv.c b/drivers/s390/net/ism_drv.c index e36e3ea165d3b..426a764cd7de8 100644 --- a/drivers/s390/net/ism_drv.c +++ b/drivers/s390/net/ism_drv.c @@ -131,6 +131,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd) struct ism_req_hdr *req = cmd; struct ism_resp_hdr *resp = cmd; + spin_lock(&ism->cmd_lock); __ism_write_cmd(ism, req + 1, sizeof(*req), req->len - sizeof(*req)); __ism_write_cmd(ism, req, 0, sizeof(*req)); @@ -144,6 +145,7 @@ static int ism_cmd(struct ism_dev *ism, void *cmd) } __ism_read_cmd(ism, resp + 1, sizeof(*resp), resp->len - sizeof(*resp)); out: + spin_unlock(&ism->cmd_lock); return resp->ret; } @@ -598,6 +600,7 @@ static int ism_probe(struct pci_dev *pdev, const struct pci_device_id *id) return -ENOMEM; spin_lock_init(&ism->lock); + spin_lock_init(&ism->cmd_lock); dev_set_drvdata(&pdev->dev, ism); ism->pdev = pdev; ism->dev.parent = &pdev->dev; diff --git a/include/linux/ism.h b/include/linux/ism.h index 5428edd909823..8358b4cd7ba6a 100644 --- a/include/linux/ism.h +++ b/include/linux/ism.h @@ -28,6 +28,7 @@ struct ism_dmb { struct ism_dev { spinlock_t lock; /* protects the ism device */ + spinlock_t cmd_lock; /* serializes cmds */ struct list_head list; struct pci_dev *pdev; From 01d05fd0d90212d70403f9f39af00a5a72fbb90b Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:21 -0400 Subject: [PATCH 19/21] erofs: fix blksize < PAGE_SIZE for file-backed mounts jira LE-4613 cve CVE-2024-56750 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Hongzhen Luo commit bae0854160939a64a092516ff1b2f221402b843b Adjust sb->s_blocksize{,_bits} directly for file-backed mounts when the fs block size is smaller than PAGE_SIZE. Previously, EROFS used sb_set_blocksize(), which caused a panic if bdev-backed mounts is not used. Fixes: fb176750266a ("erofs: add file-backed mount support") Signed-off-by: Hongzhen Luo Link: https://lore.kernel.org/r/20241015103836.3757438-1-hongzhen@linux.alibaba.com Signed-off-by: Gao Xiang (cherry picked from commit bae0854160939a64a092516ff1b2f221402b843b) Signed-off-by: Jonathan Maple --- fs/erofs/super.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/fs/erofs/super.c b/fs/erofs/super.c index bed3dbe5b7cb8..2dd7d819572f4 100644 --- a/fs/erofs/super.c +++ b/fs/erofs/super.c @@ -631,7 +631,11 @@ static int erofs_fc_fill_super(struct super_block *sb, struct fs_context *fc) errorfc(fc, "unsupported blksize for fscache mode"); return -EINVAL; } - if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) { + + if (erofs_is_fileio_mode(sbi)) { + sb->s_blocksize = 1 << sbi->blkszbits; + sb->s_blocksize_bits = sbi->blkszbits; + } else if (!sb_set_blocksize(sb, 1 << sbi->blkszbits)) { errorfc(fc, "failed to set erofs blksize"); return -EINVAL; } From 89e3c423ef8cba8b58b7cb9fcabceed98b4e0df7 Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:22 -0400 Subject: [PATCH 20/21] ALSA: hda/ca0132: Fix buffer overflow in add_tuning_control jira LE-4613 cve CVE-2025-39751 Rebuild_History Non-Buildable kernel-6.12.0-55.41.1.el10_0 commit-author Lucy Thrun commit a409c60111e6bb98fcabab2aeaa069daa9434ca0 The 'sprintf' call in 'add_tuning_control' may exceed the 44-byte buffer if either string argument is too long. This triggers a compiler warning. Replaced 'sprintf' with 'snprintf' to limit string lengths to prevent overflow. Reported-by: kernel test robot Closes: https://lore.kernel.org/oe-kbuild-all/202506100642.95jpuMY1-lkp@intel.com/ Signed-off-by: Lucy Thrun Link: https://patch.msgid.link/20250610175012.918-3-lucy.thrun@digital-rabbithole.de Signed-off-by: Takashi Iwai (cherry picked from commit a409c60111e6bb98fcabab2aeaa069daa9434ca0) Signed-off-by: Jonathan Maple --- sound/pci/hda/patch_ca0132.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sound/pci/hda/patch_ca0132.c b/sound/pci/hda/patch_ca0132.c index d40197fb5fbd5..f0b612b61ced8 100644 --- a/sound/pci/hda/patch_ca0132.c +++ b/sound/pci/hda/patch_ca0132.c @@ -4410,7 +4410,7 @@ static int add_tuning_control(struct hda_codec *codec, } knew.private_value = HDA_COMPOSE_AMP_VAL(nid, 1, 0, type); - sprintf(namestr, "%s %s Volume", name, dirstr[dir]); + snprintf(namestr, sizeof(namestr), "%s %s Volume", name, dirstr[dir]); return snd_hda_ctl_add(codec, nid, snd_ctl_new1(&knew, codec)); } From 331a7b22d7024258c760d42fc4cc2bc2a7cc772d Mon Sep 17 00:00:00 2001 From: Jonathan Maple Date: Thu, 30 Oct 2025 03:01:39 -0400 Subject: [PATCH 21/21] Rebuild rocky10_0 with kernel-6.12.0-55.41.1.el10_0 Rebuild_History BUILDABLE Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% Number of commits in upstream range v6.12~1..kernel-mainline: 66177 Number of commits in rpm: 23 Number of commits matched with upstream: 20 (86.96%) Number of commits in upstream but not in rpm: 66157 Number of commits NOT found in upstream: 3 (13.04%) Rebuilding Kernel on Branch rocky10_0_rebuild_kernel-6.12.0-55.41.1.el10_0 for kernel-6.12.0-55.41.1.el10_0 Clean Cherry Picks: 20 (100.00%) Empty Cherry Picks: 0 (0.00%) _______________________________ Full Details Located here: ciq/ciq_backports/kernel-6.12.0-55.41.1.el10_0/rebuild.details.txt Includes: * git commit header above * Empty Commits with upstream SHA * RPM ChangeLog Entries that could not be matched Individual Empty Commit failures contained in the same containing directory. The git message for empty commits will have the path for the failed commit. File names are the first 8 characters of the upstream SHA --- ....1.el10_0 => COPYING-6.12.0-55.41.1.el10_0 | 0 Makefile.rhelver | 2 +- .../rebuild.details.txt | 19 +++++++ .../kernel-6.12.0-aarch64-64k-debug.config | 4 +- configs/kernel-6.12.0-aarch64-64k.config | 4 +- ...nel-6.12.0-aarch64-automotive-debug.config | 4 +- .../kernel-6.12.0-aarch64-automotive.config | 4 +- configs/kernel-6.12.0-aarch64-debug.config | 4 +- .../kernel-6.12.0-aarch64-rt-64k-debug.config | 4 +- configs/kernel-6.12.0-aarch64-rt-64k.config | 4 +- configs/kernel-6.12.0-aarch64-rt-debug.config | 4 +- configs/kernel-6.12.0-aarch64-rt.config | 4 +- configs/kernel-6.12.0-aarch64.config | 4 +- configs/kernel-6.12.0-ppc64le-debug.config | 4 +- configs/kernel-6.12.0-ppc64le.config | 4 +- configs/kernel-6.12.0-riscv64-debug.config | 4 +- configs/kernel-6.12.0-riscv64.config | 4 +- configs/kernel-6.12.0-s390x-debug.config | 4 +- configs/kernel-6.12.0-s390x-zfcpdump.config | 4 +- configs/kernel-6.12.0-s390x.config | 4 +- ...rnel-6.12.0-x86_64-automotive-debug.config | 4 +- .../kernel-6.12.0-x86_64-automotive.config | 4 +- configs/kernel-6.12.0-x86_64-debug.config | 4 +- configs/kernel-6.12.0-x86_64-rt-debug.config | 4 +- configs/kernel-6.12.0-x86_64-rt.config | 4 +- configs/kernel-6.12.0-x86_64.config | 4 +- .../ethernet/mellanox/mlx5/core/lib/clock.h | 3 + include/linux/mlx5/driver.h | 56 ++++++++++++++++++- redhat/kernel.changelog-10.0 | 23 ++++++++ 29 files changed, 146 insertions(+), 49 deletions(-) rename COPYING-6.12.0-55.40.1.el10_0 => COPYING-6.12.0-55.41.1.el10_0 (100%) create mode 100644 ciq/ciq_backports/kernel-6.12.0-55.41.1.el10_0/rebuild.details.txt diff --git a/COPYING-6.12.0-55.40.1.el10_0 b/COPYING-6.12.0-55.41.1.el10_0 similarity index 100% rename from COPYING-6.12.0-55.40.1.el10_0 rename to COPYING-6.12.0-55.41.1.el10_0 diff --git a/Makefile.rhelver b/Makefile.rhelver index b4d7dcd4a2df2..c7e4d94479ee6 100644 --- a/Makefile.rhelver +++ b/Makefile.rhelver @@ -12,7 +12,7 @@ RHEL_MINOR = 0 # # Use this spot to avoid future merge conflicts. # Do not trim this comment. -RHEL_RELEASE = 55.40.1 +RHEL_RELEASE = 55.41.1 # # RHEL_REBASE_NUM diff --git a/ciq/ciq_backports/kernel-6.12.0-55.41.1.el10_0/rebuild.details.txt b/ciq/ciq_backports/kernel-6.12.0-55.41.1.el10_0/rebuild.details.txt new file mode 100644 index 0000000000000..4a6c45ca973d8 --- /dev/null +++ b/ciq/ciq_backports/kernel-6.12.0-55.41.1.el10_0/rebuild.details.txt @@ -0,0 +1,19 @@ +Rebuild_History BUILDABLE +Rebuilding Kernel from rpm changelog with Fuzz Limit: 87.50% +Number of commits in upstream range v6.12~1..kernel-mainline: 66177 +Number of commits in rpm: 23 +Number of commits matched with upstream: 20 (86.96%) +Number of commits in upstream but not in rpm: 66157 +Number of commits NOT found in upstream: 3 (13.04%) + +Rebuilding Kernel on Branch rocky10_0_rebuild_kernel-6.12.0-55.41.1.el10_0 for kernel-6.12.0-55.41.1.el10_0 +Clean Cherry Picks: 20 (100.00%) +Empty Cherry Picks: 0 (0.00%) +_______________________________ + +__EMPTY COMMITS__________________________ + +__CHANGES NOT IN UPSTREAM________________ +Porting to Rocky Linux 10, debranding and Rocky Linux branding' +Add partial riscv64 support for build root' +Provide basic VisionFive 2 support' diff --git a/configs/kernel-6.12.0-aarch64-64k-debug.config b/configs/kernel-6.12.0-aarch64-64k-debug.config index a39468e4904fd..67d28f4ed4c82 100644 --- a/configs/kernel-6.12.0-aarch64-64k-debug.config +++ b/configs/kernel-6.12.0-aarch64-64k-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-64k.config b/configs/kernel-6.12.0-aarch64-64k.config index 93289fc20f37d..cb7f1eaf2afd8 100644 --- a/configs/kernel-6.12.0-aarch64-64k.config +++ b/configs/kernel-6.12.0-aarch64-64k.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-automotive-debug.config b/configs/kernel-6.12.0-aarch64-automotive-debug.config index 75ef55c07e811..f2a4b38de9347 100644 --- a/configs/kernel-6.12.0-aarch64-automotive-debug.config +++ b/configs/kernel-6.12.0-aarch64-automotive-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-automotive.config b/configs/kernel-6.12.0-aarch64-automotive.config index 38b1136c11672..ac69e51588dfa 100644 --- a/configs/kernel-6.12.0-aarch64-automotive.config +++ b/configs/kernel-6.12.0-aarch64-automotive.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-debug.config b/configs/kernel-6.12.0-aarch64-debug.config index fbdfd945bf4d6..2feabadbc4576 100644 --- a/configs/kernel-6.12.0-aarch64-debug.config +++ b/configs/kernel-6.12.0-aarch64-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt-64k-debug.config b/configs/kernel-6.12.0-aarch64-rt-64k-debug.config index e7301df51f965..96dc55cd746c8 100644 --- a/configs/kernel-6.12.0-aarch64-rt-64k-debug.config +++ b/configs/kernel-6.12.0-aarch64-rt-64k-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt-64k.config b/configs/kernel-6.12.0-aarch64-rt-64k.config index 68e86211d09ce..0990e023fe90e 100644 --- a/configs/kernel-6.12.0-aarch64-rt-64k.config +++ b/configs/kernel-6.12.0-aarch64-rt-64k.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt-debug.config b/configs/kernel-6.12.0-aarch64-rt-debug.config index ed28883b98d5e..57a9e4a8502b1 100644 --- a/configs/kernel-6.12.0-aarch64-rt-debug.config +++ b/configs/kernel-6.12.0-aarch64-rt-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64-rt.config b/configs/kernel-6.12.0-aarch64-rt.config index 41c58e5e56697..2524f08ee0cdd 100644 --- a/configs/kernel-6.12.0-aarch64-rt.config +++ b/configs/kernel-6.12.0-aarch64-rt.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-aarch64.config b/configs/kernel-6.12.0-aarch64.config index f29cb94f0bfcb..f7626dcc7cd16 100644 --- a/configs/kernel-6.12.0-aarch64.config +++ b/configs/kernel-6.12.0-aarch64.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-ppc64le-debug.config b/configs/kernel-6.12.0-ppc64le-debug.config index 54772c9dbafc0..9de0e98ea64bc 100644 --- a/configs/kernel-6.12.0-ppc64le-debug.config +++ b/configs/kernel-6.12.0-ppc64le-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-ppc64le.config b/configs/kernel-6.12.0-ppc64le.config index d79df6728358d..845b8d369d638 100644 --- a/configs/kernel-6.12.0-ppc64le.config +++ b/configs/kernel-6.12.0-ppc64le.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-riscv64-debug.config b/configs/kernel-6.12.0-riscv64-debug.config index bccb65d88d394..a75241f27ca4c 100644 --- a/configs/kernel-6.12.0-riscv64-debug.config +++ b/configs/kernel-6.12.0-riscv64-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-riscv64.config b/configs/kernel-6.12.0-riscv64.config index 945ebe7001eb6..1491475035b1f 100644 --- a/configs/kernel-6.12.0-riscv64.config +++ b/configs/kernel-6.12.0-riscv64.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-s390x-debug.config b/configs/kernel-6.12.0-s390x-debug.config index f3e2692248e07..1d3388175b30a 100644 --- a/configs/kernel-6.12.0-s390x-debug.config +++ b/configs/kernel-6.12.0-s390x-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-s390x-zfcpdump.config b/configs/kernel-6.12.0-s390x-zfcpdump.config index a7ab40e92fbe2..b63267eee0579 100644 --- a/configs/kernel-6.12.0-s390x-zfcpdump.config +++ b/configs/kernel-6.12.0-s390x-zfcpdump.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-s390x.config b/configs/kernel-6.12.0-s390x.config index a61fec87569aa..2411abd20bf7b 100644 --- a/configs/kernel-6.12.0-s390x.config +++ b/configs/kernel-6.12.0-s390x.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-automotive-debug.config b/configs/kernel-6.12.0-x86_64-automotive-debug.config index edd8261a83abe..23f8513cec3be 100644 --- a/configs/kernel-6.12.0-x86_64-automotive-debug.config +++ b/configs/kernel-6.12.0-x86_64-automotive-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-automotive.config b/configs/kernel-6.12.0-x86_64-automotive.config index 911a037e19cf4..49b9d48c7c4b5 100644 --- a/configs/kernel-6.12.0-x86_64-automotive.config +++ b/configs/kernel-6.12.0-x86_64-automotive.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-debug.config b/configs/kernel-6.12.0-x86_64-debug.config index b1c97090414b0..234f3a0f65495 100644 --- a/configs/kernel-6.12.0-x86_64-debug.config +++ b/configs/kernel-6.12.0-x86_64-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-rt-debug.config b/configs/kernel-6.12.0-x86_64-rt-debug.config index 63f1503be0529..c088efd4130a6 100644 --- a/configs/kernel-6.12.0-x86_64-rt-debug.config +++ b/configs/kernel-6.12.0-x86_64-rt-debug.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64-rt.config b/configs/kernel-6.12.0-x86_64-rt.config index 2bf9f0ffc666a..309800cfbc90f 100644 --- a/configs/kernel-6.12.0-x86_64-rt.config +++ b/configs/kernel-6.12.0-x86_64-rt.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/configs/kernel-6.12.0-x86_64.config b/configs/kernel-6.12.0-x86_64.config index 541b64fa412dd..bba96d6606abf 100644 --- a/configs/kernel-6.12.0-x86_64.config +++ b/configs/kernel-6.12.0-x86_64.config @@ -12,8 +12,8 @@ CONFIG_AS_VERSION=25000 CONFIG_LD_IS_BFD=y CONFIG_LD_VERSION=25000 CONFIG_LLD_VERSION=0 -CONFIG_RUSTC_VERSION=107600 -CONFIG_RUSTC_LLVM_VERSION=170006 +CONFIG_RUSTC_VERSION=0 +CONFIG_RUSTC_LLVM_VERSION=0 CONFIG_CC_CAN_LINK=y CONFIG_CC_CAN_LINK_STATIC=y CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y diff --git a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h index c18a652c0faa1..048ad4a37fcca 100644 --- a/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h +++ b/drivers/net/ethernet/mellanox/mlx5/core/lib/clock.h @@ -35,6 +35,8 @@ #include +/* KABI checker sees the old definitions in include/linux/mlx5/driver.h */ +#ifndef __GENKSYMS__ #define MAX_PIN_NUM 8 struct mlx5_pps { u8 pin_caps[MAX_PIN_NUM]; @@ -61,6 +63,7 @@ struct mlx5_clock { struct mlx5_timer timer; bool shared; }; +#endif static inline bool mlx5_is_real_time_rq(struct mlx5_core_dev *mdev) { diff --git a/include/linux/mlx5/driver.h b/include/linux/mlx5/driver.h index 2c1e83033612d..792194a6958f5 100644 --- a/include/linux/mlx5/driver.h +++ b/include/linux/mlx5/driver.h @@ -55,6 +55,7 @@ #include #include #include +#include #include #define MLX5_ADEV_NAME "mlx5_core" @@ -706,6 +707,55 @@ struct mlx5_rsvd_gids { struct ida ida; }; +/* RHEL 10.0 GA had an embedded struct mlx5_clock in struct mlx5_core_dev. + * For PTP clock support with BF-3 (RHEL-87775), it needs to change to + * a pointer. However, changes to struct mlx5_core_dev break KABI symbols: + * mlx5_blocking_notifier_register + * mlx5_blocking_notifier_unregister + * mlx5_core_access_reg + * mlx5_core_uplink_netdev_event_replay + * + * We assume that: + * - The functions are exported to serve the in-tree drivers (mlx5_ib, + * mlx5_dpll). + * - Mixing the in-tree mlx5_core with an external mlx5_* aux binary + * driver is unlikely. + * - Even if the mixing occurs, the external driver is unlikely to touch + * the "clock" member anyway. + * + * To preserve the maximum of the KABI, we keep a dummy struct mlx5_clock where + * it was originally. To any external module accessing it, it will appear as if + * mlx5_init_clock() had aborted the HW clock init and left the struct cleared. + * To make this work, we keep the original struct layout definitions here. + */ +#define RHEL96_KABI_MAX_PIN_NUM 8 +struct RH_KABI_RENAME(mlx5_pps, rhel96_kabi_mlx5_pps) { + u8 pin_caps[RHEL96_KABI_MAX_PIN_NUM]; + struct work_struct out_work; + u64 start[RHEL96_KABI_MAX_PIN_NUM]; + u8 enabled; + u64 min_npps_period; + u64 min_out_pulse_duration_ns; +}; + +struct RH_KABI_RENAME(mlx5_timer, rhel96_kabi_mlx5_timer) { + struct cyclecounter cycles; + struct timecounter tc; + u32 nominal_c_mult; + unsigned long overflow_period; + struct delayed_work overflow_work; +}; + +struct RH_KABI_RENAME(mlx5_clock, rhel96_kabi_mlx5_clock) { + struct mlx5_nb pps_nb; + seqlock_t lock; + struct hwtstamp_config hwtstamp_config; + struct ptp_clock *ptp; + struct ptp_clock_info ptp_info; + struct RH_KABI_RENAME(mlx5_pps, rhel96_kabi_mlx5_pps) pps_info; + struct RH_KABI_RENAME(mlx5_timer, rhel96_kabi_mlx5_timer) timer; +}; + struct mlx5_clock; struct mlx5_clock_dev_state; struct mlx5_dm; @@ -791,8 +841,8 @@ struct mlx5_core_dev { #ifdef CONFIG_MLX5_FPGA struct mlx5_fpga_device *fpga; #endif - struct mlx5_clock *clock; - struct mlx5_clock_dev_state *clock_state; + struct RH_KABI_RENAME(mlx5_clock, rhel96_kabi_mlx5_clock) + RH_KABI_RENAME(clock, rhel96_kabi_dummy_clock); struct mlx5_ib_clock_info *clock_info; struct mlx5_fw_tracer *tracer; struct mlx5_rsc_dump *rsc_dump; @@ -811,6 +861,8 @@ struct mlx5_core_dev { enum mlx5_wc_state wc_state; /* sync write combining state */ struct mutex wc_state_lock; + RH_KABI_EXTEND(struct mlx5_clock *clock) + RH_KABI_EXTEND(struct mlx5_clock_dev_state *clock_state) }; struct mlx5_db { diff --git a/redhat/kernel.changelog-10.0 b/redhat/kernel.changelog-10.0 index 9b3c41ce40318..91384f8f09e32 100644 --- a/redhat/kernel.changelog-10.0 +++ b/redhat/kernel.changelog-10.0 @@ -1,3 +1,26 @@ +* Mon Oct 20 2025 Jan Stancek [6.12.0-55.41.1.el10_0] +- ALSA: hda/ca0132: Fix buffer overflow in add_tuning_control (CKI Backport Bot) [RHEL-114853] {CVE-2025-39751} +- erofs: fix blksize < PAGE_SIZE for file-backed mounts (CKI Backport Bot) [RHEL-83885] {CVE-2024-56750} +- s390/ism: fix concurrency management in ism_cmd() (CKI Backport Bot) [RHEL-114499] +- NFS: Fix filehandle bounds checking in nfs_fh_to_dentry() (CKI Backport Bot) [RHEL-113614] {CVE-2025-39730} +- net/mlx5: Generate PPS IN event on new function for shared clock (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Support one PTP device per hardware clock (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Move PPS notifier and out_work to clock_state (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Add devcom component for the clock shared by functions (Michal Schmidt) [RHEL-101997] +- net/mlx5: Change clock in mlx5_core_dev to mlx5_clock pointer (Michal Schmidt) [RHEL-101997] +- net/mlx5: Add API to get mlx5_core_dev from mlx5_clock (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Add init and destruction functions for a single HW clock (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Change parameters for PTP internal functions (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Add helper functions for PTP callbacks (Benjamin Poirier) [RHEL-101997] +- net/mlx5: Add support for MRTCQ register (Benjamin Poirier) [RHEL-101997] +- net/mlx5: use do_aux_work for PHC overflow checks (Michal Schmidt) [RHEL-101997] +- mlx5_en: use read sequence for gettimex64 (Benjamin Poirier) [RHEL-101997] +- NFS: Fix a race when updating an existing write (CKI Backport Bot) [RHEL-113859] {CVE-2025-39697} +- vsock/virtio: Validate length in packet header before skb_put() (Jon Maloy) [RHEL-114304] {CVE-2025-39718} +- mm: swap: fix potential buffer overflow in setup_clusters() (CKI Backport Bot) [RHEL-114863] {CVE-2025-39727} +- wifi: cfg80211: sme: cap SSID length in __cfg80211_connect_result() (CKI Backport Bot) [RHEL-117583] {CVE-2025-39849} +Resolves: RHEL-101997, RHEL-113614, RHEL-113859, RHEL-114304, RHEL-114499, RHEL-114853, RHEL-114863, RHEL-117583, RHEL-83885 + * Sat Oct 11 2025 CKI KWF Bot [6.12.0-55.40.1.el10_0] - scsi: lpfc: Fix buffer free/clear order in deferred receive path (CKI Backport Bot) [RHEL-119125] {CVE-2025-39841} - efivarfs: Fix slab-out-of-bounds in efivarfs_d_compare (CKI Backport Bot) [RHEL-118460] {CVE-2025-39817}