From: Glauber de Oliveira Costa <gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
To: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Cc: jeremy-TSDbQ3PG+2Y@public.gmane.org,
avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org,
Glauber de Oliveira Costa
<gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Subject: [PATCH 2/3] [PATCH] kvmclock - the host part.
Date: Fri, 11 Jan 2008 11:10:55 -0200 [thread overview]
Message-ID: <12000570802212-git-send-email-gcosta@redhat.com> (raw)
In-Reply-To: <12000570732755-git-send-email-gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
This is the host part of kvm clocksource implementation. As it does
not include clockevents, it is a fairly simple implementation. We
only have to register a per-vcpu area, and start writting to it periodically.
The area is binary compatible with xen, as we use the same shadow_info structure.
Signed-off-by: Glauber de Oliveira Costa <gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
---
arch/x86/kvm/x86.c | 64 +++++++++++++++++++++++++++++++++++++++++++-
include/asm-x86/kvm_host.h | 5 +++
include/asm-x86/kvm_para.h | 5 +++
include/linux/kvm.h | 1 +
4 files changed, 74 insertions(+), 1 deletions(-)
diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c
index 8a90403..d3fd920 100644
--- a/arch/x86/kvm/x86.c
+++ b/arch/x86/kvm/x86.c
@@ -19,6 +19,7 @@
#include "irq.h"
#include "mmu.h"
+#include <linux/clocksource.h>
#include <linux/kvm.h>
#include <linux/fs.h>
#include <linux/vmalloc.h>
@@ -412,7 +413,7 @@ static u32 msrs_to_save[] = {
#ifdef CONFIG_X86_64
MSR_CSTAR, MSR_KERNEL_GS_BASE, MSR_SYSCALL_MASK, MSR_LSTAR,
#endif
- MSR_IA32_TIME_STAMP_COUNTER,
+ MSR_IA32_TIME_STAMP_COUNTER, MSR_PARAVIRT_CLOCK,
};
static unsigned num_msrs_to_save;
@@ -467,6 +468,50 @@ static int do_set_msr(struct kvm_vcpu *vcpu, unsigned index, u64 *data)
return kvm_set_msr(vcpu, index, *data);
}
+#define WC_OFFSET offsetof(struct shared_info, wc_version)
+
+static void kvm_write_guest_time(struct kvm_vcpu *v)
+{
+ struct timespec ts, wc_ts;
+ int wc_args[3]; /* version, wc_sec, wc_nsec */
+ unsigned long flags;
+ struct kvm_vcpu_arch *vcpu = &v->arch;
+
+ if (!vcpu->shared_info)
+ return;
+
+ /* Make the update of both version numbers visible to guest */
+ wc_args[0] = ++vcpu->wc_version;
+ kvm_write_guest(v->kvm, vcpu->shared_info + WC_OFFSET, wc_args,
+ sizeof(wc_args));
+ vcpu->hv_clock.version++;
+ kvm_write_guest(v->kvm, vcpu->clock_addr, &vcpu->hv_clock,
+ sizeof(vcpu->hv_clock));
+
+ /* Keep irq disabled to prevent changes to the clock */
+ local_irq_save(flags);
+ kvm_get_msr(v, MSR_IA32_TIME_STAMP_COUNTER,
+ &vcpu->hv_clock.tsc_timestamp);
+ wc_ts = current_kernel_time();
+ ktime_get_ts(&ts);
+ local_irq_restore(flags);
+
+ /* With all the info we got, fill in the values */
+ wc_args[1] = wc_ts.tv_sec;
+ wc_args[2] = wc_ts.tv_nsec;
+ wc_args[0] = ++vcpu->wc_version;
+
+ vcpu->hv_clock.system_time = ts.tv_nsec +
+ (NSEC_PER_SEC * (u64)ts.tv_sec);
+ vcpu->hv_clock.version++;
+
+ /* And finally, let the guest see them */
+ kvm_write_guest(v->kvm, vcpu->shared_info + WC_OFFSET, wc_args,
+ sizeof(wc_args));
+ kvm_write_guest(v->kvm, vcpu->clock_addr, &vcpu->hv_clock,
+ sizeof(vcpu->hv_clock));
+}
+
int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
{
@@ -494,6 +539,18 @@ int kvm_set_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 data)
case MSR_IA32_MISC_ENABLE:
vcpu->arch.ia32_misc_enable_msr = data;
break;
+ case MSR_PARAVIRT_CLOCK: {
+ vcpu->arch.shared_info = data;
+
+ vcpu->arch.clock_addr = data + offsetof(struct vcpu_info, time)
+ + sizeof(struct vcpu_info) * vcpu->vcpu_id;
+
+ vcpu->arch.hv_clock.tsc_to_system_mul =
+ clocksource_khz2mult(tsc_khz, 22);
+ vcpu->arch.hv_clock.tsc_shift = 22;
+ kvm_write_guest_time(vcpu);
+ break;
+ }
default:
pr_unimpl(vcpu, "unhandled wrmsr: 0x%x data %llx\n", msr, data);
return 1;
@@ -553,6 +610,9 @@ int kvm_get_msr_common(struct kvm_vcpu *vcpu, u32 msr, u64 *pdata)
data = vcpu->arch.shadow_efer;
break;
#endif
+ case MSR_PARAVIRT_CLOCK:
+ data = vcpu->arch.shared_info;
+ break;
default:
pr_unimpl(vcpu, "unhandled rdmsr: 0x%x\n", msr);
return 1;
@@ -680,6 +740,7 @@ int kvm_dev_ioctl_check_extension(long ext)
case KVM_CAP_USER_MEMORY:
case KVM_CAP_SET_TSS_ADDR:
case KVM_CAP_EXT_CPUID:
+ case KVM_CAP_CLOCKSOURCE:
r = 1;
break;
case KVM_CAP_VAPIC:
@@ -737,6 +798,7 @@ out:
void kvm_arch_vcpu_load(struct kvm_vcpu *vcpu, int cpu)
{
kvm_x86_ops->vcpu_load(vcpu, cpu);
+ kvm_write_guest_time(vcpu);
}
void kvm_arch_vcpu_put(struct kvm_vcpu *vcpu)
diff --git a/include/asm-x86/kvm_host.h b/include/asm-x86/kvm_host.h
index d6db0de..bbc4b51 100644
--- a/include/asm-x86/kvm_host.h
+++ b/include/asm-x86/kvm_host.h
@@ -261,6 +261,11 @@ struct kvm_vcpu_arch {
/* emulate context */
struct x86_emulate_ctxt emulate_ctxt;
+
+ struct vcpu_time_info hv_clock;
+ gpa_t shared_info;
+ gpa_t clock_addr; /* so we avoid computing it every time */
+ int wc_version;
};
struct kvm_mem_alias {
diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h
index c6f3fd8..abe412a 100644
--- a/include/asm-x86/kvm_para.h
+++ b/include/asm-x86/kvm_para.h
@@ -1,5 +1,6 @@
#ifndef __X86_KVM_PARA_H
#define __X86_KVM_PARA_H
+#include <xen/interface/xen.h>
/* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It
* should be used to determine that a VM is running under KVM.
@@ -10,9 +11,13 @@
* paravirtualization, the appropriate feature bit should be checked.
*/
#define KVM_CPUID_FEATURES 0x40000001
+#define KVM_FEATURE_CLOCKSOURCE 0
+#define MSR_PARAVIRT_CLOCK 0x11
#ifdef __KERNEL__
#include <asm/processor.h>
+extern void kvmclock_init(void);
+
/* This instruction is vmcall. On non-VT architectures, it will generate a
* trap that we will then rewrite to the appropriate instruction.
diff --git a/include/linux/kvm.h b/include/linux/kvm.h
index 4de4fd2..78ce53f 100644
--- a/include/linux/kvm.h
+++ b/include/linux/kvm.h
@@ -232,6 +232,7 @@ struct kvm_vapic_addr {
#define KVM_CAP_SET_TSS_ADDR 4
#define KVM_CAP_EXT_CPUID 5
#define KVM_CAP_VAPIC 6
+#define KVM_CAP_CLOCKSOURCE 7
/*
* ioctls for VM fds
--
1.5.0.6
-------------------------------------------------------------------------
Check out the new SourceForge.net Marketplace.
It's the best place to buy or sell services for
just about anything Open Source.
http://ad.doubleclick.net/clk;164216239;13503038;w?http://sf.net/marketplace
next prev parent reply other threads:[~2008-01-11 13:10 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-01-11 13:10 [PATCH 0/3] KVM clock, new iteration Glauber de Oliveira Costa
[not found] ` <12000570563874-git-send-email-gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-01-11 13:10 ` [PATCH 1/3] put kvm_para.h include outside __KERNEL__ Glauber de Oliveira Costa
[not found] ` <12000570732755-git-send-email-gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-01-11 13:10 ` Glauber de Oliveira Costa [this message]
[not found] ` <12000570802212-git-send-email-gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-01-11 13:10 ` [PATCH 3/3] [PATCH] kvmclock implementation, the guest part Glauber de Oliveira Costa
[not found] ` <12000570863750-git-send-email-gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-01-11 13:23 ` Gerd Hoffmann
[not found] ` <47876DB6.3020105-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2008-01-11 13:32 ` Glauber de Oliveira Costa
2008-01-11 15:47 ` [PATCH 2/3] [PATCH] kvmclock - the host part Anthony Liguori
[not found] ` <47878F8A.4010506-rdkfGonbjUSkNkDKm+mE6A@public.gmane.org>
2008-01-12 20:49 ` Avi Kivity
[not found] ` <478927DA.3000800-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
2008-01-12 22:51 ` Anthony Liguori
2008-01-12 20:38 ` Avi Kivity
2008-01-11 15:09 ` [PATCH 1/3] put kvm_para.h include outside __KERNEL__ Amit Shah
2008-01-11 15:49 ` [PATCH 0/3] KVM clock, new iteration Anthony Liguori
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=12000570802212-git-send-email-gcosta@redhat.com \
--to=gcosta-h+wxahxf7alqt0dzr+alfa@public.gmane.org \
--cc=avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org \
--cc=jeremy-TSDbQ3PG+2Y@public.gmane.org \
--cc=kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org \
/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.