[PATCH] kvm: Fix kvmclock initialization on !CONFIG_KVM_GUEST

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

 



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 <hirofumi@xxxxxxxxxxxxxxxxxx>
---

 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 <hirofumi@xxxxxxxxxxxxxxxxxx>
--
To unsubscribe from this list: send the line "unsubscribe kvm" in
the body of a message to majordomo@xxxxxxxxxxxxxxx
More majordomo info at  http://vger.kernel.org/majordomo-info.html


[Index of Archives]     [KVM ARM]     [KVM ia64]     [KVM ppc]     [Virtualization Tools]     [Spice Development]     [Libvirt]     [Libvirt Users]     [Linux USB Devel]     [Linux Audio Users]     [Yosemite Questions]     [Linux Kernel]     [Linux SCSI]     [XFree86]
  Powered by Linux