Skip to content

Commit 7565d4d

Browse files
pyma1gregkh
authored andcommitted
ice: Fix PTP NULL pointer dereference during VSI rebuild
[ Upstream commit fc6f36e ] Fix race condition where PTP periodic work runs while VSI is being rebuilt, accessing NULL vsi->rx_rings. The sequence was: 1. ice_ptp_prepare_for_reset() cancels PTP work 2. ice_ptp_rebuild() immediately queues PTP work 3. VSI rebuild happens AFTER ice_ptp_rebuild() 4. PTP work runs and accesses NULL vsi->rx_rings Fix: Keep PTP work cancelled during rebuild, only queue it after VSI rebuild completes in ice_rebuild(). Added ice_ptp_queue_work() helper function to encapsulate the logic for queuing PTP work, ensuring it's only queued when PTP is supported and the state is ICE_PTP_READY. Error log: [ 121.392544] ice 0000:60:00.1: PTP reset successful [ 121.392692] BUG: kernel NULL pointer dereference, address: 0000000000000000 [ 121.392712] #PF: supervisor read access in kernel mode [ 121.392720] #PF: error_code(0x0000) - not-present page [ 121.392727] PGD 0 [ 121.392734] Oops: Oops: 0000 [#1] SMP NOPTI [ 121.392746] CPU: 8 UID: 0 PID: 1005 Comm: ice-ptp-0000:60 Tainted: G S 6.19.0-rc6+ #4 PREEMPT(voluntary) [ 121.392761] Tainted: [S]=CPU_OUT_OF_SPEC [ 121.392773] RIP: 0010:ice_ptp_update_cached_phctime+0xbf/0x150 [ice] [ 121.393042] Call Trace: [ 121.393047] <TASK> [ 121.393055] ice_ptp_periodic_work+0x69/0x180 [ice] [ 121.393202] kthread_worker_fn+0xa2/0x260 [ 121.393216] ? __pfx_ice_ptp_periodic_work+0x10/0x10 [ice] [ 121.393359] ? __pfx_kthread_worker_fn+0x10/0x10 [ 121.393371] kthread+0x10d/0x230 [ 121.393382] ? __pfx_kthread+0x10/0x10 [ 121.393393] ret_from_fork+0x273/0x2b0 [ 121.393407] ? __pfx_kthread+0x10/0x10 [ 121.393417] ret_from_fork_asm+0x1a/0x30 [ 121.393432] </TASK> Fixes: 803bef8 ("ice: factor out ice_ptp_rebuild_owner()") Signed-off-by: Aaron Ma <aaron.ma@canonical.com> Tested-by: Sunitha Mekala <sunithax.d.mekala@intel.com> (A Contingent worker at Intel) Signed-off-by: Tony Nguyen <anthony.l.nguyen@intel.com> Signed-off-by: Sasha Levin <sashal@kernel.org>
1 parent ef72678 commit 7565d4d

3 files changed

Lines changed: 29 additions & 5 deletions

File tree

drivers/net/ethernet/intel/ice/ice_main.c

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7815,6 +7815,9 @@ static void ice_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
78157815

78167816
/* Restore timestamp mode settings after VSI rebuild */
78177817
ice_ptp_restore_timestamp_mode(pf);
7818+
7819+
/* Start PTP periodic work after VSI is fully rebuilt */
7820+
ice_ptp_queue_work(pf);
78187821
return;
78197822

78207823
err_vsi_rebuild:

drivers/net/ethernet/intel/ice/ice_ptp.c

Lines changed: 21 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2832,6 +2832,20 @@ static void ice_ptp_periodic_work(struct kthread_work *work)
28322832
msecs_to_jiffies(err ? 10 : 500));
28332833
}
28342834

2835+
/**
2836+
* ice_ptp_queue_work - Queue PTP periodic work for a PF
2837+
* @pf: Board private structure
2838+
*
2839+
* Helper function to queue PTP periodic work after VSI rebuild completes.
2840+
* This ensures that PTP work only runs when VSI structures are ready.
2841+
*/
2842+
void ice_ptp_queue_work(struct ice_pf *pf)
2843+
{
2844+
if (test_bit(ICE_FLAG_PTP_SUPPORTED, pf->flags) &&
2845+
pf->ptp.state == ICE_PTP_READY)
2846+
kthread_queue_delayed_work(pf->ptp.kworker, &pf->ptp.work, 0);
2847+
}
2848+
28352849
/**
28362850
* ice_ptp_prepare_rebuild_sec - Prepare second NAC for PTP reset or rebuild
28372851
* @pf: Board private structure
@@ -2850,10 +2864,15 @@ static void ice_ptp_prepare_rebuild_sec(struct ice_pf *pf, bool rebuild,
28502864
struct ice_pf *peer_pf = ptp_port_to_pf(port);
28512865

28522866
if (!ice_is_primary(&peer_pf->hw)) {
2853-
if (rebuild)
2867+
if (rebuild) {
2868+
/* TODO: When implementing rebuild=true:
2869+
* 1. Ensure secondary PFs' VSIs are rebuilt
2870+
* 2. Call ice_ptp_queue_work(peer_pf) after VSI rebuild
2871+
*/
28542872
ice_ptp_rebuild(peer_pf, reset_type);
2855-
else
2873+
} else {
28562874
ice_ptp_prepare_for_reset(peer_pf, reset_type);
2875+
}
28572876
}
28582877
}
28592878
}
@@ -2999,9 +3018,6 @@ void ice_ptp_rebuild(struct ice_pf *pf, enum ice_reset_req reset_type)
29993018

30003019
ptp->state = ICE_PTP_READY;
30013020

3002-
/* Start periodic work going */
3003-
kthread_queue_delayed_work(ptp->kworker, &ptp->work, 0);
3004-
30053021
dev_info(ice_pf_to_dev(pf), "PTP reset successful\n");
30063022
return;
30073023

drivers/net/ethernet/intel/ice/ice_ptp.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -316,6 +316,7 @@ void ice_ptp_prepare_for_reset(struct ice_pf *pf,
316316
void ice_ptp_init(struct ice_pf *pf);
317317
void ice_ptp_release(struct ice_pf *pf);
318318
void ice_ptp_link_change(struct ice_pf *pf, bool linkup);
319+
void ice_ptp_queue_work(struct ice_pf *pf);
319320
#else /* IS_ENABLED(CONFIG_PTP_1588_CLOCK) */
320321

321322
static inline int ice_ptp_hwtstamp_get(struct net_device *netdev,
@@ -384,6 +385,10 @@ static inline void ice_ptp_link_change(struct ice_pf *pf, bool linkup)
384385
{
385386
}
386387

388+
static inline void ice_ptp_queue_work(struct ice_pf *pf)
389+
{
390+
}
391+
387392
static inline int ice_ptp_clock_index(struct ice_pf *pf)
388393
{
389394
return -1;

0 commit comments

Comments
 (0)