xref: /qemu/target/riscv/kvm/kvm-cpu.c (revision 9997cc1e19d1f909551783c280cfe441a0838943)
1 /*
2  * RISC-V implementation of KVM hooks
3  *
4  * Copyright (c) 2020 Huawei Technologies Co., Ltd
5  *
6  * This program is free software; you can redistribute it and/or modify it
7  * under the terms and conditions of the GNU General Public License,
8  * version 2 or later, as published by the Free Software Foundation.
9  *
10  * This program is distributed in the hope it will be useful, but WITHOUT
11  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
12  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
13  * more details.
14  *
15  * You should have received a copy of the GNU General Public License along with
16  * this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #include "qemu/osdep.h"
20 #include <sys/ioctl.h>
21 
22 #include <linux/kvm.h>
23 
24 #include "qemu-common.h"
25 #include "qemu/timer.h"
26 #include "qemu/error-report.h"
27 #include "qemu/main-loop.h"
28 #include "sysemu/sysemu.h"
29 #include "sysemu/kvm.h"
30 #include "sysemu/kvm_int.h"
31 #include "cpu.h"
32 #include "trace.h"
33 #include "hw/pci/pci.h"
34 #include "exec/memattrs.h"
35 #include "exec/address-spaces.h"
36 #include "hw/boards.h"
37 #include "hw/irq.h"
38 #include "qemu/log.h"
39 #include "hw/loader.h"
40 
41 static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
42                                  uint64_t idx)
43 {
44     uint64_t id = KVM_REG_RISCV | type | idx;
45 
46     switch (riscv_cpu_mxl(env)) {
47     case MXL_RV32:
48         id |= KVM_REG_SIZE_U32;
49         break;
50     case MXL_RV64:
51         id |= KVM_REG_SIZE_U64;
52         break;
53     default:
54         g_assert_not_reached();
55     }
56     return id;
57 }
58 
59 #define RISCV_CORE_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
60                  KVM_REG_RISCV_CORE_REG(name))
61 
62 #define RISCV_CSR_REG(env, name)  kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
63                  KVM_REG_RISCV_CSR_REG(name))
64 
65 #define RISCV_FP_F_REG(env, idx)  kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx)
66 
67 #define RISCV_FP_D_REG(env, idx)  kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx)
68 
69 #define KVM_RISCV_GET_CSR(cs, env, csr, reg) \
70     do { \
71         int ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, csr), &reg); \
72         if (ret) { \
73             return ret; \
74         } \
75     } while (0)
76 
77 #define KVM_RISCV_SET_CSR(cs, env, csr, reg) \
78     do { \
79         int ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, csr), &reg); \
80         if (ret) { \
81             return ret; \
82         } \
83     } while (0)
84 
85 static int kvm_riscv_get_regs_core(CPUState *cs)
86 {
87     int ret = 0;
88     int i;
89     target_ulong reg;
90     CPURISCVState *env = &RISCV_CPU(cs)->env;
91 
92     ret = kvm_get_one_reg(cs, RISCV_CORE_REG(env, regs.pc), &reg);
93     if (ret) {
94         return ret;
95     }
96     env->pc = reg;
97 
98     for (i = 1; i < 32; i++) {
99         uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
100         ret = kvm_get_one_reg(cs, id, &reg);
101         if (ret) {
102             return ret;
103         }
104         env->gpr[i] = reg;
105     }
106 
107     return ret;
108 }
109 
110 static int kvm_riscv_put_regs_core(CPUState *cs)
111 {
112     int ret = 0;
113     int i;
114     target_ulong reg;
115     CPURISCVState *env = &RISCV_CPU(cs)->env;
116 
117     reg = env->pc;
118     ret = kvm_set_one_reg(cs, RISCV_CORE_REG(env, regs.pc), &reg);
119     if (ret) {
120         return ret;
121     }
122 
123     for (i = 1; i < 32; i++) {
124         uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
125         reg = env->gpr[i];
126         ret = kvm_set_one_reg(cs, id, &reg);
127         if (ret) {
128             return ret;
129         }
130     }
131 
132     return ret;
133 }
134 
135 static int kvm_riscv_get_regs_csr(CPUState *cs)
136 {
137     int ret = 0;
138     CPURISCVState *env = &RISCV_CPU(cs)->env;
139 
140     KVM_RISCV_GET_CSR(cs, env, sstatus, env->mstatus);
141     KVM_RISCV_GET_CSR(cs, env, sie, env->mie);
142     KVM_RISCV_GET_CSR(cs, env, stvec, env->stvec);
143     KVM_RISCV_GET_CSR(cs, env, sscratch, env->sscratch);
144     KVM_RISCV_GET_CSR(cs, env, sepc, env->sepc);
145     KVM_RISCV_GET_CSR(cs, env, scause, env->scause);
146     KVM_RISCV_GET_CSR(cs, env, stval, env->stval);
147     KVM_RISCV_GET_CSR(cs, env, sip, env->mip);
148     KVM_RISCV_GET_CSR(cs, env, satp, env->satp);
149     return ret;
150 }
151 
152 static int kvm_riscv_put_regs_csr(CPUState *cs)
153 {
154     int ret = 0;
155     CPURISCVState *env = &RISCV_CPU(cs)->env;
156 
157     KVM_RISCV_SET_CSR(cs, env, sstatus, env->mstatus);
158     KVM_RISCV_SET_CSR(cs, env, sie, env->mie);
159     KVM_RISCV_SET_CSR(cs, env, stvec, env->stvec);
160     KVM_RISCV_SET_CSR(cs, env, sscratch, env->sscratch);
161     KVM_RISCV_SET_CSR(cs, env, sepc, env->sepc);
162     KVM_RISCV_SET_CSR(cs, env, scause, env->scause);
163     KVM_RISCV_SET_CSR(cs, env, stval, env->stval);
164     KVM_RISCV_SET_CSR(cs, env, sip, env->mip);
165     KVM_RISCV_SET_CSR(cs, env, satp, env->satp);
166 
167     return ret;
168 }
169 
170 static int kvm_riscv_get_regs_fp(CPUState *cs)
171 {
172     int ret = 0;
173     int i;
174     CPURISCVState *env = &RISCV_CPU(cs)->env;
175 
176     if (riscv_has_ext(env, RVD)) {
177         uint64_t reg;
178         for (i = 0; i < 32; i++) {
179             ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), &reg);
180             if (ret) {
181                 return ret;
182             }
183             env->fpr[i] = reg;
184         }
185         return ret;
186     }
187 
188     if (riscv_has_ext(env, RVF)) {
189         uint32_t reg;
190         for (i = 0; i < 32; i++) {
191             ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), &reg);
192             if (ret) {
193                 return ret;
194             }
195             env->fpr[i] = reg;
196         }
197         return ret;
198     }
199 
200     return ret;
201 }
202 
203 static int kvm_riscv_put_regs_fp(CPUState *cs)
204 {
205     int ret = 0;
206     int i;
207     CPURISCVState *env = &RISCV_CPU(cs)->env;
208 
209     if (riscv_has_ext(env, RVD)) {
210         uint64_t reg;
211         for (i = 0; i < 32; i++) {
212             reg = env->fpr[i];
213             ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(env, i), &reg);
214             if (ret) {
215                 return ret;
216             }
217         }
218         return ret;
219     }
220 
221     if (riscv_has_ext(env, RVF)) {
222         uint32_t reg;
223         for (i = 0; i < 32; i++) {
224             reg = env->fpr[i];
225             ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(env, i), &reg);
226             if (ret) {
227                 return ret;
228             }
229         }
230         return ret;
231     }
232 
233     return ret;
234 }
235 
236 
237 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
238     KVM_CAP_LAST_INFO
239 };
240 
241 int kvm_arch_get_registers(CPUState *cs)
242 {
243     int ret = 0;
244 
245     ret = kvm_riscv_get_regs_core(cs);
246     if (ret) {
247         return ret;
248     }
249 
250     ret = kvm_riscv_get_regs_csr(cs);
251     if (ret) {
252         return ret;
253     }
254 
255     ret = kvm_riscv_get_regs_fp(cs);
256     if (ret) {
257         return ret;
258     }
259 
260     return ret;
261 }
262 
263 int kvm_arch_put_registers(CPUState *cs, int level)
264 {
265     int ret = 0;
266 
267     ret = kvm_riscv_put_regs_core(cs);
268     if (ret) {
269         return ret;
270     }
271 
272     ret = kvm_riscv_put_regs_csr(cs);
273     if (ret) {
274         return ret;
275     }
276 
277     ret = kvm_riscv_put_regs_fp(cs);
278     if (ret) {
279         return ret;
280     }
281 
282     return ret;
283 }
284 
285 int kvm_arch_release_virq_post(int virq)
286 {
287     return 0;
288 }
289 
290 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
291                              uint64_t address, uint32_t data, PCIDevice *dev)
292 {
293     return 0;
294 }
295 
296 int kvm_arch_destroy_vcpu(CPUState *cs)
297 {
298     return 0;
299 }
300 
301 unsigned long kvm_arch_vcpu_id(CPUState *cpu)
302 {
303     return cpu->cpu_index;
304 }
305 
306 void kvm_arch_init_irq_routing(KVMState *s)
307 {
308 }
309 
310 int kvm_arch_init_vcpu(CPUState *cs)
311 {
312     int ret = 0;
313     target_ulong isa;
314     RISCVCPU *cpu = RISCV_CPU(cs);
315     CPURISCVState *env = &cpu->env;
316     uint64_t id;
317 
318     id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
319                           KVM_REG_RISCV_CONFIG_REG(isa));
320     ret = kvm_get_one_reg(cs, id, &isa);
321     if (ret) {
322         return ret;
323     }
324     env->misa_ext = isa;
325 
326     return ret;
327 }
328 
329 int kvm_arch_msi_data_to_gsi(uint32_t data)
330 {
331     abort();
332 }
333 
334 int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
335                                 int vector, PCIDevice *dev)
336 {
337     return 0;
338 }
339 
340 int kvm_arch_init(MachineState *ms, KVMState *s)
341 {
342     return 0;
343 }
344 
345 int kvm_arch_irqchip_create(KVMState *s)
346 {
347     return 0;
348 }
349 
350 int kvm_arch_process_async_events(CPUState *cs)
351 {
352     return 0;
353 }
354 
355 void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
356 {
357 }
358 
359 MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
360 {
361     return MEMTXATTRS_UNSPECIFIED;
362 }
363 
364 bool kvm_arch_stop_on_emulation_error(CPUState *cs)
365 {
366     return true;
367 }
368 
369 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
370 {
371     return 0;
372 }
373 
374 bool kvm_arch_cpu_check_are_resettable(void)
375 {
376     return true;
377 }
378