@samitouri / QOSamiQemu / commits / 6c91b423a9

target/riscv: gate riscv_cpu_update_mip with tcg_enabled()

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 <daniel.barboza@oss.qualcomm.com> Reviewed-by: Philippe Mathieu-Daudé <philmd@oss.qualcomm.com> Reviewed-by: Alistair Francis <alistair.francis@wdc.com> Message-ID: <20260703180538.3346781-17-daniel.barboza@oss.qualcomm.com> Signed-off-by: Alistair Francis <alistair.francis@wdc.com>

Daniel Henrique Barboza committed Jul 3, 2026 at 15:05 UTC 6c91b423a9a4dac2a22629491f2a3059aa40b954
2 files changed +39 -13
target/riscv/cpu.c
+14 -5
@@ -1343,14 +1343,18 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
1343 case IRQ_M_EXT:
1344 if (kvm_enabled()) {
1345 kvm_riscv_set_irq(cpu, irq, level);
1346 - } else {
1346 + }
1347 +
1348 + if (tcg_enabled()) {
1349 riscv_cpu_update_mip(env, 1 << irq, BOOL_TO_MASK(level));
1350 }
1351 break;
1352 case IRQ_S_EXT:
1353 if (kvm_enabled()) {
1354 kvm_riscv_set_irq(cpu, irq, level);
1353 - } else {
1355 + }
1356 +
1357 + if (tcg_enabled()) {
1358 env->external_seip = level;
1359 riscv_cpu_update_mip(env, 1 << irq,
1360 BOOL_TO_MASK(level | env->software_seip));
@@ -1377,9 +1381,14 @@ static void riscv_cpu_set_irq(void *opaque, int irq, int level)
1381 env->hgeip |= 1ULL << irq;
1382 }
1383
1380 - /* Update mip.SGEIP bit */
1381 - riscv_cpu_update_mip(env, MIP_SGEIP,
1382 - BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
1384 + if (kvm_enabled()) {
1385 + kvm_riscv_set_irq(cpu, irq, level);
1386 + }
1387 + if (tcg_enabled()) {
1388 + /* Update mip.SGEIP bit */
1389 + riscv_cpu_update_mip(env, MIP_SGEIP,
1390 + BOOL_TO_MASK(!!(env->hgeie & env->hgeip)));
1391 + }
1392 } else {
1393 g_assert_not_reached();
1394 }
target/riscv/time_helper.c
+25 -8
@@ -21,19 +21,34 @@
21 #include "cpu_bits.h"
22 #include "time_helper.h"
23 #include "hw/intc/riscv_aclint.h"
24 +#include "kvm/kvm_riscv.h"
25 +#include "system/kvm.h"
26 +#include "system/tcg.h"
27 +
28 +static void riscv_accel_set_irq(RISCVCPU *cpu, int irq, int level)
29 +{
30 + if (kvm_enabled()) {
31 + kvm_riscv_set_irq(cpu, irq, level);
32 + }
33 +
34 + if (tcg_enabled()) {
35 + riscv_cpu_update_mip(&cpu->env, irq, level);
36 + }
37 +}
38 +
39
40 static void riscv_vstimer_cb(void *opaque)
41 {
42 RISCVCPU *cpu = opaque;
43 CPURISCVState *env = &cpu->env;
44 env->vstime_irq = 1;
30 - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(1));
45 + riscv_accel_set_irq(cpu, 0, BOOL_TO_MASK(1));
46 }
47
48 static void riscv_stimer_cb(void *opaque)
49 {
50 RISCVCPU *cpu = opaque;
36 - riscv_cpu_update_mip(&cpu->env, MIP_STIP, BOOL_TO_MASK(1));
51 + riscv_accel_set_irq(cpu, MIP_STIP, BOOL_TO_MASK(1));
52 }
53
54 /*
@@ -48,6 +63,7 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer,
63 RISCVAclintMTimerState *mtimer = env->rdtime_fn_arg;
64 uint32_t timebase_freq;
65 uint64_t rtc_r;
66 + RISCVCPU *cpu;
67
68 if (!riscv_cpu_cfg(env)->ext_sstc || !env->rdtime_fn ||
69 !env->rdtime_fn_arg || !get_field(env->menvcfg, MENVCFG_STCE)) {
@@ -63,6 +79,7 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer,
79
80 timebase_freq = mtimer->timebase_freq;
81 rtc_r = env->rdtime_fn(env->rdtime_fn_arg) + delta;
82 + cpu = env_archcpu(env);
83
84 if (timecmp <= rtc_r) {
85 /*
@@ -71,9 +88,9 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer,
88 */
89 if (timer_irq == MIP_VSTIP) {
90 env->vstime_irq = 1;
74 - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(1));
91 + riscv_accel_set_irq(cpu, 0, BOOL_TO_MASK(1));
92 } else {
76 - riscv_cpu_update_mip(env, MIP_STIP, BOOL_TO_MASK(1));
93 + riscv_accel_set_irq(cpu, MIP_STIP, BOOL_TO_MASK(1));
94 }
95 return;
96 }
@@ -81,9 +98,9 @@ void riscv_timer_write_timecmp(CPURISCVState *env, QEMUTimer *timer,
98 /* Clear the [VS|S]TIP bit in mip */
99 if (timer_irq == MIP_VSTIP) {
100 env->vstime_irq = 0;
84 - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(0));
101 + riscv_accel_set_irq(cpu, 0, BOOL_TO_MASK(0));
102 } else {
86 - riscv_cpu_update_mip(env, timer_irq, BOOL_TO_MASK(0));
103 + riscv_accel_set_irq(cpu, timer_irq, BOOL_TO_MASK(0));
104 }
105
106 /*
@@ -151,7 +168,7 @@ static void riscv_timer_disable_timecmp(CPURISCVState *env, QEMUTimer *timer,
168 {
169 /* Disable S-mode Timer IRQ and HW-based STIP */
170 if ((timer_irq == MIP_STIP) && !get_field(env->menvcfg, MENVCFG_STCE)) {
154 - riscv_cpu_update_mip(env, timer_irq, BOOL_TO_MASK(0));
171 + riscv_accel_set_irq(env_archcpu(env), timer_irq, BOOL_TO_MASK(0));
172 timer_del(timer);
173 return;
174 }
@@ -161,7 +178,7 @@ static void riscv_timer_disable_timecmp(CPURISCVState *env, QEMUTimer *timer,
178 (!get_field(env->menvcfg, MENVCFG_STCE) ||
179 !get_field(env->henvcfg, HENVCFG_STCE))) {
180 env->vstime_irq = 0;
164 - riscv_cpu_update_mip(env, 0, BOOL_TO_MASK(0));
181 + riscv_accel_set_irq(env_archcpu(env), 0, BOOL_TO_MASK(0));
182 timer_del(timer);
183 return;
184 }