diff options
author | Marcelo Tosatti <mtosatti@redhat.com> | 2008-02-22 12:21:36 -0500 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-04-27 05:00:25 -0400 |
commit | 0cf1bfd2737f41e59f974a61eab11af206d2042a (patch) | |
tree | 4edd67efa000f4cb94ef834daa21ac07c2016989 | |
parent | a28e4f5a621289fe0d9c8a461b0c256f9e17f3bc (diff) |
x86: KVM guest: add basic paravirt support
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>
-rw-r--r-- | arch/x86/Kconfig | 8 | ||||
-rw-r--r-- | arch/x86/kernel/Makefile | 1 | ||||
-rw-r--r-- | arch/x86/kernel/kvm.c | 52 | ||||
-rw-r--r-- | arch/x86/kernel/setup_32.c | 1 | ||||
-rw-r--r-- | arch/x86/kernel/setup_64.c | 2 | ||||
-rw-r--r-- | include/linux/kvm_para.h | 6 |
6 files changed, 70 insertions, 0 deletions
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig index 40cedc255eda..e5790fe9e330 100644 --- a/arch/x86/Kconfig +++ b/arch/x86/Kconfig | |||
@@ -384,6 +384,14 @@ config KVM_CLOCK | |||
384 | provides the guest with timing infrastructure such as time of day, and | 384 | provides the guest with timing infrastructure such as time of day, and |
385 | system time | 385 | system time |
386 | 386 | ||
387 | config KVM_GUEST | ||
388 | bool "KVM Guest support" | ||
389 | select PARAVIRT | ||
390 | depends on !(X86_VISWS || X86_VOYAGER) | ||
391 | help | ||
392 | This option enables various optimizations for running under the KVM | ||
393 | hypervisor. | ||
394 | |||
387 | source "arch/x86/lguest/Kconfig" | 395 | source "arch/x86/lguest/Kconfig" |
388 | 396 | ||
389 | config PARAVIRT | 397 | config PARAVIRT |
diff --git a/arch/x86/kernel/Makefile b/arch/x86/kernel/Makefile index 483047a33024..fa19c3819540 100644 --- a/arch/x86/kernel/Makefile +++ b/arch/x86/kernel/Makefile | |||
@@ -80,6 +80,7 @@ obj-$(CONFIG_DEBUG_RODATA_TEST) += test_rodata.o | |||
80 | obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o | 80 | obj-$(CONFIG_DEBUG_NX_TEST) += test_nx.o |
81 | 81 | ||
82 | obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o | 82 | obj-$(CONFIG_VMI) += vmi_32.o vmiclock_32.o |
83 | obj-$(CONFIG_KVM_GUEST) += kvm.o | ||
83 | obj-$(CONFIG_KVM_CLOCK) += kvmclock.o | 84 | obj-$(CONFIG_KVM_CLOCK) += kvmclock.o |
84 | obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o | 85 | obj-$(CONFIG_PARAVIRT) += paravirt.o paravirt_patch_$(BITS).o |
85 | 86 | ||
diff --git a/arch/x86/kernel/kvm.c b/arch/x86/kernel/kvm.c new file mode 100644 index 000000000000..a8e36da60120 --- /dev/null +++ b/arch/x86/kernel/kvm.c | |||
@@ -0,0 +1,52 @@ | |||
1 | /* | ||
2 | * KVM paravirt_ops implementation | ||
3 | * | ||
4 | * This program is free software; you can redistribute it and/or modify | ||
5 | * it under the terms of the GNU General Public License as published by | ||
6 | * the Free Software Foundation; either version 2 of the License, or | ||
7 | * (at your option) any later version. | ||
8 | * | ||
9 | * This program is distributed in the hope that it will be useful, | ||
10 | * but WITHOUT ANY WARRANTY; without even the implied warranty of | ||
11 | * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | ||
12 | * GNU General Public License for more details. | ||
13 | * | ||
14 | * You should have received a copy of the GNU General Public License | ||
15 | * along with this program; if not, write to the Free Software | ||
16 | * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. | ||
17 | * | ||
18 | * Copyright (C) 2007, Red Hat, Inc., Ingo Molnar <mingo@redhat.com> | ||
19 | * Copyright IBM Corporation, 2007 | ||
20 | * Authors: Anthony Liguori <aliguori@us.ibm.com> | ||
21 | */ | ||
22 | |||
23 | #include <linux/module.h> | ||
24 | #include <linux/kernel.h> | ||
25 | #include <linux/kvm_para.h> | ||
26 | #include <linux/cpu.h> | ||
27 | #include <linux/mm.h> | ||
28 | |||
29 | /* | ||
30 | * No need for any "IO delay" on KVM | ||
31 | */ | ||
32 | static void kvm_io_delay(void) | ||
33 | { | ||
34 | } | ||
35 | |||
36 | static void paravirt_ops_setup(void) | ||
37 | { | ||
38 | pv_info.name = "KVM"; | ||
39 | pv_info.paravirt_enabled = 1; | ||
40 | |||
41 | if (kvm_para_has_feature(KVM_FEATURE_NOP_IO_DELAY)) | ||
42 | pv_cpu_ops.io_delay = kvm_io_delay; | ||
43 | |||
44 | } | ||
45 | |||
46 | void __init kvm_guest_init(void) | ||
47 | { | ||
48 | if (!kvm_para_available()) | ||
49 | return; | ||
50 | |||
51 | paravirt_ops_setup(); | ||
52 | } | ||
diff --git a/arch/x86/kernel/setup_32.c b/arch/x86/kernel/setup_32.c index 5a849ddd09ee..2283422af794 100644 --- a/arch/x86/kernel/setup_32.c +++ b/arch/x86/kernel/setup_32.c | |||
@@ -832,6 +832,7 @@ void __init setup_arch(char **cmdline_p) | |||
832 | */ | 832 | */ |
833 | vmi_init(); | 833 | vmi_init(); |
834 | #endif | 834 | #endif |
835 | kvm_guest_init(); | ||
835 | 836 | ||
836 | /* | 837 | /* |
837 | * NOTE: before this point _nobody_ is allowed to allocate | 838 | * NOTE: before this point _nobody_ is allowed to allocate |
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c index 8a9213c023ef..a94fb959a87a 100644 --- a/arch/x86/kernel/setup_64.c +++ b/arch/x86/kernel/setup_64.c | |||
@@ -493,6 +493,8 @@ void __init setup_arch(char **cmdline_p) | |||
493 | init_apic_mappings(); | 493 | init_apic_mappings(); |
494 | ioapic_init_mappings(); | 494 | ioapic_init_mappings(); |
495 | 495 | ||
496 | kvm_guest_init(); | ||
497 | |||
496 | /* | 498 | /* |
497 | * We trust e820 completely. No explicit ROM probing in memory. | 499 | * We trust e820 completely. No explicit ROM probing in memory. |
498 | */ | 500 | */ |
diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h index 5497aac0d2f8..9c462c91a6b1 100644 --- a/include/linux/kvm_para.h +++ b/include/linux/kvm_para.h | |||
@@ -20,6 +20,12 @@ | |||
20 | #include <asm/kvm_para.h> | 20 | #include <asm/kvm_para.h> |
21 | 21 | ||
22 | #ifdef __KERNEL__ | 22 | #ifdef __KERNEL__ |
23 | #ifdef CONFIG_KVM_GUEST | ||
24 | void __init kvm_guest_init(void); | ||
25 | #else | ||
26 | #define kvm_guest_init() do { } while (0) | ||
27 | #endif | ||
28 | |||
23 | static inline int kvm_para_has_feature(unsigned int feature) | 29 | static inline int kvm_para_has_feature(unsigned int feature) |
24 | { | 30 | { |
25 | if (kvm_arch_para_features() & (1UL << feature)) | 31 | if (kvm_arch_para_features() & (1UL << feature)) |