Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/quality.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -167,4 +167,4 @@ jobs:
steps:
- uses: actions/checkout@v6
# Executes "typos ."
- uses: crate-ci/typos@v1.43.5
- uses: crate-ci/typos@v1.46.2
4 changes: 2 additions & 2 deletions arch/src/riscv64/fdt.rs
Original file line number Diff line number Diff line change
Expand Up @@ -231,8 +231,8 @@ fn create_aia_node(fdt: &mut FdtWriter, aia_device: &Arc<Mutex<dyn Vaia>>) -> 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();
Expand Down
3 changes: 3 additions & 0 deletions hypervisor/src/arch/riscv64/aia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
28 changes: 28 additions & 0 deletions hypervisor/src/kvm/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -570,6 +570,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
Expand Down Expand Up @@ -2303,6 +2322,15 @@ impl cpu::Vcpu for KvmVcpu {
)
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;

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);
self.fd
.set_one_reg(sstateen0_id, &sstateen0.to_le_bytes())
.map_err(|e| cpu::HypervisorCpuError::SetRiscvCoreRegister(e.into()))?;

Ok(())
}

Expand Down
22 changes: 20 additions & 2 deletions hypervisor/src/kvm/riscv64/aia.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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)]
Expand All @@ -40,12 +43,21 @@ impl KvmAiaImsics {
// 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;
let aia_mode = kvm_bindings::KVM_DEV_RISCV_AIA_MODE_EMUL;
Self::set_device_attribute(
&self.device,
kvm_bindings::KVM_DEV_RISCV_AIA_GRP_CONFIG,
u64::from(kvm_bindings::KVM_DEV_RISCV_AIA_CONFIG_MODE),
&aia_mode as *const u32 as u64,
0,
)?;

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),
&mut aia_mode as *mut u32 as u64,
&mut aia_mode_readback as *mut u32 as u64,
0,
)?;

Expand All @@ -71,6 +83,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;
Expand Down Expand Up @@ -191,6 +204,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)?;
Expand Down Expand Up @@ -226,6 +240,10 @@ impl Vaia for KvmAiaImsics {
]
}

fn imsic_num_ids(&self) -> u32 {
self.imsic_num_ids
}

fn vcpu_count(&self) -> u32 {
self.vcpu_count
}
Expand Down
4 changes: 2 additions & 2 deletions vmm/src/seccomp_filters.rs
Original file line number Diff line number Diff line change
Expand Up @@ -689,7 +689,7 @@ fn vmm_thread_rules(
),
#[cfg(target_arch = "x86_64")]
(libc::SYS_unlink, vec![]),
#[cfg(target_arch = "aarch64")]
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
(libc::SYS_unlinkat, vec![]),
(libc::SYS_wait4, vec![]),
(libc::SYS_write, vec![]),
Expand Down Expand Up @@ -831,7 +831,7 @@ fn vcpu_thread_rules(
(libc::SYS_tkill, vec![]),
#[cfg(target_arch = "x86_64")]
(libc::SYS_unlink, vec![]),
#[cfg(target_arch = "aarch64")]
#[cfg(any(target_arch = "aarch64", target_arch = "riscv64"))]
(libc::SYS_unlinkat, vec![]),
(libc::SYS_write, vec![]),
(libc::SYS_writev, vec![]),
Expand Down
Loading