xref: /qemu/target/loongarch/kvm/kvm.c (revision 6edd2a9bec902bf8c4f7a7a819bf5a9a7ae0948b)
1537ba9daSTianrui Zhao /* SPDX-License-Identifier: GPL-2.0-or-later */
2537ba9daSTianrui Zhao /*
3537ba9daSTianrui Zhao  * QEMU LoongArch KVM
4537ba9daSTianrui Zhao  *
5537ba9daSTianrui Zhao  * Copyright (c) 2023 Loongson Technology Corporation Limited
6537ba9daSTianrui Zhao  */
7537ba9daSTianrui Zhao 
8537ba9daSTianrui Zhao #include "qemu/osdep.h"
9537ba9daSTianrui Zhao #include <sys/ioctl.h>
10537ba9daSTianrui Zhao #include <linux/kvm.h>
11537ba9daSTianrui Zhao 
12c23a53d8SBibo Mao #include "qapi/error.h"
13537ba9daSTianrui Zhao #include "qemu/timer.h"
14537ba9daSTianrui Zhao #include "qemu/error-report.h"
15537ba9daSTianrui Zhao #include "qemu/main-loop.h"
16537ba9daSTianrui Zhao #include "sysemu/sysemu.h"
17537ba9daSTianrui Zhao #include "sysemu/kvm.h"
18537ba9daSTianrui Zhao #include "sysemu/kvm_int.h"
19537ba9daSTianrui Zhao #include "hw/pci/pci.h"
20537ba9daSTianrui Zhao #include "exec/memattrs.h"
21537ba9daSTianrui Zhao #include "exec/address-spaces.h"
22537ba9daSTianrui Zhao #include "hw/boards.h"
23537ba9daSTianrui Zhao #include "hw/irq.h"
24537ba9daSTianrui Zhao #include "qemu/log.h"
25537ba9daSTianrui Zhao #include "hw/loader.h"
26537ba9daSTianrui Zhao #include "sysemu/runstate.h"
27537ba9daSTianrui Zhao #include "cpu-csr.h"
28537ba9daSTianrui Zhao #include "kvm_loongarch.h"
29f8447436STianrui Zhao #include "trace.h"
30537ba9daSTianrui Zhao 
31537ba9daSTianrui Zhao static bool cap_has_mp_state;
32d38e31efSBibo Mao static unsigned int brk_insn;
33537ba9daSTianrui Zhao const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
34537ba9daSTianrui Zhao     KVM_CAP_LAST_INFO
35537ba9daSTianrui Zhao };
36537ba9daSTianrui Zhao 
37f8447436STianrui Zhao static int kvm_loongarch_get_regs_core(CPUState *cs)
38f8447436STianrui Zhao {
39f8447436STianrui Zhao     int ret = 0;
40f8447436STianrui Zhao     int i;
41f8447436STianrui Zhao     struct kvm_regs regs;
42f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
43f8447436STianrui Zhao 
44f8447436STianrui Zhao     /* Get the current register set as KVM seems it */
45f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
46f8447436STianrui Zhao     if (ret < 0) {
47f8447436STianrui Zhao         trace_kvm_failed_get_regs_core(strerror(errno));
48f8447436STianrui Zhao         return ret;
49f8447436STianrui Zhao     }
50f8447436STianrui Zhao     /* gpr[0] value is always 0 */
51f8447436STianrui Zhao     env->gpr[0] = 0;
52f8447436STianrui Zhao     for (i = 1; i < 32; i++) {
53f8447436STianrui Zhao         env->gpr[i] = regs.gpr[i];
54f8447436STianrui Zhao     }
55f8447436STianrui Zhao 
56f8447436STianrui Zhao     env->pc = regs.pc;
57f8447436STianrui Zhao     return ret;
58f8447436STianrui Zhao }
59f8447436STianrui Zhao 
60f8447436STianrui Zhao static int kvm_loongarch_put_regs_core(CPUState *cs)
61f8447436STianrui Zhao {
62f8447436STianrui Zhao     int ret = 0;
63f8447436STianrui Zhao     int i;
64f8447436STianrui Zhao     struct kvm_regs regs;
65f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
66f8447436STianrui Zhao 
67f8447436STianrui Zhao     /* Set the registers based on QEMU's view of things */
68f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
69f8447436STianrui Zhao         regs.gpr[i] = env->gpr[i];
70f8447436STianrui Zhao     }
71f8447436STianrui Zhao 
72f8447436STianrui Zhao     regs.pc = env->pc;
73f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
74f8447436STianrui Zhao     if (ret < 0) {
75f8447436STianrui Zhao         trace_kvm_failed_put_regs_core(strerror(errno));
76f8447436STianrui Zhao     }
77f8447436STianrui Zhao 
78f8447436STianrui Zhao     return ret;
79f8447436STianrui Zhao }
80f8447436STianrui Zhao 
81f8447436STianrui Zhao static int kvm_loongarch_get_csr(CPUState *cs)
82f8447436STianrui Zhao {
83f8447436STianrui Zhao     int ret = 0;
84f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
85f8447436STianrui Zhao 
86f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
87f8447436STianrui Zhao                            &env->CSR_CRMD);
88f8447436STianrui Zhao 
89f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
90f8447436STianrui Zhao                            &env->CSR_PRMD);
91f8447436STianrui Zhao 
92f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
93f8447436STianrui Zhao                            &env->CSR_EUEN);
94f8447436STianrui Zhao 
95f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
96f8447436STianrui Zhao                            &env->CSR_MISC);
97f8447436STianrui Zhao 
98f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
99f8447436STianrui Zhao                            &env->CSR_ECFG);
100f8447436STianrui Zhao 
101f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
102f8447436STianrui Zhao                            &env->CSR_ESTAT);
103f8447436STianrui Zhao 
104f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
105f8447436STianrui Zhao                            &env->CSR_ERA);
106f8447436STianrui Zhao 
107f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
108f8447436STianrui Zhao                            &env->CSR_BADV);
109f8447436STianrui Zhao 
110f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
111f8447436STianrui Zhao                            &env->CSR_BADI);
112f8447436STianrui Zhao 
113f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
114f8447436STianrui Zhao                            &env->CSR_EENTRY);
115f8447436STianrui Zhao 
116f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
117f8447436STianrui Zhao                            &env->CSR_TLBIDX);
118f8447436STianrui Zhao 
119f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
120f8447436STianrui Zhao                            &env->CSR_TLBEHI);
121f8447436STianrui Zhao 
122f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
123f8447436STianrui Zhao                            &env->CSR_TLBELO0);
124f8447436STianrui Zhao 
125f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
126f8447436STianrui Zhao                            &env->CSR_TLBELO1);
127f8447436STianrui Zhao 
128f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
129f8447436STianrui Zhao                            &env->CSR_ASID);
130f8447436STianrui Zhao 
131f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
132f8447436STianrui Zhao                            &env->CSR_PGDL);
133f8447436STianrui Zhao 
134f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
135f8447436STianrui Zhao                            &env->CSR_PGDH);
136f8447436STianrui Zhao 
137f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
138f8447436STianrui Zhao                            &env->CSR_PGD);
139f8447436STianrui Zhao 
140f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
141f8447436STianrui Zhao                            &env->CSR_PWCL);
142f8447436STianrui Zhao 
143f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
144f8447436STianrui Zhao                            &env->CSR_PWCH);
145f8447436STianrui Zhao 
146f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
147f8447436STianrui Zhao                            &env->CSR_STLBPS);
148f8447436STianrui Zhao 
149f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
150f8447436STianrui Zhao                            &env->CSR_RVACFG);
151f8447436STianrui Zhao 
152f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
153f8447436STianrui Zhao                            &env->CSR_CPUID);
154f8447436STianrui Zhao 
155f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
156f8447436STianrui Zhao                            &env->CSR_PRCFG1);
157f8447436STianrui Zhao 
158f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
159f8447436STianrui Zhao                            &env->CSR_PRCFG2);
160f8447436STianrui Zhao 
161f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
162f8447436STianrui Zhao                            &env->CSR_PRCFG3);
163f8447436STianrui Zhao 
164f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
165f8447436STianrui Zhao                            &env->CSR_SAVE[0]);
166f8447436STianrui Zhao 
167f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
168f8447436STianrui Zhao                            &env->CSR_SAVE[1]);
169f8447436STianrui Zhao 
170f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
171f8447436STianrui Zhao                            &env->CSR_SAVE[2]);
172f8447436STianrui Zhao 
173f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
174f8447436STianrui Zhao                            &env->CSR_SAVE[3]);
175f8447436STianrui Zhao 
176f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
177f8447436STianrui Zhao                            &env->CSR_SAVE[4]);
178f8447436STianrui Zhao 
179f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
180f8447436STianrui Zhao                            &env->CSR_SAVE[5]);
181f8447436STianrui Zhao 
182f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
183f8447436STianrui Zhao                            &env->CSR_SAVE[6]);
184f8447436STianrui Zhao 
185f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
186f8447436STianrui Zhao                            &env->CSR_SAVE[7]);
187f8447436STianrui Zhao 
188f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
189f8447436STianrui Zhao                            &env->CSR_TID);
190f8447436STianrui Zhao 
191f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
192f8447436STianrui Zhao                            &env->CSR_CNTC);
193f8447436STianrui Zhao 
194f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
195f8447436STianrui Zhao                            &env->CSR_TICLR);
196f8447436STianrui Zhao 
197f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
198f8447436STianrui Zhao                            &env->CSR_LLBCTL);
199f8447436STianrui Zhao 
200f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
201f8447436STianrui Zhao                            &env->CSR_IMPCTL1);
202f8447436STianrui Zhao 
203f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
204f8447436STianrui Zhao                            &env->CSR_IMPCTL2);
205f8447436STianrui Zhao 
206f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
207f8447436STianrui Zhao                            &env->CSR_TLBRENTRY);
208f8447436STianrui Zhao 
209f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
210f8447436STianrui Zhao                            &env->CSR_TLBRBADV);
211f8447436STianrui Zhao 
212f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
213f8447436STianrui Zhao                            &env->CSR_TLBRERA);
214f8447436STianrui Zhao 
215f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
216f8447436STianrui Zhao                            &env->CSR_TLBRSAVE);
217f8447436STianrui Zhao 
218f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
219f8447436STianrui Zhao                            &env->CSR_TLBRELO0);
220f8447436STianrui Zhao 
221f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
222f8447436STianrui Zhao                            &env->CSR_TLBRELO1);
223f8447436STianrui Zhao 
224f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
225f8447436STianrui Zhao                            &env->CSR_TLBREHI);
226f8447436STianrui Zhao 
227f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
228f8447436STianrui Zhao                            &env->CSR_TLBRPRMD);
229f8447436STianrui Zhao 
230f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
231f8447436STianrui Zhao                            &env->CSR_DMW[0]);
232f8447436STianrui Zhao 
233f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
234f8447436STianrui Zhao                            &env->CSR_DMW[1]);
235f8447436STianrui Zhao 
236f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
237f8447436STianrui Zhao                            &env->CSR_DMW[2]);
238f8447436STianrui Zhao 
239f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
240f8447436STianrui Zhao                            &env->CSR_DMW[3]);
241f8447436STianrui Zhao 
242f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
243f8447436STianrui Zhao                            &env->CSR_TVAL);
244f8447436STianrui Zhao 
245f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
246f8447436STianrui Zhao                            &env->CSR_TCFG);
247f8447436STianrui Zhao 
248f8447436STianrui Zhao     return ret;
249f8447436STianrui Zhao }
250f8447436STianrui Zhao 
25161f6e150SBibo Mao static int kvm_loongarch_put_csr(CPUState *cs, int level)
252f8447436STianrui Zhao {
253f8447436STianrui Zhao     int ret = 0;
254f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
255f8447436STianrui Zhao 
256f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
257f8447436STianrui Zhao                            &env->CSR_CRMD);
258f8447436STianrui Zhao 
259f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
260f8447436STianrui Zhao                            &env->CSR_PRMD);
261f8447436STianrui Zhao 
262f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
263f8447436STianrui Zhao                            &env->CSR_EUEN);
264f8447436STianrui Zhao 
265f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
266f8447436STianrui Zhao                            &env->CSR_MISC);
267f8447436STianrui Zhao 
268f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
269f8447436STianrui Zhao                            &env->CSR_ECFG);
270f8447436STianrui Zhao 
271f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
272f8447436STianrui Zhao                            &env->CSR_ESTAT);
273f8447436STianrui Zhao 
274f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
275f8447436STianrui Zhao                            &env->CSR_ERA);
276f8447436STianrui Zhao 
277f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
278f8447436STianrui Zhao                            &env->CSR_BADV);
279f8447436STianrui Zhao 
280f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
281f8447436STianrui Zhao                            &env->CSR_BADI);
282f8447436STianrui Zhao 
283f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
284f8447436STianrui Zhao                            &env->CSR_EENTRY);
285f8447436STianrui Zhao 
286f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
287f8447436STianrui Zhao                            &env->CSR_TLBIDX);
288f8447436STianrui Zhao 
289f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
290f8447436STianrui Zhao                            &env->CSR_TLBEHI);
291f8447436STianrui Zhao 
292f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
293f8447436STianrui Zhao                            &env->CSR_TLBELO0);
294f8447436STianrui Zhao 
295f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
296f8447436STianrui Zhao                            &env->CSR_TLBELO1);
297f8447436STianrui Zhao 
298f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
299f8447436STianrui Zhao                            &env->CSR_ASID);
300f8447436STianrui Zhao 
301f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
302f8447436STianrui Zhao                            &env->CSR_PGDL);
303f8447436STianrui Zhao 
304f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
305f8447436STianrui Zhao                            &env->CSR_PGDH);
306f8447436STianrui Zhao 
307f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
308f8447436STianrui Zhao                            &env->CSR_PGD);
309f8447436STianrui Zhao 
310f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
311f8447436STianrui Zhao                            &env->CSR_PWCL);
312f8447436STianrui Zhao 
313f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
314f8447436STianrui Zhao                            &env->CSR_PWCH);
315f8447436STianrui Zhao 
316f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
317f8447436STianrui Zhao                            &env->CSR_STLBPS);
318f8447436STianrui Zhao 
319f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
320f8447436STianrui Zhao                            &env->CSR_RVACFG);
321f8447436STianrui Zhao 
32261f6e150SBibo Mao     /* CPUID is constant after poweron, it should be set only once */
32361f6e150SBibo Mao     if (level >= KVM_PUT_FULL_STATE) {
324f8447436STianrui Zhao         ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
325f8447436STianrui Zhao                            &env->CSR_CPUID);
32661f6e150SBibo Mao     }
327f8447436STianrui Zhao 
328f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
329f8447436STianrui Zhao                            &env->CSR_PRCFG1);
330f8447436STianrui Zhao 
331f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
332f8447436STianrui Zhao                            &env->CSR_PRCFG2);
333f8447436STianrui Zhao 
334f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
335f8447436STianrui Zhao                            &env->CSR_PRCFG3);
336f8447436STianrui Zhao 
337f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
338f8447436STianrui Zhao                            &env->CSR_SAVE[0]);
339f8447436STianrui Zhao 
340f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
341f8447436STianrui Zhao                            &env->CSR_SAVE[1]);
342f8447436STianrui Zhao 
343f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
344f8447436STianrui Zhao                            &env->CSR_SAVE[2]);
345f8447436STianrui Zhao 
346f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
347f8447436STianrui Zhao                            &env->CSR_SAVE[3]);
348f8447436STianrui Zhao 
349f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
350f8447436STianrui Zhao                            &env->CSR_SAVE[4]);
351f8447436STianrui Zhao 
352f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
353f8447436STianrui Zhao                            &env->CSR_SAVE[5]);
354f8447436STianrui Zhao 
355f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
356f8447436STianrui Zhao                            &env->CSR_SAVE[6]);
357f8447436STianrui Zhao 
358f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
359f8447436STianrui Zhao                            &env->CSR_SAVE[7]);
360f8447436STianrui Zhao 
361f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
362f8447436STianrui Zhao                            &env->CSR_TID);
363f8447436STianrui Zhao 
364f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
365f8447436STianrui Zhao                            &env->CSR_CNTC);
366f8447436STianrui Zhao 
367f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
368f8447436STianrui Zhao                            &env->CSR_TICLR);
369f8447436STianrui Zhao 
370f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
371f8447436STianrui Zhao                            &env->CSR_LLBCTL);
372f8447436STianrui Zhao 
373f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
374f8447436STianrui Zhao                            &env->CSR_IMPCTL1);
375f8447436STianrui Zhao 
376f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
377f8447436STianrui Zhao                            &env->CSR_IMPCTL2);
378f8447436STianrui Zhao 
379f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
380f8447436STianrui Zhao                            &env->CSR_TLBRENTRY);
381f8447436STianrui Zhao 
382f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
383f8447436STianrui Zhao                            &env->CSR_TLBRBADV);
384f8447436STianrui Zhao 
385f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
386f8447436STianrui Zhao                            &env->CSR_TLBRERA);
387f8447436STianrui Zhao 
388f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
389f8447436STianrui Zhao                            &env->CSR_TLBRSAVE);
390f8447436STianrui Zhao 
391f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
392f8447436STianrui Zhao                            &env->CSR_TLBRELO0);
393f8447436STianrui Zhao 
394f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
395f8447436STianrui Zhao                            &env->CSR_TLBRELO1);
396f8447436STianrui Zhao 
397f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
398f8447436STianrui Zhao                            &env->CSR_TLBREHI);
399f8447436STianrui Zhao 
400f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
401f8447436STianrui Zhao                            &env->CSR_TLBRPRMD);
402f8447436STianrui Zhao 
403f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
404f8447436STianrui Zhao                            &env->CSR_DMW[0]);
405f8447436STianrui Zhao 
406f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
407f8447436STianrui Zhao                            &env->CSR_DMW[1]);
408f8447436STianrui Zhao 
409f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
410f8447436STianrui Zhao                            &env->CSR_DMW[2]);
411f8447436STianrui Zhao 
412f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
413f8447436STianrui Zhao                            &env->CSR_DMW[3]);
414f8447436STianrui Zhao     /*
415f8447436STianrui Zhao      * timer cfg must be put at last since it is used to enable
416f8447436STianrui Zhao      * guest timer
417f8447436STianrui Zhao      */
418f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
419f8447436STianrui Zhao                            &env->CSR_TVAL);
420f8447436STianrui Zhao 
421f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
422f8447436STianrui Zhao                            &env->CSR_TCFG);
423f8447436STianrui Zhao     return ret;
424f8447436STianrui Zhao }
425f8447436STianrui Zhao 
426f8447436STianrui Zhao static int kvm_loongarch_get_regs_fp(CPUState *cs)
427f8447436STianrui Zhao {
428f8447436STianrui Zhao     int ret, i;
429f8447436STianrui Zhao     struct kvm_fpu fpu;
430f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
431f8447436STianrui Zhao 
432f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
433f8447436STianrui Zhao     if (ret < 0) {
434f8447436STianrui Zhao         trace_kvm_failed_get_fpu(strerror(errno));
435f8447436STianrui Zhao         return ret;
436f8447436STianrui Zhao     }
437f8447436STianrui Zhao 
438f8447436STianrui Zhao     env->fcsr0 = fpu.fcsr;
439f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
440f8447436STianrui Zhao         env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
44107c08661SSong Gao         env->fpr[i].vreg.UD[1] = fpu.fpr[i].val64[1];
44207c08661SSong Gao         env->fpr[i].vreg.UD[2] = fpu.fpr[i].val64[2];
44307c08661SSong Gao         env->fpr[i].vreg.UD[3] = fpu.fpr[i].val64[3];
444f8447436STianrui Zhao     }
445f8447436STianrui Zhao     for (i = 0; i < 8; i++) {
446f8447436STianrui Zhao         env->cf[i] = fpu.fcc & 0xFF;
447f8447436STianrui Zhao         fpu.fcc = fpu.fcc >> 8;
448f8447436STianrui Zhao     }
449f8447436STianrui Zhao 
450f8447436STianrui Zhao     return ret;
451f8447436STianrui Zhao }
452f8447436STianrui Zhao 
453f8447436STianrui Zhao static int kvm_loongarch_put_regs_fp(CPUState *cs)
454f8447436STianrui Zhao {
455f8447436STianrui Zhao     int ret, i;
456f8447436STianrui Zhao     struct kvm_fpu fpu;
457f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
458f8447436STianrui Zhao 
459f8447436STianrui Zhao     fpu.fcsr = env->fcsr0;
460f8447436STianrui Zhao     fpu.fcc = 0;
461f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
462f8447436STianrui Zhao         fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
46307c08661SSong Gao         fpu.fpr[i].val64[1] = env->fpr[i].vreg.UD[1];
46407c08661SSong Gao         fpu.fpr[i].val64[2] = env->fpr[i].vreg.UD[2];
46507c08661SSong Gao         fpu.fpr[i].val64[3] = env->fpr[i].vreg.UD[3];
466f8447436STianrui Zhao     }
467f8447436STianrui Zhao 
468f8447436STianrui Zhao     for (i = 0; i < 8; i++) {
469f8447436STianrui Zhao         fpu.fcc |= env->cf[i] << (8 * i);
470f8447436STianrui Zhao     }
471f8447436STianrui Zhao 
472f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
473f8447436STianrui Zhao     if (ret < 0) {
474f8447436STianrui Zhao         trace_kvm_failed_put_fpu(strerror(errno));
475f8447436STianrui Zhao     }
476f8447436STianrui Zhao 
477f8447436STianrui Zhao     return ret;
478f8447436STianrui Zhao }
479f8447436STianrui Zhao 
480a45df286SBibo Mao static int kvm_loongarch_put_lbt(CPUState *cs)
481a45df286SBibo Mao {
482a45df286SBibo Mao     CPULoongArchState *env = cpu_env(cs);
483a45df286SBibo Mao     uint64_t val;
484a45df286SBibo Mao     int ret;
485a45df286SBibo Mao 
486a45df286SBibo Mao     /* check whether vm support LBT firstly */
487a45df286SBibo Mao     if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) {
488a45df286SBibo Mao         return 0;
489a45df286SBibo Mao     }
490a45df286SBibo Mao 
491a45df286SBibo Mao     /* set six LBT registers including scr0-scr3, eflags, ftop */
492a45df286SBibo Mao     ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0);
493a45df286SBibo Mao     ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1);
494a45df286SBibo Mao     ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2);
495a45df286SBibo Mao     ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3);
496a45df286SBibo Mao     /*
497a45df286SBibo Mao      * Be cautious, KVM_REG_LOONGARCH_LBT_FTOP is defined as 64-bit however
498a45df286SBibo Mao      * lbt.ftop is 32-bit; the same with KVM_REG_LOONGARCH_LBT_EFLAGS register
499a45df286SBibo Mao      */
500a45df286SBibo Mao     val = env->lbt.eflags;
501a45df286SBibo Mao     ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val);
502a45df286SBibo Mao     val = env->lbt.ftop;
503a45df286SBibo Mao     ret |= kvm_set_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val);
504a45df286SBibo Mao 
505a45df286SBibo Mao     return ret;
506a45df286SBibo Mao }
507a45df286SBibo Mao 
508a45df286SBibo Mao static int kvm_loongarch_get_lbt(CPUState *cs)
509a45df286SBibo Mao {
510a45df286SBibo Mao     CPULoongArchState *env = cpu_env(cs);
511a45df286SBibo Mao     uint64_t val;
512a45df286SBibo Mao     int ret;
513a45df286SBibo Mao 
514a45df286SBibo Mao     /* check whether vm support LBT firstly */
515a45df286SBibo Mao     if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LBT_ALL) != 7) {
516a45df286SBibo Mao         return 0;
517a45df286SBibo Mao     }
518a45df286SBibo Mao 
519a45df286SBibo Mao     /* get six LBT registers including scr0-scr3, eflags, ftop */
520a45df286SBibo Mao     ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR0, &env->lbt.scr0);
521a45df286SBibo Mao     ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR1, &env->lbt.scr1);
522a45df286SBibo Mao     ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR2, &env->lbt.scr2);
523a45df286SBibo Mao     ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_SCR3, &env->lbt.scr3);
524a45df286SBibo Mao     ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_EFLAGS, &val);
525a45df286SBibo Mao     env->lbt.eflags = (uint32_t)val;
526a45df286SBibo Mao     ret |= kvm_get_one_reg(cs, KVM_REG_LOONGARCH_LBT_FTOP, &val);
527a45df286SBibo Mao     env->lbt.ftop = (uint32_t)val;
528a45df286SBibo Mao 
529a45df286SBibo Mao     return ret;
530a45df286SBibo Mao }
531a45df286SBibo Mao 
532a724f5a8SBibo Mao void kvm_arch_reset_vcpu(CPUState *cs)
533f8447436STianrui Zhao {
534a724f5a8SBibo Mao     CPULoongArchState *env = cpu_env(cs);
535a724f5a8SBibo Mao 
536f8447436STianrui Zhao     env->mp_state = KVM_MP_STATE_RUNNABLE;
537a724f5a8SBibo Mao     kvm_set_one_reg(cs, KVM_REG_LOONGARCH_VCPU_RESET, 0);
538f8447436STianrui Zhao }
539f8447436STianrui Zhao 
540f8447436STianrui Zhao static int kvm_loongarch_get_mpstate(CPUState *cs)
541f8447436STianrui Zhao {
542f8447436STianrui Zhao     int ret = 0;
543f8447436STianrui Zhao     struct kvm_mp_state mp_state;
544f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
545f8447436STianrui Zhao 
546f8447436STianrui Zhao     if (cap_has_mp_state) {
547f8447436STianrui Zhao         ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
548f8447436STianrui Zhao         if (ret) {
549f8447436STianrui Zhao             trace_kvm_failed_get_mpstate(strerror(errno));
550f8447436STianrui Zhao             return ret;
551f8447436STianrui Zhao         }
552f8447436STianrui Zhao         env->mp_state = mp_state.mp_state;
553f8447436STianrui Zhao     }
554f8447436STianrui Zhao 
555f8447436STianrui Zhao     return ret;
556f8447436STianrui Zhao }
557f8447436STianrui Zhao 
558f8447436STianrui Zhao static int kvm_loongarch_put_mpstate(CPUState *cs)
559f8447436STianrui Zhao {
560f8447436STianrui Zhao     int ret = 0;
561f8447436STianrui Zhao     struct kvm_mp_state mp_state = {
562f3b603b9SPhilippe Mathieu-Daudé         .mp_state = cpu_env(cs)->mp_state
563f8447436STianrui Zhao     };
564f8447436STianrui Zhao 
565f8447436STianrui Zhao     if (cap_has_mp_state) {
566f8447436STianrui Zhao         ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state);
567f8447436STianrui Zhao         if (ret) {
568f8447436STianrui Zhao             trace_kvm_failed_put_mpstate(strerror(errno));
569f8447436STianrui Zhao         }
570f8447436STianrui Zhao     }
571f8447436STianrui Zhao 
572f8447436STianrui Zhao     return ret;
573f8447436STianrui Zhao }
574f8447436STianrui Zhao 
575f8447436STianrui Zhao static int kvm_loongarch_get_cpucfg(CPUState *cs)
576f8447436STianrui Zhao {
577f8447436STianrui Zhao     int i, ret = 0;
578f8447436STianrui Zhao     uint64_t val;
579f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
580f8447436STianrui Zhao 
581f8447436STianrui Zhao     for (i = 0; i < 21; i++) {
582f8447436STianrui Zhao         ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
583f8447436STianrui Zhao         if (ret < 0) {
584f8447436STianrui Zhao             trace_kvm_failed_get_cpucfg(strerror(errno));
585f8447436STianrui Zhao         }
586f8447436STianrui Zhao         env->cpucfg[i] = (uint32_t)val;
587f8447436STianrui Zhao     }
588f8447436STianrui Zhao     return ret;
589f8447436STianrui Zhao }
590f8447436STianrui Zhao 
591fc700996SSong Gao static int kvm_check_cpucfg2(CPUState *cs)
592fc700996SSong Gao {
593fc700996SSong Gao     int ret;
594fc700996SSong Gao     uint64_t val;
595fc700996SSong Gao     struct kvm_device_attr attr = {
596fc700996SSong Gao         .group = KVM_LOONGARCH_VCPU_CPUCFG,
597fc700996SSong Gao         .attr = 2,
598fc700996SSong Gao         .addr = (uint64_t)&val,
599fc700996SSong Gao     };
600f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
601fc700996SSong Gao 
602fc700996SSong Gao     ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
603fc700996SSong Gao 
604fc700996SSong Gao     if (!ret) {
605fc700996SSong Gao         kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
606fc700996SSong Gao         env->cpucfg[2] &= val;
607fc700996SSong Gao 
608fc700996SSong Gao         if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) {
609fc700996SSong Gao             /* The FP minimal version is 1. */
610fc700996SSong Gao             env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, FP_VER, 1);
611fc700996SSong Gao         }
612fc700996SSong Gao 
613fc700996SSong Gao         if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LLFTP)) {
614fc700996SSong Gao             /* The LLFTP minimal version is 1. */
615fc700996SSong Gao             env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LLFTP_VER, 1);
616fc700996SSong Gao         }
617fc700996SSong Gao     }
618fc700996SSong Gao 
619fc700996SSong Gao     return ret;
620fc700996SSong Gao }
621fc700996SSong Gao 
622f8447436STianrui Zhao static int kvm_loongarch_put_cpucfg(CPUState *cs)
623f8447436STianrui Zhao {
624f8447436STianrui Zhao     int i, ret = 0;
625f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
626f8447436STianrui Zhao     uint64_t val;
627f8447436STianrui Zhao 
628f8447436STianrui Zhao     for (i = 0; i < 21; i++) {
629f8447436STianrui Zhao 	if (i == 2) {
630fc700996SSong Gao             ret = kvm_check_cpucfg2(cs);
631fc700996SSong Gao             if (ret) {
632fc700996SSong Gao                 return ret;
633f8447436STianrui Zhao             }
634fc700996SSong Gao 	}
635fc700996SSong Gao         val = env->cpucfg[i];
636f8447436STianrui Zhao         ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
637f8447436STianrui Zhao         if (ret < 0) {
638f8447436STianrui Zhao             trace_kvm_failed_put_cpucfg(strerror(errno));
639f8447436STianrui Zhao         }
640f8447436STianrui Zhao     }
641f8447436STianrui Zhao     return ret;
642f8447436STianrui Zhao }
643f8447436STianrui Zhao 
644a1676bb3SJulia Suvorova int kvm_arch_get_registers(CPUState *cs, Error **errp)
645537ba9daSTianrui Zhao {
646f8447436STianrui Zhao     int ret;
647f8447436STianrui Zhao 
648f8447436STianrui Zhao     ret = kvm_loongarch_get_regs_core(cs);
649f8447436STianrui Zhao     if (ret) {
650f8447436STianrui Zhao         return ret;
651537ba9daSTianrui Zhao     }
652f8447436STianrui Zhao 
6535872966dSBibo Mao     ret = kvm_loongarch_get_cpucfg(cs);
6545872966dSBibo Mao     if (ret) {
6555872966dSBibo Mao         return ret;
6565872966dSBibo Mao     }
6575872966dSBibo Mao 
658f8447436STianrui Zhao     ret = kvm_loongarch_get_csr(cs);
659f8447436STianrui Zhao     if (ret) {
660f8447436STianrui Zhao         return ret;
661f8447436STianrui Zhao     }
662f8447436STianrui Zhao 
663f8447436STianrui Zhao     ret = kvm_loongarch_get_regs_fp(cs);
664f8447436STianrui Zhao     if (ret) {
665f8447436STianrui Zhao         return ret;
666f8447436STianrui Zhao     }
667f8447436STianrui Zhao 
668a45df286SBibo Mao     ret = kvm_loongarch_get_lbt(cs);
669a45df286SBibo Mao     if (ret) {
670a45df286SBibo Mao         return ret;
671a45df286SBibo Mao     }
672a45df286SBibo Mao 
673f8447436STianrui Zhao     ret = kvm_loongarch_get_mpstate(cs);
674f8447436STianrui Zhao     return ret;
675f8447436STianrui Zhao }
676f8447436STianrui Zhao 
677a1676bb3SJulia Suvorova int kvm_arch_put_registers(CPUState *cs, int level, Error **errp)
678537ba9daSTianrui Zhao {
679f8447436STianrui Zhao     int ret;
680f8447436STianrui Zhao 
681f8447436STianrui Zhao     ret = kvm_loongarch_put_regs_core(cs);
682f8447436STianrui Zhao     if (ret) {
683f8447436STianrui Zhao         return ret;
684f8447436STianrui Zhao     }
685f8447436STianrui Zhao 
6865872966dSBibo Mao     ret = kvm_loongarch_put_cpucfg(cs);
6875872966dSBibo Mao     if (ret) {
6885872966dSBibo Mao         return ret;
6895872966dSBibo Mao     }
6905872966dSBibo Mao 
69161f6e150SBibo Mao     ret = kvm_loongarch_put_csr(cs, level);
692f8447436STianrui Zhao     if (ret) {
693f8447436STianrui Zhao         return ret;
694f8447436STianrui Zhao     }
695f8447436STianrui Zhao 
696f8447436STianrui Zhao     ret = kvm_loongarch_put_regs_fp(cs);
697f8447436STianrui Zhao     if (ret) {
698f8447436STianrui Zhao         return ret;
699f8447436STianrui Zhao     }
700f8447436STianrui Zhao 
701a45df286SBibo Mao     ret = kvm_loongarch_put_lbt(cs);
702a45df286SBibo Mao     if (ret) {
703a45df286SBibo Mao         return ret;
704a45df286SBibo Mao     }
705a45df286SBibo Mao 
706f8447436STianrui Zhao     ret = kvm_loongarch_put_mpstate(cs);
707f8447436STianrui Zhao     return ret;
708537ba9daSTianrui Zhao }
709537ba9daSTianrui Zhao 
710d11681c9STianrui Zhao static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
711d11681c9STianrui Zhao                                           RunState state)
712d11681c9STianrui Zhao {
713d11681c9STianrui Zhao     int ret;
714d11681c9STianrui Zhao     CPUState *cs = opaque;
715d11681c9STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
716d11681c9STianrui Zhao 
717d11681c9STianrui Zhao     if (running) {
718d11681c9STianrui Zhao         ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
719d11681c9STianrui Zhao                               &cpu->kvm_state_counter);
720d11681c9STianrui Zhao         if (ret < 0) {
721d11681c9STianrui Zhao             trace_kvm_failed_put_counter(strerror(errno));
722d11681c9STianrui Zhao         }
723d11681c9STianrui Zhao     } else {
724d11681c9STianrui Zhao         ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
725d11681c9STianrui Zhao                               &cpu->kvm_state_counter);
726d11681c9STianrui Zhao         if (ret < 0) {
727d11681c9STianrui Zhao             trace_kvm_failed_get_counter(strerror(errno));
728d11681c9STianrui Zhao         }
729d11681c9STianrui Zhao     }
730d11681c9STianrui Zhao }
731d11681c9STianrui Zhao 
732c23a53d8SBibo Mao static bool kvm_feature_supported(CPUState *cs, enum loongarch_features feature)
733c23a53d8SBibo Mao {
734c23a53d8SBibo Mao     int ret;
735c23a53d8SBibo Mao     struct kvm_device_attr attr;
736c23a53d8SBibo Mao 
737c23a53d8SBibo Mao     switch (feature) {
738c23a53d8SBibo Mao     case LOONGARCH_FEATURE_LBT:
739c23a53d8SBibo Mao         /*
740c23a53d8SBibo Mao          * Return all if all the LBT features are supported such as:
741c23a53d8SBibo Mao          *  KVM_LOONGARCH_VM_FEAT_X86BT
742c23a53d8SBibo Mao          *  KVM_LOONGARCH_VM_FEAT_ARMBT
743c23a53d8SBibo Mao          *  KVM_LOONGARCH_VM_FEAT_MIPSBT
744c23a53d8SBibo Mao          */
745c23a53d8SBibo Mao         attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
746c23a53d8SBibo Mao         attr.attr = KVM_LOONGARCH_VM_FEAT_X86BT;
747c23a53d8SBibo Mao         ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
748c23a53d8SBibo Mao         attr.attr = KVM_LOONGARCH_VM_FEAT_ARMBT;
749c23a53d8SBibo Mao         ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
750c23a53d8SBibo Mao         attr.attr = KVM_LOONGARCH_VM_FEAT_MIPSBT;
751c23a53d8SBibo Mao         ret |= kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
752c23a53d8SBibo Mao         return (ret == 0);
753*6edd2a9bSBibo Mao 
754*6edd2a9bSBibo Mao     case LOONGARCH_FEATURE_PMU:
755*6edd2a9bSBibo Mao         attr.group = KVM_LOONGARCH_VM_FEAT_CTRL;
756*6edd2a9bSBibo Mao         attr.attr = KVM_LOONGARCH_VM_FEAT_PMU;
757*6edd2a9bSBibo Mao         ret = kvm_vm_ioctl(kvm_state, KVM_HAS_DEVICE_ATTR, &attr);
758*6edd2a9bSBibo Mao         return (ret == 0);
759*6edd2a9bSBibo Mao 
760c23a53d8SBibo Mao     default:
761c23a53d8SBibo Mao         return false;
762c23a53d8SBibo Mao     }
763*6edd2a9bSBibo Mao 
764*6edd2a9bSBibo Mao     return false;
765c23a53d8SBibo Mao }
766c23a53d8SBibo Mao 
767c23a53d8SBibo Mao static int kvm_cpu_check_lbt(CPUState *cs, Error **errp)
768c23a53d8SBibo Mao {
769c23a53d8SBibo Mao     CPULoongArchState *env = cpu_env(cs);
770c23a53d8SBibo Mao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
771c23a53d8SBibo Mao     bool kvm_supported;
772c23a53d8SBibo Mao 
773c23a53d8SBibo Mao     kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_LBT);
774c23a53d8SBibo Mao     if (cpu->lbt == ON_OFF_AUTO_ON) {
775c23a53d8SBibo Mao         if (kvm_supported) {
776c23a53d8SBibo Mao             env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LBT_ALL, 7);
777c23a53d8SBibo Mao         } else {
778c23a53d8SBibo Mao             error_setg(errp, "'lbt' feature not supported by KVM on this host");
779c23a53d8SBibo Mao             return -ENOTSUP;
780c23a53d8SBibo Mao         }
781c23a53d8SBibo Mao     } else if ((cpu->lbt == ON_OFF_AUTO_AUTO) && kvm_supported) {
782c23a53d8SBibo Mao         env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LBT_ALL, 7);
783c23a53d8SBibo Mao     }
784c23a53d8SBibo Mao 
785c23a53d8SBibo Mao     return 0;
786c23a53d8SBibo Mao }
787c23a53d8SBibo Mao 
788*6edd2a9bSBibo Mao static int kvm_cpu_check_pmu(CPUState *cs, Error **errp)
789*6edd2a9bSBibo Mao {
790*6edd2a9bSBibo Mao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
791*6edd2a9bSBibo Mao     CPULoongArchState *env = cpu_env(cs);
792*6edd2a9bSBibo Mao     bool kvm_supported;
793*6edd2a9bSBibo Mao 
794*6edd2a9bSBibo Mao     kvm_supported = kvm_feature_supported(cs, LOONGARCH_FEATURE_PMU);
795*6edd2a9bSBibo Mao     if (cpu->pmu == ON_OFF_AUTO_ON) {
796*6edd2a9bSBibo Mao         if (!kvm_supported) {
797*6edd2a9bSBibo Mao             error_setg(errp, "'pmu' feature not supported by KVM on the host");
798*6edd2a9bSBibo Mao             return -ENOTSUP;
799*6edd2a9bSBibo Mao         }
800*6edd2a9bSBibo Mao     } else if (cpu->pmu != ON_OFF_AUTO_AUTO) {
801*6edd2a9bSBibo Mao         /* disable pmu if ON_OFF_AUTO_OFF is set */
802*6edd2a9bSBibo Mao         kvm_supported = false;
803*6edd2a9bSBibo Mao     }
804*6edd2a9bSBibo Mao 
805*6edd2a9bSBibo Mao     if (kvm_supported) {
806*6edd2a9bSBibo Mao         env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMP, 1);
807*6edd2a9bSBibo Mao         env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMNUM, 3);
808*6edd2a9bSBibo Mao         env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, PMBITS, 63);
809*6edd2a9bSBibo Mao         env->cpucfg[6] = FIELD_DP32(env->cpucfg[6], CPUCFG6, UPM, 1);
810*6edd2a9bSBibo Mao     }
811*6edd2a9bSBibo Mao     return 0;
812*6edd2a9bSBibo Mao }
813*6edd2a9bSBibo Mao 
814537ba9daSTianrui Zhao int kvm_arch_init_vcpu(CPUState *cs)
815537ba9daSTianrui Zhao {
816d38e31efSBibo Mao     uint64_t val;
817c23a53d8SBibo Mao     int ret;
818c23a53d8SBibo Mao     Error *local_err = NULL;
819d38e31efSBibo Mao 
820c23a53d8SBibo Mao     ret = 0;
821d11681c9STianrui Zhao     qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
822d38e31efSBibo Mao 
823d38e31efSBibo Mao     if (!kvm_get_one_reg(cs, KVM_REG_LOONGARCH_DEBUG_INST, &val)) {
824d38e31efSBibo Mao         brk_insn = val;
825d38e31efSBibo Mao     }
826d38e31efSBibo Mao 
827c23a53d8SBibo Mao     ret = kvm_cpu_check_lbt(cs, &local_err);
828c23a53d8SBibo Mao     if (ret < 0) {
829c23a53d8SBibo Mao         error_report_err(local_err);
830c23a53d8SBibo Mao     }
831*6edd2a9bSBibo Mao 
832*6edd2a9bSBibo Mao     ret = kvm_cpu_check_pmu(cs, &local_err);
833*6edd2a9bSBibo Mao     if (ret < 0) {
834*6edd2a9bSBibo Mao         error_report_err(local_err);
835*6edd2a9bSBibo Mao     }
836*6edd2a9bSBibo Mao 
837c23a53d8SBibo Mao     return ret;
838537ba9daSTianrui Zhao }
839537ba9daSTianrui Zhao 
840537ba9daSTianrui Zhao int kvm_arch_destroy_vcpu(CPUState *cs)
841537ba9daSTianrui Zhao {
842537ba9daSTianrui Zhao     return 0;
843537ba9daSTianrui Zhao }
844537ba9daSTianrui Zhao 
845537ba9daSTianrui Zhao unsigned long kvm_arch_vcpu_id(CPUState *cs)
846537ba9daSTianrui Zhao {
847537ba9daSTianrui Zhao     return cs->cpu_index;
848537ba9daSTianrui Zhao }
849537ba9daSTianrui Zhao 
850537ba9daSTianrui Zhao int kvm_arch_release_virq_post(int virq)
851537ba9daSTianrui Zhao {
852537ba9daSTianrui Zhao     return 0;
853537ba9daSTianrui Zhao }
854537ba9daSTianrui Zhao 
855537ba9daSTianrui Zhao int kvm_arch_msi_data_to_gsi(uint32_t data)
856537ba9daSTianrui Zhao {
857537ba9daSTianrui Zhao     abort();
858537ba9daSTianrui Zhao }
859537ba9daSTianrui Zhao 
860537ba9daSTianrui Zhao int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
861537ba9daSTianrui Zhao                              uint64_t address, uint32_t data, PCIDevice *dev)
862537ba9daSTianrui Zhao {
863537ba9daSTianrui Zhao     return 0;
864537ba9daSTianrui Zhao }
865537ba9daSTianrui Zhao 
866537ba9daSTianrui Zhao int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
867537ba9daSTianrui Zhao                                 int vector, PCIDevice *dev)
868537ba9daSTianrui Zhao {
869537ba9daSTianrui Zhao     return 0;
870537ba9daSTianrui Zhao }
871537ba9daSTianrui Zhao 
872537ba9daSTianrui Zhao void kvm_arch_init_irq_routing(KVMState *s)
873537ba9daSTianrui Zhao {
874537ba9daSTianrui Zhao }
875537ba9daSTianrui Zhao 
876537ba9daSTianrui Zhao int kvm_arch_get_default_type(MachineState *ms)
877537ba9daSTianrui Zhao {
878537ba9daSTianrui Zhao     return 0;
879537ba9daSTianrui Zhao }
880537ba9daSTianrui Zhao 
881537ba9daSTianrui Zhao int kvm_arch_init(MachineState *ms, KVMState *s)
882537ba9daSTianrui Zhao {
88341958c99STianrui Zhao     cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
884537ba9daSTianrui Zhao     return 0;
885537ba9daSTianrui Zhao }
886537ba9daSTianrui Zhao 
887537ba9daSTianrui Zhao int kvm_arch_irqchip_create(KVMState *s)
888537ba9daSTianrui Zhao {
889537ba9daSTianrui Zhao     return 0;
890537ba9daSTianrui Zhao }
891537ba9daSTianrui Zhao 
892537ba9daSTianrui Zhao void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
893537ba9daSTianrui Zhao {
894537ba9daSTianrui Zhao }
895537ba9daSTianrui Zhao 
896537ba9daSTianrui Zhao MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
897537ba9daSTianrui Zhao {
898537ba9daSTianrui Zhao     return MEMTXATTRS_UNSPECIFIED;
899537ba9daSTianrui Zhao }
900537ba9daSTianrui Zhao 
901537ba9daSTianrui Zhao int kvm_arch_process_async_events(CPUState *cs)
902537ba9daSTianrui Zhao {
903537ba9daSTianrui Zhao     return cs->halted;
904537ba9daSTianrui Zhao }
905537ba9daSTianrui Zhao 
906537ba9daSTianrui Zhao bool kvm_arch_stop_on_emulation_error(CPUState *cs)
907537ba9daSTianrui Zhao {
908537ba9daSTianrui Zhao     return true;
909537ba9daSTianrui Zhao }
910537ba9daSTianrui Zhao 
911d38e31efSBibo Mao void kvm_arch_update_guest_debug(CPUState *cpu, struct kvm_guest_debug *dbg)
912d38e31efSBibo Mao {
913d38e31efSBibo Mao     if (kvm_sw_breakpoints_active(cpu)) {
914d38e31efSBibo Mao         dbg->control |= KVM_GUESTDBG_ENABLE | KVM_GUESTDBG_USE_SW_BP;
915d38e31efSBibo Mao     }
916d38e31efSBibo Mao }
917d38e31efSBibo Mao 
918d38e31efSBibo Mao int kvm_arch_insert_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
919d38e31efSBibo Mao {
920d38e31efSBibo Mao     if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 0) ||
921d38e31efSBibo Mao         cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk_insn, 4, 1)) {
922d38e31efSBibo Mao         error_report("%s failed", __func__);
923d38e31efSBibo Mao         return -EINVAL;
924d38e31efSBibo Mao     }
925d38e31efSBibo Mao     return 0;
926d38e31efSBibo Mao }
927d38e31efSBibo Mao 
928d38e31efSBibo Mao int kvm_arch_remove_sw_breakpoint(CPUState *cs, struct kvm_sw_breakpoint *bp)
929d38e31efSBibo Mao {
930d38e31efSBibo Mao     static uint32_t brk;
931d38e31efSBibo Mao 
932d38e31efSBibo Mao     if (cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&brk, 4, 0) ||
933d38e31efSBibo Mao         brk != brk_insn ||
934d38e31efSBibo Mao         cpu_memory_rw_debug(cs, bp->pc, (uint8_t *)&bp->saved_insn, 4, 1)) {
935d38e31efSBibo Mao         error_report("%s failed", __func__);
936d38e31efSBibo Mao         return -EINVAL;
937d38e31efSBibo Mao     }
938d38e31efSBibo Mao     return 0;
939d38e31efSBibo Mao }
940d38e31efSBibo Mao 
941d38e31efSBibo Mao int kvm_arch_insert_hw_breakpoint(vaddr addr, vaddr len, int type)
942d38e31efSBibo Mao {
943d38e31efSBibo Mao     return -ENOSYS;
944d38e31efSBibo Mao }
945d38e31efSBibo Mao 
946d38e31efSBibo Mao int kvm_arch_remove_hw_breakpoint(vaddr addr, vaddr len, int type)
947d38e31efSBibo Mao {
948d38e31efSBibo Mao     return -ENOSYS;
949d38e31efSBibo Mao }
950d38e31efSBibo Mao 
951d38e31efSBibo Mao void kvm_arch_remove_all_hw_breakpoints(void)
952d38e31efSBibo Mao {
953d38e31efSBibo Mao }
954d38e31efSBibo Mao 
955d38e31efSBibo Mao static bool kvm_loongarch_handle_debug(CPUState *cs, struct kvm_run *run)
956d38e31efSBibo Mao {
957d38e31efSBibo Mao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
958d38e31efSBibo Mao     CPULoongArchState *env = &cpu->env;
959d38e31efSBibo Mao 
960d38e31efSBibo Mao     kvm_cpu_synchronize_state(cs);
961d38e31efSBibo Mao     if (cs->singlestep_enabled) {
962d38e31efSBibo Mao         return true;
963d38e31efSBibo Mao     }
964d38e31efSBibo Mao 
965d38e31efSBibo Mao     if (kvm_find_sw_breakpoint(cs, env->pc)) {
966d38e31efSBibo Mao         return true;
967d38e31efSBibo Mao     }
968d38e31efSBibo Mao 
969d38e31efSBibo Mao     return false;
970d38e31efSBibo Mao }
971d38e31efSBibo Mao 
972537ba9daSTianrui Zhao int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
973537ba9daSTianrui Zhao {
974a05a950fSTianrui Zhao     int ret = 0;
975f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
976a05a950fSTianrui Zhao     MemTxAttrs attrs = {};
977a05a950fSTianrui Zhao 
978a05a950fSTianrui Zhao     attrs.requester_id = env_cpu(env)->cpu_index;
979a05a950fSTianrui Zhao 
980a05a950fSTianrui Zhao     trace_kvm_arch_handle_exit(run->exit_reason);
981a05a950fSTianrui Zhao     switch (run->exit_reason) {
982a05a950fSTianrui Zhao     case KVM_EXIT_LOONGARCH_IOCSR:
9835e90b8dbSBibo Mao         address_space_rw(env->address_space_iocsr,
984a05a950fSTianrui Zhao                          run->iocsr_io.phys_addr,
985a05a950fSTianrui Zhao                          attrs,
986a05a950fSTianrui Zhao                          run->iocsr_io.data,
987a05a950fSTianrui Zhao                          run->iocsr_io.len,
988a05a950fSTianrui Zhao                          run->iocsr_io.is_write);
989a05a950fSTianrui Zhao         break;
990d38e31efSBibo Mao 
991d38e31efSBibo Mao     case KVM_EXIT_DEBUG:
992d38e31efSBibo Mao         if (kvm_loongarch_handle_debug(cs, run)) {
993d38e31efSBibo Mao             ret = EXCP_DEBUG;
994d38e31efSBibo Mao         }
995d38e31efSBibo Mao         break;
996d38e31efSBibo Mao 
997a05a950fSTianrui Zhao     default:
998a05a950fSTianrui Zhao         ret = -1;
999a05a950fSTianrui Zhao         warn_report("KVM: unknown exit reason %d", run->exit_reason);
1000a05a950fSTianrui Zhao         break;
1001a05a950fSTianrui Zhao     }
1002a05a950fSTianrui Zhao     return ret;
1003537ba9daSTianrui Zhao }
1004537ba9daSTianrui Zhao 
10058dcbad51STianrui Zhao int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level)
10068dcbad51STianrui Zhao {
10078dcbad51STianrui Zhao     struct kvm_interrupt intr;
10088dcbad51STianrui Zhao     CPUState *cs = CPU(cpu);
10098dcbad51STianrui Zhao 
10108dcbad51STianrui Zhao     if (level) {
10118dcbad51STianrui Zhao         intr.irq = irq;
10128dcbad51STianrui Zhao     } else {
10138dcbad51STianrui Zhao         intr.irq = -irq;
10148dcbad51STianrui Zhao     }
10158dcbad51STianrui Zhao 
10168dcbad51STianrui Zhao     trace_kvm_set_intr(irq, level);
10178dcbad51STianrui Zhao     return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
10188dcbad51STianrui Zhao }
10198dcbad51STianrui Zhao 
1020537ba9daSTianrui Zhao void kvm_arch_accel_class_init(ObjectClass *oc)
1021537ba9daSTianrui Zhao {
1022537ba9daSTianrui Zhao }
1023