From 649ca23345cc5b56ec08abe635b43b1740617ad9 Mon Sep 17 00:00:00 2001 From: wangyf0611 Date: Thu, 21 May 2026 15:47:53 +0800 Subject: [PATCH] arch, hypervisor: Report KVM IMSIC interrupt IDs The RISC-V AIA FDT node currently advertises a fixed riscv,num-ids value. That can diverge from the interrupt identity count configured by KVM, which matters for guests running with an emulated IMSIC. Record the NR_IDS value reported by KVM and expose that value through the generated device tree. Read back the KVM-selected AIA mode without forcing an emulation mode. Assisted-by: OpenAI-Codex:GPT-5 Signed-off-by: wangyf0611 --- arch/src/riscv64/fdt.rs | 4 ++-- hypervisor/src/arch/riscv64/aia.rs | 3 +++ hypervisor/src/kvm/riscv64/aia.rs | 20 +++++++++++++------- 3 files changed, 18 insertions(+), 9 deletions(-) diff --git a/arch/src/riscv64/fdt.rs b/arch/src/riscv64/fdt.rs index f97e6d6b5..b4a6160f3 100644 --- a/arch/src/riscv64/fdt.rs +++ b/arch/src/riscv64/fdt.rs @@ -231,8 +231,8 @@ fn create_aia_node(fdt: &mut FdtWriter, aia_device: &Arc>) -> Fd fdt.property_u32("#interrupt-cells", 0u32)?; fdt.property_null("interrupt-controller")?; fdt.property_null("msi-controller")?; - // TODO complete num-ids - fdt.property_u32("riscv,num-ids", 2047u32)?; + let imsic_num_ids = aia_device.lock().unwrap().imsic_num_ids(); + fdt.property_u32("riscv,num-ids", imsic_num_ids)?; fdt.property_u32("phandle", AIA_IMSIC_PHANDLE)?; let mut irq_cells = Vec::new(); diff --git a/hypervisor/src/arch/riscv64/aia.rs b/hypervisor/src/arch/riscv64/aia.rs index 2ba8d70eb..0172f4b39 100644 --- a/hypervisor/src/arch/riscv64/aia.rs +++ b/hypervisor/src/arch/riscv64/aia.rs @@ -46,6 +46,9 @@ pub trait Vaia: Send + Sync { /// Returns an array with IMSIC device properties fn imsic_properties(&self) -> [u32; 4]; + /// Returns the number of IMSIC interrupt identities exposed to the guest + fn imsic_num_ids(&self) -> u32; + /// Returns the number of vCPUs this AIA handles fn vcpu_count(&self) -> u32; diff --git a/hypervisor/src/kvm/riscv64/aia.rs b/hypervisor/src/kvm/riscv64/aia.rs index 0915119af..ffc19543d 100644 --- a/hypervisor/src/kvm/riscv64/aia.rs +++ b/hypervisor/src/kvm/riscv64/aia.rs @@ -24,6 +24,9 @@ pub struct KvmAiaImsics { /// Number of CPUs handled by the device vcpu_count: u32, + + /// Number of IMSIC interrupt identities configured by KVM + imsic_num_ids: u32, } #[derive(Clone, Default, Serialize, Deserialize)] @@ -37,20 +40,17 @@ impl KvmAiaImsics { /// Setup the device-specific attributes fn init_device_attributes(&mut self, nr_irqs: u32) -> Result<()> { - // AIA part attributes - // Getting the working mode of RISC-V AIA, defaults to EMUL, passible - // variants are EMUL, HW_ACCL, AUTO - let mut aia_mode = kvm_bindings::KVM_DEV_RISCV_AIA_MODE_EMUL; + // Read the working mode selected by KVM. Possible modes are EMUL, + // HW_ACCL and AUTO. + let mut aia_mode_readback: u32 = 0; Self::get_device_attribute( &self.device, kvm_bindings::KVM_DEV_RISCV_AIA_GRP_CONFIG, u64::from(kvm_bindings::KVM_DEV_RISCV_AIA_CONFIG_MODE), - &raw mut aia_mode as u64, + &raw mut aia_mode_readback as u64, 0, )?; - // Report AIA MODE - // Setting up the number of wired interrupt sources Self::set_device_attribute( &self.device, @@ -71,6 +71,7 @@ impl KvmAiaImsics { )?; // Report NR_IDS + self.imsic_num_ids = aia_nr_ids; // Setting up hart_bits let max_hart_index = self.vcpu_count as u64 - 1; @@ -191,6 +192,7 @@ impl KvmAiaImsics { vcpu_count: config.vcpu_count, aplic_addr: config.aplic_addr, imsic_addr: config.imsic_addr, + imsic_num_ids: 0, }; aia_device.init_device_attributes(config.nr_irqs)?; @@ -226,6 +228,10 @@ impl Vaia for KvmAiaImsics { ] } + fn imsic_num_ids(&self) -> u32 { + self.imsic_num_ids + } + fn vcpu_count(&self) -> u32 { self.vcpu_count }