From: Jakub Kicinski <kuba@kernel.org>
To: hramamurthy@google.com
Cc: Jakub Kicinski <kuba@kernel.org>,
netdev@vger.kernel.org, joshwash@google.com,
andrew+netdev@lunn.ch, davem@davemloft.net, edumazet@google.com,
pabeni@redhat.com, richardcochran@gmail.com, willemb@google.com,
nktgrg@google.com, jfraker@google.com, ziweixiao@google.com,
maolson@google.com, thostet@google.com, jordanrhee@google.com,
jefrogers@google.com, alok.a.tiwari@oracle.com, yyd@google.com,
linux-kernel@vger.kernel.org, namangulati@google.com
Subject: Re: [PATCH net-next v2 3/3] gve: implement PTP gettimex64
Date: Sun, 29 Mar 2026 14:20:02 -0700 [thread overview]
Message-ID: <20260329212002.2875815-1-kuba@kernel.org> (raw)
In-Reply-To: <20260326224527.1044097-4-hramamurthy@google.com>
This is an AI-generated review of your patch. The human sending this
email has considered the AI review valid, or at least plausible.
---
Subject: gve: implement PTP gettimex64
This commit implements the PTP gettimex64 function to enable chrony and
phc2sys to synchronize the system clock to the NIC clock. It reads the
NIC timestamp along with pre and post system cycle counters to minimize
the uncertainty window.
> diff --git a/drivers/net/ethernet/google/gve/gve_ptp.c b/drivers/net/ethernet/google/gve/gve_ptp.c
> index 140b8fbce4f4..bea794541f30 100644
> --- a/drivers/net/ethernet/google/gve/gve_ptp.c
> +++ b/drivers/net/ethernet/google/gve/gve_ptp.c
> @@ -10,28 +10,203 @@
[ ... ]
> +static int gve_adminq_read_timestamp(struct gve_priv *priv,
> + cycles_t *pre_cycles,
> + cycles_t *post_cycles)
> +{
> + unsigned long delay_us = 1000;
> + int retry_count = 0;
> + int err;
> +
> + lockdep_assert_held(&priv->nic_ts_read_lock);
> +
> + do {
> + *pre_cycles = get_cycles();
> + err = gve_adminq_report_nic_ts(priv, priv->nic_ts_report_bus);
> +
> + /* Ensure cycle counter is sampled after AdminQ cmd returns */
> + rmb();
> + *post_cycles = get_cycles();
Are execution barriers needed around get_cycles() here? rmb() orders
memory accesses, but the CPU might still speculatively execute the cycle
counter reads out of order with respect to the AdminQ commands.
Could this speculative reordering cause the strict bounds validation in
gve_ptp_gettimex64() to fail spuriously?
[ ... ]
> static int gve_ptp_gettimex64(struct ptp_clock_info *info,
> struct timespec64 *ts,
> struct ptp_system_timestamp *sts)
> {
> - return -EOPNOTSUPP;
> + struct gve_ptp *ptp = container_of(info, struct gve_ptp, info);
> + struct gve_sysclock_sample sysclock = {0};
> + struct gve_priv *priv = ptp->priv;
> + struct system_time_snapshot snap;
> + u64 nic_ts;
> + int err;
> +
> + /* Take system clock snapshot before sampling cycle counters */
> + if (sts)
> + ktime_get_snapshot(&snap);
> +
> + err = gve_clock_nic_ts_read(priv, &nic_ts, &sysclock);
Could the system time snapshot become stale here?
If priv->nic_ts_read_lock is contended, or if gve_adminq_read_timestamp()
retries and sleeps, the snapshot might be taken significantly before the
actual hardware read.
Would it be more accurate to take the snapshot immediately before reading the
hardware, inside the mutex?
> + if (err)
> + return err;
> +
> + if (sts) {
> + /* Reject samples with out of order system clock values */
> + if (!(sysclock.host_pre_cycles <= sysclock.nic_pre_cycles &&
> + sysclock.nic_pre_cycles <= sysclock.nic_post_cycles &&
> + sysclock.nic_post_cycles <= sysclock.host_post_cycles)) {
> + dev_err_ratelimited(&priv->pdev->dev,
> + "AdminQ system clock cycle counts out of order. Expecting %llu <= %llu <= %llu <= %llu\n",
> + (u64)sysclock.host_pre_cycles,
> + sysclock.nic_pre_cycles,
> + sysclock.nic_post_cycles,
> + (u64)sysclock.host_post_cycles);
> + return -EBADMSG;
How does this behave on architectures where get_cycles() is not implemented
and returns 0, or with older firmware that leaves nic_pre_cycles and
nic_post_cycles as 0?
It looks like the bounds check would unconditionally fail and return -EBADMSG.
Since userspace tools like chrony usually expect -EOPNOTSUPP for unsupported
extended ioctls to fall back to basic PTP ioctls, will returning -EBADMSG
cause a hard failure for clock synchronization?
[ ... ]
> @@ -132,7 +307,7 @@ int gve_init_clock(struct gve_priv *priv)
> goto release_ptp;
> }
> mutex_init(&priv->nic_ts_read_lock);
> - err = gve_clock_nic_ts_read(priv, &nic_raw);
> + err = gve_clock_nic_ts_read(priv, &nic_raw, NULL);
> if (err) {
> dev_err(&priv->pdev->dev, "failed to read NIC clock %d\n", err);
> goto release_nic_ts_report;
Is there a race condition exposing the PTP device to userspace before its
resources are fully initialized?
Looking at gve_init_clock(), gve_ptp_init() is called before allocating
nic_ts_report and initializing nic_ts_read_lock:
err = gve_ptp_init(priv);
if (err)
return err;
priv->nic_ts_report = dma_alloc_coherent(...);
...
mutex_init(&priv->nic_ts_read_lock);
If a concurrent userspace process immediately invokes the
PTP_SYS_OFFSET_EXTENDED ioctl after gve_ptp_init() registers the /dev/ptpX
device, could it call gve_ptp_gettimex64() and attempt to lock the
uninitialized mutex or dereference the NULL nic_ts_report pointer?
Additionally, in the error path for gve_init_clock():
release_nic_ts_report:
mutex_destroy(&priv->nic_ts_read_lock);
dma_free_coherent(...);
priv->nic_ts_report = NULL;
release_ptp:
gve_ptp_release(priv);
Could destroying the mutex and freeing the memory before gve_ptp_release()
create a use-after-free window if an ioctl is currently running?
next prev parent reply other threads:[~2026-03-29 21:20 UTC|newest]
Thread overview: 11+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-03-26 22:45 [PATCH net-next v2 0/3] gve: add support for PTP gettimex64 Harshitha Ramamurthy
2026-03-26 22:45 ` [PATCH net-next v2 1/3] gve: skip error logging for retryable AdminQ commands Harshitha Ramamurthy
2026-03-27 2:28 ` Li Xiasong
2026-03-27 3:56 ` Jordan Rhee
2026-03-27 5:06 ` Li Xiasong
2026-03-26 22:45 ` [PATCH net-next v2 2/3] gve: make nic clock reads thread safe Harshitha Ramamurthy
2026-03-29 21:19 ` Jakub Kicinski
2026-03-30 4:06 ` Jordan Rhee
2026-03-26 22:45 ` [PATCH net-next v2 3/3] gve: implement PTP gettimex64 Harshitha Ramamurthy
2026-03-29 21:20 ` Jakub Kicinski [this message]
2026-03-30 4:31 ` Jordan Rhee
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=20260329212002.2875815-1-kuba@kernel.org \
--to=kuba@kernel.org \
--cc=alok.a.tiwari@oracle.com \
--cc=andrew+netdev@lunn.ch \
--cc=davem@davemloft.net \
--cc=edumazet@google.com \
--cc=hramamurthy@google.com \
--cc=jefrogers@google.com \
--cc=jfraker@google.com \
--cc=jordanrhee@google.com \
--cc=joshwash@google.com \
--cc=linux-kernel@vger.kernel.org \
--cc=maolson@google.com \
--cc=namangulati@google.com \
--cc=netdev@vger.kernel.org \
--cc=nktgrg@google.com \
--cc=pabeni@redhat.com \
--cc=richardcochran@gmail.com \
--cc=thostet@google.com \
--cc=willemb@google.com \
--cc=yyd@google.com \
--cc=ziweixiao@google.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox