blob: cc5dfb43370676d3787e4b0ebaa9548ba93793a8 [file] [log] [blame]
Ingo Molnar102d8322007-02-19 14:37:47 +02001#ifndef __LINUX_KVM_PARA_H
2#define __LINUX_KVM_PARA_H
3
Anthony Liguori7aa81cc2007-09-17 14:57:50 -05004/* 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/* Return values for hypercalls */
15#define KVM_ENOSYS 1000
16
17#ifdef __KERNEL__
18#include <asm/processor.h>
19
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.
Ingo Molnar102d8322007-02-19 14:37:47 +020028 *
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050029 * 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.
Ingo Molnar102d8322007-02-19 14:37:47 +020033 */
34
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050035static 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}
Ingo Molnar102d8322007-02-19 14:37:47 +020043
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050044static 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}
Ingo Molnar102d8322007-02-19 14:37:47 +020052
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050053static 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}
Ingo Molnar102d8322007-02-19 14:37:47 +020062
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050063static 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}
Ingo Molnar102d8322007-02-19 14:37:47 +020072
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050073static 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}
Ingo Molnar102d8322007-02-19 14:37:47 +020083
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050084static inline int kvm_para_available(void)
85{
86 unsigned int eax, ebx, ecx, edx;
87 char signature[13];
Ingo Molnar102d8322007-02-19 14:37:47 +020088
Anthony Liguori7aa81cc2007-09-17 14:57:50 -050089 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
101static inline int kvm_para_has_feature(unsigned int feature)
102{
103 if (cpuid_eax(KVM_CPUID_FEATURES) & (1UL << feature))
104 return 1;
105 return 0;
106}
107
108#endif
Ingo Molnarc21415e2007-02-19 14:37:47 +0200109
Ingo Molnar102d8322007-02-19 14:37:47 +0200110#endif