xref: /qemu/target/riscv/kvm/kvm-cpu.c (revision 937f0b45120bea964ca4ababbe98e1a2de05a077)
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 static int kvm_riscv_get_regs_core(CPUState *cs)
78 {
79     int ret = 0;
80     int i;
81     target_ulong reg;
82     CPURISCVState *env = &RISCV_CPU(cs)->env;
83 
84     ret = kvm_get_one_reg(cs, RISCV_CORE_REG(env, regs.pc), &reg);
85     if (ret) {
86         return ret;
87     }
88     env->pc = reg;
89 
90     for (i = 1; i < 32; i++) {
91         uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
92         ret = kvm_get_one_reg(cs, id, &reg);
93         if (ret) {
94             return ret;
95         }
96         env->gpr[i] = reg;
97     }
98 
99     return ret;
100 }
101 
102 static int kvm_riscv_get_regs_csr(CPUState *cs)
103 {
104     int ret = 0;
105     CPURISCVState *env = &RISCV_CPU(cs)->env;
106 
107     KVM_RISCV_GET_CSR(cs, env, sstatus, env->mstatus);
108     KVM_RISCV_GET_CSR(cs, env, sie, env->mie);
109     KVM_RISCV_GET_CSR(cs, env, stvec, env->stvec);
110     KVM_RISCV_GET_CSR(cs, env, sscratch, env->sscratch);
111     KVM_RISCV_GET_CSR(cs, env, sepc, env->sepc);
112     KVM_RISCV_GET_CSR(cs, env, scause, env->scause);
113     KVM_RISCV_GET_CSR(cs, env, stval, env->stval);
114     KVM_RISCV_GET_CSR(cs, env, sip, env->mip);
115     KVM_RISCV_GET_CSR(cs, env, satp, env->satp);
116     return ret;
117 }
118 
119 static int kvm_riscv_get_regs_fp(CPUState *cs)
120 {
121     int ret = 0;
122     int i;
123     CPURISCVState *env = &RISCV_CPU(cs)->env;
124 
125     if (riscv_has_ext(env, RVD)) {
126         uint64_t reg;
127         for (i = 0; i < 32; i++) {
128             ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), &reg);
129             if (ret) {
130                 return ret;
131             }
132             env->fpr[i] = reg;
133         }
134         return ret;
135     }
136 
137     if (riscv_has_ext(env, RVF)) {
138         uint32_t reg;
139         for (i = 0; i < 32; i++) {
140             ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), &reg);
141             if (ret) {
142                 return ret;
143             }
144             env->fpr[i] = reg;
145         }
146         return ret;
147     }
148 
149     return ret;
150 }
151 
152 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
153     KVM_CAP_LAST_INFO
154 };
155 
156 int kvm_arch_get_registers(CPUState *cs)
157 {
158     int ret = 0;
159 
160     ret = kvm_riscv_get_regs_core(cs);
161     if (ret) {
162         return ret;
163     }
164 
165     ret = kvm_riscv_get_regs_csr(cs);
166     if (ret) {
167         return ret;
168     }
169 
170     ret = kvm_riscv_get_regs_fp(cs);
171     if (ret) {
172         return ret;
173     }
174 
175     return ret;
176 }
177 
178 int kvm_arch_put_registers(CPUState *cs, int level)
179 {
180     return 0;
181 }
182 
183 int kvm_arch_release_virq_post(int virq)
184 {
185     return 0;
186 }
187 
188 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
189                              uint64_t address, uint32_t data, PCIDevice *dev)
190 {
191     return 0;
192 }
193 
194 int kvm_arch_destroy_vcpu(CPUState *cs)
195 {
196     return 0;
197 }
198 
199 unsigned long kvm_arch_vcpu_id(CPUState *cpu)
200 {
201     return cpu->cpu_index;
202 }
203 
204 void kvm_arch_init_irq_routing(KVMState *s)
205 {
206 }
207 
208 int kvm_arch_init_vcpu(CPUState *cs)
209 {
210     int ret = 0;
211     target_ulong isa;
212     RISCVCPU *cpu = RISCV_CPU(cs);
213     CPURISCVState *env = &cpu->env;
214     uint64_t id;
215 
216     id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
217                           KVM_REG_RISCV_CONFIG_REG(isa));
218     ret = kvm_get_one_reg(cs, id, &isa);
219     if (ret) {
220         return ret;
221     }
222     env->misa_ext = isa;
223 
224     return ret;
225 }
226 
227 int kvm_arch_msi_data_to_gsi(uint32_t data)
228 {
229     abort();
230 }
231 
232 int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
233                                 int vector, PCIDevice *dev)
234 {
235     return 0;
236 }
237 
238 int kvm_arch_init(MachineState *ms, KVMState *s)
239 {
240     return 0;
241 }
242 
243 int kvm_arch_irqchip_create(KVMState *s)
244 {
245     return 0;
246 }
247 
248 int kvm_arch_process_async_events(CPUState *cs)
249 {
250     return 0;
251 }
252 
253 void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
254 {
255 }
256 
257 MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
258 {
259     return MEMTXATTRS_UNSPECIFIED;
260 }
261 
262 bool kvm_arch_stop_on_emulation_error(CPUState *cs)
263 {
264     return true;
265 }
266 
267 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
268 {
269     return 0;
270 }
271 
272 bool kvm_arch_cpu_check_are_resettable(void)
273 {
274     return true;
275 }
276