[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PULL v2 16/39] hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode a
From: |
Alistair Francis |
Subject: |
[PULL v2 16/39] hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode aplic-imsic |
Date: |
Fri, 20 Dec 2024 11:54:16 +1000 |
From: Daniel Henrique Barboza <dbarboza@ventanamicro.com>
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 <dbarboza@ventanamicro.com>
Acked-by: Alistair Francis <alistair.francis@wdc.com>
Message-ID: <20241119191706.718860-7-dbarboza@ventanamicro.com>
Signed-off-by: Alistair Francis <alistair.francis@wdc.com>
---
include/hw/intc/riscv_aplic.h | 6 +++++
hw/intc/riscv_aplic.c | 42 +++++++++++++++++++++++++++--------
hw/riscv/virt.c | 6 ++++-
3 files changed, 44 insertions(+), 10 deletions(-)
diff --git a/include/hw/intc/riscv_aplic.h b/include/hw/intc/riscv_aplic.h
index 74ae5d87b5..489b9133c2 100644
--- a/include/hw/intc/riscv_aplic.h
+++ b/include/hw/intc/riscv_aplic.h
@@ -68,11 +68,17 @@ struct RISCVAPLICState {
uint32_t num_irqs;
bool msimode;
bool mmode;
+
+ /* To support KVM aia=aplic-imsic with irqchip split mode */
+ bool kvm_splitmode;
+ uint32_t kvm_msicfgaddr;
+ uint32_t kvm_msicfgaddrH;
};
void riscv_aplic_add_child(DeviceState *parent, DeviceState *child);
bool riscv_is_kvm_aia_aplic_imsic(bool msimode);
bool riscv_use_emulated_aplic(bool msimode);
+void riscv_aplic_set_kvm_msicfgaddr(RISCVAPLICState *aplic, hwaddr addr);
DeviceState *riscv_aplic_create(hwaddr addr, hwaddr size,
uint32_t hartid_base, uint32_t num_harts, uint32_t num_sources,
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),
diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c
index 937dfd1ef2..43a1c86c33 100644
--- a/hw/riscv/virt.c
+++ b/hw/riscv/virt.c
@@ -1300,7 +1300,7 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType
aia_type, int aia_guests,
int base_hartid, int hart_count)
{
int i;
- hwaddr addr;
+ hwaddr addr = 0;
uint32_t guest_bits;
DeviceState *aplic_s = NULL;
DeviceState *aplic_m = NULL;
@@ -1350,6 +1350,10 @@ static DeviceState *virt_create_aia(RISCVVirtAIAType
aia_type, int aia_guests,
VIRT_IRQCHIP_NUM_PRIO_BITS,
msimode, false, aplic_m);
+ if (kvm_enabled() && msimode) {
+ riscv_aplic_set_kvm_msicfgaddr(RISCV_APLIC(aplic_s), addr);
+ }
+
return kvm_enabled() ? aplic_s : aplic_m;
}
--
2.47.1
- [PULL v2 07/39] hw/riscv/virt.c, riscv-iommu-sys.c: add MSIx support, (continued)
- [PULL v2 07/39] hw/riscv/virt.c, riscv-iommu-sys.c: add MSIx support, Alistair Francis, 2024/12/19
- [PULL v2 08/39] hw/riscv/riscv-iommu: implement reset protocol, Alistair Francis, 2024/12/19
- [PULL v2 09/39] docs/specs: add riscv-iommu-sys information, Alistair Francis, 2024/12/19
- [PULL v2 10/39] target/riscv: Add Tenstorrent Ascalon CPU, Alistair Francis, 2024/12/19
- [PULL v2 13/39] hw/riscv/virt.c: rename helper to virt_use_kvm_aia_aplic_imsic(), Alistair Francis, 2024/12/19
- [PULL v2 15/39] hw/riscv/virt.c, riscv_aplic.c: add 'emulated_aplic' helpers, Alistair Francis, 2024/12/19
- [PULL v2 11/39] hw/intc/riscv_aplic: rename is_kvm_aia(), Alistair Francis, 2024/12/19
- [PULL v2 12/39] hw/riscv/virt.c: reduce virt_use_kvm_aia() usage, Alistair Francis, 2024/12/19
- [PULL v2 14/39] target/riscv/kvm: consider irqchip_split() in aia_create(), Alistair Francis, 2024/12/19
- [PULL v2 17/39] target/riscv/kvm: remove irqchip_split() restriction, Alistair Francis, 2024/12/19
- [PULL v2 16/39] hw/intc/riscv_aplic: add kvm_msicfgaddr for split mode aplic-imsic,
Alistair Francis <=
- [PULL v2 18/39] docs: update riscv/virt.rst with kernel-irqchip=split support, Alistair Francis, 2024/12/19
- [PULL v2 19/39] hw/riscv: Add Microblaze V generic board, Alistair Francis, 2024/12/19
- [PULL v2 20/39] qtest: allow SPCR acpi table changes, Alistair Francis, 2024/12/19
- [PULL v2 21/39] hw/acpi: Upgrade ACPI SPCR table to support SPCR table revision 4 format, Alistair Francis, 2024/12/19
- [PULL v2 22/39] tests/qtest/bios-tables-test: Update virt SPCR golden reference for RISC-V, Alistair Francis, 2024/12/19
- [PULL v2 24/39] hw/char/riscv_htif: Explicit little-endian implementation, Alistair Francis, 2024/12/19
- [PULL v2 29/39] target/riscv: Add svukte extension capability variable, Alistair Francis, 2024/12/19
- [PULL v2 23/39] MAINTAINERS: Cover RISC-V HTIF interface, Alistair Francis, 2024/12/19
- [PULL v2 30/39] target/riscv: Support senvcfg[UKTE] bit when svukte extension is enabled, Alistair Francis, 2024/12/19
- [PULL v2 28/39] hw/riscv: Add the checking if DTB overlaps to kernel or initrd, Alistair Francis, 2024/12/19