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