aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm/kvm_para.h
diff options
context:
space:
mode:
Diffstat (limited to 'arch/powerpc/include/asm/kvm_para.h')
-rw-r--r--arch/powerpc/include/asm/kvm_para.h114
1 files changed, 113 insertions, 1 deletions
diff --git a/arch/powerpc/include/asm/kvm_para.h b/arch/powerpc/include/asm/kvm_para.h
index e402999ba193..556fd59ee0f1 100644
--- a/arch/powerpc/include/asm/kvm_para.h
+++ b/arch/powerpc/include/asm/kvm_para.h
@@ -21,6 +21,7 @@
21#define __POWERPC_KVM_PARA_H__ 21#define __POWERPC_KVM_PARA_H__
22 22
23#include <linux/types.h> 23#include <linux/types.h>
24#include <linux/of.h>
24 25
25struct kvm_vcpu_arch_shared { 26struct kvm_vcpu_arch_shared {
26 __u64 sprg0; 27 __u64 sprg0;
@@ -34,16 +35,127 @@ struct kvm_vcpu_arch_shared {
34 __u32 dsisr; 35 __u32 dsisr;
35}; 36};
36 37
38#define KVM_SC_MAGIC_R0 0x4b564d21 /* "KVM!" */
39#define HC_VENDOR_KVM (42 << 16)
40#define HC_EV_SUCCESS 0
41#define HC_EV_UNIMPLEMENTED 12
42
37#ifdef __KERNEL__ 43#ifdef __KERNEL__
38 44
45#ifdef CONFIG_KVM_GUEST
46
47static inline int kvm_para_available(void)
48{
49 struct device_node *hyper_node;
50
51 hyper_node = of_find_node_by_path("/hypervisor");
52 if (!hyper_node)
53 return 0;
54
55 if (!of_device_is_compatible(hyper_node, "linux,kvm"))
56 return 0;
57
58 return 1;
59}
60
61extern unsigned long kvm_hypercall(unsigned long *in,
62 unsigned long *out,
63 unsigned long nr);
64
65#else
66
39static inline int kvm_para_available(void) 67static inline int kvm_para_available(void)
40{ 68{
41 return 0; 69 return 0;
42} 70}
43 71
72static unsigned long kvm_hypercall(unsigned long *in,
73 unsigned long *out,
74 unsigned long nr)
75{
76 return HC_EV_UNIMPLEMENTED;
77}
78
79#endif
80
81static inline long kvm_hypercall0_1(unsigned int nr, unsigned long *r2)
82{
83 unsigned long in[8];
84 unsigned long out[8];
85 unsigned long r;
86
87 r = kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
88 *r2 = out[0];
89
90 return r;
91}
92
93static inline long kvm_hypercall0(unsigned int nr)
94{
95 unsigned long in[8];
96 unsigned long out[8];
97
98 return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
99}
100
101static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
102{
103 unsigned long in[8];
104 unsigned long out[8];
105
106 in[0] = p1;
107 return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
108}
109
110static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
111 unsigned long p2)
112{
113 unsigned long in[8];
114 unsigned long out[8];
115
116 in[0] = p1;
117 in[1] = p2;
118 return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
119}
120
121static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
122 unsigned long p2, unsigned long p3)
123{
124 unsigned long in[8];
125 unsigned long out[8];
126
127 in[0] = p1;
128 in[1] = p2;
129 in[2] = p3;
130 return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
131}
132
133static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
134 unsigned long p2, unsigned long p3,
135 unsigned long p4)
136{
137 unsigned long in[8];
138 unsigned long out[8];
139
140 in[0] = p1;
141 in[1] = p2;
142 in[2] = p3;
143 in[3] = p4;
144 return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
145}
146
147
44static inline unsigned int kvm_arch_para_features(void) 148static inline unsigned int kvm_arch_para_features(void)
45{ 149{
46 return 0; 150 unsigned long r;
151
152 if (!kvm_para_available())
153 return 0;
154
155 if(kvm_hypercall0_1(KVM_HC_FEATURES, &r))
156 return 0;
157
158 return r;
47} 159}
48 160
49#endif /* __KERNEL__ */ 161#endif /* __KERNEL__ */