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