xref: /openbmc/qemu/target/loongarch/kvm/kvm.c (revision effd60c8)
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 /*
3  * QEMU LoongArch KVM
4  *
5  * Copyright (c) 2023 Loongson Technology Corporation Limited
6  */
7 
8 #include "qemu/osdep.h"
9 #include <sys/ioctl.h>
10 #include <linux/kvm.h>
11 
12 #include "qemu/timer.h"
13 #include "qemu/error-report.h"
14 #include "qemu/main-loop.h"
15 #include "sysemu/sysemu.h"
16 #include "sysemu/kvm.h"
17 #include "sysemu/kvm_int.h"
18 #include "hw/pci/pci.h"
19 #include "exec/memattrs.h"
20 #include "exec/address-spaces.h"
21 #include "hw/boards.h"
22 #include "hw/irq.h"
23 #include "qemu/log.h"
24 #include "hw/loader.h"
25 #include "migration/migration.h"
26 #include "sysemu/runstate.h"
27 #include "cpu-csr.h"
28 #include "kvm_loongarch.h"
29 #include "trace.h"
30 
31 static bool cap_has_mp_state;
32 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
33     KVM_CAP_LAST_INFO
34 };
35 
36 static int kvm_loongarch_get_regs_core(CPUState *cs)
37 {
38     int ret = 0;
39     int i;
40     struct kvm_regs regs;
41     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
42     CPULoongArchState *env = &cpu->env;
43 
44     /* Get the current register set as KVM seems it */
45     ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
46     if (ret < 0) {
47         trace_kvm_failed_get_regs_core(strerror(errno));
48         return ret;
49     }
50     /* gpr[0] value is always 0 */
51     env->gpr[0] = 0;
52     for (i = 1; i < 32; i++) {
53         env->gpr[i] = regs.gpr[i];
54     }
55 
56     env->pc = regs.pc;
57     return ret;
58 }
59 
60 static int kvm_loongarch_put_regs_core(CPUState *cs)
61 {
62     int ret = 0;
63     int i;
64     struct kvm_regs regs;
65     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
66     CPULoongArchState *env = &cpu->env;
67 
68     /* Set the registers based on QEMU's view of things */
69     for (i = 0; i < 32; i++) {
70         regs.gpr[i] = env->gpr[i];
71     }
72 
73     regs.pc = env->pc;
74     ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
75     if (ret < 0) {
76         trace_kvm_failed_put_regs_core(strerror(errno));
77     }
78 
79     return ret;
80 }
81 
82 static int kvm_loongarch_get_csr(CPUState *cs)
83 {
84     int ret = 0;
85     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
86     CPULoongArchState *env = &cpu->env;
87 
88     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
89                            &env->CSR_CRMD);
90 
91     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
92                            &env->CSR_PRMD);
93 
94     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
95                            &env->CSR_EUEN);
96 
97     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
98                            &env->CSR_MISC);
99 
100     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
101                            &env->CSR_ECFG);
102 
103     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
104                            &env->CSR_ESTAT);
105 
106     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
107                            &env->CSR_ERA);
108 
109     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
110                            &env->CSR_BADV);
111 
112     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
113                            &env->CSR_BADI);
114 
115     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
116                            &env->CSR_EENTRY);
117 
118     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
119                            &env->CSR_TLBIDX);
120 
121     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
122                            &env->CSR_TLBEHI);
123 
124     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
125                            &env->CSR_TLBELO0);
126 
127     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
128                            &env->CSR_TLBELO1);
129 
130     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
131                            &env->CSR_ASID);
132 
133     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
134                            &env->CSR_PGDL);
135 
136     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
137                            &env->CSR_PGDH);
138 
139     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
140                            &env->CSR_PGD);
141 
142     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
143                            &env->CSR_PWCL);
144 
145     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
146                            &env->CSR_PWCH);
147 
148     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
149                            &env->CSR_STLBPS);
150 
151     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
152                            &env->CSR_RVACFG);
153 
154     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
155                            &env->CSR_CPUID);
156 
157     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
158                            &env->CSR_PRCFG1);
159 
160     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
161                            &env->CSR_PRCFG2);
162 
163     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
164                            &env->CSR_PRCFG3);
165 
166     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
167                            &env->CSR_SAVE[0]);
168 
169     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
170                            &env->CSR_SAVE[1]);
171 
172     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
173                            &env->CSR_SAVE[2]);
174 
175     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
176                            &env->CSR_SAVE[3]);
177 
178     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
179                            &env->CSR_SAVE[4]);
180 
181     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
182                            &env->CSR_SAVE[5]);
183 
184     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
185                            &env->CSR_SAVE[6]);
186 
187     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
188                            &env->CSR_SAVE[7]);
189 
190     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
191                            &env->CSR_TID);
192 
193     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
194                            &env->CSR_CNTC);
195 
196     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
197                            &env->CSR_TICLR);
198 
199     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
200                            &env->CSR_LLBCTL);
201 
202     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
203                            &env->CSR_IMPCTL1);
204 
205     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
206                            &env->CSR_IMPCTL2);
207 
208     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
209                            &env->CSR_TLBRENTRY);
210 
211     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
212                            &env->CSR_TLBRBADV);
213 
214     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
215                            &env->CSR_TLBRERA);
216 
217     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
218                            &env->CSR_TLBRSAVE);
219 
220     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
221                            &env->CSR_TLBRELO0);
222 
223     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
224                            &env->CSR_TLBRELO1);
225 
226     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
227                            &env->CSR_TLBREHI);
228 
229     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
230                            &env->CSR_TLBRPRMD);
231 
232     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
233                            &env->CSR_DMW[0]);
234 
235     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
236                            &env->CSR_DMW[1]);
237 
238     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
239                            &env->CSR_DMW[2]);
240 
241     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
242                            &env->CSR_DMW[3]);
243 
244     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
245                            &env->CSR_TVAL);
246 
247     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
248                            &env->CSR_TCFG);
249 
250     return ret;
251 }
252 
253 static int kvm_loongarch_put_csr(CPUState *cs)
254 {
255     int ret = 0;
256     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
257     CPULoongArchState *env = &cpu->env;
258 
259     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
260                            &env->CSR_CRMD);
261 
262     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
263                            &env->CSR_PRMD);
264 
265     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
266                            &env->CSR_EUEN);
267 
268     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
269                            &env->CSR_MISC);
270 
271     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
272                            &env->CSR_ECFG);
273 
274     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
275                            &env->CSR_ESTAT);
276 
277     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
278                            &env->CSR_ERA);
279 
280     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
281                            &env->CSR_BADV);
282 
283     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
284                            &env->CSR_BADI);
285 
286     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
287                            &env->CSR_EENTRY);
288 
289     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
290                            &env->CSR_TLBIDX);
291 
292     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
293                            &env->CSR_TLBEHI);
294 
295     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
296                            &env->CSR_TLBELO0);
297 
298     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
299                            &env->CSR_TLBELO1);
300 
301     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
302                            &env->CSR_ASID);
303 
304     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
305                            &env->CSR_PGDL);
306 
307     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
308                            &env->CSR_PGDH);
309 
310     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
311                            &env->CSR_PGD);
312 
313     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
314                            &env->CSR_PWCL);
315 
316     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
317                            &env->CSR_PWCH);
318 
319     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
320                            &env->CSR_STLBPS);
321 
322     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
323                            &env->CSR_RVACFG);
324 
325     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
326                            &env->CSR_CPUID);
327 
328     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
329                            &env->CSR_PRCFG1);
330 
331     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
332                            &env->CSR_PRCFG2);
333 
334     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
335                            &env->CSR_PRCFG3);
336 
337     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
338                            &env->CSR_SAVE[0]);
339 
340     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
341                            &env->CSR_SAVE[1]);
342 
343     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
344                            &env->CSR_SAVE[2]);
345 
346     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
347                            &env->CSR_SAVE[3]);
348 
349     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
350                            &env->CSR_SAVE[4]);
351 
352     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
353                            &env->CSR_SAVE[5]);
354 
355     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
356                            &env->CSR_SAVE[6]);
357 
358     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
359                            &env->CSR_SAVE[7]);
360 
361     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
362                            &env->CSR_TID);
363 
364     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
365                            &env->CSR_CNTC);
366 
367     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
368                            &env->CSR_TICLR);
369 
370     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
371                            &env->CSR_LLBCTL);
372 
373     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
374                            &env->CSR_IMPCTL1);
375 
376     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
377                            &env->CSR_IMPCTL2);
378 
379     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
380                            &env->CSR_TLBRENTRY);
381 
382     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
383                            &env->CSR_TLBRBADV);
384 
385     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
386                            &env->CSR_TLBRERA);
387 
388     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
389                            &env->CSR_TLBRSAVE);
390 
391     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
392                            &env->CSR_TLBRELO0);
393 
394     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
395                            &env->CSR_TLBRELO1);
396 
397     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
398                            &env->CSR_TLBREHI);
399 
400     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
401                            &env->CSR_TLBRPRMD);
402 
403     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
404                            &env->CSR_DMW[0]);
405 
406     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
407                            &env->CSR_DMW[1]);
408 
409     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
410                            &env->CSR_DMW[2]);
411 
412     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
413                            &env->CSR_DMW[3]);
414     /*
415      * timer cfg must be put at last since it is used to enable
416      * guest timer
417      */
418     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
419                            &env->CSR_TVAL);
420 
421     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
422                            &env->CSR_TCFG);
423     return ret;
424 }
425 
426 static int kvm_loongarch_get_regs_fp(CPUState *cs)
427 {
428     int ret, i;
429     struct kvm_fpu fpu;
430 
431     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
432     CPULoongArchState *env = &cpu->env;
433 
434     ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
435     if (ret < 0) {
436         trace_kvm_failed_get_fpu(strerror(errno));
437         return ret;
438     }
439 
440     env->fcsr0 = fpu.fcsr;
441     for (i = 0; i < 32; i++) {
442         env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
443     }
444     for (i = 0; i < 8; i++) {
445         env->cf[i] = fpu.fcc & 0xFF;
446         fpu.fcc = fpu.fcc >> 8;
447     }
448 
449     return ret;
450 }
451 
452 static int kvm_loongarch_put_regs_fp(CPUState *cs)
453 {
454     int ret, i;
455     struct kvm_fpu fpu;
456 
457     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
458     CPULoongArchState *env = &cpu->env;
459 
460     fpu.fcsr = env->fcsr0;
461     fpu.fcc = 0;
462     for (i = 0; i < 32; i++) {
463         fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
464     }
465 
466     for (i = 0; i < 8; i++) {
467         fpu.fcc |= env->cf[i] << (8 * i);
468     }
469 
470     ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
471     if (ret < 0) {
472         trace_kvm_failed_put_fpu(strerror(errno));
473     }
474 
475     return ret;
476 }
477 
478 void kvm_arch_reset_vcpu(CPULoongArchState *env)
479 {
480     env->mp_state = KVM_MP_STATE_RUNNABLE;
481 }
482 
483 static int kvm_loongarch_get_mpstate(CPUState *cs)
484 {
485     int ret = 0;
486     struct kvm_mp_state mp_state;
487     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
488     CPULoongArchState *env = &cpu->env;
489 
490     if (cap_has_mp_state) {
491         ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
492         if (ret) {
493             trace_kvm_failed_get_mpstate(strerror(errno));
494             return ret;
495         }
496         env->mp_state = mp_state.mp_state;
497     }
498 
499     return ret;
500 }
501 
502 static int kvm_loongarch_put_mpstate(CPUState *cs)
503 {
504     int ret = 0;
505 
506     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
507     CPULoongArchState *env = &cpu->env;
508 
509     struct kvm_mp_state mp_state = {
510         .mp_state = env->mp_state
511     };
512 
513     if (cap_has_mp_state) {
514         ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state);
515         if (ret) {
516             trace_kvm_failed_put_mpstate(strerror(errno));
517         }
518     }
519 
520     return ret;
521 }
522 
523 static int kvm_loongarch_get_cpucfg(CPUState *cs)
524 {
525     int i, ret = 0;
526     uint64_t val;
527     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
528     CPULoongArchState *env = &cpu->env;
529 
530     for (i = 0; i < 21; i++) {
531         ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
532         if (ret < 0) {
533             trace_kvm_failed_get_cpucfg(strerror(errno));
534         }
535         env->cpucfg[i] = (uint32_t)val;
536     }
537     return ret;
538 }
539 
540 static int kvm_loongarch_put_cpucfg(CPUState *cs)
541 {
542     int i, ret = 0;
543     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
544     CPULoongArchState *env = &cpu->env;
545     uint64_t val;
546 
547     for (i = 0; i < 21; i++) {
548         val = env->cpucfg[i];
549         /* LSX and LASX and LBT are not supported in kvm now */
550         if (i == 2) {
551             val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT));
552             val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
553                      BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
554                      BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
555         }
556         ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
557         if (ret < 0) {
558             trace_kvm_failed_put_cpucfg(strerror(errno));
559         }
560     }
561     return ret;
562 }
563 
564 int kvm_arch_get_registers(CPUState *cs)
565 {
566     int ret;
567 
568     ret = kvm_loongarch_get_regs_core(cs);
569     if (ret) {
570         return ret;
571     }
572 
573     ret = kvm_loongarch_get_csr(cs);
574     if (ret) {
575         return ret;
576     }
577 
578     ret = kvm_loongarch_get_regs_fp(cs);
579     if (ret) {
580         return ret;
581     }
582 
583     ret = kvm_loongarch_get_mpstate(cs);
584     if (ret) {
585         return ret;
586     }
587 
588     ret = kvm_loongarch_get_cpucfg(cs);
589     return ret;
590 }
591 
592 int kvm_arch_put_registers(CPUState *cs, int level)
593 {
594     int ret;
595 
596     ret = kvm_loongarch_put_regs_core(cs);
597     if (ret) {
598         return ret;
599     }
600 
601     ret = kvm_loongarch_put_csr(cs);
602     if (ret) {
603         return ret;
604     }
605 
606     ret = kvm_loongarch_put_regs_fp(cs);
607     if (ret) {
608         return ret;
609     }
610 
611     ret = kvm_loongarch_put_mpstate(cs);
612     if (ret) {
613         return ret;
614     }
615 
616     ret = kvm_loongarch_put_cpucfg(cs);
617     return ret;
618 }
619 
620 static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
621                                           RunState state)
622 {
623     int ret;
624     CPUState *cs = opaque;
625     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
626 
627     if (running) {
628         ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
629                               &cpu->kvm_state_counter);
630         if (ret < 0) {
631             trace_kvm_failed_put_counter(strerror(errno));
632         }
633     } else {
634         ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
635                               &cpu->kvm_state_counter);
636         if (ret < 0) {
637             trace_kvm_failed_get_counter(strerror(errno));
638         }
639     }
640 }
641 
642 int kvm_arch_init_vcpu(CPUState *cs)
643 {
644     qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
645     return 0;
646 }
647 
648 int kvm_arch_destroy_vcpu(CPUState *cs)
649 {
650     return 0;
651 }
652 
653 unsigned long kvm_arch_vcpu_id(CPUState *cs)
654 {
655     return cs->cpu_index;
656 }
657 
658 int kvm_arch_release_virq_post(int virq)
659 {
660     return 0;
661 }
662 
663 int kvm_arch_msi_data_to_gsi(uint32_t data)
664 {
665     abort();
666 }
667 
668 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
669                              uint64_t address, uint32_t data, PCIDevice *dev)
670 {
671     return 0;
672 }
673 
674 int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
675                                 int vector, PCIDevice *dev)
676 {
677     return 0;
678 }
679 
680 void kvm_arch_init_irq_routing(KVMState *s)
681 {
682 }
683 
684 int kvm_arch_get_default_type(MachineState *ms)
685 {
686     return 0;
687 }
688 
689 int kvm_arch_init(MachineState *ms, KVMState *s)
690 {
691     cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
692     return 0;
693 }
694 
695 int kvm_arch_irqchip_create(KVMState *s)
696 {
697     return 0;
698 }
699 
700 void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
701 {
702 }
703 
704 MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
705 {
706     return MEMTXATTRS_UNSPECIFIED;
707 }
708 
709 int kvm_arch_process_async_events(CPUState *cs)
710 {
711     return cs->halted;
712 }
713 
714 bool kvm_arch_stop_on_emulation_error(CPUState *cs)
715 {
716     return true;
717 }
718 
719 bool kvm_arch_cpu_check_are_resettable(void)
720 {
721     return true;
722 }
723 
724 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
725 {
726     int ret = 0;
727     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
728     CPULoongArchState *env = &cpu->env;
729     MemTxAttrs attrs = {};
730 
731     attrs.requester_id = env_cpu(env)->cpu_index;
732 
733     trace_kvm_arch_handle_exit(run->exit_reason);
734     switch (run->exit_reason) {
735     case KVM_EXIT_LOONGARCH_IOCSR:
736         address_space_rw(env->address_space_iocsr,
737                          run->iocsr_io.phys_addr,
738                          attrs,
739                          run->iocsr_io.data,
740                          run->iocsr_io.len,
741                          run->iocsr_io.is_write);
742         break;
743     default:
744         ret = -1;
745         warn_report("KVM: unknown exit reason %d", run->exit_reason);
746         break;
747     }
748     return ret;
749 }
750 
751 int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level)
752 {
753     struct kvm_interrupt intr;
754     CPUState *cs = CPU(cpu);
755 
756     if (level) {
757         intr.irq = irq;
758     } else {
759         intr.irq = -irq;
760     }
761 
762     trace_kvm_set_intr(irq, level);
763     return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
764 }
765 
766 void kvm_arch_accel_class_init(ObjectClass *oc)
767 {
768 }
769