xref: /qemu/target/loongarch/kvm/kvm.c (revision a05a950f2faf63ec14347153cded4f113af020f0)
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 
253f8447436STianrui Zhao static int kvm_loongarch_put_csr(CPUState *cs)
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 
325f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CPUID),
326f8447436STianrui Zhao                            &env->CSR_CPUID);
327f8447436STianrui Zhao 
328f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG1),
329f8447436STianrui Zhao                            &env->CSR_PRCFG1);
330f8447436STianrui Zhao 
331f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG2),
332f8447436STianrui Zhao                            &env->CSR_PRCFG2);
333f8447436STianrui Zhao 
334f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_PRCFG3),
335f8447436STianrui Zhao                            &env->CSR_PRCFG3);
336f8447436STianrui Zhao 
337f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(0)),
338f8447436STianrui Zhao                            &env->CSR_SAVE[0]);
339f8447436STianrui Zhao 
340f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(1)),
341f8447436STianrui Zhao                            &env->CSR_SAVE[1]);
342f8447436STianrui Zhao 
343f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(2)),
344f8447436STianrui Zhao                            &env->CSR_SAVE[2]);
345f8447436STianrui Zhao 
346f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(3)),
347f8447436STianrui Zhao                            &env->CSR_SAVE[3]);
348f8447436STianrui Zhao 
349f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(4)),
350f8447436STianrui Zhao                            &env->CSR_SAVE[4]);
351f8447436STianrui Zhao 
352f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(5)),
353f8447436STianrui Zhao                            &env->CSR_SAVE[5]);
354f8447436STianrui Zhao 
355f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(6)),
356f8447436STianrui Zhao                            &env->CSR_SAVE[6]);
357f8447436STianrui Zhao 
358f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_SAVE(7)),
359f8447436STianrui Zhao                            &env->CSR_SAVE[7]);
360f8447436STianrui Zhao 
361f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TID),
362f8447436STianrui Zhao                            &env->CSR_TID);
363f8447436STianrui Zhao 
364f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_CNTC),
365f8447436STianrui Zhao                            &env->CSR_CNTC);
366f8447436STianrui Zhao 
367f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TICLR),
368f8447436STianrui Zhao                            &env->CSR_TICLR);
369f8447436STianrui Zhao 
370f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_LLBCTL),
371f8447436STianrui Zhao                            &env->CSR_LLBCTL);
372f8447436STianrui Zhao 
373f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL1),
374f8447436STianrui Zhao                            &env->CSR_IMPCTL1);
375f8447436STianrui Zhao 
376f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_IMPCTL2),
377f8447436STianrui Zhao                            &env->CSR_IMPCTL2);
378f8447436STianrui Zhao 
379f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRENTRY),
380f8447436STianrui Zhao                            &env->CSR_TLBRENTRY);
381f8447436STianrui Zhao 
382f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRBADV),
383f8447436STianrui Zhao                            &env->CSR_TLBRBADV);
384f8447436STianrui Zhao 
385f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRERA),
386f8447436STianrui Zhao                            &env->CSR_TLBRERA);
387f8447436STianrui Zhao 
388f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRSAVE),
389f8447436STianrui Zhao                            &env->CSR_TLBRSAVE);
390f8447436STianrui Zhao 
391f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO0),
392f8447436STianrui Zhao                            &env->CSR_TLBRELO0);
393f8447436STianrui Zhao 
394f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRELO1),
395f8447436STianrui Zhao                            &env->CSR_TLBRELO1);
396f8447436STianrui Zhao 
397f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBREHI),
398f8447436STianrui Zhao                            &env->CSR_TLBREHI);
399f8447436STianrui Zhao 
400f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TLBRPRMD),
401f8447436STianrui Zhao                            &env->CSR_TLBRPRMD);
402f8447436STianrui Zhao 
403f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(0)),
404f8447436STianrui Zhao                            &env->CSR_DMW[0]);
405f8447436STianrui Zhao 
406f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(1)),
407f8447436STianrui Zhao                            &env->CSR_DMW[1]);
408f8447436STianrui Zhao 
409f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(2)),
410f8447436STianrui Zhao                            &env->CSR_DMW[2]);
411f8447436STianrui Zhao 
412f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_DMW(3)),
413f8447436STianrui Zhao                            &env->CSR_DMW[3]);
414f8447436STianrui Zhao     /*
415f8447436STianrui Zhao      * timer cfg must be put at last since it is used to enable
416f8447436STianrui Zhao      * guest timer
417f8447436STianrui Zhao      */
418f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TVAL),
419f8447436STianrui Zhao                            &env->CSR_TVAL);
420f8447436STianrui Zhao 
421f8447436STianrui Zhao     ret |= kvm_set_one_reg(cs, KVM_IOC_CSRID(LOONGARCH_CSR_TCFG),
422f8447436STianrui Zhao                            &env->CSR_TCFG);
423f8447436STianrui Zhao     return ret;
424f8447436STianrui Zhao }
425f8447436STianrui Zhao 
426f8447436STianrui Zhao static int kvm_loongarch_get_regs_fp(CPUState *cs)
427f8447436STianrui Zhao {
428f8447436STianrui Zhao     int ret, i;
429f8447436STianrui Zhao     struct kvm_fpu fpu;
430f8447436STianrui Zhao 
431f8447436STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
432f8447436STianrui Zhao     CPULoongArchState *env = &cpu->env;
433f8447436STianrui Zhao 
434f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_GET_FPU, &fpu);
435f8447436STianrui Zhao     if (ret < 0) {
436f8447436STianrui Zhao         trace_kvm_failed_get_fpu(strerror(errno));
437f8447436STianrui Zhao         return ret;
438f8447436STianrui Zhao     }
439f8447436STianrui Zhao 
440f8447436STianrui Zhao     env->fcsr0 = fpu.fcsr;
441f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
442f8447436STianrui Zhao         env->fpr[i].vreg.UD[0] = fpu.fpr[i].val64[0];
443f8447436STianrui Zhao     }
444f8447436STianrui Zhao     for (i = 0; i < 8; i++) {
445f8447436STianrui Zhao         env->cf[i] = fpu.fcc & 0xFF;
446f8447436STianrui Zhao         fpu.fcc = fpu.fcc >> 8;
447f8447436STianrui Zhao     }
448f8447436STianrui Zhao 
449f8447436STianrui Zhao     return ret;
450f8447436STianrui Zhao }
451f8447436STianrui Zhao 
452f8447436STianrui Zhao static int kvm_loongarch_put_regs_fp(CPUState *cs)
453f8447436STianrui Zhao {
454f8447436STianrui Zhao     int ret, i;
455f8447436STianrui Zhao     struct kvm_fpu fpu;
456f8447436STianrui Zhao 
457f8447436STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
458f8447436STianrui Zhao     CPULoongArchState *env = &cpu->env;
459f8447436STianrui Zhao 
460f8447436STianrui Zhao     fpu.fcsr = env->fcsr0;
461f8447436STianrui Zhao     fpu.fcc = 0;
462f8447436STianrui Zhao     for (i = 0; i < 32; i++) {
463f8447436STianrui Zhao         fpu.fpr[i].val64[0] = env->fpr[i].vreg.UD[0];
464f8447436STianrui Zhao     }
465f8447436STianrui Zhao 
466f8447436STianrui Zhao     for (i = 0; i < 8; i++) {
467f8447436STianrui Zhao         fpu.fcc |= env->cf[i] << (8 * i);
468f8447436STianrui Zhao     }
469f8447436STianrui Zhao 
470f8447436STianrui Zhao     ret = kvm_vcpu_ioctl(cs, KVM_SET_FPU, &fpu);
471f8447436STianrui Zhao     if (ret < 0) {
472f8447436STianrui Zhao         trace_kvm_failed_put_fpu(strerror(errno));
473f8447436STianrui Zhao     }
474f8447436STianrui Zhao 
475f8447436STianrui Zhao     return ret;
476f8447436STianrui Zhao }
477f8447436STianrui Zhao 
478f8447436STianrui Zhao void kvm_arch_reset_vcpu(CPULoongArchState *env)
479f8447436STianrui Zhao {
480f8447436STianrui Zhao     env->mp_state = KVM_MP_STATE_RUNNABLE;
481f8447436STianrui Zhao }
482f8447436STianrui Zhao 
483f8447436STianrui Zhao static int kvm_loongarch_get_mpstate(CPUState *cs)
484f8447436STianrui Zhao {
485f8447436STianrui Zhao     int ret = 0;
486f8447436STianrui Zhao     struct kvm_mp_state mp_state;
487f8447436STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
488f8447436STianrui Zhao     CPULoongArchState *env = &cpu->env;
489f8447436STianrui Zhao 
490f8447436STianrui Zhao     if (cap_has_mp_state) {
491f8447436STianrui Zhao         ret = kvm_vcpu_ioctl(cs, KVM_GET_MP_STATE, &mp_state);
492f8447436STianrui Zhao         if (ret) {
493f8447436STianrui Zhao             trace_kvm_failed_get_mpstate(strerror(errno));
494f8447436STianrui Zhao             return ret;
495f8447436STianrui Zhao         }
496f8447436STianrui Zhao         env->mp_state = mp_state.mp_state;
497f8447436STianrui Zhao     }
498f8447436STianrui Zhao 
499f8447436STianrui Zhao     return ret;
500f8447436STianrui Zhao }
501f8447436STianrui Zhao 
502f8447436STianrui Zhao static int kvm_loongarch_put_mpstate(CPUState *cs)
503f8447436STianrui Zhao {
504f8447436STianrui Zhao     int ret = 0;
505f8447436STianrui Zhao 
506f8447436STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
507f8447436STianrui Zhao     CPULoongArchState *env = &cpu->env;
508f8447436STianrui Zhao 
509f8447436STianrui Zhao     struct kvm_mp_state mp_state = {
510f8447436STianrui Zhao         .mp_state = env->mp_state
511f8447436STianrui Zhao     };
512f8447436STianrui Zhao 
513f8447436STianrui Zhao     if (cap_has_mp_state) {
514f8447436STianrui Zhao         ret = kvm_vcpu_ioctl(cs, KVM_SET_MP_STATE, &mp_state);
515f8447436STianrui Zhao         if (ret) {
516f8447436STianrui Zhao             trace_kvm_failed_put_mpstate(strerror(errno));
517f8447436STianrui Zhao         }
518f8447436STianrui Zhao     }
519f8447436STianrui Zhao 
520f8447436STianrui Zhao     return ret;
521f8447436STianrui Zhao }
522f8447436STianrui Zhao 
523f8447436STianrui Zhao static int kvm_loongarch_get_cpucfg(CPUState *cs)
524f8447436STianrui Zhao {
525f8447436STianrui Zhao     int i, ret = 0;
526f8447436STianrui Zhao     uint64_t val;
527f8447436STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
528f8447436STianrui Zhao     CPULoongArchState *env = &cpu->env;
529f8447436STianrui Zhao 
530f8447436STianrui Zhao     for (i = 0; i < 21; i++) {
531f8447436STianrui Zhao         ret = kvm_get_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
532f8447436STianrui Zhao         if (ret < 0) {
533f8447436STianrui Zhao             trace_kvm_failed_get_cpucfg(strerror(errno));
534f8447436STianrui Zhao         }
535f8447436STianrui Zhao         env->cpucfg[i] = (uint32_t)val;
536f8447436STianrui Zhao     }
537f8447436STianrui Zhao     return ret;
538f8447436STianrui Zhao }
539f8447436STianrui Zhao 
540f8447436STianrui Zhao static int kvm_loongarch_put_cpucfg(CPUState *cs)
541f8447436STianrui Zhao {
542f8447436STianrui Zhao     int i, ret = 0;
543f8447436STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
544f8447436STianrui Zhao     CPULoongArchState *env = &cpu->env;
545f8447436STianrui Zhao     uint64_t val;
546f8447436STianrui Zhao 
547f8447436STianrui Zhao     for (i = 0; i < 21; i++) {
548f8447436STianrui Zhao         val = env->cpucfg[i];
549f8447436STianrui Zhao         /* LSX and LASX and LBT are not supported in kvm now */
550f8447436STianrui Zhao         if (i == 2) {
551f8447436STianrui Zhao             val &= ~(BIT(R_CPUCFG2_LSX_SHIFT) | BIT(R_CPUCFG2_LASX_SHIFT));
552f8447436STianrui Zhao             val &= ~(BIT(R_CPUCFG2_LBT_X86_SHIFT) |
553f8447436STianrui Zhao                      BIT(R_CPUCFG2_LBT_ARM_SHIFT) |
554f8447436STianrui Zhao                      BIT(R_CPUCFG2_LBT_MIPS_SHIFT));
555f8447436STianrui Zhao         }
556f8447436STianrui Zhao         ret = kvm_set_one_reg(cs, KVM_IOC_CPUCFG(i), &val);
557f8447436STianrui Zhao         if (ret < 0) {
558f8447436STianrui Zhao             trace_kvm_failed_put_cpucfg(strerror(errno));
559f8447436STianrui Zhao         }
560f8447436STianrui Zhao     }
561f8447436STianrui Zhao     return ret;
562f8447436STianrui Zhao }
563f8447436STianrui Zhao 
564537ba9daSTianrui Zhao int kvm_arch_get_registers(CPUState *cs)
565537ba9daSTianrui Zhao {
566f8447436STianrui Zhao     int ret;
567f8447436STianrui Zhao 
568f8447436STianrui Zhao     ret = kvm_loongarch_get_regs_core(cs);
569f8447436STianrui Zhao     if (ret) {
570f8447436STianrui Zhao         return ret;
571537ba9daSTianrui Zhao     }
572f8447436STianrui Zhao 
573f8447436STianrui Zhao     ret = kvm_loongarch_get_csr(cs);
574f8447436STianrui Zhao     if (ret) {
575f8447436STianrui Zhao         return ret;
576f8447436STianrui Zhao     }
577f8447436STianrui Zhao 
578f8447436STianrui Zhao     ret = kvm_loongarch_get_regs_fp(cs);
579f8447436STianrui Zhao     if (ret) {
580f8447436STianrui Zhao         return ret;
581f8447436STianrui Zhao     }
582f8447436STianrui Zhao 
583f8447436STianrui Zhao     ret = kvm_loongarch_get_mpstate(cs);
584f8447436STianrui Zhao     if (ret) {
585f8447436STianrui Zhao         return ret;
586f8447436STianrui Zhao     }
587f8447436STianrui Zhao 
588f8447436STianrui Zhao     ret = kvm_loongarch_get_cpucfg(cs);
589f8447436STianrui Zhao     return ret;
590f8447436STianrui Zhao }
591f8447436STianrui Zhao 
592537ba9daSTianrui Zhao int kvm_arch_put_registers(CPUState *cs, int level)
593537ba9daSTianrui Zhao {
594f8447436STianrui Zhao     int ret;
595f8447436STianrui Zhao 
596f8447436STianrui Zhao     ret = kvm_loongarch_put_regs_core(cs);
597f8447436STianrui Zhao     if (ret) {
598f8447436STianrui Zhao         return ret;
599f8447436STianrui Zhao     }
600f8447436STianrui Zhao 
601f8447436STianrui Zhao     ret = kvm_loongarch_put_csr(cs);
602f8447436STianrui Zhao     if (ret) {
603f8447436STianrui Zhao         return ret;
604f8447436STianrui Zhao     }
605f8447436STianrui Zhao 
606f8447436STianrui Zhao     ret = kvm_loongarch_put_regs_fp(cs);
607f8447436STianrui Zhao     if (ret) {
608f8447436STianrui Zhao         return ret;
609f8447436STianrui Zhao     }
610f8447436STianrui Zhao 
611f8447436STianrui Zhao     ret = kvm_loongarch_put_mpstate(cs);
612f8447436STianrui Zhao     if (ret) {
613f8447436STianrui Zhao         return ret;
614f8447436STianrui Zhao     }
615f8447436STianrui Zhao 
616f8447436STianrui Zhao     ret = kvm_loongarch_put_cpucfg(cs);
617f8447436STianrui Zhao     return ret;
618537ba9daSTianrui Zhao }
619537ba9daSTianrui Zhao 
620d11681c9STianrui Zhao static void kvm_loongarch_vm_stage_change(void *opaque, bool running,
621d11681c9STianrui Zhao                                           RunState state)
622d11681c9STianrui Zhao {
623d11681c9STianrui Zhao     int ret;
624d11681c9STianrui Zhao     CPUState *cs = opaque;
625d11681c9STianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
626d11681c9STianrui Zhao 
627d11681c9STianrui Zhao     if (running) {
628d11681c9STianrui Zhao         ret = kvm_set_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
629d11681c9STianrui Zhao                               &cpu->kvm_state_counter);
630d11681c9STianrui Zhao         if (ret < 0) {
631d11681c9STianrui Zhao             trace_kvm_failed_put_counter(strerror(errno));
632d11681c9STianrui Zhao         }
633d11681c9STianrui Zhao     } else {
634d11681c9STianrui Zhao         ret = kvm_get_one_reg(cs, KVM_REG_LOONGARCH_COUNTER,
635d11681c9STianrui Zhao                               &cpu->kvm_state_counter);
636d11681c9STianrui Zhao         if (ret < 0) {
637d11681c9STianrui Zhao             trace_kvm_failed_get_counter(strerror(errno));
638d11681c9STianrui Zhao         }
639d11681c9STianrui Zhao     }
640d11681c9STianrui Zhao }
641d11681c9STianrui Zhao 
642537ba9daSTianrui Zhao int kvm_arch_init_vcpu(CPUState *cs)
643537ba9daSTianrui Zhao {
644d11681c9STianrui Zhao     qemu_add_vm_change_state_handler(kvm_loongarch_vm_stage_change, cs);
645537ba9daSTianrui Zhao     return 0;
646537ba9daSTianrui Zhao }
647537ba9daSTianrui Zhao 
648537ba9daSTianrui Zhao int kvm_arch_destroy_vcpu(CPUState *cs)
649537ba9daSTianrui Zhao {
650537ba9daSTianrui Zhao     return 0;
651537ba9daSTianrui Zhao }
652537ba9daSTianrui Zhao 
653537ba9daSTianrui Zhao unsigned long kvm_arch_vcpu_id(CPUState *cs)
654537ba9daSTianrui Zhao {
655537ba9daSTianrui Zhao     return cs->cpu_index;
656537ba9daSTianrui Zhao }
657537ba9daSTianrui Zhao 
658537ba9daSTianrui Zhao int kvm_arch_release_virq_post(int virq)
659537ba9daSTianrui Zhao {
660537ba9daSTianrui Zhao     return 0;
661537ba9daSTianrui Zhao }
662537ba9daSTianrui Zhao 
663537ba9daSTianrui Zhao int kvm_arch_msi_data_to_gsi(uint32_t data)
664537ba9daSTianrui Zhao {
665537ba9daSTianrui Zhao     abort();
666537ba9daSTianrui Zhao }
667537ba9daSTianrui Zhao 
668537ba9daSTianrui Zhao int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
669537ba9daSTianrui Zhao                              uint64_t address, uint32_t data, PCIDevice *dev)
670537ba9daSTianrui Zhao {
671537ba9daSTianrui Zhao     return 0;
672537ba9daSTianrui Zhao }
673537ba9daSTianrui Zhao 
674537ba9daSTianrui Zhao int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
675537ba9daSTianrui Zhao                                 int vector, PCIDevice *dev)
676537ba9daSTianrui Zhao {
677537ba9daSTianrui Zhao     return 0;
678537ba9daSTianrui Zhao }
679537ba9daSTianrui Zhao 
680537ba9daSTianrui Zhao void kvm_arch_init_irq_routing(KVMState *s)
681537ba9daSTianrui Zhao {
682537ba9daSTianrui Zhao }
683537ba9daSTianrui Zhao 
684537ba9daSTianrui Zhao int kvm_arch_get_default_type(MachineState *ms)
685537ba9daSTianrui Zhao {
686537ba9daSTianrui Zhao     return 0;
687537ba9daSTianrui Zhao }
688537ba9daSTianrui Zhao 
689537ba9daSTianrui Zhao int kvm_arch_init(MachineState *ms, KVMState *s)
690537ba9daSTianrui Zhao {
69141958c99STianrui Zhao     cap_has_mp_state = kvm_check_extension(s, KVM_CAP_MP_STATE);
692537ba9daSTianrui Zhao     return 0;
693537ba9daSTianrui Zhao }
694537ba9daSTianrui Zhao 
695537ba9daSTianrui Zhao int kvm_arch_irqchip_create(KVMState *s)
696537ba9daSTianrui Zhao {
697537ba9daSTianrui Zhao     return 0;
698537ba9daSTianrui Zhao }
699537ba9daSTianrui Zhao 
700537ba9daSTianrui Zhao void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
701537ba9daSTianrui Zhao {
702537ba9daSTianrui Zhao }
703537ba9daSTianrui Zhao 
704537ba9daSTianrui Zhao MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
705537ba9daSTianrui Zhao {
706537ba9daSTianrui Zhao     return MEMTXATTRS_UNSPECIFIED;
707537ba9daSTianrui Zhao }
708537ba9daSTianrui Zhao 
709537ba9daSTianrui Zhao int kvm_arch_process_async_events(CPUState *cs)
710537ba9daSTianrui Zhao {
711537ba9daSTianrui Zhao     return cs->halted;
712537ba9daSTianrui Zhao }
713537ba9daSTianrui Zhao 
714537ba9daSTianrui Zhao bool kvm_arch_stop_on_emulation_error(CPUState *cs)
715537ba9daSTianrui Zhao {
716537ba9daSTianrui Zhao     return true;
717537ba9daSTianrui Zhao }
718537ba9daSTianrui Zhao 
719537ba9daSTianrui Zhao bool kvm_arch_cpu_check_are_resettable(void)
720537ba9daSTianrui Zhao {
721537ba9daSTianrui Zhao     return true;
722537ba9daSTianrui Zhao }
723537ba9daSTianrui Zhao 
724537ba9daSTianrui Zhao int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
725537ba9daSTianrui Zhao {
726*a05a950fSTianrui Zhao     int ret = 0;
727*a05a950fSTianrui Zhao     LoongArchCPU *cpu = LOONGARCH_CPU(cs);
728*a05a950fSTianrui Zhao     CPULoongArchState *env = &cpu->env;
729*a05a950fSTianrui Zhao     MemTxAttrs attrs = {};
730*a05a950fSTianrui Zhao 
731*a05a950fSTianrui Zhao     attrs.requester_id = env_cpu(env)->cpu_index;
732*a05a950fSTianrui Zhao 
733*a05a950fSTianrui Zhao     trace_kvm_arch_handle_exit(run->exit_reason);
734*a05a950fSTianrui Zhao     switch (run->exit_reason) {
735*a05a950fSTianrui Zhao     case KVM_EXIT_LOONGARCH_IOCSR:
736*a05a950fSTianrui Zhao         address_space_rw(&env->address_space_iocsr,
737*a05a950fSTianrui Zhao                          run->iocsr_io.phys_addr,
738*a05a950fSTianrui Zhao                          attrs,
739*a05a950fSTianrui Zhao                          run->iocsr_io.data,
740*a05a950fSTianrui Zhao                          run->iocsr_io.len,
741*a05a950fSTianrui Zhao                          run->iocsr_io.is_write);
742*a05a950fSTianrui Zhao         break;
743*a05a950fSTianrui Zhao     default:
744*a05a950fSTianrui Zhao         ret = -1;
745*a05a950fSTianrui Zhao         warn_report("KVM: unknown exit reason %d", run->exit_reason);
746*a05a950fSTianrui Zhao         break;
747*a05a950fSTianrui Zhao     }
748*a05a950fSTianrui Zhao     return ret;
749537ba9daSTianrui Zhao }
750537ba9daSTianrui Zhao 
751537ba9daSTianrui Zhao void kvm_arch_accel_class_init(ObjectClass *oc)
752537ba9daSTianrui Zhao {
753537ba9daSTianrui Zhao }
754