KVM virtual PTP driver (v2)
Subsystems (7)
cover KVM virtual PTP driver (v2)
This patchset implements a virtual PTP driver which allows guest to sync its clock to the host clock with high precision ( error is < 10ns).
Changelog from v1
Patch1:
v2: unify nsec_base (Radim)
Patch2:
v2: improve documentation (Radim)
change hypercall name to KVM_HC_CLOCK_PAIRING (Radim) increase padding size
Patch3:
v2: check for kvmclock (Radim)
initialize global variables before device registration (Radim)
PATCH 1/3 KVM: x86: provide realtime host clock via vsyscall notifiers
Expose the realtime host clock and save the TSC value used for the clock calculation.
--- arch/x86/kvm/x86.c | 36 ++++++++++++++++++++++++++++++++++++ 1 file changed, 36 insertions(+)
v2: unify nsec_base (Radim)
arch/x86/kvm/x86.c +36 -0
@@ -1139,6 +1139,7 @@u64 boot_ns;u64 nsec_base; +u64 wall_time_sec; };static struct pvclock_gtod_data pvclock_gtod_data;
@@ -1162,6 +1163,8 @@ vdata->boot_ns = boot_ns; vdata->nsec_base = tk->tkr_mono.xtime_nsec; + vdata->wall_time_sec = tk->xtime_sec; + write_seqcount_end(&vdata->seq); }#endif
@@ -1623,6 +1626,28 @@return mode; } +static int do_realtime (struct timespec *ts,cycle_t *cycle_now) +{ +struct pvclock_gtod_data *gtod = &pvclock_gtod_data; +unsigned long seq; +int mode; +u64 ns; + +do { + seq =read_seqcount_begin (>od->seq); + mode = gtod->clock.vclock_mode; + ts->tv_sec = gtod->wall_time_sec; + ns = gtod->nsec_base; + ns +=vgettsc (cycle_now); + ns >>= gtod->clock.shift; + }while (unlikely (read_seqcount_retry (>od->seq, seq))); + + ts->tv_sec +=__iter_div_u64_rem (ns,NSEC_PER_SEC , &ns); + ts->tv_nsec = ns; + +return mode; +} +/* returns true if host is using tsc clocksource */ static bool kvm_get_time_and_clockread (s64 *kernel_ns,cycle_t *cycle_now) {
@@ -1632,6 +1657,17 @@ return do_monotonic_boot(kernel_ns, cycle_now) == VCLOCK_TSC; } + +/* returns true if host is using tsc clocksource */ +static bool kvm_get_walltime_and_clockread (struct timespec *ts, +cycle_t *cycle_now) +{ +/* checked again under seqlock below */ +if (pvclock_gtod_data.clock.vclock_mode !=VCLOCK_TSC ) +return false; + +return do_realtime (ts, cycle_now) ==VCLOCK_TSC ; +}#endif /*
PATCH 2/3 KVM: x86: add KVM_HC_CLOCK_OFFSET hypercall
In reply to Marcelo TosattiAdd a hypercall to retrieve the host realtime clock and the TSC value used to calculate that clock read.
Used to implement clock synchronization between
host and guest.
--- Documentation/virtual/kvm/hypercalls.txt | 33 ++++++++++++++++++++++++ arch/x86/include/uapi/asm/kvm_para.h | 9 ++++++ arch/x86/kvm/x86.c | 41 +++++++++++++++++++++++++++++++ include/uapi/linux/kvm_para.h | 3 ++ 4 files changed, 86 insertions(+)
v2: improve documentation (Radim)
change hypercall name to KVM_HC_CLOCK_PAIRING (Radim) increase padding size
arch/x86/include/uapi/asm/kvm_para.h +9 -0
@@ -50,6 +50,15 @@__u32 pad[11 ]; }; +#define KVM_CLOCK_PAIRING_WALLCLOCK 0 +struct kvm_clock_offset { +__s64 sec; +__s64 nsec; +__u64 tsc; +__u32 flags; +__u32 pad[9 ]; +}; +#define KVM_STEAL_ALIGNMENT_BITS 5#define KVM_STEAL_VALID_BITS ((-1ULL << (KVM_STEAL_ALIGNMENT_BITS + 1)))#define KVM_STEAL_RESERVED_MASK (((1 << KVM_STEAL_ALIGNMENT_BITS) - 1 ) << 1)
Documentation/virtual/kvm/hypercalls.txt +33 -0
@@ -81,3 +81,36 @@ same guest can wakeup the sleeping vcpu by issuing KVM_HC_KICK_CPU hypercall, specifying APIC ID (a1) of the vcpu to be woken up. An additional argument (a0) is used in the hypercall for future use. + + +6. KVM_HC_CLOCK_PAIRING +------------------------ +Architecture: x86 +Status: active +Purpose: Hypercall used to synchronize host and guest clocks. +Usage: + +a0: guest physical address where host copies +"struct kvm_clock_offset" structure. + +a1: clock_type, ATM only KVM_CLOCK_PAIRING_WALLCLOCK (0) +is supported (hosts CLOCK_REALTIME clock). + + struct kvm_clock_offset { + __s64 sec; + __s64 nsec; + __u64 tsc; + __u32 flags; + __u32 pad[9]; + }; + + Where: + * sec: seconds from clock_type clock. + * nsec: nanoseconds from clock_type clock. + * tsc: TSC value used to calculate sec/nsec pair + (this hypercall only works when host uses TSC clocksource). + * flags: flags, unused (0) at the moment. + +Returns KVM_EOPNOTSUPP if the host does not use TSC clocksource, +or if clock type is different than KVM_CLOCK_PAIRING_WALLCLOCK. +
arch/x86/kvm/x86.c +41 -0
53 lines not on this page · raw message
include/uapi/linux/kvm_para.h +3 -0
@@ -14,6 +14,8 @@#define KVM_EFAULT EFAULT#define KVM_E2BIG E2BIG#define KVM_EPERM EPERM +#define KVM_EOPNOTSUPP EOPNOTSUPP +#define KVM_ENOMEM ENOMEM#define KVM_HC_VAPIC_POLL_IRQ 1#define KVM_HC_MMU_OP 2
@@ -23,6 +25,7 @@#define KVM_HC_MIPS_GET_CLOCK_FREQ 6#define KVM_HC_MIPS_EXIT_VM 7#define KVM_HC_MIPS_CONSOLE_OUTPUT 8 +#define KVM_HC_CLOCK_PAIRING 9/* * hypercalls use architecture specific
PATCH 3/3 PTP: add kvm PTP driver
In reply to Marcelo TosattiAdd a driver with gettime method returning hosts realtime clock. This allows Chrony to synchronize host and guest clocks with high precision (see results below).
chronyc> sources
MS Name/IP address Stratum Poll Reach LastRx Last sample
===============================================================================
#* PHC0 0 3 377 6 +4ns[ +4ns] +/- 3ns
To configure Chronyd to use PHC refclock, add the
following line to its configuration file:
refclock PHC /dev/ptpX poll 3 dpoll -2 offset 0
Where /dev/ptpX is the kvmclock PTP clock.
--- drivers/ptp/Kconfig | 12 +++ drivers/ptp/Makefile | 1 drivers/ptp/ptp_kvm.c | 179 ++++++++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 192 insertions(+)
v2: check for kvmclock (Radim)
initialize global variables before device registration (Radim)
drivers/ptp/Kconfig +12 -0
@@ -90,4 +90,16 @@ To compile this driver as a module, choose M here: the module will be called ptp_pch. +config PTP_1588_CLOCK_KVM + tristate "KVM virtual PTP clock" + depends on PTP_1588_CLOCK + depends on KVM_GUEST + default y + help + This driver adds support for using kvm infrastructure as a PTP + clock. This clock is only useful if you are using KVM guests. + + To compile this driver as a module, choose M here: the module + will be called ptp_kvm. + endmenu
drivers/ptp/ptp_kvm.c new file +179 -0
179 lines not on this page · raw message
drivers/ptp/Makefile +1 -0
@@ -6,3 +6,4 @@ obj-$(CONFIG_PTP_1588_CLOCK) += ptp.o obj-$(CONFIG_PTP_1588_CLOCK_IXP46X) += ptp_ixp46x.o obj-$(CONFIG_PTP_1588_CLOCK_PCH) += ptp_pch.o +obj-$(CONFIG_PTP_1588_CLOCK_KVM) += ptp_kvm.o