Skip to content

Commit

Permalink
Merge 193033
Browse files Browse the repository at this point in the history
Fix the Xen TOD update when the hypervisor wall clock is nudged.

 The "wall clock" in the current code is actually the hypervisor start time.
 The time of day is the "start time" plus the hypervisor "uptime".

 Large enough bumps in the dom0 clock lead to a hypervisor "bump" which is
 implemented as a bump in the start time, not the uptime. The clock.c routines
 were reading in the hypervisor start time and then using this as the TOD.
 This meant that any hypervisor time bump would cause the FreeBSD DomU to
 set its TOD to the hypervisor start time, rather than the actual TOD.

 This fix is a bit hacky and some reshuffling should be done later on
 to clarify what is going on. I've left the wall clock code alone.
 (The code which updates shadow_tv and shadow_tv_version.)
 A new routine adds the uptime to the shadow_tv, which is then used to
 update the TOD.

 I've included some debugging so it is obvious when the clock is nudged.
  • Loading branch information
kmacy committed Jun 11, 2009
1 parent 520e81a commit 88165a4
Showing 1 changed file with 14 additions and 0 deletions.
14 changes: 14 additions & 0 deletions sys/i386/xen/clock.c
Expand Up @@ -87,6 +87,7 @@ __FBSDID("$FreeBSD$");
#include <machine/xen/xenfunc.h>
#include <xen/interface/vcpu.h>
#include <machine/cpu.h>
#include <machine/xen/xen_clock_util.h>

/*
* 32-bit time_t's can't reach leap years before 1904 or after 2036, so we
Expand Down Expand Up @@ -237,6 +238,15 @@ static void update_wallclock(void)

}

static void
add_uptime_to_wallclock(void)
{
struct timespec ut;

xen_fetch_uptime(&ut);
timespecadd(&shadow_tv, &ut);
}

/*
* Reads a consistent set of time-base values from Xen, into a shadow data
* area. Must be called with the xtime_lock held for writing.
Expand Down Expand Up @@ -332,7 +342,9 @@ clkintr(void *arg)
*/

if (shadow_tv_version != HYPERVISOR_shared_info->wc_version) {
printf("[XEN] hypervisor wallclock nudged; nudging TOD.\n");
update_wallclock();
add_uptime_to_wallclock();
tc_setclock(&shadow_tv);
}

Expand Down Expand Up @@ -543,6 +555,7 @@ domu_inittodr(time_t base)
struct timespec ts;

update_wallclock();
add_uptime_to_wallclock();

RTC_LOCK;

Expand Down Expand Up @@ -592,6 +605,7 @@ domu_resettodr(void)
op.u.settime.system_time = shadow->system_timestamp;
HYPERVISOR_dom0_op(&op);
update_wallclock();
add_uptime_to_wallclock();
} else if (independent_wallclock) {
/* notyet */
;
Expand Down

0 comments on commit 88165a4

Please sign in to comment.