From: Quan Xu <quan.xu0@gmail.com>
To: pbonzini@redhat.com, rkrcmar@redhat.com
Cc: yang.zhang.wz@gmail.com, kvm@vger.kernel.org,
linux-kernel@vger.kernel.org, Ben Luo <bn0418@gmail.com>,
Quan Xu <quan.xu0@gmail.com>
Subject: [PATCH RFC 7/7] kvm: guest: reprogram guest timer
Date: Fri, 8 Dec 2017 16:39:50 +0800 [thread overview]
Message-ID: <1512722390-3654-8-git-send-email-quan.xu0@gmail.com> (raw)
In-Reply-To: <1512722390-3654-1-git-send-email-quan.xu0@gmail.com>
From: Ben Luo <bn0418@gmail.com>
In general, KVM guest programs tsc-deadline timestamp to
MSR_IA32_TSC_DEADLINE MSR.
When pvtimer is enabled, we introduce a new mechanism to
reprogram KVM guest timer. A periodically working kthread
scans share page and synchronize timer setting for guest
on a dedicated CPU. The next time event of the periodically
working kthread is a threshold to decide whether to program
tsc-deadline timestamp to MSR_IA32_TSC_DEADLINE MSR, or to
share page.
Signed-off-by: Yang Zhang <yang.zhang.wz@gmail.com>
Signed-off-by: Quan Xu <quan.xu0@gmail.com>
Signed-off-by: Ben Luo <bn0418@gmail.com>
---
arch/x86/include/asm/kvm_para.h | 9 +++++++++
arch/x86/kernel/apic/apic.c | 9 ++++++---
arch/x86/kernel/kvm.c | 38 ++++++++++++++++++++++++++++++++++++++
3 files changed, 53 insertions(+), 3 deletions(-)
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index c373e44..109e706 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -5,6 +5,7 @@
#include <asm/processor.h>
#include <asm/alternative.h>
#include <uapi/asm/kvm_para.h>
+#include <linux/hrtimer.h>
extern void kvmclock_init(void);
extern int kvm_register_clock(char *txt);
@@ -92,6 +93,8 @@ static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
void kvm_async_pf_task_wait(u32 token, int interrupt_kernel);
void kvm_async_pf_task_wake(u32 token);
u32 kvm_read_and_reset_pf_reason(void);
+int kvm_pv_timer_next_event(unsigned long tsc,
+ struct clock_event_device *evt);
extern void kvm_disable_steal_time(void);
#ifdef CONFIG_PARAVIRT_SPINLOCKS
@@ -126,6 +129,12 @@ static inline void kvm_disable_steal_time(void)
{
return;
}
+
+static inline int kvm_pv_timer_next_event(unsigned long tsc,
+ struct clock_event_device *evt)
+{
+ return 0;
+}
#endif
#endif /* _ASM_X86_KVM_PARA_H */
diff --git a/arch/x86/kernel/apic/apic.c b/arch/x86/kernel/apic/apic.c
index ff89177..286c1b3 100644
--- a/arch/x86/kernel/apic/apic.c
+++ b/arch/x86/kernel/apic/apic.c
@@ -471,10 +471,13 @@ static int lapic_next_event(unsigned long delta,
static int lapic_next_deadline(unsigned long delta,
struct clock_event_device *evt)
{
- u64 tsc;
+ u64 tsc = rdtsc() + (((u64) delta) * TSC_DIVISOR);
- tsc = rdtsc();
- wrmsrl(MSR_IA32_TSC_DEADLINE, tsc + (((u64) delta) * TSC_DIVISOR));
+ /* TODO: undisciplined function call */
+ if (kvm_pv_timer_next_event(tsc, evt))
+ return 0;
+
+ wrmsrl(MSR_IA32_TSC_DEADLINE, tsc);
return 0;
}
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index 8bb9594..ec7aff1 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -328,6 +328,35 @@ static notrace void kvm_guest_apic_eoi_write(u32 reg, u32 val)
apic->native_eoi_write(APIC_EOI, APIC_EOI_ACK);
}
+static DEFINE_PER_CPU(int, pvtimer_enabled);
+static DEFINE_PER_CPU(struct pvtimer_vcpu_event_info,
+ pvtimer_shared_buf) = {0};
+#define PVTIMER_PADDING 25000
+int kvm_pv_timer_next_event(unsigned long tsc,
+ struct clock_event_device *evt)
+{
+ struct pvtimer_vcpu_event_info *src;
+ u64 now;
+
+ if (!this_cpu_read(pvtimer_enabled))
+ return false;
+
+ src = this_cpu_ptr(&pvtimer_shared_buf);
+ xchg((u64 *)&src->expire_tsc, tsc);
+
+ barrier();
+
+ if (tsc < src->next_sync_tsc)
+ return false;
+
+ rdtscll(now);
+ if (tsc < now || tsc - now < PVTIMER_PADDING)
+ return false;
+
+ return true;
+}
+EXPORT_SYMBOL_GPL(kvm_pv_timer_next_event);
+
static void kvm_guest_cpu_init(void)
{
if (!kvm_para_available())
@@ -362,6 +391,15 @@ static void kvm_guest_cpu_init(void)
if (has_steal_clock)
kvm_register_steal_time();
+
+ if (kvm_para_has_feature(KVM_FEATURE_PV_TIMER)) {
+ unsigned long data;
+
+ data = slow_virt_to_phys(this_cpu_ptr(&pvtimer_shared_buf))
+ | KVM_MSR_ENABLED;
+ wrmsrl(MSR_KVM_PV_TIMER_EN, data);
+ this_cpu_write(pvtimer_enabled, 1);
+ }
}
static void kvm_pv_disable_apf(void)
--
1.7.1
next prev parent reply other threads:[~2017-12-08 8:41 UTC|newest]
Thread overview: 16+ messages / expand[flat|nested] mbox.gz Atom feed top
2017-12-08 8:39 [PATCH RFC 0/7] kvm pvtimer Quan Xu
2017-12-08 8:39 ` [PATCH RFC 1/7] kvm: x86: emulate MSR_KVM_PV_TIMER_EN MSR Quan Xu
2017-12-08 8:39 ` [PATCH RFC 2/7] kvm: x86: add a function to exchange value Quan Xu
2017-12-08 8:39 ` [PATCH RFC 3/7] KVM: timer: synchronize tsc-deadline timestamp for guest Quan Xu
2017-12-08 15:06 ` Konrad Rzeszutek Wilk
2017-12-14 1:54 ` Quan Xu
2017-12-08 8:39 ` [PATCH RFC 4/7] KVM: timer: program timer to a dedicated CPU Quan Xu
2017-12-08 8:39 ` [PATCH RFC 5/7] KVM: timer: ignore timer migration if pvtimer is enabled Quan Xu
2017-12-08 8:39 ` [PATCH RFC 6/7] Doc/KVM: introduce a new cpuid bit for kvm pvtimer Quan Xu
2017-12-08 8:39 ` Quan Xu [this message]
2017-12-08 15:10 ` [PATCH RFC 0/7] " Konrad Rzeszutek Wilk
[not found] ` <CAFv8KnF1Re7Zn2LVvqh=Sr8MmaWJJwZBB1i5ws03GvPVKXRjzA@mail.gmail.com>
2017-12-13 16:28 ` Konrad Rzeszutek Wilk
2017-12-14 2:32 ` Quan Xu
2017-12-14 11:56 ` Paolo Bonzini
2017-12-14 12:06 ` Quan Xu
2017-12-14 13:00 ` Paolo Bonzini
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=1512722390-3654-8-git-send-email-quan.xu0@gmail.com \
--to=quan.xu0@gmail.com \
--cc=bn0418@gmail.com \
--cc=kvm@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=pbonzini@redhat.com \
--cc=rkrcmar@redhat.com \
--cc=yang.zhang.wz@gmail.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®