If !CONFIG_KVM_GUEST, kvm_smp_prepare_boot_cpu() is not defined. So,
kvm_register_clock("primary cpu clock") in kvm_smp_prepare_boot_cpu()
is not called.

The detail of problem is hv_clock percpu usage. hv_clock is percpu
variable, but kvmclock_init() is called _before_ initializing percpu
area, and doesn't update address after initialized percpu area.

So, host kvm modify the memory area _before_ initializing percpu. This
became the cause of strange memory corruption on guest OS.


This fixes it by adding kvm_smp_prepare_boot_cpu().  [we might be
better to kill the usage before percpu initialization.]

Signed-off-by: OGAWA Hirofumi <[email protected]>
---

 arch/x86/kernel/kvmclock.c |   17 +++++++++++++++++
 1 file changed, 17 insertions(+)

diff -puN arch/x86/kernel/kvmclock.c~kvm-fix-kvmclock-init 
arch/x86/kernel/kvmclock.c
--- tux3fs/arch/x86/kernel/kvmclock.c~kvm-fix-kvmclock-init     2012-08-15 
22:15:22.000000000 +0900
+++ tux3fs-hirofumi/arch/x86/kernel/kvmclock.c  2012-08-15 22:16:14.000000000 
+0900
@@ -145,6 +145,14 @@ static void kvm_restore_sched_clock_stat
        kvm_register_clock("primary cpu clock, resume");
 }
 
+#if defined(CONFIG_SMP) && !defined(CONFIG_KVM_GUEST)
+static void __init kvm_smp_prepare_boot_cpu(void)
+{
+       WARN_ON(kvm_register_clock("primary cpu clock"));
+       native_smp_prepare_boot_cpu();
+}
+#endif
+
 #ifdef CONFIG_X86_LOCAL_APIC
 static void __cpuinit kvm_setup_secondary_clock(void)
 {
@@ -194,6 +202,12 @@ void __init kvmclock_init(void)
        printk(KERN_INFO "kvm-clock: Using msrs %x and %x",
                msr_kvm_system_time, msr_kvm_wall_clock);
 
+       /*
+        * This is temporary register until percpu is initialized.
+        * After percpu was initialized, we register real hv_clock via
+        * kvm_smp_prepare_boot_cpu().
+        * FIXME: it wouldn't be good to use before percpu is initialized.
+        */
        if (kvm_register_clock("boot clock"))
                return;
        pv_time_ops.sched_clock = kvm_clock_read;
@@ -210,6 +224,9 @@ void __init kvmclock_init(void)
 #ifdef CONFIG_KEXEC
        machine_ops.crash_shutdown  = kvm_crash_shutdown;
 #endif
+#if defined(CONFIG_SMP) && !defined(CONFIG_KVM_GUEST)
+       smp_ops.smp_prepare_boot_cpu = kvm_smp_prepare_boot_cpu;
+#endif
        kvm_get_preset_lpj();
        clocksource_register_hz(&kvm_clock, NSEC_PER_SEC);
        pv_info.paravirt_enabled = 1;
_

-- 
OGAWA Hirofumi <[email protected]>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to [email protected]
More majordomo info at  http://vger.kernel.org/majordomo-info.html

Reply via email to