diff --git a/alioth/src/hv/hv.rs b/alioth/src/hv/hv.rs index 1ee7e8b..2c6eccf 100644 --- a/alioth/src/hv/hv.rs +++ b/alioth/src/hv/hv.rs @@ -233,6 +233,16 @@ pub trait GicV2: Debug + Send + Sync + 'static { fn set_num_irqs(&self, val: u32) -> Result<()>; } +#[cfg(target_arch = "aarch64")] +pub trait GicV3: Debug + Send + Sync + 'static { + fn init(&self) -> Result<()>; +} + +#[cfg(target_arch = "aarch64")] +pub trait Its: Debug + Send + Sync + 'static { + fn init(&self) -> Result<()>; +} + #[derive(Debug, Clone, Deserialize)] pub enum Coco { #[cfg(target_arch = "x86_64")] @@ -289,6 +299,21 @@ pub trait Vm { type GicV2: GicV2; #[cfg(target_arch = "aarch64")] fn create_gic_v2(&self, distributor_base: u64, cpu_interface_base: u64) -> Result; + + #[cfg(target_arch = "aarch64")] + type GicV3: GicV3; + #[cfg(target_arch = "aarch64")] + fn create_gic_v3( + &self, + distributor_base: u64, + redistributor_base: u64, + redistributor_count: u32, + ) -> Result; + + #[cfg(target_arch = "aarch64")] + type Its: Its; + #[cfg(target_arch = "aarch64")] + fn create_its(&self, base: u64) -> Result; } pub trait Hypervisor { diff --git a/alioth/src/hv/hvf/vm.rs b/alioth/src/hv/hvf/vm.rs index b76a340..2531f67 100644 --- a/alioth/src/hv/hvf/vm.rs +++ b/alioth/src/hv/hvf/vm.rs @@ -26,8 +26,8 @@ use crate::hv::hvf::bindings::{ use crate::hv::hvf::check_ret; use crate::hv::hvf::vcpu::HvfVcpu; use crate::hv::{ - error, GicV2, IoeventFd, IoeventFdRegistry, IrqFd, IrqSender, MemMapOption, MsiSender, Result, - Vm, VmMemory, + error, GicV2, GicV3, IoeventFd, IoeventFdRegistry, IrqFd, IrqSender, Its, MemMapOption, + MsiSender, Result, Vm, VmMemory, }; #[derive(Debug)] @@ -196,6 +196,24 @@ impl GicV2 for HvfGicV2 { } } +#[derive(Debug)] +pub struct HvfGicV3; + +impl GicV3 for HvfGicV3 { + fn init(&self) -> Result<()> { + unimplemented!() + } +} + +#[derive(Debug)] +pub struct HvfIts; + +impl Its for HvfIts { + fn init(&self) -> Result<()> { + unimplemented!() + } +} + #[derive(Debug)] pub struct HvfVm { pub(super) vcpus: Mutex>, @@ -250,4 +268,17 @@ impl Vm for HvfVm { fn create_irq_sender(&self, _pin: u8) -> Result { unimplemented!() } + type GicV3 = HvfGicV3; + fn create_gic_v3( + &self, + _distributor_base: u64, + _redistributor_base: u64, + _redistributor_count: u32, + ) -> Result { + unimplemented!() + } + type Its = HvfIts; + fn create_its(&self, _base: u64) -> Result { + unimplemented!() + } } diff --git a/alioth/src/hv/kvm/bindings.rs b/alioth/src/hv/kvm/bindings.rs index 9c74fb3..ab86741 100644 --- a/alioth/src/hv/kvm/bindings.rs +++ b/alioth/src/hv/kvm/bindings.rs @@ -14,6 +14,8 @@ use std::fmt::{Debug, Formatter, Result}; +#[cfg(target_arch = "aarch64")] +use bitfield::bitfield; use bitflags::bitflags; use crate::c_enum; @@ -530,6 +532,8 @@ c_enum! { pub struct KvmDevType(u32); { ARM_VGIC_V2 = 5; + ARM_VGIC_V3 = 7; + ARM_ITS = 8; } } @@ -542,15 +546,21 @@ c_enum! { CPU_REGS = 2; NR_IRQS = 3; CTL = 4; + REDIS_REG = 5; + CPU_SYSREGS = 6; } } #[cfg(target_arch = "aarch64")] c_enum! { - pub struct KvmVgicV2AddrType(u64); + pub struct KvmVgicAddrType(u64); { - DIST = 0; - CPU = 1; + DIST_V2 = 0; + CPU_V2 = 1; + DIST_V3 = 2; + REDIST_V3 = 3; + ITS = 4; + REDIST_REGION_V3 = 5; } } @@ -559,9 +569,24 @@ c_enum! { pub struct KvmDevArmVgicCtrl(u64); { INIT = 0; + ITS_SAVE_TABLES = 1; + ITS_RESTORE_TABLES = 2; + VGIC_SAVE_PENDING_TABLES = 3; + ITS_RESET = 4; } } +#[cfg(target_arch = "aarch64")] +bitfield! { + #[derive(Copy, Clone, Default, PartialEq, Eq, Hash)] + #[repr(transparent)] + pub struct KvmVgicV3RedistRegion(u64); + impl Debug; + pub count, set_count: 63, 52; + pub base, set_base: 51, 16; + pub index, set_index: 11, 0; +} + #[cfg(target_arch = "aarch64")] #[repr(C)] #[derive(Debug, Copy, Clone, Default)] diff --git a/alioth/src/hv/kvm/vm/aarch64.rs b/alioth/src/hv/kvm/vm/aarch64.rs index 47a4a31..5fe16b8 100644 --- a/alioth/src/hv/kvm/vm/aarch64.rs +++ b/alioth/src/hv/kvm/vm/aarch64.rs @@ -13,12 +13,12 @@ // limitations under the License. use crate::hv::kvm::bindings::{ - KvmDevArmVgicCtrl, KvmDevArmVgicGrp, KvmDevType, KvmVgicV2AddrType, + KvmDevArmVgicCtrl, KvmDevArmVgicGrp, KvmDevType, KvmVgicAddrType, KvmVgicV3RedistRegion, }; use crate::hv::kvm::device::KvmDevice; use crate::hv::kvm::vm::KvmVm; use crate::hv::kvm::Result; -use crate::hv::GicV2; +use crate::hv::{GicV2, GicV3, Its}; #[derive(Debug)] pub struct KvmGicV2 { @@ -83,14 +83,82 @@ impl KvmVm { let gic = KvmGicV2 { dev }; gic.dev.set_attr( KvmDevArmVgicGrp::ADDR.raw(), - KvmVgicV2AddrType::DIST.raw(), + KvmVgicAddrType::DIST_V2.raw(), &distributor_base, )?; gic.dev.set_attr( KvmDevArmVgicGrp::ADDR.raw(), - KvmVgicV2AddrType::CPU.raw(), + KvmVgicAddrType::CPU_V2.raw(), &cpu_interface_base, )?; Ok(gic) } } + +#[derive(Debug)] +pub struct KvmGicV3 { + dev: KvmDevice, +} + +impl GicV3 for KvmGicV3 { + fn init(&self) -> Result<()> { + self.dev.set_attr( + KvmDevArmVgicGrp::CTL.raw(), + KvmDevArmVgicCtrl::INIT.raw(), + &(), + )?; + Ok(()) + } +} + +impl KvmVm { + pub fn kvm_create_gic_v3( + &self, + distributor_base: u64, + redistributor_base: u64, + redistributor_count: u32, + ) -> Result { + let dev = KvmDevice::new(&self.vm, KvmDevType::ARM_VGIC_V3)?; + dev.set_attr( + KvmDevArmVgicGrp::ADDR.raw(), + KvmVgicAddrType::DIST_V3.raw(), + &distributor_base, + )?; + let mut redist_region = KvmVgicV3RedistRegion(redistributor_base); + redist_region.set_count(redistributor_count as u64); + dev.set_attr( + KvmDevArmVgicGrp::ADDR.raw(), + KvmVgicAddrType::REDIST_REGION_V3.raw(), + &redist_region, + )?; + Ok(KvmGicV3 { dev }) + } +} + +#[derive(Debug)] +pub struct KvmIts { + dev: KvmDevice, +} + +impl Its for KvmIts { + fn init(&self) -> Result<()> { + self.dev.set_attr( + KvmDevArmVgicGrp::CTL.raw(), + KvmDevArmVgicCtrl::INIT.raw(), + &(), + )?; + Ok(()) + } +} + +impl KvmVm { + pub fn kvm_create_its(&self, base: u64) -> Result { + let dev = KvmDevice::new(&self.vm, KvmDevType::ARM_ITS)?; + dev.set_attr( + KvmDevArmVgicGrp::ADDR.raw(), + KvmVgicAddrType::ITS.raw(), + &base, + )?; + Ok(KvmIts { dev }) + } +} diff --git a/alioth/src/hv/kvm/vm/vm.rs b/alioth/src/hv/kvm/vm/vm.rs index da34c99..8ab65c2 100644 --- a/alioth/src/hv/kvm/vm/vm.rs +++ b/alioth/src/hv/kvm/vm/vm.rs @@ -663,6 +663,25 @@ impl Vm for KvmVm { fn create_gic_v2(&self, distributor_base: u64, cpu_interface_base: u64) -> Result { self.kvm_create_gic_v2(distributor_base, cpu_interface_base) } + + #[cfg(target_arch = "aarch64")] + type GicV3 = aarch64::KvmGicV3; + #[cfg(target_arch = "aarch64")] + fn create_gic_v3( + &self, + distributor_base: u64, + redistributor_base: u64, + redistributor_count: u32, + ) -> Result { + self.kvm_create_gic_v3(distributor_base, redistributor_base, redistributor_count) + } + + #[cfg(target_arch = "aarch64")] + type Its = aarch64::KvmIts; + #[cfg(target_arch = "aarch64")] + fn create_its(&self, base: u64) -> Result { + self.kvm_create_its(base) + } } #[cfg(test)]