diff options
-rw-r--r-- | include/asm-x86/kvm_para.h | 105 | ||||
-rw-r--r-- | include/linux/kvm_para.h | 105 |
2 files changed, 117 insertions, 93 deletions
diff --git a/include/asm-x86/kvm_para.h b/include/asm-x86/kvm_para.h new file mode 100644 index 000000000000..c6f3fd8d8c53 --- /dev/null +++ b/include/asm-x86/kvm_para.h | |||
@@ -0,0 +1,105 @@ | |||
1 | #ifndef __X86_KVM_PARA_H | ||
2 | #define __X86_KVM_PARA_H | ||
3 | |||
4 | /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It | ||
5 | * should be used to determine that a VM is running under KVM. | ||
6 | */ | ||
7 | #define KVM_CPUID_SIGNATURE 0x40000000 | ||
8 | |||
9 | /* This CPUID returns a feature bitmap in eax. Before enabling a particular | ||
10 | * paravirtualization, the appropriate feature bit should be checked. | ||
11 | */ | ||
12 | #define KVM_CPUID_FEATURES 0x40000001 | ||
13 | |||
14 | #ifdef __KERNEL__ | ||
15 | #include <asm/processor.h> | ||
16 | |||
17 | /* This instruction is vmcall. On non-VT architectures, it will generate a | ||
18 | * trap that we will then rewrite to the appropriate instruction. | ||
19 | */ | ||
20 | #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1" | ||
21 | |||
22 | /* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun | ||
23 | * instruction. The hypervisor may replace it with something else but only the | ||
24 | * instructions are guaranteed to be supported. | ||
25 | * | ||
26 | * Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively. | ||
27 | * The hypercall number should be placed in rax and the return value will be | ||
28 | * placed in rax. No other registers will be clobbered unless explicited | ||
29 | * noted by the particular hypercall. | ||
30 | */ | ||
31 | |||
32 | static inline long kvm_hypercall0(unsigned int nr) | ||
33 | { | ||
34 | long ret; | ||
35 | asm volatile(KVM_HYPERCALL | ||
36 | : "=a"(ret) | ||
37 | : "a"(nr)); | ||
38 | return ret; | ||
39 | } | ||
40 | |||
41 | static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) | ||
42 | { | ||
43 | long ret; | ||
44 | asm volatile(KVM_HYPERCALL | ||
45 | : "=a"(ret) | ||
46 | : "a"(nr), "b"(p1)); | ||
47 | return ret; | ||
48 | } | ||
49 | |||
50 | static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, | ||
51 | unsigned long p2) | ||
52 | { | ||
53 | long ret; | ||
54 | asm volatile(KVM_HYPERCALL | ||
55 | : "=a"(ret) | ||
56 | : "a"(nr), "b"(p1), "c"(p2)); | ||
57 | return ret; | ||
58 | } | ||
59 | |||
60 | static inline long kvm_hypercall3(unsigned int nr, unsigned long p1, | ||
61 | unsigned long p2, unsigned long p3) | ||
62 | { | ||
63 | long ret; | ||
64 | asm volatile(KVM_HYPERCALL | ||
65 | : "=a"(ret) | ||
66 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3)); | ||
67 | return ret; | ||
68 | } | ||
69 | |||
70 | static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, | ||
71 | unsigned long p2, unsigned long p3, | ||
72 | unsigned long p4) | ||
73 | { | ||
74 | long ret; | ||
75 | asm volatile(KVM_HYPERCALL | ||
76 | : "=a"(ret) | ||
77 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)); | ||
78 | return ret; | ||
79 | } | ||
80 | |||
81 | static inline int kvm_para_available(void) | ||
82 | { | ||
83 | unsigned int eax, ebx, ecx, edx; | ||
84 | char signature[13]; | ||
85 | |||
86 | cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); | ||
87 | memcpy(signature + 0, &ebx, 4); | ||
88 | memcpy(signature + 4, &ecx, 4); | ||
89 | memcpy(signature + 8, &edx, 4); | ||
90 | signature[12] = 0; | ||
91 | |||
92 | if (strcmp(signature, "KVMKVMKVM") == 0) | ||
93 | return 1; | ||
94 | |||
95 | return 0; | ||
96 | } | ||
97 | |||
98 | static inline unsigned int kvm_arch_para_features(void) | ||
99 | { | ||
100 | return cpuid_eax(KVM_CPUID_FEATURES); | ||
101 | } | ||
102 | |||
103 | #endif | ||
104 | |||
105 | #endif | ||
diff --git a/include/linux/kvm_para.h b/include/linux/kvm_para.h index cc5dfb433706..e4db25ffdb52 100644 --- a/include/linux/kvm_para.h +++ b/include/linux/kvm_para.h | |||
@@ -1,110 +1,29 @@ | |||
1 | #ifndef __LINUX_KVM_PARA_H | 1 | #ifndef __LINUX_KVM_PARA_H |
2 | #define __LINUX_KVM_PARA_H | 2 | #define __LINUX_KVM_PARA_H |
3 | 3 | ||
4 | /* This CPUID returns the signature 'KVMKVMKVM' in ebx, ecx, and edx. It | 4 | /* |
5 | * should be used to determine that a VM is running under KVM. | 5 | * This header file provides a method for making a hypercall to the host |
6 | * Architectures should define: | ||
7 | * - kvm_hypercall0, kvm_hypercall1... | ||
8 | * - kvm_arch_para_features | ||
9 | * - kvm_para_available | ||
6 | */ | 10 | */ |
7 | #define KVM_CPUID_SIGNATURE 0x40000000 | ||
8 | |||
9 | /* This CPUID returns a feature bitmap in eax. Before enabling a particular | ||
10 | * paravirtualization, the appropriate feature bit should be checked. | ||
11 | */ | ||
12 | #define KVM_CPUID_FEATURES 0x40000001 | ||
13 | 11 | ||
14 | /* Return values for hypercalls */ | 12 | /* Return values for hypercalls */ |
15 | #define KVM_ENOSYS 1000 | 13 | #define KVM_ENOSYS 1000 |
16 | 14 | ||
17 | #ifdef __KERNEL__ | 15 | #ifdef __KERNEL__ |
18 | #include <asm/processor.h> | 16 | /* |
19 | 17 | * hypercalls use architecture specific | |
20 | /* This instruction is vmcall. On non-VT architectures, it will generate a | ||
21 | * trap that we will then rewrite to the appropriate instruction. | ||
22 | */ | ||
23 | #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1" | ||
24 | |||
25 | /* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun | ||
26 | * instruction. The hypervisor may replace it with something else but only the | ||
27 | * instructions are guaranteed to be supported. | ||
28 | * | ||
29 | * Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively. | ||
30 | * The hypercall number should be placed in rax and the return value will be | ||
31 | * placed in rax. No other registers will be clobbered unless explicited | ||
32 | * noted by the particular hypercall. | ||
33 | */ | 18 | */ |
34 | 19 | #include <asm/kvm_para.h> | |
35 | static inline long kvm_hypercall0(unsigned int nr) | ||
36 | { | ||
37 | long ret; | ||
38 | asm volatile(KVM_HYPERCALL | ||
39 | : "=a"(ret) | ||
40 | : "a"(nr)); | ||
41 | return ret; | ||
42 | } | ||
43 | |||
44 | static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) | ||
45 | { | ||
46 | long ret; | ||
47 | asm volatile(KVM_HYPERCALL | ||
48 | : "=a"(ret) | ||
49 | : "a"(nr), "b"(p1)); | ||
50 | return ret; | ||
51 | } | ||
52 | |||
53 | static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, | ||
54 | unsigned long p2) | ||
55 | { | ||
56 | long ret; | ||
57 | asm volatile(KVM_HYPERCALL | ||
58 | : "=a"(ret) | ||
59 | : "a"(nr), "b"(p1), "c"(p2)); | ||
60 | return ret; | ||
61 | } | ||
62 | |||
63 | static inline long kvm_hypercall3(unsigned int nr, unsigned long p1, | ||
64 | unsigned long p2, unsigned long p3) | ||
65 | { | ||
66 | long ret; | ||
67 | asm volatile(KVM_HYPERCALL | ||
68 | : "=a"(ret) | ||
69 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3)); | ||
70 | return ret; | ||
71 | } | ||
72 | |||
73 | static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, | ||
74 | unsigned long p2, unsigned long p3, | ||
75 | unsigned long p4) | ||
76 | { | ||
77 | long ret; | ||
78 | asm volatile(KVM_HYPERCALL | ||
79 | : "=a"(ret) | ||
80 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4)); | ||
81 | return ret; | ||
82 | } | ||
83 | |||
84 | static inline int kvm_para_available(void) | ||
85 | { | ||
86 | unsigned int eax, ebx, ecx, edx; | ||
87 | char signature[13]; | ||
88 | |||
89 | cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); | ||
90 | memcpy(signature + 0, &ebx, 4); | ||
91 | memcpy(signature + 4, &ecx, 4); | ||
92 | memcpy(signature + 8, &edx, 4); | ||
93 | signature[12] = 0; | ||
94 | |||
95 | if (strcmp(signature, "KVMKVMKVM") == 0) | ||
96 | return 1; | ||
97 | |||
98 | return 0; | ||
99 | } | ||
100 | 20 | ||
101 | static inline int kvm_para_has_feature(unsigned int feature) | 21 | static inline int kvm_para_has_feature(unsigned int feature) |
102 | { | 22 | { |
103 | if (cpuid_eax(KVM_CPUID_FEATURES) & (1UL << feature)) | 23 | if (kvm_arch_para_features() & (1UL << feature)) |
104 | return 1; | 24 | return 1; |
105 | return 0; | 25 | return 0; |
106 | } | 26 | } |
27 | #endif /* __KERNEL__ */ | ||
28 | #endif /* __LINUX_KVM_PARA_H */ | ||
107 | 29 | ||
108 | #endif | ||
109 | |||
110 | #endif | ||