[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH v4 46/47] x86/kvmclock: Plumb in AP-online and BSP-resume to kvmlock, for documentation



Invoke kvmclock_cpu_action() with AP_ONLINE and BSP_RESUME, even though
kvmclock doesn't need to do anything in either case, so that the asymmetry
of kvmclock is a detail buried in kvmclock, and to explicitly document
that doing nothing during those phases is intentional and correct.

For all intents and purposes, no functional change intended.

Signed-off-by: Sean Christopherson <seanjc@xxxxxxxxxx>
---
 arch/x86/include/asm/kvm_para.h |  2 ++
 arch/x86/kernel/kvm.c           | 22 +++++++++++++-------
 arch/x86/kernel/kvmclock.c      | 37 ++++++++++++++++++++++++++-------
 3 files changed, 45 insertions(+), 16 deletions(-)

diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h
index 08686ff19caa..763ed017738a 100644
--- a/arch/x86/include/asm/kvm_para.h
+++ b/arch/x86/include/asm/kvm_para.h
@@ -120,6 +120,8 @@ static inline long kvm_sev_hypercall3(unsigned int nr, 
unsigned long p1,
 #ifdef CONFIG_KVM_GUEST
 enum kvm_guest_cpu_action {
        KVM_GUEST_BSP_SUSPEND,
+       KVM_GUEST_BSP_RESUME,
+       KVM_GUEST_AP_ONLINE,
        KVM_GUEST_AP_OFFLINE,
        KVM_GUEST_SHUTDOWN,
 };
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
index fd1c417b4f9b..2ed4bf13e3ed 100644
--- a/arch/x86/kernel/kvm.c
+++ b/arch/x86/kernel/kvm.c
@@ -474,18 +474,24 @@ static void kvm_guest_cpu_offline(enum 
kvm_guest_cpu_action action)
        kvmclock_cpu_action(action);
 }
 
+static void __kvm_cpu_online(unsigned int cpu, enum kvm_guest_cpu_action 
action)
+{
+       unsigned long flags;
+
+       local_irq_save(flags);
+       kvmclock_cpu_action(action);
+       kvm_guest_cpu_init();
+       local_irq_restore(flags);
+}
+
+#ifdef CONFIG_SMP
+
 static int kvm_cpu_online(unsigned int cpu)
 {
-       unsigned long flags;
-
-       local_irq_save(flags);
-       kvm_guest_cpu_init();
-       local_irq_restore(flags);
+       __kvm_cpu_online(cpu, KVM_GUEST_AP_ONLINE);
        return 0;
 }
 
-#ifdef CONFIG_SMP
-
 static DEFINE_PER_CPU(cpumask_var_t, __pv_cpu_mask);
 
 static bool pv_tlb_flush_supported(void)
@@ -750,7 +756,7 @@ static int kvm_suspend(void *data)
 
 static void kvm_resume(void *data)
 {
-       kvm_cpu_online(raw_smp_processor_id());
+       __kvm_cpu_online(raw_smp_processor_id(), KVM_GUEST_BSP_RESUME);
 
 #ifdef CONFIG_ARCH_CPUIDLE_HALTPOLL
        if (kvm_para_has_feature(KVM_FEATURE_POLL_CONTROL) && has_guest_poll)
diff --git a/arch/x86/kernel/kvmclock.c b/arch/x86/kernel/kvmclock.c
index cd65ad328637..d122912b8856 100644
--- a/arch/x86/kernel/kvmclock.c
+++ b/arch/x86/kernel/kvmclock.c
@@ -129,7 +129,7 @@ static void kvm_save_sched_clock_state(void)
 #ifdef CONFIG_SMP
 static void kvm_setup_secondary_clock(void)
 {
-       kvm_register_clock("secondary cpu clock");
+       kvm_register_clock("secondary cpu, startup");
 }
 #endif
 
@@ -153,13 +153,34 @@ static void kvmclock_resume(struct clocksource *cs)
 
 void kvmclock_cpu_action(enum kvm_guest_cpu_action action)
 {
-       /*
-        * Don't disable kvmclock on the BSP during suspend.  If kvmclock is
-        * being used for sched_clock, then it needs to be kept alive until the
-        * last minute, and restored as quickly as possible after resume.
-        */
-       if (action != KVM_GUEST_BSP_SUSPEND)
+       switch (action) {
+               /*
+                * The BSP's clock is managed via clocksource suspend/resume,
+                * to ensure it's enabled/disabled when timekeeping needs it
+                * to be, e.g. before reading wallclock (which uses kvmclock).
+                */
+       case KVM_GUEST_BSP_SUSPEND:
+       case KVM_GUEST_BSP_RESUME:
+               break;
+       case KVM_GUEST_AP_ONLINE:
+               /*
+                * Secondary CPUs use a dedicated hook to enable kvmclock early
+                * during bringup, there's nothing to be done during CPU online
+                * (which runs at CPUHP_AP_ONLINE_DYN).  When kvmclock is being
+                * used as sched_clock, kvmclock must be enabled *very* early,
+                * and even when kvmclock is "only" being used for the main
+                * clocksource, it still needs to be enabled long before the
+                * dynamic CPUHP calls are made.
+                */
+               break;
+       case KVM_GUEST_AP_OFFLINE:
+       case KVM_GUEST_SHUTDOWN:
                kvmclock_disable();
+               break;
+       default:
+               WARN_ON_ONCE(1);
+               break;
+       }
 }
 
 /*
@@ -360,7 +381,7 @@ void __init kvmclock_init(bool prefer_tsc)
                msr_kvm_system_time, msr_kvm_wall_clock);
 
        this_cpu_write(hv_clock_per_cpu, &hv_clock_boot[0]);
-       kvm_register_clock("primary cpu clock");
+       kvm_register_clock("primary cpu, online");
        pvclock_set_pvti_cpu0_va(hv_clock_boot);
 
        if (kvm_para_has_feature(KVM_FEATURE_CLOCKSOURCE_STABLE_BIT)) {
-- 
2.54.0.823.g6e5bcc1fc9-goog




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.