linux/drivers/net/wireless/intel/iwlwifi/mld/debugfs.h
Pagadala Yesu Anjaneyulu 8301e2636c wifi: iwlwifi: mld: Ensure wiphy lock is held during debugfs read operations
The WIPHY_DEBUGFS_READ_WRITE_FILE_OPS_MLD macro is intended to call
read/write handlers with the wiphy lock held. However, the current
implementation uses the MLD_DEBUGFS_READ_WRAPPER macro, which does
not hold the wiphy lock during read operations. This fix updates
the WIPHY_DEBUGFS_READ_WRITE_FILE_OPS_MLD macro to use the
WIPHY_DEBUGFS_READ_WRAPPER_MLD macro instead, ensuring that the
wiphy lock is held during both read and write operations.

Signed-off-by: Pagadala Yesu Anjaneyulu <pagadala.yesu.anjaneyulu@intel.com>
Signed-off-by: Miri Korenblit <miriam.rachel.korenblit@intel.com>
Link: https://patch.msgid.link/20250313002008.2001d2335e9d.I607a8bd12efc6d1190cef1fca44279dbdd2756ea@changeid
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
2025-03-18 09:51:24 +01:00

244 lines
8 KiB
C

/* SPDX-License-Identifier: GPL-2.0 OR BSD-3-Clause */
/*
* Copyright (C) 2024-2025 Intel Corporation
*/
#include "iface.h"
#include "sta.h"
#define MLD_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \
struct dbgfs_##name##_data { \
argtype *arg; \
bool read_done; \
ssize_t rlen; \
char buf[buflen]; \
}; \
static int _iwl_dbgfs_##name##_open(struct inode *inode, \
struct file *file) \
{ \
struct dbgfs_##name##_data *data; \
\
if ((file->f_flags & O_ACCMODE) == O_RDWR) \
return -EOPNOTSUPP; \
\
data = kzalloc(sizeof(*data), GFP_KERNEL); \
if (!data) \
return -ENOMEM; \
\
data->read_done = false; \
data->arg = inode->i_private; \
file->private_data = data; \
\
return 0; \
}
#define MLD_DEBUGFS_READ_WRAPPER(name) \
static ssize_t _iwl_dbgfs_##name##_read(struct file *file, \
char __user *user_buf, \
size_t count, loff_t *ppos) \
{ \
struct dbgfs_##name##_data *data = file->private_data; \
\
if (!data->read_done) { \
data->read_done = true; \
data->rlen = iwl_dbgfs_##name##_read(data->arg, \
sizeof(data->buf),\
data->buf); \
} \
\
if (data->rlen < 0) \
return data->rlen; \
return simple_read_from_buffer(user_buf, count, ppos, \
data->buf, data->rlen); \
}
static int _iwl_dbgfs_release(struct inode *inode, struct file *file)
{
kfree(file->private_data);
return 0;
}
#define _MLD_DEBUGFS_READ_FILE_OPS(name, buflen, argtype) \
MLD_DEBUGFS_OPEN_WRAPPER(name, buflen, argtype) \
MLD_DEBUGFS_READ_WRAPPER(name) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.read = _iwl_dbgfs_##name##_read, \
.open = _iwl_dbgfs_##name##_open, \
.llseek = generic_file_llseek, \
.release = _iwl_dbgfs_release, \
}
#define WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER(name) \
static ssize_t iwl_dbgfs_##name##_write_handler(struct wiphy *wiphy, \
struct file *file, char *buf, \
size_t count, void *data) \
{ \
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); \
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); \
return iwl_dbgfs_##name##_write(mld, buf, count, data); \
}
static inline struct iwl_mld *
iwl_mld_from_link_sta(struct ieee80211_link_sta *link_sta)
{
struct ieee80211_vif *vif =
iwl_mld_sta_from_mac80211(link_sta->sta)->vif;
return iwl_mld_vif_from_mac80211(vif)->mld;
}
static inline struct iwl_mld *
iwl_mld_from_bss_conf(struct ieee80211_bss_conf *link)
{
return iwl_mld_vif_from_mac80211(link->vif)->mld;
}
static inline struct iwl_mld *iwl_mld_from_vif(struct ieee80211_vif *vif)
{
return iwl_mld_vif_from_mac80211(vif)->mld;
}
#define WIPHY_DEBUGFS_WRITE_WRAPPER(name, bufsz, objtype) \
WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER(name) \
static ssize_t __iwl_dbgfs_##name##_write(struct file *file, \
const char __user *user_buf, \
size_t count, loff_t *ppos) \
{ \
struct ieee80211_##objtype *arg = file->private_data; \
struct iwl_mld *mld = iwl_mld_from_##objtype(arg); \
char buf[bufsz] = {}; \
\
return wiphy_locked_debugfs_write(mld->wiphy, file, \
buf, sizeof(buf), \
user_buf, count, \
iwl_dbgfs_##name##_write_handler, \
arg); \
}
#define WIPHY_DEBUGFS_WRITE_FILE_OPS(name, bufsz, objtype) \
WIPHY_DEBUGFS_WRITE_WRAPPER(name, bufsz, objtype) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = __iwl_dbgfs_##name##_write, \
.open = simple_open, \
.llseek = generic_file_llseek, \
}
#define WIPHY_DEBUGFS_READ_HANDLER_WRAPPER_MLD(name) \
static ssize_t iwl_dbgfs_##name##_read_handler(struct wiphy *wiphy, \
struct file *file, char *buf, \
size_t count, void *data) \
{ \
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); \
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); \
return iwl_dbgfs_##name##_read(mld, buf, count); \
}
#define WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER_MLD(name) \
static ssize_t iwl_dbgfs_##name##_write_handler(struct wiphy *wiphy, \
struct file *file, char *buf, \
size_t count, void *data) \
{ \
struct ieee80211_hw *hw = wiphy_to_ieee80211_hw(wiphy); \
struct iwl_mld *mld = IWL_MAC80211_GET_MLD(hw); \
return iwl_dbgfs_##name##_write(mld, buf, count); \
}
#define WIPHY_DEBUGFS_WRITE_WRAPPER_MLD(name) \
WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER_MLD(name) \
static ssize_t __iwl_dbgfs_##name##_write(struct file *file, \
const char __user *user_buf, \
size_t count, loff_t *ppos) \
{ \
struct dbgfs_##name##_data *data = file->private_data; \
struct iwl_mld *mld = data->arg; \
\
return wiphy_locked_debugfs_write(mld->wiphy, file, \
data->buf, sizeof(data->buf), \
user_buf, count, \
iwl_dbgfs_##name##_write_handler, \
NULL); \
}
#define WIPHY_DEBUGFS_READ_WRAPPER_MLD(name) \
WIPHY_DEBUGFS_READ_HANDLER_WRAPPER_MLD(name) \
static ssize_t __iwl_dbgfs_##name##_read(struct file *file, \
char __user *user_buf, \
size_t count, loff_t *ppos) \
{ \
struct dbgfs_##name##_data *data = file->private_data; \
struct iwl_mld *mld = data->arg; \
\
if (!data->read_done) { \
data->read_done = true; \
data->rlen = wiphy_locked_debugfs_read(mld->wiphy, \
file, data->buf, sizeof(data->buf), \
user_buf, count, ppos, \
iwl_dbgfs_##name##_read_handler, NULL); \
return data->rlen; \
} \
\
if (data->rlen < 0) \
return data->rlen; \
return simple_read_from_buffer(user_buf, count, ppos, \
data->buf, data->rlen); \
}
#define WIPHY_DEBUGFS_READ_FILE_OPS_MLD(name, bufsz) \
MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct iwl_mld) \
WIPHY_DEBUGFS_READ_WRAPPER_MLD(name) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.read = __iwl_dbgfs_##name##_read, \
.open = _iwl_dbgfs_##name##_open, \
.llseek = generic_file_llseek, \
.release = _iwl_dbgfs_release, \
}
#define WIPHY_DEBUGFS_WRITE_FILE_OPS_MLD(name, bufsz) \
MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct iwl_mld) \
WIPHY_DEBUGFS_WRITE_WRAPPER_MLD(name) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = __iwl_dbgfs_##name##_write, \
.open = _iwl_dbgfs_##name##_open, \
.llseek = generic_file_llseek, \
.release = _iwl_dbgfs_release, \
}
#define WIPHY_DEBUGFS_READ_WRITE_FILE_OPS_MLD(name, bufsz) \
MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct iwl_mld) \
WIPHY_DEBUGFS_WRITE_WRAPPER_MLD(name) \
WIPHY_DEBUGFS_READ_WRAPPER_MLD(name) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = __iwl_dbgfs_##name##_write, \
.read = __iwl_dbgfs_##name##_read, \
.open = _iwl_dbgfs_##name##_open, \
.llseek = generic_file_llseek, \
.release = _iwl_dbgfs_release, \
}
#define WIPHY_DEBUGFS_WRITE_WRAPPER_IEEE80211(name, bufsz, objtype) \
WIPHY_DEBUGFS_WRITE_HANDLER_WRAPPER(name) \
static ssize_t _iwl_dbgfs_##name##_write(struct file *file, \
const char __user *user_buf, \
size_t count, loff_t *ppos) \
{ \
struct dbgfs_##name##_data *data = file->private_data; \
struct ieee80211_##objtype *arg = data->arg; \
struct iwl_mld *mld = iwl_mld_from_##objtype(arg); \
char buf[bufsz] = {}; \
\
return wiphy_locked_debugfs_write(mld->wiphy, file, \
buf, sizeof(buf), \
user_buf, count, \
iwl_dbgfs_##name##_write_handler, \
arg); \
}
#define IEEE80211_WIPHY_DEBUGFS_READ_WRITE_FILE_OPS(name, bufsz, objtype) \
MLD_DEBUGFS_OPEN_WRAPPER(name, bufsz, struct ieee80211_##objtype) \
WIPHY_DEBUGFS_WRITE_WRAPPER_IEEE80211(name, bufsz, objtype) \
MLD_DEBUGFS_READ_WRAPPER(name) \
static const struct file_operations iwl_dbgfs_##name##_ops = { \
.write = _iwl_dbgfs_##name##_write, \
.read = _iwl_dbgfs_##name##_read, \
.open = _iwl_dbgfs_##name##_open, \
.llseek = generic_file_llseek, \
.release = _iwl_dbgfs_release, \
}