From e0c87e30678394cbca7585ef103b773a396be4d8 Mon Sep 17 00:00:00 2001 From: Daniel Henrique Barboza Date: Tue, 19 Nov 2024 16:17:04 -0300 Subject: hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode aplic-imsic The last step to enable KVM AIA aplic-imsic with irqchip in split mode is to deal with how MSIs are going to be sent. In our current design we don't allow an APLIC controller to send MSIs unless it's on m-mode. And we also do not allow Supervisor MSI address configuration via the 'smsiaddrcfg' and 'smsiaddrcfgh' registers unless it's also a m-mode APLIC controller. Add a new RISCVACPLICState attribute called 'kvm_msicfgaddr'. This attribute represents the base configuration address for MSIs, in our case the base addr of the IMSIC controller. This attribute is being set only when running irqchip_split() mode with aia=aplic-imsic. During riscv_aplic_msi_send() we'll check if the attribute was set to skip the check for a m-mode APLIC controller and to change the resulting MSI addr by adding kvm_msicfgaddr right before address_space_stl_le(). Signed-off-by: Daniel Henrique Barboza Acked-by: Alistair Francis Message-ID: <20241119191706.718860-7-dbarboza@ventanamicro.com> Signed-off-by: Alistair Francis --- hw/intc/riscv_aplic.c | 42 +++++++++++++++++++++++++++++++++--------- 1 file changed, 33 insertions(+), 9 deletions(-) (limited to 'hw/intc') diff --git a/hw/intc/riscv_aplic.c b/hw/intc/riscv_aplic.c index ba4e802888..1e4cdb500c 100644 --- a/hw/intc/riscv_aplic.c +++ b/hw/intc/riscv_aplic.c @@ -177,6 +177,16 @@ bool riscv_use_emulated_aplic(bool msimode) #endif } +void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr) +{ +#ifdef CONFIG_KVM + if (riscv_use_emulated_aplic(aplic->msimode)) { + aplic->kvm_msicfgaddr = extract64(addr, 0, 32); + aplic->kvm_msicfgaddrH = extract64(addr, 32, 32); + } +#endif +} + static bool riscv_aplic_irq_rectified_val(RISCVAPLICState *aplic, uint32_t irq) { @@ -381,13 +391,16 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic, uint32_t lhxs, lhxw, hhxs, hhxw, group_idx, msicfgaddr, msicfgaddrH; aplic_m = aplic; - while (aplic_m && !aplic_m->mmode) { - aplic_m = aplic_m->parent; - } - if (!aplic_m) { - qemu_log_mask(LOG_GUEST_ERROR, "%s: m-level APLIC not found\n", - __func__); - return; + + if (!aplic->kvm_splitmode) { + while (aplic_m && !aplic_m->mmode) { + aplic_m = aplic_m->parent; + } + if (!aplic_m) { + qemu_log_mask(LOG_GUEST_ERROR, "%s: m-level APLIC not found\n", + __func__); + return; + } } if (aplic->mmode) { @@ -419,6 +432,11 @@ static void riscv_aplic_msi_send(RISCVAPLICState *aplic, addr |= (uint64_t)(guest_idx & APLIC_xMSICFGADDR_PPN_HART(lhxs)); addr <<= APLIC_xMSICFGADDR_PPN_SHIFT; + if (aplic->kvm_splitmode) { + addr |= aplic->kvm_msicfgaddr; + addr |= ((uint64_t)aplic->kvm_msicfgaddrH << 32); + } + address_space_stl_le(&address_space_memory, addr, eiid, MEMTXATTRS_UNSPECIFIED, &result); if (result != MEMTX_OK) { @@ -892,6 +910,10 @@ static void riscv_aplic_realize(DeviceState *dev, Error **errp) memory_region_init_io(&aplic->mmio, OBJECT(dev), &riscv_aplic_ops, aplic, TYPE_RISCV_APLIC, aplic->aperture_size); sysbus_init_mmio(SYS_BUS_DEVICE(dev), &aplic->mmio); + + if (kvm_enabled()) { + aplic->kvm_splitmode = true; + } } /* @@ -939,8 +961,8 @@ static const Property riscv_aplic_properties[] = { static const VMStateDescription vmstate_riscv_aplic = { .name = "riscv_aplic", - .version_id = 1, - .minimum_version_id = 1, + .version_id = 2, + .minimum_version_id = 2, .fields = (const VMStateField[]) { VMSTATE_UINT32(domaincfg, RISCVAPLICState), VMSTATE_UINT32(mmsicfgaddr, RISCVAPLICState), @@ -948,6 +970,8 @@ static const VMStateDescription vmstate_riscv_aplic = { VMSTATE_UINT32(smsicfgaddr, RISCVAPLICState), VMSTATE_UINT32(smsicfgaddrH, RISCVAPLICState), VMSTATE_UINT32(genmsi, RISCVAPLICState), + VMSTATE_UINT32(kvm_msicfgaddr, RISCVAPLICState), + VMSTATE_UINT32(kvm_msicfgaddrH, RISCVAPLICState), VMSTATE_VARRAY_UINT32(sourcecfg, RISCVAPLICState, num_irqs, 0, vmstate_info_uint32, uint32_t), -- cgit 1.4.1