diff options
author | Christian Borntraeger <borntraeger@de.ibm.com> | 2007-10-11 09:34:17 -0400 |
---|---|---|
committer | Avi Kivity <avi@qumranet.com> | 2008-01-30 10:52:55 -0500 |
commit | 5f43238d036fb30e73563e81e42d9c6f1de5551a (patch) | |
tree | 5188b44c4c34b75ae61eca7465df23aa448546a2 /include/linux/kvm_para.h | |
parent | 8c392696e749171531d155ea5cefdfc1c970fd18 (diff) |
KVM: Per-architecture hypercall definitions
Currently kvm provides hypercalls only for x86* architectures. To
provide hypercall infrastructure for other kvm architectures I split
kvm_para.h into a generic header file and architecture specific
definitions.
Signed-off-by: Christian Borntraeger <borntraeger@de.ibm.com>
Signed-off-by: Avi Kivity <avi@qumranet.com>
Diffstat (limited to 'include/linux/kvm_para.h')
-rw-r--r-- | include/linux/kvm_para.h | 105 |
1 files changed, 12 insertions, 93 deletions
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 | ||