From: "Jiawen Wu" <jiawenwu@trustnetic.com>
To: "'Vadim Fedorenko'" <vadim.fedorenko@linux.dev>,
<netdev@vger.kernel.org>
Cc: "'Mengyuan Lou'" <mengyuanlou@net-swift.com>,
"'Andrew Lunn'" <andrew+netdev@lunn.ch>,
"'David S. Miller'" <davem@davemloft.net>,
"'Eric Dumazet'" <edumazet@google.com>,
"'Jakub Kicinski'" <kuba@kernel.org>,
"'Paolo Abeni'" <pabeni@redhat.com>,
"'Richard Cochran'" <richardcochran@gmail.com>
Subject: RE: [PATCH net] net: libwx: fix concurrent bitmap overwrite in PTP setup
Date: Tue, 18 Aug 2026 09:50:02 +0800 [thread overview]
Message-ID: <00e001dd2eb3$e2c6b580$a8542080$@trustnetic.com> (raw)
In-Reply-To: <31eca887-50d8-40b2-b206-eff0a50b4a8f@linux.dev>
On Mon, Aug 17, 2026 9:07 PM, Vadim Fedorenko wrote:
> On 17/08/2026 03:17, Jiawen Wu wrote:
> > In wx_ptp_set_timestamp_mode(), the driver copies the global `wx->flags`
> > bitmap to a local variable, modifies the PTP-related bits, and then writes
> > the entire bitmap back using memcpy().
> >
> > This Read-Copy-Update pattern is unsafe and introduces a critical race
> > condition. Other asynchronous contexts (such as Tx timeout routines or
> > GPIO IRQ handlers) update individual bits in `wx->flags` concurrently
> > using atomic bitops like set_bit() or clear_bit(). The memcpy() write-back
> > can silently overwrite and drop these concurrent changes, potentially
> > causing the driver to miss critical module reset or PCIe recovery requests.
> >
> > Fix this by removing the local bitmap copy. Instead, evaluate the intended
> > PTP flag states locally and apply them directly to `wx->flags` using
> > atomic set_bit() and clear_bit() operations only after the hardware is
> > successfully configured.
> >
> > Fixes: 06e75161b9d4 ("net: wangxun: Add support for PTP clock")
> > Signed-off-by: Jiawen Wu <jiawenwu@trustnetic.com>
> > ---
> > drivers/net/ethernet/wangxun/libwx/wx_ptp.c | 22 ++++++++++-----------
> > 1 file changed, 10 insertions(+), 12 deletions(-)
> >
> > diff --git a/drivers/net/ethernet/wangxun/libwx/wx_ptp.c b/drivers/net/ethernet/wangxun/libwx/wx_ptp.c
> > index 44f3e6505246..7d4bd7b258b7 100644
> > --- a/drivers/net/ethernet/wangxun/libwx/wx_ptp.c
> > +++ b/drivers/net/ethernet/wangxun/libwx/wx_ptp.c
> > @@ -555,13 +555,12 @@ static int wx_ptp_set_timestamp_mode(struct wx *wx,
> > {
> > u32 tsync_tx_ctl = WX_TSC_1588_CTL_ENABLED;
> > u32 tsync_rx_ctl = WX_PSR_1588_CTL_ENABLED;
> > - DECLARE_BITMAP(flags, WX_PF_FLAGS_NBITS);
> > u32 tsync_rx_mtrl = PTP_EV_PORT << 16;
> > + bool rx_in_register = false;
> > + bool rx_enabled = false;
>
> why do you need 2 variables if their values are equal in all cases?
You are right!
>
> > bool is_l2 = false;
> > u32 regval;
> >
> > - memcpy(flags, wx->flags, sizeof(wx->flags));
> > -
> > switch (config->tx_type) {
> > case HWTSTAMP_TX_OFF:
> > tsync_tx_ctl = 0;
> > @@ -576,20 +575,18 @@ static int wx_ptp_set_timestamp_mode(struct wx *wx,
> > case HWTSTAMP_FILTER_NONE:
> > tsync_rx_ctl = 0;
> > tsync_rx_mtrl = 0;
> > - clear_bit(WX_FLAG_RX_HWTSTAMP_ENABLED, flags);
> > - clear_bit(WX_FLAG_RX_HWTSTAMP_IN_REGISTER, flags);
> > break;
> > case HWTSTAMP_FILTER_PTP_V1_L4_SYNC:
> > tsync_rx_ctl |= WX_PSR_1588_CTL_TYPE_L4_V1;
> > tsync_rx_mtrl |= WX_PSR_1588_MSG_V1_SYNC;
> > - set_bit(WX_FLAG_RX_HWTSTAMP_ENABLED, flags);
> > - set_bit(WX_FLAG_RX_HWTSTAMP_IN_REGISTER, flags);
> > + rx_enabled = true;
> > + rx_in_register = true;
> > break;
> > case HWTSTAMP_FILTER_PTP_V1_L4_DELAY_REQ:
> > tsync_rx_ctl |= WX_PSR_1588_CTL_TYPE_L4_V1;
> > tsync_rx_mtrl |= WX_PSR_1588_MSG_V1_DELAY_REQ;
> > - set_bit(WX_FLAG_RX_HWTSTAMP_ENABLED, flags);
> > - set_bit(WX_FLAG_RX_HWTSTAMP_IN_REGISTER, flags);
> > + rx_enabled = true;
> > + rx_in_register = true;
> > break;
> > case HWTSTAMP_FILTER_PTP_V2_EVENT:
> > case HWTSTAMP_FILTER_PTP_V2_L2_EVENT:
> > @@ -602,9 +599,9 @@ static int wx_ptp_set_timestamp_mode(struct wx *wx,
> > case HWTSTAMP_FILTER_PTP_V2_L4_DELAY_REQ:
> > tsync_rx_ctl |= WX_PSR_1588_CTL_TYPE_EVENT_V2;
> > is_l2 = true;
> > + rx_enabled = true;
> > + rx_in_register = true;
> > config->rx_filter = HWTSTAMP_FILTER_PTP_V2_EVENT;
> > - set_bit(WX_FLAG_RX_HWTSTAMP_ENABLED, flags);
> > - set_bit(WX_FLAG_RX_HWTSTAMP_IN_REGISTER, flags);
> > break;
> > default:
> > /* register PSR_1588_MSG must be set in order to do V1 packets,
> > @@ -643,7 +640,8 @@ static int wx_ptp_set_timestamp_mode(struct wx *wx,
> > WX_WRITE_FLUSH(wx);
> >
> > /* configure adapter flags only when HW is actually configured */
> > - memcpy(wx->flags, flags, sizeof(wx->flags));
> > + assign_bit(WX_FLAG_RX_HWTSTAMP_ENABLED, wx->flags, rx_enabled);
> > + assign_bit(WX_FLAG_RX_HWTSTAMP_IN_REGISTER, wx->flags, rx_in_register);
> >
> > /* clear TX/RX timestamp state, just to be sure */
> > wx_ptp_clear_tx_timestamp(wx);
>
>
prev parent reply other threads:[~2026-08-18 1:51 UTC|newest]
Thread overview: 3+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-08-17 2:17 [PATCH net] net: libwx: fix concurrent bitmap overwrite in PTP setup Jiawen Wu
2026-08-17 13:07 ` Vadim Fedorenko
2026-08-18 1:50 ` Jiawen Wu [this message]
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to='00e001dd2eb3$e2c6b580$a8542080$@trustnetic.com' \
--to=jiawenwu@trustnetic.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=kuba@kernel.org \
--cc=mengyuanlou@net-swift.com \
--cc=netdev@vger.kernel.org \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
--cc=vadim.fedorenko@linux.dev \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.