diff options
Diffstat (limited to 'arch/x86/include/asm/kvm_para.h')
-rw-r--r-- | arch/x86/include/asm/kvm_para.h | 147 |
1 files changed, 147 insertions, 0 deletions
diff --git a/arch/x86/include/asm/kvm_para.h b/arch/x86/include/asm/kvm_para.h new file mode 100644 index 000000000000..30054fded4fb --- /dev/null +++ b/arch/x86/include/asm/kvm_para.h | |||
@@ -0,0 +1,147 @@ | |||
1 | #ifndef ASM_X86__KVM_PARA_H | ||
2 | #define ASM_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 | #define KVM_FEATURE_CLOCKSOURCE 0 | ||
14 | #define KVM_FEATURE_NOP_IO_DELAY 1 | ||
15 | #define KVM_FEATURE_MMU_OP 2 | ||
16 | |||
17 | #define MSR_KVM_WALL_CLOCK 0x11 | ||
18 | #define MSR_KVM_SYSTEM_TIME 0x12 | ||
19 | |||
20 | #define KVM_MAX_MMU_OP_BATCH 32 | ||
21 | |||
22 | /* Operations for KVM_HC_MMU_OP */ | ||
23 | #define KVM_MMU_OP_WRITE_PTE 1 | ||
24 | #define KVM_MMU_OP_FLUSH_TLB 2 | ||
25 | #define KVM_MMU_OP_RELEASE_PT 3 | ||
26 | |||
27 | /* Payload for KVM_HC_MMU_OP */ | ||
28 | struct kvm_mmu_op_header { | ||
29 | __u32 op; | ||
30 | __u32 pad; | ||
31 | }; | ||
32 | |||
33 | struct kvm_mmu_op_write_pte { | ||
34 | struct kvm_mmu_op_header header; | ||
35 | __u64 pte_phys; | ||
36 | __u64 pte_val; | ||
37 | }; | ||
38 | |||
39 | struct kvm_mmu_op_flush_tlb { | ||
40 | struct kvm_mmu_op_header header; | ||
41 | }; | ||
42 | |||
43 | struct kvm_mmu_op_release_pt { | ||
44 | struct kvm_mmu_op_header header; | ||
45 | __u64 pt_phys; | ||
46 | }; | ||
47 | |||
48 | #ifdef __KERNEL__ | ||
49 | #include <asm/processor.h> | ||
50 | |||
51 | extern void kvmclock_init(void); | ||
52 | |||
53 | |||
54 | /* This instruction is vmcall. On non-VT architectures, it will generate a | ||
55 | * trap that we will then rewrite to the appropriate instruction. | ||
56 | */ | ||
57 | #define KVM_HYPERCALL ".byte 0x0f,0x01,0xc1" | ||
58 | |||
59 | /* For KVM hypercalls, a three-byte sequence of either the vmrun or the vmmrun | ||
60 | * instruction. The hypervisor may replace it with something else but only the | ||
61 | * instructions are guaranteed to be supported. | ||
62 | * | ||
63 | * Up to four arguments may be passed in rbx, rcx, rdx, and rsi respectively. | ||
64 | * The hypercall number should be placed in rax and the return value will be | ||
65 | * placed in rax. No other registers will be clobbered unless explicited | ||
66 | * noted by the particular hypercall. | ||
67 | */ | ||
68 | |||
69 | static inline long kvm_hypercall0(unsigned int nr) | ||
70 | { | ||
71 | long ret; | ||
72 | asm volatile(KVM_HYPERCALL | ||
73 | : "=a"(ret) | ||
74 | : "a"(nr) | ||
75 | : "memory"); | ||
76 | return ret; | ||
77 | } | ||
78 | |||
79 | static inline long kvm_hypercall1(unsigned int nr, unsigned long p1) | ||
80 | { | ||
81 | long ret; | ||
82 | asm volatile(KVM_HYPERCALL | ||
83 | : "=a"(ret) | ||
84 | : "a"(nr), "b"(p1) | ||
85 | : "memory"); | ||
86 | return ret; | ||
87 | } | ||
88 | |||
89 | static inline long kvm_hypercall2(unsigned int nr, unsigned long p1, | ||
90 | unsigned long p2) | ||
91 | { | ||
92 | long ret; | ||
93 | asm volatile(KVM_HYPERCALL | ||
94 | : "=a"(ret) | ||
95 | : "a"(nr), "b"(p1), "c"(p2) | ||
96 | : "memory"); | ||
97 | return ret; | ||
98 | } | ||
99 | |||
100 | static inline long kvm_hypercall3(unsigned int nr, unsigned long p1, | ||
101 | unsigned long p2, unsigned long p3) | ||
102 | { | ||
103 | long ret; | ||
104 | asm volatile(KVM_HYPERCALL | ||
105 | : "=a"(ret) | ||
106 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3) | ||
107 | : "memory"); | ||
108 | return ret; | ||
109 | } | ||
110 | |||
111 | static inline long kvm_hypercall4(unsigned int nr, unsigned long p1, | ||
112 | unsigned long p2, unsigned long p3, | ||
113 | unsigned long p4) | ||
114 | { | ||
115 | long ret; | ||
116 | asm volatile(KVM_HYPERCALL | ||
117 | : "=a"(ret) | ||
118 | : "a"(nr), "b"(p1), "c"(p2), "d"(p3), "S"(p4) | ||
119 | : "memory"); | ||
120 | return ret; | ||
121 | } | ||
122 | |||
123 | static inline int kvm_para_available(void) | ||
124 | { | ||
125 | unsigned int eax, ebx, ecx, edx; | ||
126 | char signature[13]; | ||
127 | |||
128 | cpuid(KVM_CPUID_SIGNATURE, &eax, &ebx, &ecx, &edx); | ||
129 | memcpy(signature + 0, &ebx, 4); | ||
130 | memcpy(signature + 4, &ecx, 4); | ||
131 | memcpy(signature + 8, &edx, 4); | ||
132 | signature[12] = 0; | ||
133 | |||
134 | if (strcmp(signature, "KVMKVMKVM") == 0) | ||
135 | return 1; | ||
136 | |||
137 | return 0; | ||
138 | } | ||
139 | |||
140 | static inline unsigned int kvm_arch_para_features(void) | ||
141 | { | ||
142 | return cpuid_eax(KVM_CPUID_FEATURES); | ||
143 | } | ||
144 | |||
145 | #endif | ||
146 | |||
147 | #endif /* ASM_X86__KVM_PARA_H */ | ||