From 9c2e2a67cc8740a280a1e01a08aa644091fb05cc Mon Sep 17 00:00:00 2001 From: wangyf0611 Date: Thu, 21 May 2026 15:47:44 +0800 Subject: [PATCH] hypervisor: Enable sstateen0 for KVM vCPUs KVM initializes RISC-V vCPUs with sstateen0 cleared. When AIA is exposed to the guest, Linux touches supervisor AIA CSRs while bringing up the IMSIC path, and those accesses fail if the stateen bits remain disabled. Program sstateen0 for newly created vCPUs so the guest can use the supervisor interrupt state needed by AIA. Assisted-by: OpenAI-Codex:GPT-5 Signed-off-by: wangyf0611 --- hypervisor/src/kvm/mod.rs | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 4ed7c0ec7..e100c8fd8 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -834,6 +834,25 @@ impl vm::Vm for KvmVm { .create_vcpu(id as u64) .map_err(|e| vm::HypervisorVmError::CreateVcpu(e.into()))?; + #[cfg(target_arch = "riscv64")] + { + // KVM defaults sstateen0 to zero for new RISC-V vCPUs. When AIA is + // exposed, Linux accesses supervisor AIA CSRs during IMSIC init; + // leave all state enabled so those CSR accesses do not trap as + // illegal instructions in the guest. + let sstateen0 = u64::MAX; + let sstateen0_id = kvm_bindings::KVM_REG_RISCV as u64 + | u64::from(kvm_bindings::KVM_REG_SIZE_U64) + | u64::from(kvm_bindings::KVM_REG_RISCV_CSR) + | u64::from(kvm_bindings::KVM_REG_RISCV_CSR_SMSTATEEN); + fd.set_one_reg(sstateen0_id, &sstateen0.to_le_bytes()) + .map_err(|e| { + vm::HypervisorVmError::CreateVcpu(anyhow!( + "Failed to enable RISC-V sstateen0 for vCPU {id}: {e}" + )) + })?; + } + #[cfg(target_arch = "x86_64")] // Safety: `xsave_size` will not change after vcpu creation because: // 1. `xsave_size` depends on cpuid