x86: KVM guest: add basic paravirt support
authorMarcelo Tosatti <mtosatti@redhat.com>
Fri, 22 Feb 2008 17:21:36 +0000 (12:21 -0500)
committerAvi Kivity <avi@qumranet.com>
Sun, 27 Apr 2008 09:00:25 +0000 (12:00 +0300)
Add basic KVM paravirt support. Avoid vm-exits on IO delays.

Signed-off-by: Marcelo Tosatti <mtosatti@redhat.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
arch/x86/Kconfig
arch/x86/kernel/Makefile
arch/x86/kernel/kvm.c [new file with mode: 0644]
arch/x86/kernel/setup_32.c
arch/x86/kernel/setup_64.c
include/linux/kvm_para.h

index 40cedc255eda8c096529e0f649dc17e874edf970..e5790fe9e330acf69482fd7e988c47b9075295b5 100644 (file)
@@ -384,6 +384,14 @@ config KVM_CLOCK
          provides the guest with timing infrastructure such as time of day, and
          system time
 
+config KVM_GUEST
+       bool "KVM Guest support"
+       select PARAVIRT
+       depends on !(X86_VISWS || X86_VOYAGER)
+       help
+        This option enables various optimizations for running under the KVM
+        hypervisor.
+
 source "arch/x86/lguest/Kconfig"
 
 config PARAVIRT
index 483047a33024578c7f0d5b2c6bc511ca49955d2c..fa19c3819540d0f823bd675f61457bab2fc31b30 100644 (file)
@@ -80,6 +80,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST)       += test_rodata.o
 obj-$(CONFIG_DEBUG_NX_TEST)    += test_nx.o
 
 obj-$(CONFIG_VMI)              += vmi_32.o vmiclock_32.o
+obj-$(CONFIG_KVM_GUEST)                += kvm.o
 obj-$(CONFIG_KVM_CLOCK)                += kvmclock.o
 obj-$(CONFIG_PARAVIRT)         += paravirt.o paravirt_patch_$(BITS).o
 
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c
new file mode 100644 (file)
index 0000000..a8e36da
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * KVM paravirt_ops implementation
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+ *
+ * Copyright (C) 2007, Red Hat, Inc., Ingo Molnar <mingo@redhat.com>
+ * Copyright IBM Corporation, 2007
+ *   Authors: Anthony Liguori <aliguori@us.ibm.com>
+ */
+
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/kvm_para.h>
+#include <linux/cpu.h>
+#include <linux/mm.h>
+
+/*
+ * No need for any "IO delay" on KVM
+ */
+static void kvm_io_delay(void)
+{
+}
+
+static void paravirt_ops_setup(void)
+{
+       pv_info.name = "KVM";
+       pv_info.paravirt_enabled = 1;
+
+       if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY))
+               pv_cpu_ops.io_delay = kvm_io_delay;
+
+}
+
+void __init kvm_guest_init(void)
+{
+       if (!kvm_para_available())
+               return;
+
+       paravirt_ops_setup();
+}
index 5a849ddd09ee95c409d217a9d05813d4d01efe44..2283422af7946fef30a86189dddb0a7a12fe3fc1 100644 (file)
@@ -832,6 +832,7 @@ void __init setup_arch(char **cmdline_p)
         */
        vmi_init();
 #endif
+       kvm_guest_init();
 
        /*
         * NOTE: before this point _nobody_ is allowed to allocate
index 8a9213c023effbabacda48c076650fec1cf38684..a94fb959a87a3f35c0eec00bdf696b195b378d30 100644 (file)
@@ -493,6 +493,8 @@ void __init setup_arch(char **cmdline_p)
        init_apic_mappings();
        ioapic_init_mappings();
 
+       kvm_guest_init();
+
        /*
         * We trust e820 completely. No explicit ROM probing in memory.
         */
index 5497aac0d2f829d4efe3df98f8c34496d947243f..9c462c91a6b12f36574691407afc33dc60c209e5 100644 (file)
 #include <asm/kvm_para.h>
 
 #ifdef __KERNEL__
+#ifdef CONFIG_KVM_GUEST
+void __init kvm_guest_init(void);
+#else
+#define kvm_guest_init() do { } while (0)
+#endif
+
 static inline int kvm_para_has_feature(unsigned int feature)
 {
        if (kvm_arch_para_features() & (1UL << feature))