All of lore.kernel.org
 help / color / mirror / Atom feed
From: Avi Kivity <avi-atKUWr5tajBWk0Htik3J/w@public.gmane.org>
To: Glauber de Oliveira Costa
	<gcosta-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
Cc: kvm-devel-5NWGOfrQmneRv+LV9MX5uipxlwaOVQ5f@public.gmane.org
Subject: Re: KVM Paravirt clock - take2
Date: Wed, 24 Oct 2007 12:03:13 +0200	[thread overview]
Message-ID: <471F1861.70700@qumranet.com> (raw)
In-Reply-To: <471E7F53.7030407-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>

Glauber de Oliveira Costa wrote:
> -----BEGIN PGP SIGNED MESSAGE-----
> Hash: SHA1
>
> Hi Folks,
>
> Here's an updated version of the kvm paravirt clock infrastructure. Some
> of the issues you all raised were addressed, some were not. This work
> basically focus on general issues / clocksource, so don't expect to see
> much new things here in the clock events area.
>
>   

Me like.

Please separate the guest and host parts; this allows backporting the 
guest part to older kernels.

> +
> +/* This is our clockevents structure. We only support one shot operation */
> +static struct clock_event_device kvm_clockevent = {
> +	.name		= "kvm-timer",
> +	.features	= CLOCK_EVT_FEAT_ONESHOT,
> +	.shift		= 0,
> +	.mult		= 1,
> +	.max_delta_ns	= 0xffffffff,
> +	.min_delta_ns	= 1000000,
>   

Why this particular number?  Doesn't it depend on the host's clocksource?

> @@ -1564,6 +1566,36 @@ int kvm_emulate_halt(struct kvm_vcpu *vcpu)
>  }
>  EXPORT_SYMBOL_GPL(kvm_emulate_halt);
>  
> +static struct kvm_hv_clock hv_clock;
> +
> +static void kvm_write_guest_time(struct kvm_vcpu *vcpu)
> +{
> +	struct kvm *kvm = vcpu->kvm;
> +	struct timespec ts;
> +	void *clock_addr;
> +
> +	if ((!kvm->clock_page) || !(kvm->clock_gpa))
> +		return;
>   

Why two checks?

> +
> +	clock_addr = kmap(kvm->clock_page);
>   

kmap_atomic() is much faster and more akpm-resistant.

> +
> +	/* Updates version to the next odd number, indicating we're writing */
> +	hv_clock.version++;
> +	/* Updating the tsc count is the first thing we do */
> +	kvm_get_msr(vcpu, MSR_IA32_TIME_STAMP_COUNTER, &hv_clock.last_tsc);
> +	ktime_get_ts(&ts);
> +	hv_clock.now_ns = ts.tv_nsec + NSEC_PER_SEC * ts.tv_sec;
> +	hv_clock.wc_sec = get_seconds();
> +	hv_clock.version++;
> +	WARN_ON(hv_clock.version & 1);
>   

smp_wmb()s are missing here.

The guest can trigger the WARN_ON() by being naughty with .version.

> +
> +	memcpy(clock_addr, &hv_clock, sizeof(hv_clock));
> +	mark_page_dirty(kvm, kvm->clock_gpa >> PAGE_SHIFT);
> +	kunmap(kvm->clock_page);
> +
> +	kvm->time_needs_update = 0;
> +}
> +
>  int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
>  {
>  	unsigned long nr, a0, a1, a2, a3, ret;
> @@ -1584,7 +1616,37 @@ int kvm_emulate_hypercall(struct kvm_vcpu *vcpu)
>  		a3 &= 0xFFFFFFFF;
>  	}
>  
> +	ret = 0;
>  	switch (nr) {
> +	case  KVM_HCALL_REGISTER_CLOCK: {
> +		if (!irqchip_in_kernel(vcpu->kvm)) {
> +			ret = -1;
>   

Return a proper KVM error.

> +			break;
> +		}
> +
> +		vcpu->kvm->clock_gpa = a0;
>   

i386 gpas are 64-bit.  Better define it as a gfn (that absolves you of 
checking alignment too).

> +		vcpu->kvm->clock_page = gfn_to_page(vcpu->kvm, a0 >> PAGE_SHIFT);
> +
>   

You're touching shared state here.  Can probably cause problems if the 
guest turns nasty.

>  static inline int kvm_mmu_page_fault(struct kvm_vcpu *vcpu, gva_t gva,
> diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h
> index c6f3fd8..8dec29f 100644
> --- a/include/asm-x86/kvm_para.h
> +++ b/include/asm-x86/kvm_para.h
> @@ -10,9 +10,12 @@
>   * paravirtualization, the appropriate feature bit should be checked.
>   */
>  #define KVM_CPUID_FEATURES	0x40000001
> +#define KVM_FEATURE_CLOCKEVENTS 0
> +#define KVM_FEATURE_CLOCKSOURCE 1
>  
>  #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.
> @@ -29,6 +32,26 @@
>   * noted by the particular hypercall.
>   */
>  
> +#define KVM_HCALL_REGISTER_CLOCK 0
>   

Let's start hypercall numbers at 1 to trap some cases on uninitialized 
data coming that way.

>  	long ret;
> diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h
> index e4db25f..4c2afd0 100644
> --- a/include/linux/kvm_para.h
> +++ b/include/linux/kvm_para.h
> @@ -9,6 +9,10 @@
>   * - kvm_para_available
>   */
>  
> +#define KVM_CPUID_FEATURES	0x40000001
> +#define KVM_FEATURE_CLOCKEVENTS 0
> +#define KVM_FEATURE_CLOCKSOURCE 1
> +
>  /* Return values for hypercalls */
>  #define KVM_ENOSYS		1000
>  

Need to expose the capability to userspace as well via 
KVM_CHECK_EXTENSION so userspace will know to expose it to the guest.

Finally, how about making this per-vcpu?  That solves problems with tscs 
running differently on different cpus, you don't need the wmb()s on the 
host side, is faster for the guest due to less cacheline bouncing, I 
could go on forever.


-- 
error compiling committee.c: too many arguments to function


-------------------------------------------------------------------------
This SF.net email is sponsored by: Splunk Inc.
Still grepping through log files to find problems?  Stop.
Now Search log events and configuration files using AJAX and a browser.
Download your FREE copy of Splunk now >> http://get.splunk.com/

      parent reply	other threads:[~2007-10-24 10:03 UTC|newest]

Thread overview: 2+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2007-10-23 23:10 KVM Paravirt clock - take2 Glauber de Oliveira Costa
     [not found] ` <471E7F53.7030407-H+wXaHxf7aLQT0dZR+AlfA@public.gmane.org>
2007-10-24 10:03   ` Avi Kivity [this message]

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=471F1861.70700@qumranet.com \
    --to=avi-atkuwr5tajbwk0htik3j/w@public.gmane.org \
    --cc=gcosta-H+wXaHxf7aLQT0dZR+AlfA@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.