2 * RISC-V implementation of KVM hooks
4 * Copyright (c) 2020 Huawei Technologies Co., Ltd
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.
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
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/>.
19 #include "qemu/osdep.h"
20 #include <sys/ioctl.h>
22 #include <linux/kvm.h>
24 #include "qemu/timer.h"
25 #include "qapi/error.h"
26 #include "qemu/error-report.h"
27 #include "qemu/main-loop.h"
28 #include "qapi/visitor.h"
29 #include "sysemu/sysemu.h"
30 #include "sysemu/kvm.h"
31 #include "sysemu/kvm_int.h"
34 #include "hw/pci/pci.h"
35 #include "exec/memattrs.h"
36 #include "exec/address-spaces.h"
37 #include "hw/boards.h"
40 #include "hw/loader.h"
41 #include "kvm_riscv.h"
42 #include "sbi_ecall_interface.h"
43 #include "chardev/char-fe.h"
44 #include "migration/migration.h"
45 #include "sysemu/runstate.h"
47 static uint64_t kvm_riscv_reg_id(CPURISCVState *env, uint64_t type,
50 uint64_t id = KVM_REG_RISCV | type | idx;
52 switch (riscv_cpu_mxl(env)) {
54 id |= KVM_REG_SIZE_U32;
57 id |= KVM_REG_SIZE_U64;
60 g_assert_not_reached();
65 #define RISCV_CORE_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, \
66 KVM_REG_RISCV_CORE_REG(name))
68 #define RISCV_CSR_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_CSR, \
69 KVM_REG_RISCV_CSR_REG(name))
71 #define RISCV_TIMER_REG(env, name) kvm_riscv_reg_id(env, KVM_REG_RISCV_TIMER, \
72 KVM_REG_RISCV_TIMER_REG(name))
74 #define RISCV_FP_F_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_F, idx)
76 #define RISCV_FP_D_REG(env, idx) kvm_riscv_reg_id(env, KVM_REG_RISCV_FP_D, idx)
78 #define KVM_RISCV_GET_CSR(cs, env, csr, reg) \
80 int ret = kvm_get_one_reg(cs, RISCV_CSR_REG(env, csr), ®); \
86 #define KVM_RISCV_SET_CSR(cs, env, csr, reg) \
88 int ret = kvm_set_one_reg(cs, RISCV_CSR_REG(env, csr), ®); \
94 #define KVM_RISCV_GET_TIMER(cs, env, name, reg) \
96 int ret = kvm_get_one_reg(cs, RISCV_TIMER_REG(env, name), ®); \
102 #define KVM_RISCV_SET_TIMER(cs, env, name, reg) \
104 int ret = kvm_set_one_reg(cs, RISCV_TIMER_REG(env, name), ®); \
110 typedef struct KVMCPUConfig {
112 const char *description;
119 #define KVM_MISA_CFG(_bit, _reg_id) \
120 {.offset = _bit, .kvm_reg_id = _reg_id}
122 /* KVM ISA extensions */
123 static KVMCPUConfig kvm_misa_ext_cfgs[] = {
124 KVM_MISA_CFG(RVA, KVM_RISCV_ISA_EXT_A),
125 KVM_MISA_CFG(RVC, KVM_RISCV_ISA_EXT_C),
126 KVM_MISA_CFG(RVD, KVM_RISCV_ISA_EXT_D),
127 KVM_MISA_CFG(RVF, KVM_RISCV_ISA_EXT_F),
128 KVM_MISA_CFG(RVH, KVM_RISCV_ISA_EXT_H),
129 KVM_MISA_CFG(RVI, KVM_RISCV_ISA_EXT_I),
130 KVM_MISA_CFG(RVM, KVM_RISCV_ISA_EXT_M),
133 static void kvm_cpu_set_misa_ext_cfg(Object *obj, Visitor *v,
135 void *opaque, Error **errp)
137 KVMCPUConfig *misa_ext_cfg = opaque;
138 target_ulong misa_bit = misa_ext_cfg->offset;
139 RISCVCPU *cpu = RISCV_CPU(obj);
140 CPURISCVState *env = &cpu->env;
141 bool value, host_bit;
143 if (!visit_type_bool(v, name, &value, errp)) {
147 host_bit = env->misa_ext_mask & misa_bit;
149 if (value == host_bit) {
154 misa_ext_cfg->user_set = true;
159 * Forbid users to enable extensions that aren't
160 * available in the hart.
162 error_setg(errp, "Enabling MISA bit '%s' is not allowed: it's not "
163 "enabled in the host", misa_ext_cfg->name);
166 static void kvm_riscv_update_cpu_misa_ext(RISCVCPU *cpu, CPUState *cs)
168 CPURISCVState *env = &cpu->env;
172 for (i = 0; i < ARRAY_SIZE(kvm_misa_ext_cfgs); i++) {
173 KVMCPUConfig *misa_cfg = &kvm_misa_ext_cfgs[i];
174 target_ulong misa_bit = misa_cfg->offset;
176 if (!misa_cfg->user_set) {
180 /* If we're here we're going to disable the MISA bit */
182 id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
183 misa_cfg->kvm_reg_id);
184 ret = kvm_set_one_reg(cs, id, ®);
187 * We're not checking for -EINVAL because if the bit is about
188 * to be disabled, it means that it was already enabled by
189 * KVM. We determined that by fetching the 'isa' register
190 * during init() time. Any error at this point is worth
193 error_report("Unable to set KVM reg %s, error %d",
194 misa_cfg->name, ret);
197 env->misa_ext &= ~misa_bit;
201 #define CPUCFG(_prop) offsetof(struct RISCVCPUConfig, _prop)
203 #define KVM_EXT_CFG(_name, _prop, _reg_id) \
204 {.name = _name, .offset = CPUCFG(_prop), \
205 .kvm_reg_id = _reg_id}
207 static KVMCPUConfig kvm_multi_ext_cfgs[] = {
208 KVM_EXT_CFG("zicbom", ext_icbom, KVM_RISCV_ISA_EXT_ZICBOM),
209 KVM_EXT_CFG("zicboz", ext_icboz, KVM_RISCV_ISA_EXT_ZICBOZ),
210 KVM_EXT_CFG("zihintpause", ext_zihintpause, KVM_RISCV_ISA_EXT_ZIHINTPAUSE),
211 KVM_EXT_CFG("zbb", ext_zbb, KVM_RISCV_ISA_EXT_ZBB),
212 KVM_EXT_CFG("ssaia", ext_ssaia, KVM_RISCV_ISA_EXT_SSAIA),
213 KVM_EXT_CFG("sstc", ext_sstc, KVM_RISCV_ISA_EXT_SSTC),
214 KVM_EXT_CFG("svinval", ext_svinval, KVM_RISCV_ISA_EXT_SVINVAL),
215 KVM_EXT_CFG("svpbmt", ext_svpbmt, KVM_RISCV_ISA_EXT_SVPBMT),
218 static void *kvmconfig_get_cfg_addr(RISCVCPU *cpu, KVMCPUConfig *kvmcfg)
220 return (void *)&cpu->cfg + kvmcfg->offset;
223 static void kvm_cpu_cfg_set(RISCVCPU *cpu, KVMCPUConfig *multi_ext,
226 bool *ext_enabled = kvmconfig_get_cfg_addr(cpu, multi_ext);
231 static uint32_t kvm_cpu_cfg_get(RISCVCPU *cpu,
232 KVMCPUConfig *multi_ext)
234 bool *ext_enabled = kvmconfig_get_cfg_addr(cpu, multi_ext);
239 static void kvm_cpu_set_multi_ext_cfg(Object *obj, Visitor *v,
241 void *opaque, Error **errp)
243 KVMCPUConfig *multi_ext_cfg = opaque;
244 RISCVCPU *cpu = RISCV_CPU(obj);
245 bool value, host_val;
247 if (!visit_type_bool(v, name, &value, errp)) {
251 host_val = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
254 * Ignore if the user is setting the same value
257 if (value == host_val) {
261 if (!multi_ext_cfg->supported) {
263 * Error out if the user is trying to enable an
264 * extension that KVM doesn't support. Ignore
268 error_setg(errp, "KVM does not support disabling extension %s",
269 multi_ext_cfg->name);
275 multi_ext_cfg->user_set = true;
276 kvm_cpu_cfg_set(cpu, multi_ext_cfg, value);
279 static KVMCPUConfig kvm_cbom_blocksize = {
280 .name = "cbom_blocksize",
281 .offset = CPUCFG(cbom_blocksize),
282 .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicbom_block_size)
285 static KVMCPUConfig kvm_cboz_blocksize = {
286 .name = "cboz_blocksize",
287 .offset = CPUCFG(cboz_blocksize),
288 .kvm_reg_id = KVM_REG_RISCV_CONFIG_REG(zicboz_block_size)
291 static void kvm_cpu_set_cbomz_blksize(Object *obj, Visitor *v,
293 void *opaque, Error **errp)
295 KVMCPUConfig *cbomz_cfg = opaque;
296 RISCVCPU *cpu = RISCV_CPU(obj);
297 uint16_t value, *host_val;
299 if (!visit_type_uint16(v, name, &value, errp)) {
303 host_val = kvmconfig_get_cfg_addr(cpu, cbomz_cfg);
305 if (value != *host_val) {
306 error_report("Unable to set %s to a different value than "
308 cbomz_cfg->name, *host_val);
312 cbomz_cfg->user_set = true;
315 static void kvm_riscv_update_cpu_cfg_isa_ext(RISCVCPU *cpu, CPUState *cs)
317 CPURISCVState *env = &cpu->env;
321 for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
322 KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i];
324 if (!multi_ext_cfg->user_set) {
328 id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
329 multi_ext_cfg->kvm_reg_id);
330 reg = kvm_cpu_cfg_get(cpu, multi_ext_cfg);
331 ret = kvm_set_one_reg(cs, id, ®);
333 error_report("Unable to %s extension %s in KVM, error %d",
334 reg ? "enable" : "disable",
335 multi_ext_cfg->name, ret);
341 static void kvm_riscv_add_cpu_user_properties(Object *cpu_obj)
345 for (i = 0; i < ARRAY_SIZE(kvm_misa_ext_cfgs); i++) {
346 KVMCPUConfig *misa_cfg = &kvm_misa_ext_cfgs[i];
347 int bit = misa_cfg->offset;
349 misa_cfg->name = riscv_get_misa_ext_name(bit);
350 misa_cfg->description = riscv_get_misa_ext_description(bit);
352 object_property_add(cpu_obj, misa_cfg->name, "bool",
354 kvm_cpu_set_misa_ext_cfg,
356 object_property_set_description(cpu_obj, misa_cfg->name,
357 misa_cfg->description);
360 for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
361 KVMCPUConfig *multi_cfg = &kvm_multi_ext_cfgs[i];
363 object_property_add(cpu_obj, multi_cfg->name, "bool",
365 kvm_cpu_set_multi_ext_cfg,
369 object_property_add(cpu_obj, "cbom_blocksize", "uint16",
370 NULL, kvm_cpu_set_cbomz_blksize,
371 NULL, &kvm_cbom_blocksize);
373 object_property_add(cpu_obj, "cboz_blocksize", "uint16",
374 NULL, kvm_cpu_set_cbomz_blksize,
375 NULL, &kvm_cboz_blocksize);
378 static int kvm_riscv_get_regs_core(CPUState *cs)
383 CPURISCVState *env = &RISCV_CPU(cs)->env;
385 ret = kvm_get_one_reg(cs, RISCV_CORE_REG(env, regs.pc), ®);
391 for (i = 1; i < 32; i++) {
392 uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
393 ret = kvm_get_one_reg(cs, id, ®);
403 static int kvm_riscv_put_regs_core(CPUState *cs)
408 CPURISCVState *env = &RISCV_CPU(cs)->env;
411 ret = kvm_set_one_reg(cs, RISCV_CORE_REG(env, regs.pc), ®);
416 for (i = 1; i < 32; i++) {
417 uint64_t id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CORE, i);
419 ret = kvm_set_one_reg(cs, id, ®);
428 static int kvm_riscv_get_regs_csr(CPUState *cs)
431 CPURISCVState *env = &RISCV_CPU(cs)->env;
433 KVM_RISCV_GET_CSR(cs, env, sstatus, env->mstatus);
434 KVM_RISCV_GET_CSR(cs, env, sie, env->mie);
435 KVM_RISCV_GET_CSR(cs, env, stvec, env->stvec);
436 KVM_RISCV_GET_CSR(cs, env, sscratch, env->sscratch);
437 KVM_RISCV_GET_CSR(cs, env, sepc, env->sepc);
438 KVM_RISCV_GET_CSR(cs, env, scause, env->scause);
439 KVM_RISCV_GET_CSR(cs, env, stval, env->stval);
440 KVM_RISCV_GET_CSR(cs, env, sip, env->mip);
441 KVM_RISCV_GET_CSR(cs, env, satp, env->satp);
445 static int kvm_riscv_put_regs_csr(CPUState *cs)
448 CPURISCVState *env = &RISCV_CPU(cs)->env;
450 KVM_RISCV_SET_CSR(cs, env, sstatus, env->mstatus);
451 KVM_RISCV_SET_CSR(cs, env, sie, env->mie);
452 KVM_RISCV_SET_CSR(cs, env, stvec, env->stvec);
453 KVM_RISCV_SET_CSR(cs, env, sscratch, env->sscratch);
454 KVM_RISCV_SET_CSR(cs, env, sepc, env->sepc);
455 KVM_RISCV_SET_CSR(cs, env, scause, env->scause);
456 KVM_RISCV_SET_CSR(cs, env, stval, env->stval);
457 KVM_RISCV_SET_CSR(cs, env, sip, env->mip);
458 KVM_RISCV_SET_CSR(cs, env, satp, env->satp);
463 static int kvm_riscv_get_regs_fp(CPUState *cs)
467 CPURISCVState *env = &RISCV_CPU(cs)->env;
469 if (riscv_has_ext(env, RVD)) {
471 for (i = 0; i < 32; i++) {
472 ret = kvm_get_one_reg(cs, RISCV_FP_D_REG(env, i), ®);
481 if (riscv_has_ext(env, RVF)) {
483 for (i = 0; i < 32; i++) {
484 ret = kvm_get_one_reg(cs, RISCV_FP_F_REG(env, i), ®);
496 static int kvm_riscv_put_regs_fp(CPUState *cs)
500 CPURISCVState *env = &RISCV_CPU(cs)->env;
502 if (riscv_has_ext(env, RVD)) {
504 for (i = 0; i < 32; i++) {
506 ret = kvm_set_one_reg(cs, RISCV_FP_D_REG(env, i), ®);
514 if (riscv_has_ext(env, RVF)) {
516 for (i = 0; i < 32; i++) {
518 ret = kvm_set_one_reg(cs, RISCV_FP_F_REG(env, i), ®);
529 static void kvm_riscv_get_regs_timer(CPUState *cs)
531 CPURISCVState *env = &RISCV_CPU(cs)->env;
533 if (env->kvm_timer_dirty) {
537 KVM_RISCV_GET_TIMER(cs, env, time, env->kvm_timer_time);
538 KVM_RISCV_GET_TIMER(cs, env, compare, env->kvm_timer_compare);
539 KVM_RISCV_GET_TIMER(cs, env, state, env->kvm_timer_state);
540 KVM_RISCV_GET_TIMER(cs, env, frequency, env->kvm_timer_frequency);
542 env->kvm_timer_dirty = true;
545 static void kvm_riscv_put_regs_timer(CPUState *cs)
548 CPURISCVState *env = &RISCV_CPU(cs)->env;
550 if (!env->kvm_timer_dirty) {
554 KVM_RISCV_SET_TIMER(cs, env, time, env->kvm_timer_time);
555 KVM_RISCV_SET_TIMER(cs, env, compare, env->kvm_timer_compare);
558 * To set register of RISCV_TIMER_REG(state) will occur a error from KVM
559 * on env->kvm_timer_state == 0, It's better to adapt in KVM, but it
560 * doesn't matter that adaping in QEMU now.
561 * TODO If KVM changes, adapt here.
563 if (env->kvm_timer_state) {
564 KVM_RISCV_SET_TIMER(cs, env, state, env->kvm_timer_state);
568 * For now, migration will not work between Hosts with different timer
569 * frequency. Therefore, we should check whether they are the same here
570 * during the migration.
572 if (migration_is_running(migrate_get_current()->state)) {
573 KVM_RISCV_GET_TIMER(cs, env, frequency, reg);
574 if (reg != env->kvm_timer_frequency) {
575 error_report("Dst Hosts timer frequency != Src Hosts");
579 env->kvm_timer_dirty = false;
582 typedef struct KVMScratchCPU {
589 * Heavily inspired by kvm_arm_create_scratch_host_vcpu()
590 * from target/arm/kvm.c.
592 static bool kvm_riscv_create_scratch_vcpu(KVMScratchCPU *scratch)
594 int kvmfd = -1, vmfd = -1, cpufd = -1;
596 kvmfd = qemu_open_old("/dev/kvm", O_RDWR);
601 vmfd = ioctl(kvmfd, KVM_CREATE_VM, 0);
602 } while (vmfd == -1 && errno == EINTR);
606 cpufd = ioctl(vmfd, KVM_CREATE_VCPU, 0);
611 scratch->kvmfd = kvmfd;
612 scratch->vmfd = vmfd;
613 scratch->cpufd = cpufd;
631 static void kvm_riscv_destroy_scratch_vcpu(KVMScratchCPU *scratch)
633 close(scratch->cpufd);
634 close(scratch->vmfd);
635 close(scratch->kvmfd);
638 static void kvm_riscv_init_machine_ids(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
640 CPURISCVState *env = &cpu->env;
641 struct kvm_one_reg reg;
644 reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
645 KVM_REG_RISCV_CONFIG_REG(mvendorid));
646 reg.addr = (uint64_t)&cpu->cfg.mvendorid;
647 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
649 error_report("Unable to retrieve mvendorid from host, error %d", ret);
652 reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
653 KVM_REG_RISCV_CONFIG_REG(marchid));
654 reg.addr = (uint64_t)&cpu->cfg.marchid;
655 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
657 error_report("Unable to retrieve marchid from host, error %d", ret);
660 reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
661 KVM_REG_RISCV_CONFIG_REG(mimpid));
662 reg.addr = (uint64_t)&cpu->cfg.mimpid;
663 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
665 error_report("Unable to retrieve mimpid from host, error %d", ret);
669 static void kvm_riscv_init_misa_ext_mask(RISCVCPU *cpu,
670 KVMScratchCPU *kvmcpu)
672 CPURISCVState *env = &cpu->env;
673 struct kvm_one_reg reg;
676 reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
677 KVM_REG_RISCV_CONFIG_REG(isa));
678 reg.addr = (uint64_t)&env->misa_ext_mask;
679 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
682 error_report("Unable to fetch ISA register from KVM, "
684 kvm_riscv_destroy_scratch_vcpu(kvmcpu);
688 env->misa_ext = env->misa_ext_mask;
691 static void kvm_riscv_read_cbomz_blksize(RISCVCPU *cpu, KVMScratchCPU *kvmcpu,
692 KVMCPUConfig *cbomz_cfg)
694 CPURISCVState *env = &cpu->env;
695 struct kvm_one_reg reg;
698 reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
699 cbomz_cfg->kvm_reg_id);
700 reg.addr = (uint64_t)kvmconfig_get_cfg_addr(cpu, cbomz_cfg);
701 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
703 error_report("Unable to read KVM reg %s, error %d",
704 cbomz_cfg->name, ret);
709 static void kvm_riscv_init_multiext_cfg(RISCVCPU *cpu, KVMScratchCPU *kvmcpu)
711 CPURISCVState *env = &cpu->env;
715 for (i = 0; i < ARRAY_SIZE(kvm_multi_ext_cfgs); i++) {
716 KVMCPUConfig *multi_ext_cfg = &kvm_multi_ext_cfgs[i];
717 struct kvm_one_reg reg;
719 reg.id = kvm_riscv_reg_id(env, KVM_REG_RISCV_ISA_EXT,
720 multi_ext_cfg->kvm_reg_id);
721 reg.addr = (uint64_t)&val;
722 ret = ioctl(kvmcpu->cpufd, KVM_GET_ONE_REG, ®);
724 if (errno == EINVAL) {
725 /* Silently default to 'false' if KVM does not support it. */
726 multi_ext_cfg->supported = false;
729 error_report("Unable to read ISA_EXT KVM register %s, "
730 "error %d", multi_ext_cfg->name, ret);
731 kvm_riscv_destroy_scratch_vcpu(kvmcpu);
735 multi_ext_cfg->supported = true;
738 kvm_cpu_cfg_set(cpu, multi_ext_cfg, val);
741 if (cpu->cfg.ext_icbom) {
742 kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cbom_blocksize);
745 if (cpu->cfg.ext_icboz) {
746 kvm_riscv_read_cbomz_blksize(cpu, kvmcpu, &kvm_cboz_blocksize);
750 void kvm_riscv_init_user_properties(Object *cpu_obj)
752 RISCVCPU *cpu = RISCV_CPU(cpu_obj);
753 KVMScratchCPU kvmcpu;
755 if (!kvm_riscv_create_scratch_vcpu(&kvmcpu)) {
759 kvm_riscv_add_cpu_user_properties(cpu_obj);
760 kvm_riscv_init_machine_ids(cpu, &kvmcpu);
761 kvm_riscv_init_misa_ext_mask(cpu, &kvmcpu);
762 kvm_riscv_init_multiext_cfg(cpu, &kvmcpu);
764 kvm_riscv_destroy_scratch_vcpu(&kvmcpu);
767 const KVMCapabilityInfo kvm_arch_required_capabilities[] = {
771 int kvm_arch_get_registers(CPUState *cs)
775 ret = kvm_riscv_get_regs_core(cs);
780 ret = kvm_riscv_get_regs_csr(cs);
785 ret = kvm_riscv_get_regs_fp(cs);
793 int kvm_arch_put_registers(CPUState *cs, int level)
797 ret = kvm_riscv_put_regs_core(cs);
802 ret = kvm_riscv_put_regs_csr(cs);
807 ret = kvm_riscv_put_regs_fp(cs);
815 int kvm_arch_release_virq_post(int virq)
820 int kvm_arch_fixup_msi_route(struct kvm_irq_routing_entry *route,
821 uint64_t address, uint32_t data, PCIDevice *dev)
826 int kvm_arch_destroy_vcpu(CPUState *cs)
831 unsigned long kvm_arch_vcpu_id(CPUState *cpu)
833 return cpu->cpu_index;
836 static void kvm_riscv_vm_state_change(void *opaque, bool running,
839 CPUState *cs = opaque;
842 kvm_riscv_put_regs_timer(cs);
844 kvm_riscv_get_regs_timer(cs);
848 void kvm_arch_init_irq_routing(KVMState *s)
852 static int kvm_vcpu_set_machine_ids(RISCVCPU *cpu, CPUState *cs)
854 CPURISCVState *env = &cpu->env;
859 id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
860 KVM_REG_RISCV_CONFIG_REG(mvendorid));
862 * cfg.mvendorid is an uint32 but a target_ulong will
863 * be written. Assign it to a target_ulong var to avoid
864 * writing pieces of other cpu->cfg fields in the reg.
866 reg = cpu->cfg.mvendorid;
867 ret = kvm_set_one_reg(cs, id, ®);
872 id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
873 KVM_REG_RISCV_CONFIG_REG(marchid));
874 ret = kvm_set_one_reg(cs, id, &cpu->cfg.marchid);
879 id = kvm_riscv_reg_id(env, KVM_REG_RISCV_CONFIG,
880 KVM_REG_RISCV_CONFIG_REG(mimpid));
881 ret = kvm_set_one_reg(cs, id, &cpu->cfg.mimpid);
886 int kvm_arch_init_vcpu(CPUState *cs)
889 RISCVCPU *cpu = RISCV_CPU(cs);
891 qemu_add_vm_change_state_handler(kvm_riscv_vm_state_change, cs);
893 if (!object_dynamic_cast(OBJECT(cpu), TYPE_RISCV_CPU_HOST)) {
894 ret = kvm_vcpu_set_machine_ids(cpu, cs);
900 kvm_riscv_update_cpu_misa_ext(cpu, cs);
901 kvm_riscv_update_cpu_cfg_isa_ext(cpu, cs);
906 int kvm_arch_msi_data_to_gsi(uint32_t data)
911 int kvm_arch_add_msi_route_post(struct kvm_irq_routing_entry *route,
912 int vector, PCIDevice *dev)
917 int kvm_arch_init(MachineState *ms, KVMState *s)
922 int kvm_arch_irqchip_create(KVMState *s)
927 int kvm_arch_process_async_events(CPUState *cs)
932 void kvm_arch_pre_run(CPUState *cs, struct kvm_run *run)
936 MemTxAttrs kvm_arch_post_run(CPUState *cs, struct kvm_run *run)
938 return MEMTXATTRS_UNSPECIFIED;
941 bool kvm_arch_stop_on_emulation_error(CPUState *cs)
946 static int kvm_riscv_handle_sbi(CPUState *cs, struct kvm_run *run)
950 switch (run->riscv_sbi.extension_id) {
951 case SBI_EXT_0_1_CONSOLE_PUTCHAR:
952 ch = run->riscv_sbi.args[0];
953 qemu_chr_fe_write(serial_hd(0)->be, &ch, sizeof(ch));
955 case SBI_EXT_0_1_CONSOLE_GETCHAR:
956 ret = qemu_chr_fe_read_all(serial_hd(0)->be, &ch, sizeof(ch));
957 if (ret == sizeof(ch)) {
958 run->riscv_sbi.ret[0] = ch;
960 run->riscv_sbi.ret[0] = -1;
965 qemu_log_mask(LOG_UNIMP,
966 "%s: un-handled SBI EXIT, specific reasons is %lu\n",
967 __func__, run->riscv_sbi.extension_id);
974 int kvm_arch_handle_exit(CPUState *cs, struct kvm_run *run)
977 switch (run->exit_reason) {
978 case KVM_EXIT_RISCV_SBI:
979 ret = kvm_riscv_handle_sbi(cs, run);
982 qemu_log_mask(LOG_UNIMP, "%s: un-handled exit reason %d\n",
983 __func__, run->exit_reason);
990 void kvm_riscv_reset_vcpu(RISCVCPU *cpu)
992 CPURISCVState *env = &cpu->env;
994 if (!kvm_enabled()) {
997 env->pc = cpu->env.kernel_addr;
998 env->gpr[10] = kvm_arch_vcpu_id(CPU(cpu)); /* a0 */
999 env->gpr[11] = cpu->env.fdt_addr; /* a1 */
1003 void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level)
1006 unsigned virq = level ? KVM_INTERRUPT_SET : KVM_INTERRUPT_UNSET;
1008 if (irq != IRQ_S_EXT) {
1009 perror("kvm riscv set irq != IRQ_S_EXT\n");
1013 ret = kvm_vcpu_ioctl(CPU(cpu), KVM_INTERRUPT, &virq);
1015 perror("Set irq failed");
1020 bool kvm_arch_cpu_check_are_resettable(void)
1025 void kvm_arch_accel_class_init(ObjectClass *oc)