]>
Commit | Line | Data |
---|---|---|
bbf45ba5 HB |
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 | ||
96bc451a AG |
23 | #include <linux/types.h> |
24 | ||
25 | struct kvm_vcpu_arch_shared { | |
fad93fe1 AG |
26 | __u64 scratch1; |
27 | __u64 scratch2; | |
28 | __u64 scratch3; | |
5c6cedf4 | 29 | __u64 critical; /* Guest may not get interrupts if == r1 */ |
a73a9599 AG |
30 | __u64 sprg0; |
31 | __u64 sprg1; | |
32 | __u64 sprg2; | |
33 | __u64 sprg3; | |
de7906c3 AG |
34 | __u64 srr0; |
35 | __u64 srr1; | |
5e030186 | 36 | __u64 dar; |
666e7252 | 37 | __u64 msr; |
d562de48 | 38 | __u32 dsisr; |
90bba358 | 39 | __u32 int_pending; /* Tells the guest if we have an interrupt */ |
df1bfa25 | 40 | __u32 sr[16]; |
96bc451a AG |
41 | }; |
42 | ||
2a342ed5 AG |
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 | ||
5fc87407 AG |
48 | #define KVM_FEATURE_MAGIC_PAGE 1 |
49 | ||
7508e16c AG |
50 | #define KVM_MAGIC_FEAT_SR (1 << 0) |
51 | ||
bbf45ba5 HB |
52 | #ifdef __KERNEL__ |
53 | ||
2a342ed5 AG |
54 | #ifdef CONFIG_KVM_GUEST |
55 | ||
26e673c3 AG |
56 | #include <linux/of.h> |
57 | ||
2a342ed5 AG |
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 | ||
bbf45ba5 HB |
78 | static inline int kvm_para_available(void) |
79 | { | |
80 | return 0; | |
81 | } | |
82 | ||
2a342ed5 AG |
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 | ||
bbf45ba5 HB |
159 | static inline unsigned int kvm_arch_para_features(void) |
160 | { | |
2a342ed5 AG |
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; | |
bbf45ba5 HB |
170 | } |
171 | ||
172 | #endif /* __KERNEL__ */ | |
173 | ||
174 | #endif /* __POWERPC_KVM_PARA_H__ */ |