hw/riscv/virt.c, riscv_aplic.c: add 'emulated_aplic' helpers

The current logic to determine if we don't need an emulated APLIC
controller, i.e. KVM will provide for us, is to determine if we're
running KVM, with in-kernel irqchip support, and running
aia=aplic-imsic. This is modelled by riscv_is_kvm_aia_aplic_imsic() and
virt_use_kvm_aia_aplic_imsic().

This won't suffice to support irqchip_split() mode: it will match
exactly the same conditions as the one above, but setting the irqchip to
'split' mode will now require us to emulate an APLIC s-mode controller,
like we're doing with 'aia=aplic'.

Create a new riscv_use_emulated_aplic() helper that will encapsulate
this logic. Replace the uses of "riscv_is_kvm_aia_aplic_imsic()" with
this helper every time we're taking a decision on emulate an APLIC
controller or not. Do the same in virt.c with virt_use_emulated_aplic().

Signed-off-by: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
Reviewed-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20241119191706.718860-6-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
This commit is contained in:
Daniel Henrique Barboza 2024-11-19 16:17:03 -03:00 committed by Alistair Francis
parent 3fd619db23
commit b319ef15b8
3 changed files with 34 additions and 5 deletions

View File

@ -32,6 +32,7 @@
#include "target/riscv/cpu.h" #include "target/riscv/cpu.h"
#include "sysemu/sysemu.h" #include "sysemu/sysemu.h"
#include "sysemu/kvm.h" #include "sysemu/kvm.h"
#include "sysemu/tcg.h"
#include "kvm/kvm_riscv.h" #include "kvm/kvm_riscv.h"
#include "migration/vmstate.h" #include "migration/vmstate.h"
@ -159,6 +160,23 @@ bool riscv_is_kvm_aia_aplic_imsic(bool msimode)
return kvm_irqchip_in_kernel() && msimode; return kvm_irqchip_in_kernel() && msimode;
} }
bool riscv_use_emulated_aplic(bool msimode)
{
#ifdef CONFIG_KVM
if (tcg_enabled()) {
return true;
}
if (!riscv_is_kvm_aia_aplic_imsic(msimode)) {
return true;
}
return kvm_kernel_irqchip_split();
#else
return true;
#endif
}
static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic, static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic,
uint32_t irq) uint32_t irq)
{ {
@ -857,7 +875,7 @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
uint32_t i; uint32_t i;
RISCVAPLICState *aplic = RISCV_APLIC(dev); RISCVAPLICState *aplic = RISCV_APLIC(dev);
if (!riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) { if (riscv_use_emulated_aplic(aplic->msimode)) {
aplic->bitfield_words = (aplic->num_irqs + 31) >> 5; aplic->bitfield_words = (aplic->num_irqs + 31) >> 5;
aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs); aplic->sourcecfg = g_new0(uint32_t, aplic->num_irqs);
aplic->state = g_new0(uint32_t, aplic->num_irqs); aplic->state = g_new0(uint32_t, aplic->num_irqs);
@ -881,7 +899,7 @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp)
* have IRQ lines delegated by their parent APLIC. * have IRQ lines delegated by their parent APLIC.
*/ */
if (!aplic->parent) { if (!aplic->parent) {
if (kvm_enabled() && riscv_is_kvm_aia_aplic_imsic(aplic->msimode)) { if (kvm_enabled() && !riscv_use_emulated_aplic(aplic->msimode)) {
qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs); qdev_init_gpio_in(dev, riscv_kvm_aplic_request, aplic->num_irqs);
} else { } else {
qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs); qdev_init_gpio_in(dev, riscv_aplic_request, aplic->num_irqs);
@ -1025,7 +1043,7 @@ DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal); sysbus_realize_and_unref(SYS_BUS_DEVICE(dev), &error_fatal);
if (!riscv_is_kvm_aia_aplic_imsic(msimode)) { if (riscv_use_emulated_aplic(msimode)) {
sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr); sysbus_mmio_map(SYS_BUS_DEVICE(dev), 0, addr);
} }

View File

@ -66,6 +66,13 @@ static bool virt_use_kvm_aia_aplic_imsic(RISCVVirtAIAType aia_type)
return riscv_is_kvm_aia_aplic_imsic(msimode); return riscv_is_kvm_aia_aplic_imsic(msimode);
} }
static bool virt_use_emulated_aplic(RISCVVirtAIAType aia_type)
{
bool msimode = aia_type == VIRT_AIA_TYPE_APLIC_IMSIC;
return riscv_use_emulated_aplic(msimode);
}
static bool virt_aclint_allowed(void) static bool virt_aclint_allowed(void)
{ {
return tcg_enabled() || qtest_enabled(); return tcg_enabled() || qtest_enabled();
@ -779,8 +786,11 @@ static void create_fdt_sockets(RISCVVirtState *s, const MemMapEntry *memmap,
*msi_pcie_phandle = msi_s_phandle; *msi_pcie_phandle = msi_s_phandle;
} }
/* KVM AIA aplic-imsic only has one APLIC instance */ /*
if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) { * With KVM AIA aplic-imsic, using an irqchip without split
* mode, we'll use only one APLIC instance.
*/
if (!virt_use_emulated_aplic(s->aia_type)) {
create_fdt_socket_aplic(s, memmap, 0, create_fdt_socket_aplic(s, memmap, 0,
msi_m_phandle, msi_s_phandle, phandle, msi_m_phandle, msi_s_phandle, phandle,
&intc_phandles[0], xplic_phandles, &intc_phandles[0], xplic_phandles,

View File

@ -72,6 +72,7 @@ struct RISCVAPLICState {
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child); void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
bool riscv_is_kvm_aia_aplic_imsic(bool msimode); bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
bool riscv_use_emulated_aplic(bool msimode);
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size, DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources, uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,