xref: /qemu/target/loongarch/kvm/kvm.c (revision 5872966db7abaa7f8753541b7a9f242df9752b50)
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 
12537ba9daSTianrui Zhao #include "qemu/timer.h"
13537ba9daSTianrui Zhao #include "qemu/error-report.h"
14537ba9daSTianrui Zhao #include "qemu/main-loop.h"
15537ba9daSTianrui Zhao #include "sysemu/sysemu.h"
16537ba9daSTianrui Zhao #include "sysemu/kvm.h"
17537ba9daSTianrui Zhao #include "sysemu/kvm_int.h"
18537ba9daSTianrui Zhao #include "hw/pci/pci.h"
19537ba9daSTianrui Zhao #include "exec/memattrs.h"
20537ba9daSTianrui Zhao #include "exec/address-spaces.h"
21537ba9daSTianrui Zhao #include "hw/boards.h"
22537ba9daSTianrui Zhao #include "hw/irq.h"
23537ba9daSTianrui Zhao #include "qemu/log.h"
24537ba9daSTianrui Zhao #include "hw/loader.h"
25537ba9daSTianrui Zhao #include "sysemu/runstate.h"
26537ba9daSTianrui Zhao #include "cpu-csr.h"
27537ba9daSTianrui Zhao #include "kvm_loongarch.h"
28f8447436STianrui Zhao #include "trace.h"
29537ba9daSTianrui Zhao 
30537ba9daSTianrui Zhao static bool cap_has_mp_state;
31537ba9daSTianrui Zhao const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
32537ba9daSTianrui Zhao     KVM_CAP_LAST_INFO
33537ba9daSTianrui Zhao };
34537ba9daSTianrui Zhao 
35f8447436STianrui Zhao static int kvm_loongarch_get_regs_core(CPUState *cs)
36f8447436STianrui Zhao {
37f8447436STianrui Zhao     int ret = 0;
38f8447436STianrui Zhao     int i;
39f8447436STianrui Zhao     struct kvm_regs regs;
40f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
41f8447436STianrui Zhao 
42f8447436STianrui Zhao     /* Get the current register set as KVM seems it */
43f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_GET_REGS, &regs);
44f8447436STianrui Zhao     if (ret < 0) {
45f8447436STianrui Zhao         trace_kvm_failed_get_regs_core(strerror(errno));
46f8447436STianrui Zhao         return ret;
47f8447436STianrui Zhao     }
48f8447436STianrui Zhao     /* gpr[0] value is always 0 */
49f8447436STianrui Zhao     env->gpr[0] = 0;
50f8447436STianrui Zhao     for (i = 1; i < 32; i++) {
51f8447436STianrui Zhao         env->gpr[i] = regs.gpr[i];
52f8447436STianrui Zhao     }
53f8447436STianrui Zhao 
54f8447436STianrui Zhao     env->pc = regs.pc;
55f8447436STianrui Zhao     return ret;
56f8447436STianrui Zhao }
57f8447436STianrui Zhao 
58f8447436STianrui Zhao static int kvm_loongarch_put_regs_core(CPUState *cs)
59f8447436STianrui Zhao {
60f8447436STianrui Zhao     int ret = 0;
61f8447436STianrui Zhao     int i;
62f8447436STianrui Zhao     struct kvm_regs regs;
63f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
64f8447436STianrui Zhao 
65f8447436STianrui Zhao     /* Set the registers based on QEMU's view of things */
66f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
67f8447436STianrui Zhao         regs.gpr[i] = env->gpr[i];
68f8447436STianrui Zhao     }
69f8447436STianrui Zhao 
70f8447436STianrui Zhao     regs.pc = env->pc;
71f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_SET_REGS, &regs);
72f8447436STianrui Zhao     if (ret < 0) {
73f8447436STianrui Zhao         trace_kvm_failed_put_regs_core(strerror(errno));
74f8447436STianrui Zhao     }
75f8447436STianrui Zhao 
76f8447436STianrui Zhao     return ret;
77f8447436STianrui Zhao }
78f8447436STianrui Zhao 
79f8447436STianrui Zhao static int kvm_loongarch_get_csr(CPUState *cs)
80f8447436STianrui Zhao {
81f8447436STianrui Zhao     int ret = 0;
82f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
83f8447436STianrui Zhao 
84f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
85f8447436STianrui Zhao                            &env->CSR_CRMD);
86f8447436STianrui Zhao 
87f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
88f8447436STianrui Zhao                            &env->CSR_PRMD);
89f8447436STianrui Zhao 
90f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
91f8447436STianrui Zhao                            &env->CSR_EUEN);
92f8447436STianrui Zhao 
93f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
94f8447436STianrui Zhao                            &env->CSR_MISC);
95f8447436STianrui Zhao 
96f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
97f8447436STianrui Zhao                            &env->CSR_ECFG);
98f8447436STianrui Zhao 
99f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
100f8447436STianrui Zhao                            &env->CSR_ESTAT);
101f8447436STianrui Zhao 
102f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
103f8447436STianrui Zhao                            &env->CSR_ERA);
104f8447436STianrui Zhao 
105f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
106f8447436STianrui Zhao                            &env->CSR_BADV);
107f8447436STianrui Zhao 
108f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
109f8447436STianrui Zhao                            &env->CSR_BADI);
110f8447436STianrui Zhao 
111f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
112f8447436STianrui Zhao                            &env->CSR_EENTRY);
113f8447436STianrui Zhao 
114f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
115f8447436STianrui Zhao                            &env->CSR_TLBIDX);
116f8447436STianrui Zhao 
117f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
118f8447436STianrui Zhao                            &env->CSR_TLBEHI);
119f8447436STianrui Zhao 
120f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
121f8447436STianrui Zhao                            &env->CSR_TLBELO0);
122f8447436STianrui Zhao 
123f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
124f8447436STianrui Zhao                            &env->CSR_TLBELO1);
125f8447436STianrui Zhao 
126f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
127f8447436STianrui Zhao                            &env->CSR_ASID);
128f8447436STianrui Zhao 
129f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
130f8447436STianrui Zhao                            &env->CSR_PGDL);
131f8447436STianrui Zhao 
132f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
133f8447436STianrui Zhao                            &env->CSR_PGDH);
134f8447436STianrui Zhao 
135f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
136f8447436STianrui Zhao                            &env->CSR_PGD);
137f8447436STianrui Zhao 
138f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
139f8447436STianrui Zhao                            &env->CSR_PWCL);
140f8447436STianrui Zhao 
141f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
142f8447436STianrui Zhao                            &env->CSR_PWCH);
143f8447436STianrui Zhao 
144f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
145f8447436STianrui Zhao                            &env->CSR_STLBPS);
146f8447436STianrui Zhao 
147f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
148f8447436STianrui Zhao                            &env->CSR_RVACFG);
149f8447436STianrui Zhao 
150f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
151f8447436STianrui Zhao                            &env->CSR_CPUID);
152f8447436STianrui Zhao 
153f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
154f8447436STianrui Zhao                            &env->CSR_PRCFG1);
155f8447436STianrui Zhao 
156f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
157f8447436STianrui Zhao                            &env->CSR_PRCFG2);
158f8447436STianrui Zhao 
159f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
160f8447436STianrui Zhao                            &env->CSR_PRCFG3);
161f8447436STianrui Zhao 
162f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
163f8447436STianrui Zhao                            &env->CSR_SAVE[0]);
164f8447436STianrui Zhao 
165f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
166f8447436STianrui Zhao                            &env->CSR_SAVE[1]);
167f8447436STianrui Zhao 
168f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
169f8447436STianrui Zhao                            &env->CSR_SAVE[2]);
170f8447436STianrui Zhao 
171f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
172f8447436STianrui Zhao                            &env->CSR_SAVE[3]);
173f8447436STianrui Zhao 
174f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
175f8447436STianrui Zhao                            &env->CSR_SAVE[4]);
176f8447436STianrui Zhao 
177f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
178f8447436STianrui Zhao                            &env->CSR_SAVE[5]);
179f8447436STianrui Zhao 
180f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
181f8447436STianrui Zhao                            &env->CSR_SAVE[6]);
182f8447436STianrui Zhao 
183f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
184f8447436STianrui Zhao                            &env->CSR_SAVE[7]);
185f8447436STianrui Zhao 
186f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
187f8447436STianrui Zhao                            &env->CSR_TID);
188f8447436STianrui Zhao 
189f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
190f8447436STianrui Zhao                            &env->CSR_CNTC);
191f8447436STianrui Zhao 
192f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
193f8447436STianrui Zhao                            &env->CSR_TICLR);
194f8447436STianrui Zhao 
195f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
196f8447436STianrui Zhao                            &env->CSR_LLBCTL);
197f8447436STianrui Zhao 
198f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
199f8447436STianrui Zhao                            &env->CSR_IMPCTL1);
200f8447436STianrui Zhao 
201f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
202f8447436STianrui Zhao                            &env->CSR_IMPCTL2);
203f8447436STianrui Zhao 
204f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
205f8447436STianrui Zhao                            &env->CSR_TLBRENTRY);
206f8447436STianrui Zhao 
207f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
208f8447436STianrui Zhao                            &env->CSR_TLBRBADV);
209f8447436STianrui Zhao 
210f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
211f8447436STianrui Zhao                            &env->CSR_TLBRERA);
212f8447436STianrui Zhao 
213f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
214f8447436STianrui Zhao                            &env->CSR_TLBRSAVE);
215f8447436STianrui Zhao 
216f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
217f8447436STianrui Zhao                            &env->CSR_TLBRELO0);
218f8447436STianrui Zhao 
219f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
220f8447436STianrui Zhao                            &env->CSR_TLBRELO1);
221f8447436STianrui Zhao 
222f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
223f8447436STianrui Zhao                            &env->CSR_TLBREHI);
224f8447436STianrui Zhao 
225f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
226f8447436STianrui Zhao                            &env->CSR_TLBRPRMD);
227f8447436STianrui Zhao 
228f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
229f8447436STianrui Zhao                            &env->CSR_DMW[0]);
230f8447436STianrui Zhao 
231f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
232f8447436STianrui Zhao                            &env->CSR_DMW[1]);
233f8447436STianrui Zhao 
234f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
235f8447436STianrui Zhao                            &env->CSR_DMW[2]);
236f8447436STianrui Zhao 
237f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
238f8447436STianrui Zhao                            &env->CSR_DMW[3]);
239f8447436STianrui Zhao 
240f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
241f8447436STianrui Zhao                            &env->CSR_TVAL);
242f8447436STianrui Zhao 
243f8447436STianrui Zhao     ret |= kvm_get_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
244f8447436STianrui Zhao                            &env->CSR_TCFG);
245f8447436STianrui Zhao 
246f8447436STianrui Zhao     return ret;
247f8447436STianrui Zhao }
248f8447436STianrui Zhao 
24961f6e150SBibo Mao static int kvm_loongarch_put_csr(CPUState *cs, int level)
250f8447436STianrui Zhao {
251f8447436STianrui Zhao     int ret = 0;
252f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
253f8447436STianrui Zhao 
254f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CRMD),
255f8447436STianrui Zhao                            &env->CSR_CRMD);
256f8447436STianrui Zhao 
257f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRMD),
258f8447436STianrui Zhao                            &env->CSR_PRMD);
259f8447436STianrui Zhao 
260f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EUEN),
261f8447436STianrui Zhao                            &env->CSR_EUEN);
262f8447436STianrui Zhao 
263f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_MISC),
264f8447436STianrui Zhao                            &env->CSR_MISC);
265f8447436STianrui Zhao 
266f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ECFG),
267f8447436STianrui Zhao                            &env->CSR_ECFG);
268f8447436STianrui Zhao 
269f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ESTAT),
270f8447436STianrui Zhao                            &env->CSR_ESTAT);
271f8447436STianrui Zhao 
272f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ERA),
273f8447436STianrui Zhao                            &env->CSR_ERA);
274f8447436STianrui Zhao 
275f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADV),
276f8447436STianrui Zhao                            &env->CSR_BADV);
277f8447436STianrui Zhao 
278f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_BADI),
279f8447436STianrui Zhao                            &env->CSR_BADI);
280f8447436STianrui Zhao 
281f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_EENTRY),
282f8447436STianrui Zhao                            &env->CSR_EENTRY);
283f8447436STianrui Zhao 
284f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBIDX),
285f8447436STianrui Zhao                            &env->CSR_TLBIDX);
286f8447436STianrui Zhao 
287f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBEHI),
288f8447436STianrui Zhao                            &env->CSR_TLBEHI);
289f8447436STianrui Zhao 
290f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO0),
291f8447436STianrui Zhao                            &env->CSR_TLBELO0);
292f8447436STianrui Zhao 
293f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBELO1),
294f8447436STianrui Zhao                            &env->CSR_TLBELO1);
295f8447436STianrui Zhao 
296f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_ASID),
297f8447436STianrui Zhao                            &env->CSR_ASID);
298f8447436STianrui Zhao 
299f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDL),
300f8447436STianrui Zhao                            &env->CSR_PGDL);
301f8447436STianrui Zhao 
302f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGDH),
303f8447436STianrui Zhao                            &env->CSR_PGDH);
304f8447436STianrui Zhao 
305f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PGD),
306f8447436STianrui Zhao                            &env->CSR_PGD);
307f8447436STianrui Zhao 
308f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCL),
309f8447436STianrui Zhao                            &env->CSR_PWCL);
310f8447436STianrui Zhao 
311f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PWCH),
312f8447436STianrui Zhao                            &env->CSR_PWCH);
313f8447436STianrui Zhao 
314f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_STLBPS),
315f8447436STianrui Zhao                            &env->CSR_STLBPS);
316f8447436STianrui Zhao 
317f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_RVACFG),
318f8447436STianrui Zhao                            &env->CSR_RVACFG);
319f8447436STianrui Zhao 
32061f6e150SBibo Mao     /* CPUID is constant after poweron, it should be set only once */
32161f6e150SBibo Mao     if (level >= KVM_PUT_FULL_STATE) {
322f8447436STianrui Zhao         ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
323f8447436STianrui Zhao                            &env->CSR_CPUID);
32461f6e150SBibo Mao     }
325f8447436STianrui Zhao 
326f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
327f8447436STianrui Zhao                            &env->CSR_PRCFG1);
328f8447436STianrui Zhao 
329f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
330f8447436STianrui Zhao                            &env->CSR_PRCFG2);
331f8447436STianrui Zhao 
332f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
333f8447436STianrui Zhao                            &env->CSR_PRCFG3);
334f8447436STianrui Zhao 
335f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
336f8447436STianrui Zhao                            &env->CSR_SAVE[0]);
337f8447436STianrui Zhao 
338f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
339f8447436STianrui Zhao                            &env->CSR_SAVE[1]);
340f8447436STianrui Zhao 
341f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
342f8447436STianrui Zhao                            &env->CSR_SAVE[2]);
343f8447436STianrui Zhao 
344f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
345f8447436STianrui Zhao                            &env->CSR_SAVE[3]);
346f8447436STianrui Zhao 
347f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
348f8447436STianrui Zhao                            &env->CSR_SAVE[4]);
349f8447436STianrui Zhao 
350f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
351f8447436STianrui Zhao                            &env->CSR_SAVE[5]);
352f8447436STianrui Zhao 
353f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
354f8447436STianrui Zhao                            &env->CSR_SAVE[6]);
355f8447436STianrui Zhao 
356f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
357f8447436STianrui Zhao                            &env->CSR_SAVE[7]);
358f8447436STianrui Zhao 
359f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
360f8447436STianrui Zhao                            &env->CSR_TID);
361f8447436STianrui Zhao 
362f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
363f8447436STianrui Zhao                            &env->CSR_CNTC);
364f8447436STianrui Zhao 
365f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
366f8447436STianrui Zhao                            &env->CSR_TICLR);
367f8447436STianrui Zhao 
368f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
369f8447436STianrui Zhao                            &env->CSR_LLBCTL);
370f8447436STianrui Zhao 
371f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
372f8447436STianrui Zhao                            &env->CSR_IMPCTL1);
373f8447436STianrui Zhao 
374f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
375f8447436STianrui Zhao                            &env->CSR_IMPCTL2);
376f8447436STianrui Zhao 
377f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
378f8447436STianrui Zhao                            &env->CSR_TLBRENTRY);
379f8447436STianrui Zhao 
380f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
381f8447436STianrui Zhao                            &env->CSR_TLBRBADV);
382f8447436STianrui Zhao 
383f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
384f8447436STianrui Zhao                            &env->CSR_TLBRERA);
385f8447436STianrui Zhao 
386f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
387f8447436STianrui Zhao                            &env->CSR_TLBRSAVE);
388f8447436STianrui Zhao 
389f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
390f8447436STianrui Zhao                            &env->CSR_TLBRELO0);
391f8447436STianrui Zhao 
392f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
393f8447436STianrui Zhao                            &env->CSR_TLBRELO1);
394f8447436STianrui Zhao 
395f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
396f8447436STianrui Zhao                            &env->CSR_TLBREHI);
397f8447436STianrui Zhao 
398f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
399f8447436STianrui Zhao                            &env->CSR_TLBRPRMD);
400f8447436STianrui Zhao 
401f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
402f8447436STianrui Zhao                            &env->CSR_DMW[0]);
403f8447436STianrui Zhao 
404f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
405f8447436STianrui Zhao                            &env->CSR_DMW[1]);
406f8447436STianrui Zhao 
407f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
408f8447436STianrui Zhao                            &env->CSR_DMW[2]);
409f8447436STianrui Zhao 
410f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
411f8447436STianrui Zhao                            &env->CSR_DMW[3]);
412f8447436STianrui Zhao     /*
413f8447436STianrui Zhao      * timer cfg must be put at last since it is used to enable
414f8447436STianrui Zhao      * guest timer
415f8447436STianrui Zhao      */
416f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
417f8447436STianrui Zhao                            &env->CSR_TVAL);
418f8447436STianrui Zhao 
419f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
420f8447436STianrui Zhao                            &env->CSR_TCFG);
421f8447436STianrui Zhao     return ret;
422f8447436STianrui Zhao }
423f8447436STianrui Zhao 
424f8447436STianrui Zhao static int kvm_loongarch_get_regs_fp(CPUState *cs)
425f8447436STianrui Zhao {
426f8447436STianrui Zhao     int ret, i;
427f8447436STianrui Zhao     struct kvm_fpu fpu;
428f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
429f8447436STianrui Zhao 
430f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
431f8447436STianrui Zhao     if (ret < 0) {
432f8447436STianrui Zhao         trace_kvm_failed_get_fpu(strerror(errno));
433f8447436STianrui Zhao         return ret;
434f8447436STianrui Zhao     }
435f8447436STianrui Zhao 
436f8447436STianrui Zhao     env->fcsr0 = fpu.fcsr;
437f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
438f8447436STianrui Zhao         env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
439f8447436STianrui Zhao     }
440f8447436STianrui Zhao     for (i = 0; i < 8; i++) {
441f8447436STianrui Zhao         env->cf[i] = fpu.fcc & 0xFF;
442f8447436STianrui Zhao         fpu.fcc = fpu.fcc >> 8;
443f8447436STianrui Zhao     }
444f8447436STianrui Zhao 
445f8447436STianrui Zhao     return ret;
446f8447436STianrui Zhao }
447f8447436STianrui Zhao 
448f8447436STianrui Zhao static int kvm_loongarch_put_regs_fp(CPUState *cs)
449f8447436STianrui Zhao {
450f8447436STianrui Zhao     int ret, i;
451f8447436STianrui Zhao     struct kvm_fpu fpu;
452f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
453f8447436STianrui Zhao 
454f8447436STianrui Zhao     fpu.fcsr = env->fcsr0;
455f8447436STianrui Zhao     fpu.fcc = 0;
456f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
457f8447436STianrui Zhao         fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
458f8447436STianrui Zhao     }
459f8447436STianrui Zhao 
460f8447436STianrui Zhao     for (i = 0; i < 8; i++) {
461f8447436STianrui Zhao         fpu.fcc |= env->cf[i] << (8 * i);
462f8447436STianrui Zhao     }
463f8447436STianrui Zhao 
464f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
465f8447436STianrui Zhao     if (ret < 0) {
466f8447436STianrui Zhao         trace_kvm_failed_put_fpu(strerror(errno));
467f8447436STianrui Zhao     }
468f8447436STianrui Zhao 
469f8447436STianrui Zhao     return ret;
470f8447436STianrui Zhao }
471f8447436STianrui Zhao 
472f8447436STianrui Zhao void kvm_arch_reset_vcpu(CPULoongArchState *env)
473f8447436STianrui Zhao {
474f8447436STianrui Zhao     env->mp_state = KVM_MP_STATE_RUNNABLE;
475f8447436STianrui Zhao }
476f8447436STianrui Zhao 
477f8447436STianrui Zhao static int kvm_loongarch_get_mpstate(CPUState *cs)
478f8447436STianrui Zhao {
479f8447436STianrui Zhao     int ret = 0;
480f8447436STianrui Zhao     struct kvm_mp_state mp_state;
481f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
482f8447436STianrui Zhao 
483f8447436STianrui Zhao     if (cap_has_mp_state) {
484f8447436STianrui Zhao         ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
485f8447436STianrui Zhao         if (ret) {
486f8447436STianrui Zhao             trace_kvm_failed_get_mpstate(strerror(errno));
487f8447436STianrui Zhao             return ret;
488f8447436STianrui Zhao         }
489f8447436STianrui Zhao         env->mp_state = mp_state.mp_state;
490f8447436STianrui Zhao     }
491f8447436STianrui Zhao 
492f8447436STianrui Zhao     return ret;
493f8447436STianrui Zhao }
494f8447436STianrui Zhao 
495f8447436STianrui Zhao static int kvm_loongarch_put_mpstate(CPUState *cs)
496f8447436STianrui Zhao {
497f8447436STianrui Zhao     int ret = 0;
498f8447436STianrui Zhao     struct kvm_mp_state mp_state = {
499f3b603b9SPhilippe Mathieu-Daudé         .mp_state = cpu_env(cs)->mp_state
500f8447436STianrui Zhao     };
501f8447436STianrui Zhao 
502f8447436STianrui Zhao     if (cap_has_mp_state) {
503f8447436STianrui Zhao         ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state);
504f8447436STianrui Zhao         if (ret) {
505f8447436STianrui Zhao             trace_kvm_failed_put_mpstate(strerror(errno));
506f8447436STianrui Zhao         }
507f8447436STianrui Zhao     }
508f8447436STianrui Zhao 
509f8447436STianrui Zhao     return ret;
510f8447436STianrui Zhao }
511f8447436STianrui Zhao 
512f8447436STianrui Zhao static int kvm_loongarch_get_cpucfg(CPUState *cs)
513f8447436STianrui Zhao {
514f8447436STianrui Zhao     int i, ret = 0;
515f8447436STianrui Zhao     uint64_t val;
516f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
517f8447436STianrui Zhao 
518f8447436STianrui Zhao     for (i = 0; i < 21; i++) {
519f8447436STianrui Zhao         ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
520f8447436STianrui Zhao         if (ret < 0) {
521f8447436STianrui Zhao             trace_kvm_failed_get_cpucfg(strerror(errno));
522f8447436STianrui Zhao         }
523f8447436STianrui Zhao         env->cpucfg[i] = (uint32_t)val;
524f8447436STianrui Zhao     }
525f8447436STianrui Zhao     return ret;
526f8447436STianrui Zhao }
527f8447436STianrui Zhao 
528fc700996SSong Gao static int kvm_check_cpucfg2(CPUState *cs)
529fc700996SSong Gao {
530fc700996SSong Gao     int ret;
531fc700996SSong Gao     uint64_t val;
532fc700996SSong Gao     struct kvm_device_attr attr = {
533fc700996SSong Gao         .group = KVM_LOONGARCH_VCPU_CPUCFG,
534fc700996SSong Gao         .attr = 2,
535fc700996SSong Gao         .addr = (uint64_t)&val,
536fc700996SSong Gao     };
537f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
538fc700996SSong Gao 
539fc700996SSong Gao     ret = kvm_vcpu_ioctl(cs, KVM_HAS_DEVICE_ATTR, &attr);
540fc700996SSong Gao 
541fc700996SSong Gao     if (!ret) {
542fc700996SSong Gao         kvm_vcpu_ioctl(cs, KVM_GET_DEVICE_ATTR, &attr);
543fc700996SSong Gao         env->cpucfg[2] &= val;
544fc700996SSong Gao 
545fc700996SSong Gao         if (FIELD_EX32(env->cpucfg[2], CPUCFG2, FP)) {
546fc700996SSong Gao             /* The FP minimal version is 1. */
547fc700996SSong Gao             env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, FP_VER, 1);
548fc700996SSong Gao         }
549fc700996SSong Gao 
550fc700996SSong Gao         if (FIELD_EX32(env->cpucfg[2], CPUCFG2, LLFTP)) {
551fc700996SSong Gao             /* The LLFTP minimal version is 1. */
552fc700996SSong Gao             env->cpucfg[2] = FIELD_DP32(env->cpucfg[2], CPUCFG2, LLFTP_VER, 1);
553fc700996SSong Gao         }
554fc700996SSong Gao     }
555fc700996SSong Gao 
556fc700996SSong Gao     return ret;
557fc700996SSong Gao }
558fc700996SSong Gao 
559f8447436STianrui Zhao static int kvm_loongarch_put_cpucfg(CPUState *cs)
560f8447436STianrui Zhao {
561f8447436STianrui Zhao     int i, ret = 0;
562f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
563f8447436STianrui Zhao     uint64_t val;
564f8447436STianrui Zhao 
565f8447436STianrui Zhao     for (i = 0; i < 21; i++) {
566f8447436STianrui Zhao 	if (i == 2) {
567fc700996SSong Gao             ret = kvm_check_cpucfg2(cs);
568fc700996SSong Gao             if (ret) {
569fc700996SSong Gao                 return ret;
570f8447436STianrui Zhao             }
571fc700996SSong Gao 	}
572fc700996SSong Gao         val = env->cpucfg[i];
573f8447436STianrui Zhao         ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
574f8447436STianrui Zhao         if (ret < 0) {
575f8447436STianrui Zhao             trace_kvm_failed_put_cpucfg(strerror(errno));
576f8447436STianrui Zhao         }
577f8447436STianrui Zhao     }
578f8447436STianrui Zhao     return ret;
579f8447436STianrui Zhao }
580f8447436STianrui Zhao 
581537ba9daSTianrui Zhao int kvm_arch_get_registers(CPUState *cs)
582537ba9daSTianrui Zhao {
583f8447436STianrui Zhao     int ret;
584f8447436STianrui Zhao 
585f8447436STianrui Zhao     ret = kvm_loongarch_get_regs_core(cs);
586f8447436STianrui Zhao     if (ret) {
587f8447436STianrui Zhao         return ret;
588537ba9daSTianrui Zhao     }
589f8447436STianrui Zhao 
590*5872966dSBibo Mao     ret = kvm_loongarch_get_cpucfg(cs);
591*5872966dSBibo Mao     if (ret) {
592*5872966dSBibo Mao         return ret;
593*5872966dSBibo Mao     }
594*5872966dSBibo Mao 
595f8447436STianrui Zhao     ret = kvm_loongarch_get_csr(cs);
596f8447436STianrui Zhao     if (ret) {
597f8447436STianrui Zhao         return ret;
598f8447436STianrui Zhao     }
599f8447436STianrui Zhao 
600f8447436STianrui Zhao     ret = kvm_loongarch_get_regs_fp(cs);
601f8447436STianrui Zhao     if (ret) {
602f8447436STianrui Zhao         return ret;
603f8447436STianrui Zhao     }
604f8447436STianrui Zhao 
605f8447436STianrui Zhao     ret = kvm_loongarch_get_mpstate(cs);
606f8447436STianrui Zhao     return ret;
607f8447436STianrui Zhao }
608f8447436STianrui Zhao 
609537ba9daSTianrui Zhao int kvm_arch_put_registers(CPUState *cs, int level)
610537ba9daSTianrui Zhao {
611f8447436STianrui Zhao     int ret;
612f8447436STianrui Zhao 
613f8447436STianrui Zhao     ret = kvm_loongarch_put_regs_core(cs);
614f8447436STianrui Zhao     if (ret) {
615f8447436STianrui Zhao         return ret;
616f8447436STianrui Zhao     }
617f8447436STianrui Zhao 
618*5872966dSBibo Mao     ret = kvm_loongarch_put_cpucfg(cs);
619*5872966dSBibo Mao     if (ret) {
620*5872966dSBibo Mao         return ret;
621*5872966dSBibo Mao     }
622*5872966dSBibo Mao 
62361f6e150SBibo Mao     ret = kvm_loongarch_put_csr(cs, level);
624f8447436STianrui Zhao     if (ret) {
625f8447436STianrui Zhao         return ret;
626f8447436STianrui Zhao     }
627f8447436STianrui Zhao 
628f8447436STianrui Zhao     ret = kvm_loongarch_put_regs_fp(cs);
629f8447436STianrui Zhao     if (ret) {
630f8447436STianrui Zhao         return ret;
631f8447436STianrui Zhao     }
632f8447436STianrui Zhao 
633f8447436STianrui Zhao     ret = kvm_loongarch_put_mpstate(cs);
634f8447436STianrui Zhao     return ret;
635537ba9daSTianrui Zhao }
636537ba9daSTianrui Zhao 
637d11681c9STianrui Zhao static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
638d11681c9STianrui Zhao                                           RunState state)
639d11681c9STianrui Zhao {
640d11681c9STianrui Zhao     int ret;
641d11681c9STianrui Zhao     CPUState *cs = opaque;
642d11681c9STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
643d11681c9STianrui Zhao 
644d11681c9STianrui Zhao     if (running) {
645d11681c9STianrui Zhao         ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
646d11681c9STianrui Zhao                               &cpu->kvm_state_counter);
647d11681c9STianrui Zhao         if (ret < 0) {
648d11681c9STianrui Zhao             trace_kvm_failed_put_counter(strerror(errno));
649d11681c9STianrui Zhao         }
650d11681c9STianrui Zhao     } else {
651d11681c9STianrui Zhao         ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
652d11681c9STianrui Zhao                               &cpu->kvm_state_counter);
653d11681c9STianrui Zhao         if (ret < 0) {
654d11681c9STianrui Zhao             trace_kvm_failed_get_counter(strerror(errno));
655d11681c9STianrui Zhao         }
656d11681c9STianrui Zhao     }
657d11681c9STianrui Zhao }
658d11681c9STianrui Zhao 
659537ba9daSTianrui Zhao int kvm_arch_init_vcpu(CPUState *cs)
660537ba9daSTianrui Zhao {
661d11681c9STianrui Zhao     qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
662537ba9daSTianrui Zhao     return 0;
663537ba9daSTianrui Zhao }
664537ba9daSTianrui Zhao 
665537ba9daSTianrui Zhao int kvm_arch_destroy_vcpu(CPUState *cs)
666537ba9daSTianrui Zhao {
667537ba9daSTianrui Zhao     return 0;
668537ba9daSTianrui Zhao }
669537ba9daSTianrui Zhao 
670537ba9daSTianrui Zhao unsigned long kvm_arch_vcpu_id(CPUState *cs)
671537ba9daSTianrui Zhao {
672537ba9daSTianrui Zhao     return cs->cpu_index;
673537ba9daSTianrui Zhao }
674537ba9daSTianrui Zhao 
675537ba9daSTianrui Zhao int kvm_arch_release_virq_post(int virq)
676537ba9daSTianrui Zhao {
677537ba9daSTianrui Zhao     return 0;
678537ba9daSTianrui Zhao }
679537ba9daSTianrui Zhao 
680537ba9daSTianrui Zhao int kvm_arch_msi_data_to_gsi(uint32_t data)
681537ba9daSTianrui Zhao {
682537ba9daSTianrui Zhao     abort();
683537ba9daSTianrui Zhao }
684537ba9daSTianrui Zhao 
685537ba9daSTianrui Zhao int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
686537ba9daSTianrui Zhao                              uint64_t address, uint32_t data, PCIDevice *dev)
687537ba9daSTianrui Zhao {
688537ba9daSTianrui Zhao     return 0;
689537ba9daSTianrui Zhao }
690537ba9daSTianrui Zhao 
691537ba9daSTianrui Zhao int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
692537ba9daSTianrui Zhao                                 int vector, PCIDevice *dev)
693537ba9daSTianrui Zhao {
694537ba9daSTianrui Zhao     return 0;
695537ba9daSTianrui Zhao }
696537ba9daSTianrui Zhao 
697537ba9daSTianrui Zhao void kvm_arch_init_irq_routing(KVMState *s)
698537ba9daSTianrui Zhao {
699537ba9daSTianrui Zhao }
700537ba9daSTianrui Zhao 
701537ba9daSTianrui Zhao int kvm_arch_get_default_type(MachineState *ms)
702537ba9daSTianrui Zhao {
703537ba9daSTianrui Zhao     return 0;
704537ba9daSTianrui Zhao }
705537ba9daSTianrui Zhao 
706537ba9daSTianrui Zhao int kvm_arch_init(MachineState *ms, KVMState *s)
707537ba9daSTianrui Zhao {
70841958c99STianrui Zhao     cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
709537ba9daSTianrui Zhao     return 0;
710537ba9daSTianrui Zhao }
711537ba9daSTianrui Zhao 
712537ba9daSTianrui Zhao int kvm_arch_irqchip_create(KVMState *s)
713537ba9daSTianrui Zhao {
714537ba9daSTianrui Zhao     return 0;
715537ba9daSTianrui Zhao }
716537ba9daSTianrui Zhao 
717537ba9daSTianrui Zhao void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
718537ba9daSTianrui Zhao {
719537ba9daSTianrui Zhao }
720537ba9daSTianrui Zhao 
721537ba9daSTianrui Zhao MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
722537ba9daSTianrui Zhao {
723537ba9daSTianrui Zhao     return MEMTXATTRS_UNSPECIFIED;
724537ba9daSTianrui Zhao }
725537ba9daSTianrui Zhao 
726537ba9daSTianrui Zhao int kvm_arch_process_async_events(CPUState *cs)
727537ba9daSTianrui Zhao {
728537ba9daSTianrui Zhao     return cs->halted;
729537ba9daSTianrui Zhao }
730537ba9daSTianrui Zhao 
731537ba9daSTianrui Zhao bool kvm_arch_stop_on_emulation_error(CPUState *cs)
732537ba9daSTianrui Zhao {
733537ba9daSTianrui Zhao     return true;
734537ba9daSTianrui Zhao }
735537ba9daSTianrui Zhao 
736537ba9daSTianrui Zhao int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
737537ba9daSTianrui Zhao {
738a05a950fSTianrui Zhao     int ret = 0;
739f3b603b9SPhilippe Mathieu-Daudé     CPULoongArchState *env = cpu_env(cs);
740a05a950fSTianrui Zhao     MemTxAttrs attrs = {};
741a05a950fSTianrui Zhao 
742a05a950fSTianrui Zhao     attrs.requester_id = env_cpu(env)->cpu_index;
743a05a950fSTianrui Zhao 
744a05a950fSTianrui Zhao     trace_kvm_arch_handle_exit(run->exit_reason);
745a05a950fSTianrui Zhao     switch (run->exit_reason) {
746a05a950fSTianrui Zhao     case KVM_EXIT_LOONGARCH_IOCSR:
7475e90b8dbSBibo Mao         address_space_rw(env->address_space_iocsr,
748a05a950fSTianrui Zhao                          run->iocsr_io.phys_addr,
749a05a950fSTianrui Zhao                          attrs,
750a05a950fSTianrui Zhao                          run->iocsr_io.data,
751a05a950fSTianrui Zhao                          run->iocsr_io.len,
752a05a950fSTianrui Zhao                          run->iocsr_io.is_write);
753a05a950fSTianrui Zhao         break;
754a05a950fSTianrui Zhao     default:
755a05a950fSTianrui Zhao         ret = -1;
756a05a950fSTianrui Zhao         warn_report("KVM: unknown exit reason %d", run->exit_reason);
757a05a950fSTianrui Zhao         break;
758a05a950fSTianrui Zhao     }
759a05a950fSTianrui Zhao     return ret;
760537ba9daSTianrui Zhao }
761537ba9daSTianrui Zhao 
7628dcbad51STianrui Zhao int kvm_loongarch_set_interrupt(LoongArchCPU *cpu, int irq, int level)
7638dcbad51STianrui Zhao {
7648dcbad51STianrui Zhao     struct kvm_interrupt intr;
7658dcbad51STianrui Zhao     CPUState *cs = CPU(cpu);
7668dcbad51STianrui Zhao 
7678dcbad51STianrui Zhao     if (level) {
7688dcbad51STianrui Zhao         intr.irq = irq;
7698dcbad51STianrui Zhao     } else {
7708dcbad51STianrui Zhao         intr.irq = -irq;
7718dcbad51STianrui Zhao     }
7728dcbad51STianrui Zhao 
7738dcbad51STianrui Zhao     trace_kvm_set_intr(irq, level);
7748dcbad51STianrui Zhao     return kvm_vcpu_ioctl(cs, KVM_INTERRUPT, &intr);
7758dcbad51STianrui Zhao }
7768dcbad51STianrui Zhao 
777537ba9daSTianrui Zhao void kvm_arch_accel_class_init(ObjectClass *oc)
778537ba9daSTianrui Zhao {
779537ba9daSTianrui Zhao }
780