aboutsummaryrefslogtreecommitdiffstats
path: root/arch/powerpc/include/asm/kvm_para.h
diff options
context:
space:
mode:
authorAlexander Graf <agraf@suse.de>2010-07-29 08:47:48 -0400
committerAvi Kivity <avi@redhat.com>2010-10-24 04:50:45 -0400
commit2a342ed57756ad5d8af5456959433884367e5ab2 (patch)
treebb3f1d707916bc53f48919ace0d0f757c7e2083b /arch/powerpc/include/asm/kvm_para.h
parenta73a9599e03eef1324d5aeecaebc1b339d2e1664 (diff)
KVM: PPC: Implement hypervisor interface
To communicate with KVM directly we need to plumb some sort of interface between the guest and KVM. Usually those interfaces use hypercalls. This hypercall implementation is described in the last patch of the series in a special documentation file. Please read that for further information. This patch implements stubs to handle KVM PPC hypercalls on the host and guest side alike. Signed-off-by: Alexander Graf <agraf@suse.de> Signed-off-by: Avi Kivity <avi@redhat.com>
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__ */