The number of interrupt identities supported by the host's KVM AIA is limited. On Spacemit K3 and Tenstorrent Atlantis to 63. virt machine alwayas aks for 255 identities, so it fails if on those platforms.
Read and apply host limit from KVM AIA device and apply. Resolves: https://gitlab.com/qemu-project/qemu/-/work_items/4599 Signed-off-by: Stefan Butz <[email protected]> --- hw/riscv/virt.c | 12 +++++++++++- target/riscv/kvm/kvm-cpu.c | 16 ++++++++++++++++ target/riscv/kvm/kvm-stub.c | 5 +++++ target/riscv/kvm/kvm_riscv.h | 1 + 4 files changed, 33 insertions(+), 1 deletion(-) diff --git a/hw/riscv/virt.c b/hw/riscv/virt.c index 28fa31d538..2af85ec5c3 100644 --- a/hw/riscv/virt.c +++ b/hw/riscv/virt.c @@ -78,6 +78,16 @@ static bool virt_use_emulated_aplic(RISCVVirtAIAType aia_type) return riscv_use_emulated_aplic(msimode); } +static void virt_kvm_aia_create(RISCVVirtState *s) +{ + kvm_riscv_aia_create(); + + s->num_msis = MIN(s->num_msis, kvm_riscv_aia_get_num_ids()); + if (!virt_use_emulated_aplic(s->aia_type)) { + s->num_sources = MIN(s->num_sources, s->num_msis); + } +} + static bool virt_aclint_allowed(void) { return tcg_enabled() || qtest_enabled(); @@ -734,7 +744,7 @@ static void virt_machine_init(MachineState *machine) } if (kvm_enabled() && virt_use_kvm_aia_aplic_imsic(s->aia_type)) { - kvm_riscv_aia_create(); + virt_kvm_aia_create(s); } /* Initialize sockets */ diff --git a/target/riscv/kvm/kvm-cpu.c b/target/riscv/kvm/kvm-cpu.c index 1098581e7a..0409af3255 100644 --- a/target/riscv/kvm/kvm-cpu.c +++ b/target/riscv/kvm/kvm-cpu.c @@ -1870,6 +1870,22 @@ void kvm_riscv_aia_create(void) } } +uint64_t kvm_riscv_aia_get_num_ids(void) +{ + uint64_t num_ids; + int ret; + + ret = kvm_device_access(aia_fd, KVM_DEV_RISCV_AIA_GRP_CONFIG, + KVM_DEV_RISCV_AIA_CONFIG_IDS, + &num_ids, false, NULL); + if (ret < 0) { + error_report("KVM AIA: failed to get number of msi"); + exit(1); + } + + return num_ids; +} + void kvm_riscv_aia_init(MachineState *machine, uint64_t group_shift, uint64_t aia_irq_num, uint64_t aia_msi_num, uint64_t aplic_base, uint64_t imsic_base, diff --git a/target/riscv/kvm/kvm-stub.c b/target/riscv/kvm/kvm-stub.c index 672f635b08..f5f5418b3c 100644 --- a/target/riscv/kvm/kvm-stub.c +++ b/target/riscv/kvm/kvm-stub.c @@ -14,6 +14,11 @@ void kvm_riscv_aia_create(void) g_assert_not_reached(); } +uint64_t kvm_riscv_aia_get_num_ids(void) +{ + g_assert_not_reached(); +} + void kvm_riscv_aia_init(MachineState *machine, uint64_t group_shift, uint64_t aia_irq_num, uint64_t aia_msi_num, uint64_t aplic_base, uint64_t imsic_base, diff --git a/target/riscv/kvm/kvm_riscv.h b/target/riscv/kvm/kvm_riscv.h index 532e42b0df..d8ae73fa1e 100644 --- a/target/riscv/kvm/kvm_riscv.h +++ b/target/riscv/kvm/kvm_riscv.h @@ -24,6 +24,7 @@ void kvm_riscv_reset_vcpu(RISCVCPU *cpu); void kvm_riscv_set_irq(RISCVCPU *cpu, int irq, int level); void kvm_riscv_aia_create(void); +uint64_t kvm_riscv_aia_get_num_ids(void); void kvm_riscv_aia_init(MachineState *machine, uint64_t group_shift, uint64_t aia_irq_num, uint64_t aia_msi_num, uint64_t aplic_base, uint64_t imsic_base, -- Git-157)
