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