diff --git a/alioth/src/hv/hv.rs b/alioth/src/hv/hv.rs index 2c6eccf..8641f5a 100644 --- a/alioth/src/hv/hv.rs +++ b/alioth/src/hv/hv.rs @@ -266,7 +266,10 @@ pub trait Vm { type IoeventFdRegistry: IoeventFdRegistry; fn create_vcpu(&self, id: u32) -> Result; fn create_irq_sender(&self, pin: u8) -> Result; - fn create_msi_sender(&self) -> Result; + fn create_msi_sender( + &self, + #[cfg(target_arch = "aarch64")] devid: u32, + ) -> Result; fn create_vm_memory(&mut self) -> Result; fn create_ioeventfd_registry(&self) -> Result; fn stop_vcpu(id: u32, handle: &JoinHandle) -> Result<(), Error>; diff --git a/alioth/src/hv/hvf/vm.rs b/alioth/src/hv/hvf/vm.rs index 2531f67..ed8c8ab 100644 --- a/alioth/src/hv/hvf/vm.rs +++ b/alioth/src/hv/hvf/vm.rs @@ -236,7 +236,7 @@ impl Vm for HvfVm { fn create_ioeventfd_registry(&self) -> Result { unimplemented!() } - fn create_msi_sender(&self) -> Result { + fn create_msi_sender(&self, _devid: u32) -> Result { unimplemented!() } fn create_vcpu(&self, id: u32) -> Result { diff --git a/alioth/src/hv/kvm/bindings.rs b/alioth/src/hv/kvm/bindings.rs index ab86741..a48087e 100644 --- a/alioth/src/hv/kvm/bindings.rs +++ b/alioth/src/hv/kvm/bindings.rs @@ -428,13 +428,22 @@ impl Debug for KvmIrqRouting { } } +bitflags! { + #[derive(Default, Debug, Clone, Copy, PartialEq, Eq)] + #[repr(transparent)] + pub struct KvmMsiFlag: u32 { + #[cfg(target_arch = "aarch64")] + const VALID_DEVID = 1 << 0; + } +} + #[repr(C)] #[derive(Debug, Copy, Clone, Default)] pub struct KvmMsi { pub address_lo: u32, pub address_hi: u32, pub data: u32, - pub flags: u32, + pub flags: KvmMsiFlag, pub devid: u32, pub pad: [u8; 12usize], } diff --git a/alioth/src/hv/kvm/vm/vm.rs b/alioth/src/hv/kvm/vm/vm.rs index 8ab65c2..085ef77 100644 --- a/alioth/src/hv/kvm/vm/vm.rs +++ b/alioth/src/hv/kvm/vm/vm.rs @@ -31,6 +31,8 @@ use snafu::ResultExt; #[cfg(target_arch = "x86_64")] use crate::arch::sev::{SnpPageType, SnpPolicy}; use crate::ffi; +#[cfg(target_arch = "aarch64")] +use crate::hv::kvm::bindings::KvmMsiFlag; #[cfg(target_arch = "x86_64")] use crate::hv::kvm::bindings::KVM_IRQCHIP_IOAPIC; use crate::hv::kvm::bindings::{ @@ -419,6 +421,8 @@ const MAX_GSI_ROUTES: usize = 256; #[derive(Debug)] pub struct KvmMsiSender { vm: Arc, + #[cfg(target_arch = "aarch64")] + devid: u32, } impl MsiSender for KvmMsiSender { @@ -429,6 +433,10 @@ impl MsiSender for KvmMsiSender { address_lo: addr as u32, address_hi: (addr >> 32) as u32, data, + #[cfg(target_arch = "aarch64")] + devid: self.devid, + #[cfg(target_arch = "aarch64")] + flags: KvmMsiFlag::VALID_DEVID, ..Default::default() }; unsafe { kvm_signal_msi(&self.vm, &kvm_msi) }.context(error::SendInterrupt)?; @@ -599,7 +607,10 @@ impl Vm for KvmVm { }) } - fn create_msi_sender(&self) -> Result { + fn create_msi_sender( + &self, + #[cfg(target_arch = "aarch64")] devid: u32, + ) -> Result { if self.vm.check_extension(KvmCap::SIGNAL_MSI)? == 0 { return error::Capability { cap: "KVM_CAP_SIGNAL_MSI", @@ -608,6 +619,8 @@ impl Vm for KvmVm { } Ok(KvmMsiSender { vm: self.vm.clone(), + #[cfg(target_arch = "aarch64")] + devid, }) } diff --git a/alioth/src/vm.rs b/alioth/src/vm.rs index d8e4af6..8bfab61 100644 --- a/alioth/src/vm.rs +++ b/alioth/src/vm.rs @@ -211,6 +211,7 @@ where D: Virtio, { let name = Arc::new(name); + let bdf = self.board.pci_bus.reserve(None, name.clone()).unwrap(); let dev = param.build(name.clone())?; let registry = self.board.vm.create_ioeventfd_registry()?; let virtio_dev = VirtioDevice::new( @@ -220,11 +221,14 @@ where ®istry, self.board.config.coco.is_some(), )?; - let msi_sender = self.board.vm.create_msi_sender()?; + let msi_sender = self.board.vm.create_msi_sender( + #[cfg(target_arch = "aarch64")] + u32::from(bdf.0), + )?; let dev = VirtioPciDevice::new(virtio_dev, msi_sender, registry)?; let dev = Arc::new(dev); let pci_dev = PciDevice::new(name.clone(), dev.clone()); - self.add_pci_dev(None, pci_dev)?; + self.add_pci_dev(Some(bdf), pci_dev)?; Ok(dev) }