From: Gerd Hoffmann <kraxel@redhat.com>
To: Avi Kivity <avi@qumranet.com>
Cc: kvm-devel <kvm-devel@lists.sourceforge.net>,
Jeremy Fitzhardinge <jeremy@goop.org>,
Glauber de Oliveira Costa <gcosta@redhat.com>
Subject: Re: pv clock: kvm is incompatible with xen :-(
Date: Fri, 11 Apr 2008 17:01:14 +0200 [thread overview]
Message-ID: <47FF7D3A.5000602@redhat.com> (raw)
In-Reply-To: <47FF6B43.1070305@redhat.com>
[-- Attachment #1: Type: text/plain, Size: 992 bytes --]
Gerd Hoffmann wrote:
> Wall clock is off a few hours though. Oops.
>
> I think the way wall clock and system clock work together in xen (Jeremy
> correct me if I'm wrong) is that the wall clock specifies the point in
> time where the system clock started going. As kvm fills in host system
> time into the guest system time fields the guest wall clock fields
> should be filled with the host boot time timestamp I'd say.
Following up myself with a quick&dirty patch to tackle this issue too.
This one calculates the boot time. That should be solveable better,
include/linux/time.h lists two functions which sound promising:
extern void getboottime(struct timespec *ts);
extern void monotonic_to_bootbased(struct timespec *ts);
Neither of them is available to modules though, so I can't test without
rebooting my laptop ...
monotonic_to_bootbased() sounds like we would get hosts ntp adjustments
in the guests for free.
cheers,
Gerd
--
http://kraxel.fedorapeople.org/xenner/
[-- Attachment #2: kvmclock-2.diff --]
[-- Type: text/x-patch, Size: 2348 bytes --]
diff -up kvm-65/kernel/x86.c.fix kvm-65/kernel/x86.c
--- kvm-65/kernel/x86.c.fix 2008-04-06 21:23:07.000000000 +0200
+++ kvm-65/kernel/x86.c 2008-04-11 16:17:23.000000000 +0200
@@ -490,7 +490,7 @@ static void kvm_write_wall_clock(struct
{
static int version;
struct kvm_wall_clock wc;
- struct timespec wc_ts;
+ struct timespec now,sys,boot;
if (!wall_clock)
return;
@@ -499,9 +499,11 @@ static void kvm_write_wall_clock(struct
kvm_write_guest(kvm, wall_clock, &version, sizeof(version));
- wc_ts = current_kernel_time();
- wc.wc_sec = wc_ts.tv_sec;
- wc.wc_nsec = wc_ts.tv_nsec;
+ now = current_kernel_time();
+ ktime_get_ts(&sys);
+ boot = ns_to_timespec(timespec_to_ns(&now) - timespec_to_ns(&sys));
+ wc.wc_sec = boot.tv_sec;
+ wc.wc_nsec = boot.tv_nsec;
wc.wc_version = version;
kvm_write_guest(kvm, wall_clock, &wc, sizeof(wc));
@@ -548,6 +550,44 @@ static void kvm_write_guest_time(struct
mark_page_dirty(v->kvm, vcpu->time >> PAGE_SHIFT);
}
+static uint32_t div_frac(uint32_t dividend, uint32_t divisor)
+{
+ uint32_t quotient, remainder;
+
+ __asm__ ( "divl %4"
+ : "=a" (quotient), "=d" (remainder)
+ : "0" (0), "1" (dividend), "r" (divisor) );
+ return quotient;
+}
+
+static void kvm_set_time_scale(uint32_t tsc_khz, struct kvm_vcpu_time_info *hv_clock)
+{
+ uint64_t nsecs = 1000000000LL;
+ int32_t shift = 0;
+ uint64_t tps64;
+ uint32_t tps32;
+
+ tps64 = tsc_khz * 1000LL;
+ while (tps64 > nsecs*2) {
+ tps64 >>= 1;
+ shift--;
+ }
+
+ tps32 = (uint32_t)tps64;
+ while (tps32 <= (uint32_t)nsecs) {
+ tps32 <<= 1;
+ shift++;
+ }
+
+ hv_clock->tsc_shift = shift;
+ hv_clock->tsc_to_system_mul = div_frac(nsecs, tps32);
+
+#if 0
+ printk(KERN_DEBUG "%s: tsc_khz %u, tsc_shift %d, tsc_mul %u\n",
+ __FUNCTION__, tsc_khz, hv_clock->tsc_shift,
+ hv_clock->tsc_to_system_mul);
+#endif
+}
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
@@ -596,9 +636,7 @@ int kvm_set_msr_common(struct kvm_vcpu *
/* ...but clean it before doing the actual write */
vcpu->arch.time_offset = data & ~(PAGE_MASK | 1);
- vcpu->arch.hv_clock.tsc_to_system_mul =
- clocksource_khz2mult(kvm_tsc_khz, 22);
- vcpu->arch.hv_clock.tsc_shift = 22;
+ kvm_set_time_scale(kvm_tsc_khz, &vcpu->arch.hv_clock);
down_read(¤t->mm->mmap_sem);
vcpu->arch.time_page =
[-- Attachment #3: Type: text/plain, Size: 320 bytes --]
-------------------------------------------------------------------------
This SF.net email is sponsored by the 2008 JavaOne(SM) Conference
Don't miss this year's exciting event. There's still time to save $100.
Use priority code J8TL2D2.
http://ad.doubleclick.net/clk;198757673;13503038;p?http://java.sun.com/javaone
[-- Attachment #4: Type: text/plain, Size: 158 bytes --]
_______________________________________________
kvm-devel mailing list
kvm-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/kvm-devel
next prev parent reply other threads:[~2008-04-11 15:01 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-11 7:33 pv clock: kvm is incompatible with xen :-( Gerd Hoffmann
2008-04-11 12:06 ` Avi Kivity
2008-04-11 13:44 ` Gerd Hoffmann
2008-04-11 15:01 ` Gerd Hoffmann [this message]
2008-04-11 19:02 ` Jeremy Fitzhardinge
2008-04-18 14:26 ` Gerd Hoffmann
2008-04-18 22:23 ` Jeremy Fitzhardinge
2008-04-21 7:31 ` Gerd Hoffmann
2008-04-21 11:46 ` Jeremy Fitzhardinge
2008-04-21 12:50 ` Gerd Hoffmann
2008-04-21 13:34 ` Jeremy Fitzhardinge
2008-04-21 14:20 ` Gerd Hoffmann
2008-04-22 17:54 ` Glauber Costa
2008-04-23 6:03 ` Gerd Hoffmann
2008-04-24 12:57 ` Glauber Costa
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=47FF7D3A.5000602@redhat.com \
--to=kraxel@redhat.com \
--cc=avi@qumranet.com \
--cc=gcosta@redhat.com \
--cc=jeremy@goop.org \
--cc=kvm-devel@lists.sourceforge.net \
/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.