Compare commits
3 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 70461c559e | |||
| f4e3941330 | |||
| 5674337d5a |
@@ -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();
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -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
|
||||
@@ -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(())
|
||||
}
|
||||
|
||||
|
||||
@@ -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)]
|
||||
@@ -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,
|
||||
)?;
|
||||
|
||||
@@ -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;
|
||||
@@ -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)?;
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -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![]),
|
||||
@@ -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![]),
|
||||
|
||||
Reference in New Issue
Block a user