1 /*
2  * This program is free software; you can redistribute it and/or modify
3  * it under the terms of the GNU General Public License, version 2, as
4  * published by the Free Software Foundation.
5  *
6  * This program is distributed in the hope that it will be useful,
7  * but WITHOUT ANY WARRANTY; without even the implied warranty of
8  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
9  * GNU General Public License for more details.
10  *
11  * You should have received a copy of the GNU General Public License
12  * along with this program; if not, write to the Free Software
13  * Foundation, 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14  *
15  * Copyright IBM Corp. 2008
16  *
17  * Authors: Hollis Blanchard <hollisb@us.ibm.com>
18  */
19 
20 #ifndef __POWERPC_KVM_PARA_H__
21 #define __POWERPC_KVM_PARA_H__
22 
23 #include <linux/types.h>
24 
25 struct kvm_vcpu_arch_shared {
26 	__u64 scratch1;
27 	__u64 scratch2;
28 	__u64 scratch3;
29 	__u64 critical;		/* Guest may not get interrupts if == r1 */
30 	__u64 sprg0;
31 	__u64 sprg1;
32 	__u64 sprg2;
33 	__u64 sprg3;
34 	__u64 srr0;
35 	__u64 srr1;
36 	__u64 dar;
37 	__u64 msr;
38 	__u32 dsisr;
39 	__u32 int_pending;	/* Tells the guest if we have an interrupt */
40 	__u32 sr[16];
41 };
42 
43 #define KVM_SC_MAGIC_R0		0x4b564d21 /* "KVM!" */
44 #define HC_VENDOR_KVM		(42 << 16)
45 #define HC_EV_SUCCESS		0
46 #define HC_EV_UNIMPLEMENTED	12
47 
48 #define KVM_FEATURE_MAGIC_PAGE	1
49 
50 #define KVM_MAGIC_FEAT_SR	(1 << 0)
51 
52 #ifdef __KERNEL__
53 
54 #ifdef CONFIG_KVM_GUEST
55 
56 #include <linux/of.h>
57 
58 static inline int kvm_para_available(void)
59 {
60 	struct device_node *hyper_node;
61 
62 	hyper_node = of_find_node_by_path("/hypervisor");
63 	if (!hyper_node)
64 		return 0;
65 
66 	if (!of_device_is_compatible(hyper_node, "linux,kvm"))
67 		return 0;
68 
69 	return 1;
70 }
71 
72 extern unsigned long kvm_hypercall(unsigned long *in,
73 				   unsigned long *out,
74 				   unsigned long nr);
75 
76 #else
77 
78 static inline int kvm_para_available(void)
79 {
80 	return 0;
81 }
82 
83 static unsigned long kvm_hypercall(unsigned long *in,
84 				   unsigned long *out,
85 				   unsigned long nr)
86 {
87 	return HC_EV_UNIMPLEMENTED;
88 }
89 
90 #endif
91 
92 static inline long kvm_hypercall0_1(unsigned int nr, unsigned long *r2)
93 {
94 	unsigned long in[8];
95 	unsigned long out[8];
96 	unsigned long r;
97 
98 	r = kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
99 	*r2 = out[0];
100 
101 	return r;
102 }
103 
104 static inline long kvm_hypercall0(unsigned int nr)
105 {
106 	unsigned long in[8];
107 	unsigned long out[8];
108 
109 	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
110 }
111 
112 static inline long kvm_hypercall1(unsigned int nr, unsigned long p1)
113 {
114 	unsigned long in[8];
115 	unsigned long out[8];
116 
117 	in[0] = p1;
118 	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
119 }
120 
121 static inline long kvm_hypercall2(unsigned int nr, unsigned long p1,
122 				  unsigned long p2)
123 {
124 	unsigned long in[8];
125 	unsigned long out[8];
126 
127 	in[0] = p1;
128 	in[1] = p2;
129 	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
130 }
131 
132 static inline long kvm_hypercall3(unsigned int nr, unsigned long p1,
133 				  unsigned long p2, unsigned long p3)
134 {
135 	unsigned long in[8];
136 	unsigned long out[8];
137 
138 	in[0] = p1;
139 	in[1] = p2;
140 	in[2] = p3;
141 	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
142 }
143 
144 static inline long kvm_hypercall4(unsigned int nr, unsigned long p1,
145 				  unsigned long p2, unsigned long p3,
146 				  unsigned long p4)
147 {
148 	unsigned long in[8];
149 	unsigned long out[8];
150 
151 	in[0] = p1;
152 	in[1] = p2;
153 	in[2] = p3;
154 	in[3] = p4;
155 	return kvm_hypercall(in, out, nr | HC_VENDOR_KVM);
156 }
157 
158 
159 static inline unsigned int kvm_arch_para_features(void)
160 {
161 	unsigned long r;
162 
163 	if (!kvm_para_available())
164 		return 0;
165 
166 	if(kvm_hypercall0_1(KVM_HC_FEATURES, &r))
167 		return 0;
168 
169 	return r;
170 }
171 
172 #endif /* __KERNEL__ */
173 
174 #endif /* __POWERPC_KVM_PARA_H__ */
175