riscv_cpu_update_mip() is a TCG only call. Its KVM equivalent is kvm_riscv_set_irq(). cpu.c gates the KVM only function with a kvm_enabled() check, making it unavailable for TCG only builds. We need to do the same for riscv_cpu_update_mip() otherwise a KVM only build will fail because it doesn't know what this function is.
Use tcg_enabled() for the couple of riscv_cpu_update_mip() calls we have unguarded in cpu.c. We have way more calls to deal with in time_helper.c which isn't using kvm_riscv_set_irq() at all, so create a riscv_accel_set_irq() local helper that will choose whether to use the KVM or TCG API. The reason we're going through all this hassle in time_helper.c is because hw/int/riscv_aclint.c uses it, and if we don't do something about we won't have riscv_aclint working for KVM. Whether this is a real problem or not and we should remove aclint support for KVM is question for another day. Signed-off-by: Daniel Henrique Barboza <[email protected]> Reviewed-by: Philippe Mathieu-Daudé <[email protected]> --- target/riscv/cpu.c | 19 ++++++++++++++----- target/riscv/time_helper.c | 33 +++++++++++++++++++++++++-------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/target/riscv/cpu.c b/target/riscv/cpu.c index 7bd5bc0fc1..8f9d2967ef 100644 --- a/target/riscv/cpu.c +++ b/target/riscv/cpu.c @@ -1336,14 +1336,18 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) case IRQ_M_EXT: if (kvm_enabled()) { kvm_riscv_set_irq(cpu, irq, level); - } else { + } + + if (tcg_enabled()) { riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level)); } break; case IRQ_S_EXT: if (kvm_enabled()) { kvm_riscv_set_irq(cpu, irq, level); - } else { + } + + if (tcg_enabled()) { env->external_seip = level; riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level | env->software_seip)); @@ -1370,9 +1374,14 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level) env->hgeip |= 1ULL << irq; } - /* Update mip.SGEIP bit */ - riscv_cpu_update_mip(env, MIP_SGEIP, - BOOL_TO_MASK(!!(env->hgeie & env->hgeip))); + if (kvm_enabled()) { + kvm_riscv_set_irq(cpu, irq, level); + } + if (tcg_enabled()) { + /* Update mip.SGEIP bit */ + riscv_cpu_update_mip(env, MIP_SGEIP, + BOOL_TO_MASK(!!(env->hgeie & env->hgeip))); + } } else { g_assert_not_reached(); } diff --git a/target/riscv/time_helper.c b/target/riscv/time_helper.c index 400e917354..ede1a4c2a3 100644 --- a/target/riscv/time_helper.c +++ b/target/riscv/time_helper.c @@ -21,19 +21,34 @@ #include "cpu_bits.h" #include "time_helper.h" #include "hw/intc/riscv_aclint.h" +#include "kvm/kvm_riscv.h" +#include "system/kvm.h" +#include "system/tcg.h" + +static void riscv_accel_set_irq(RISCVCPU *cpu, int irq, int level) +{ + if (kvm_enabled()) { + kvm_riscv_set_irq(cpu, irq, level); + } + + if (tcg_enabled()) { + riscv_cpu_update_mip(&cpu->env, irq, level); + } +} + static void riscv_vstimer_cb(void *opaque) { RISCVCPU *cpu = opaque; CPURISCVState *env = &cpu->env; env->vstime_irq = 1; - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(1)); + riscv_accel_set_irq(cpu, 0, BOOL_TO_MASK(1)); } static void riscv_stimer_cb(void *opaque) { RISCVCPU *cpu = opaque; - riscv_cpu_update_mip(&cpu->env, MIP_STIP, BOOL_TO_MASK(1)); + riscv_accel_set_irq(cpu, MIP_STIP, BOOL_TO_MASK(1)); } /* @@ -48,6 +63,7 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer, RISCVAclintMTimerState *mtimer = env->rdtime_fn_arg; uint32_t timebase_freq; uint64_t rtc_r; + RISCVCPU *cpu; if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn || !env->rdtime_fn_arg || !get_field(env->menvcfg, MENVCFG_STCE)) { @@ -63,6 +79,7 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer, timebase_freq = mtimer->timebase_freq; rtc_r = env->rdtime_fn(env->rdtime_fn_arg) + delta; + cpu = env_archcpu(env); if (timecmp <= rtc_r) { /* @@ -71,9 +88,9 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer, */ if (timer_irq == MIP_VSTIP) { env->vstime_irq = 1; - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(1)); + riscv_accel_set_irq(cpu, 0, BOOL_TO_MASK(1)); } else { - riscv_cpu_update_mip(env, MIP_STIP, BOOL_TO_MASK(1)); + riscv_accel_set_irq(cpu, MIP_STIP, BOOL_TO_MASK(1)); } return; } @@ -81,9 +98,9 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer, /* Clear the [VS|S]TIP bit in mip */ if (timer_irq == MIP_VSTIP) { env->vstime_irq = 0; - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(0)); + riscv_accel_set_irq(cpu, 0, BOOL_TO_MASK(0)); } else { - riscv_cpu_update_mip(env, timer_irq, BOOL_TO_MASK(0)); + riscv_accel_set_irq(cpu, timer_irq, BOOL_TO_MASK(0)); } /* @@ -151,7 +168,7 @@ static void riscv_timer_disable_timecmp(CPURISCVState *env, QEMUTimer *timer, { /* Disable S-mode Timer IRQ and HW-based STIP */ if ((timer_irq == MIP_STIP) && !get_field(env->menvcfg, MENVCFG_STCE)) { - riscv_cpu_update_mip(env, timer_irq, BOOL_TO_MASK(0)); + riscv_accel_set_irq(env_archcpu(env), timer_irq, BOOL_TO_MASK(0)); timer_del(timer); return; } @@ -161,7 +178,7 @@ static void riscv_timer_disable_timecmp(CPURISCVState *env, QEMUTimer *timer, (!get_field(env->menvcfg, MENVCFG_STCE) || !get_field(env->henvcfg, HENVCFG_STCE))) { env->vstime_irq = 0; - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(0)); + riscv_accel_set_irq(env_archcpu(env), 0, BOOL_TO_MASK(0)); timer_del(timer); return; } -- 2.43.0
