]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
wifi: mac80211_hwsim: protect tsf_offset using a spinlock
authorBenjamin Berg <benjamin.berg@intel.com>
Wed, 6 May 2026 03:44:23 +0000 (06:44 +0300)
committerJohannes Berg <johannes.berg@intel.com>
Wed, 6 May 2026 09:41:50 +0000 (11:41 +0200)
To implement NAN synchronization in hwsim, the TSF needs to be adjusted
regularly from the RX path. Add a spinlock so that this can be done in a
safe manner.

Signed-off-by: Benjamin Berg <benjamin.berg@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20260506064301.18f36f264eb9.I0da5477220b896e2177bd521f7d9a8f2595631e6@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
drivers/net/wireless/virtual/mac80211_hwsim_i.h
drivers/net/wireless/virtual/mac80211_hwsim_main.c

index 5432de92beab3e58658f6a375492d822b7f229ab..7a6495ea79e7ae8484783e463381e85cb4c3c9eb 100644 (file)
@@ -102,6 +102,7 @@ struct mac80211_hwsim_data {
        u32 wmediumd;
 
        /* difference between this hw's clock and the real clock, in usecs */
+       spinlock_t tsf_offset_lock;
        s64 tsf_offset;
 
        /* Stats */
index 76f1028bc42e0d28bab791db54721e850ed03712..2de44c5fb1ffa08c543c2d1f47f426b8e67d1690 100644 (file)
@@ -1256,13 +1256,17 @@ static inline u64 mac80211_hwsim_get_sim_tsf(void)
 ktime_t mac80211_hwsim_tsf_to_boottime(struct mac80211_hwsim_data *data,
                                       u64 tsf)
 {
-       return us_to_ktime(tsf - data->tsf_offset);
+       scoped_guard(spinlock_bh, &data->tsf_offset_lock) {
+               return us_to_ktime(tsf - data->tsf_offset);
+       }
 }
 
 u64 mac80211_hwsim_boottime_to_tsf(struct mac80211_hwsim_data *data,
                                   ktime_t ts)
 {
-       return ktime_to_us(ts + data->tsf_offset);
+       scoped_guard(spinlock_bh, &data->tsf_offset_lock) {
+               return ktime_to_us(ts) + data->tsf_offset;
+       }
 }
 
 u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
@@ -1271,14 +1275,18 @@ u64 mac80211_hwsim_get_tsf(struct ieee80211_hw *hw,
        struct mac80211_hwsim_data *data = hw->priv;
        u64 sim_time = mac80211_hwsim_get_sim_tsf();
 
-       return sim_time + data->tsf_offset;
+       scoped_guard(spinlock_bh, &data->tsf_offset_lock) {
+               return sim_time + data->tsf_offset;
+       }
 }
 
 static __le64 __mac80211_hwsim_get_tsf(struct mac80211_hwsim_data *data)
 {
        u64 sim_time = mac80211_hwsim_get_sim_tsf();
 
-       return cpu_to_le64(sim_time + data->tsf_offset);
+       scoped_guard(spinlock_bh, &data->tsf_offset_lock) {
+               return cpu_to_le64(sim_time + data->tsf_offset);
+       }
 }
 
 static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
@@ -1293,11 +1301,13 @@ static void mac80211_hwsim_set_tsf(struct ieee80211_hw *hw,
        if (conf && !conf->enable_beacon)
                return;
 
-       /* adjust after beaconing with new timestamp at old TBTT */
-       if (tsf > now)
-               data->tsf_offset += delta;
-       else
-               data->tsf_offset -= delta;
+       scoped_guard(spinlock_bh, &data->tsf_offset_lock) {
+               /* adjust after beaconing with new timestamp at old TBTT */
+               if (tsf > now)
+                       data->tsf_offset += delta;
+               else
+                       data->tsf_offset -= delta;
+       }
 }
 
 static void mac80211_hwsim_monitor_rx(struct ieee80211_hw *hw,
@@ -1577,6 +1587,8 @@ static void mac80211_hwsim_write_tsf(struct mac80211_hwsim_data *data,
        /* TODO: get MCS */
        int bitrate = 100;
 
+       spin_lock_bh(&data->tsf_offset_lock);
+
        txrate = ieee80211_get_tx_rate(data->hw, info);
        if (txrate)
                bitrate = txrate->bitrate;
@@ -1602,6 +1614,8 @@ static void mac80211_hwsim_write_tsf(struct mac80211_hwsim_data *data,
                                                          10 * 8 * 10 /
                                                          bitrate);
        }
+
+       spin_unlock_bh(&data->tsf_offset_lock);
 }
 
 static void mac80211_hwsim_tx_frame_nl(struct ieee80211_hw *hw,
@@ -5664,6 +5678,8 @@ static int mac80211_hwsim_new_radio(struct genl_info *info,
        hw->wiphy->mbssid_max_interfaces = 8;
        hw->wiphy->ema_max_profile_periodicity = 3;
 
+       spin_lock_init(&data->tsf_offset_lock);
+
        data->rx_rssi = DEFAULT_RX_RSSI;
 
        INIT_DELAYED_WORK(&data->roc_start, hw_roc_start);