1 /* SPDX-License-Identifier: GPL-2.0 */
2 #ifndef _ASM_LOONGARCH_KVM_PARA_H
3 #define _ASM_LOONGARCH_KVM_PARA_H
4
5 #include <uapi/asm/kvm_para.h>
6
7 #define KVM_HYPERCALL ".word 0x002b8000"
8 /*
9 * Hypcall code field
10 */
11 #define KVM_HC_CODE_SERIVCE 0x0
12 #define KVM_HC_CODE_SWDBG 0x5
13 /*
14 * function id
15 * 0x00000 ~ 0xfffff Standard Hypervisor Calls
16 */
17 #define KVM_HC_FUNC_FEATURE 0x0
18 #define KVM_HC_FUNC_NOTIFY 0x1
19 #define KVM_HC_FUNC_IPI 0x2
20 /*
21 * LoongArch support PV feature list
22 */
23 #define KVM_FEATURE_STEAL_TIME 0
24 #define KVM_FEATURE_MULTI_IPI 1
25 #define KVM_FEATURE_PARAVIRT_SPINLOCK 2
26 /*
27 * LoongArch hypcall return code
28 */
29 #define KVM_RET_SUC 1
30 #define KVM_RET_NOT_SUPPORTED -1
31
32 #define KVM_VCPU_PREEMPTED (1 << 0)
33
34 /*
35 * Hypercalls interface for KVM.
36 *
37 * a0: function identifier
38 * a1-a6: args
39 * Return value will be placed in v0.
40 * Up to 6 arguments are passed in a1, a2, a3, a4, a5, a6.
41 */
kvm_hypercall0(u64 fid)42 static inline long kvm_hypercall0(u64 fid)
43 {
44 register long ret asm("v0");
45 register unsigned long fun asm("a0") = fid;
46
47 __asm__ __volatile__(
48 KVM_HYPERCALL
49 : "=r" (ret)
50 : "r" (fun)
51 : "memory"
52 );
53
54 return ret;
55 }
56
kvm_hypercall1(u64 fid, unsigned long arg0)57 static inline long kvm_hypercall1(u64 fid, unsigned long arg0)
58 {
59 register long ret asm("v0");
60 register unsigned long fun asm("a0") = fid;
61 register unsigned long a1 asm("a1") = arg0;
62
63 __asm__ __volatile__(
64 KVM_HYPERCALL
65 : "=r" (ret)
66 : "r" (fun), "r" (a1)
67 : "memory"
68 );
69
70 return ret;
71 }
72
kvm_hypercall2(u64 fid, unsigned long arg0, unsigned long arg1)73 static inline long kvm_hypercall2(u64 fid,
74 unsigned long arg0, unsigned long arg1)
75 {
76 register long ret asm("v0");
77 register unsigned long fun asm("a0") = fid;
78 register unsigned long a1 asm("a1") = arg0;
79 register unsigned long a2 asm("a2") = arg1;
80
81 __asm__ __volatile__(
82 KVM_HYPERCALL
83 : "=r" (ret)
84 : "r" (fun), "r" (a1), "r" (a2)
85 : "memory"
86 );
87
88 return ret;
89 }
90
kvm_hypercall3(u64 fid, unsigned long arg0, unsigned long arg1, unsigned long arg2)91 static inline long kvm_hypercall3(u64 fid,
92 unsigned long arg0, unsigned long arg1, unsigned long arg2)
93 {
94 register long ret asm("v0");
95 register unsigned long fun asm("a0") = fid;
96 register unsigned long a1 asm("a1") = arg0;
97 register unsigned long a2 asm("a2") = arg1;
98 register unsigned long a3 asm("a3") = arg2;
99
100 __asm__ __volatile__(
101 KVM_HYPERCALL
102 : "=r" (ret)
103 : "r" (fun), "r" (a1), "r" (a2), "r" (a3)
104 : "memory"
105 );
106
107 return ret;
108 }
109
kvm_hypercall4(u64 fid, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3)110 static inline long kvm_hypercall4(u64 fid,
111 unsigned long arg0, unsigned long arg1, unsigned long arg2,
112 unsigned long arg3)
113 {
114 register long ret asm("v0");
115 register unsigned long fun asm("a0") = fid;
116 register unsigned long a1 asm("a1") = arg0;
117 register unsigned long a2 asm("a2") = arg1;
118 register unsigned long a3 asm("a3") = arg2;
119 register unsigned long a4 asm("a4") = arg3;
120
121 __asm__ __volatile__(
122 KVM_HYPERCALL
123 : "=r" (ret)
124 : "i"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4)
125 : "memory"
126 );
127
128 return ret;
129 }
130
kvm_hypercall5(u64 fid, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4)131 static inline long kvm_hypercall5(u64 fid,
132 unsigned long arg0, unsigned long arg1, unsigned long arg2,
133 unsigned long arg3, unsigned long arg4)
134 {
135 register long ret asm("v0");
136 register unsigned long fun asm("a0") = fid;
137 register unsigned long a1 asm("a1") = arg0;
138 register unsigned long a2 asm("a2") = arg1;
139 register unsigned long a3 asm("a3") = arg2;
140 register unsigned long a4 asm("a4") = arg3;
141 register unsigned long a5 asm("a5") = arg4;
142
143 __asm__ __volatile__(
144 KVM_HYPERCALL
145 : "=r" (ret)
146 : "i"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5)
147 : "memory"
148 );
149
150 return ret;
151 }
152
kvm_hypercall6(u64 fid, unsigned long arg0, unsigned long arg1, unsigned long arg2, unsigned long arg3, unsigned long arg4, unsigned long arg5)153 static inline long kvm_hypercall6(u64 fid,
154 unsigned long arg0, unsigned long arg1, unsigned long arg2,
155 unsigned long arg3, unsigned long arg4, unsigned long arg5)
156 {
157 register long ret asm("v0");
158 register unsigned long fun asm("a0") = fid;
159 register unsigned long a1 asm("a1") = arg0;
160 register unsigned long a2 asm("a2") = arg1;
161 register unsigned long a3 asm("a3") = arg2;
162 register unsigned long a4 asm("a4") = arg3;
163 register unsigned long a5 asm("a5") = arg4;
164 register unsigned long a6 asm("a6") = arg5;
165
166 __asm__ __volatile__(
167 KVM_HYPERCALL
168 : "=r" (ret)
169 : "i"(fun), "r" (a1), "r" (a2), "r" (a3), "r" (a4), "r" (a5), "r" (a6)
170 : "memory"
171 );
172
173 return ret;
174 }
175
kvm_check_and_clear_guest_paused(void)176 static inline bool kvm_check_and_clear_guest_paused(void)
177 {
178 return false;
179 }
180
kvm_arch_para_features(void)181 static inline unsigned int kvm_arch_para_features(void)
182 {
183 return 0;
184 }
185
kvm_arch_para_hints(void)186 static inline unsigned int kvm_arch_para_hints(void)
187 {
188 return 0;
189 }
190
191 #ifdef CONFIG_PARAVIRT_SPINLOCKS
192 void __init kvm_spinlock_init(void);
193 #else /* !CONFIG_PARAVIRT_SPINLOCKS */
kvm_spinlock_init(void)194 static inline void kvm_spinlock_init(void)
195 {
196 }
197 #endif /* CONFIG_PARAVIRT_SPINLOCKS */
198
199 #endif /* _ASM_LOONGARCH_KVM_PARA_H */
200