Skip to content

Commit

Permalink
hv_utils: return error if host timesysnc update is stale
Browse files Browse the repository at this point in the history
If for any reason, host timesync messages were not processed by
the guest, hv_ptp_gettime() returns a stale value and the
caller (clock_gettime, PTP ioctl etc) has no means to know this
now. Return an error so that the caller knows about this.

Signed-off-by: Vineeth Pillai <viremana@linux.microsoft.com>
Reviewed-by: Michael Kelley <mikelley@microsoft.com>
Link: https://lore.kernel.org/r/20200821152523.99364-1-viremana@linux.microsoft.com
Signed-off-by: Wei Liu <wei.liu@kernel.org>
  • Loading branch information
Vineeth Pillai authored and Wei Liu committed Aug 24, 2020
1 parent b9d8cf2 commit 90b125f
Showing 1 changed file with 35 additions and 11 deletions.
46 changes: 35 additions & 11 deletions drivers/hv/hv_util.c
Original file line number Diff line number Diff line change
Expand Up @@ -282,26 +282,52 @@ static struct {
spinlock_t lock;
} host_ts;

static struct timespec64 hv_get_adj_host_time(void)
static inline u64 reftime_to_ns(u64 reftime)
{
struct timespec64 ts;
u64 newtime, reftime;
return (reftime - WLTIMEDELTA) * 100;
}

/*
* Hard coded threshold for host timesync delay: 600 seconds
*/
static const u64 HOST_TIMESYNC_DELAY_THRESH = 600 * (u64)NSEC_PER_SEC;

static int hv_get_adj_host_time(struct timespec64 *ts)
{
u64 newtime, reftime, timediff_adj;
unsigned long flags;
int ret = 0;

spin_lock_irqsave(&host_ts.lock, flags);
reftime = hv_read_reference_counter();
newtime = host_ts.host_time + (reftime - host_ts.ref_time);
ts = ns_to_timespec64((newtime - WLTIMEDELTA) * 100);

/*
* We need to let the caller know that last update from host
* is older than the max allowable threshold. clock_gettime()
* and PTP ioctl do not have a documented error that we could
* return for this specific case. Use ESTALE to report this.
*/
timediff_adj = reftime - host_ts.ref_time;
if (timediff_adj * 100 > HOST_TIMESYNC_DELAY_THRESH) {
pr_warn_once("TIMESYNC IC: Stale time stamp, %llu nsecs old\n",
(timediff_adj * 100));
ret = -ESTALE;
}

newtime = host_ts.host_time + timediff_adj;
*ts = ns_to_timespec64(reftime_to_ns(newtime));
spin_unlock_irqrestore(&host_ts.lock, flags);

return ts;
return ret;
}

static void hv_set_host_time(struct work_struct *work)
{
struct timespec64 ts = hv_get_adj_host_time();

do_settimeofday64(&ts);
struct timespec64 ts;

if (!hv_get_adj_host_time(&ts))
do_settimeofday64(&ts);
}

/*
Expand Down Expand Up @@ -622,9 +648,7 @@ static int hv_ptp_adjtime(struct ptp_clock_info *ptp, s64 delta)

static int hv_ptp_gettime(struct ptp_clock_info *info, struct timespec64 *ts)
{
*ts = hv_get_adj_host_time();

return 0;
return hv_get_adj_host_time(ts);
}

static struct ptp_clock_info ptp_hyperv_info = {
Expand Down

0 comments on commit 90b125f

Please sign in to comment.