From b3fa56544c21109a4e4361ff6327df4fa429edc3 Mon Sep 17 00:00:00 2001 From: Michael Zhao Date: Mon, 6 Sep 2021 20:58:48 +0800 Subject: [PATCH] virtio-devices: iommu: Support AArch64 The MSI IOVA address on X86 and AArch64 is different. This commit refactored the code to receive the MSI IOVA address and size from device_manager, which provides the actual IOVA space data for both architectures. Signed-off-by: Michael Zhao --- virtio-devices/src/iommu.rs | 15 +++++++++++---- vmm/src/device_manager.rs | 15 +++++++++++++++ 2 files changed, 26 insertions(+), 4 deletions(-) diff --git a/virtio-devices/src/iommu.rs b/virtio-devices/src/iommu.rs index d52b9042f..4f7d8f7bf 100644 --- a/virtio-devices/src/iommu.rs +++ b/virtio-devices/src/iommu.rs @@ -54,8 +54,6 @@ const EVENT_Q_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 2; /// will conflict with x86. const PROBE_PROP_SIZE: u32 = (size_of::() + size_of::()) as u32; -const MSI_IOVA_START: u64 = 0xfee0_0000; -const MSI_IOVA_END: u64 = 0xfeef_ffff; /// Virtio IOMMU features #[allow(unused)] @@ -352,6 +350,7 @@ impl Request { mapping: &Arc, ext_mapping: &BTreeMap>, ext_domain_mapping: &mut BTreeMap>, + msi_iova_space: (u64, u64), ) -> result::Result { // The head contains the request type which MUST be readable. if avail_desc.is_write_only() { @@ -372,6 +371,8 @@ impl Request { return Err(Error::InvalidRequest); }; + let (msi_iova_start, msi_iova_end) = msi_iova_space; + // Create the reply let mut reply: Vec = Vec::new(); @@ -515,8 +516,8 @@ impl Request { let resv_mem = VirtioIommuProbeResvMem { subtype: VIRTIO_IOMMU_RESV_MEM_T_MSI, - start: MSI_IOVA_START, - end: MSI_IOVA_END, + start: msi_iova_start, + end: msi_iova_end, ..Default::default() }; reply.extend_from_slice(resv_mem.as_slice()); @@ -562,6 +563,7 @@ struct IommuEpollHandler { mapping: Arc, ext_mapping: BTreeMap>, ext_domain_mapping: BTreeMap>, + msi_iova_space: (u64, u64), } impl IommuEpollHandler { @@ -576,6 +578,7 @@ impl IommuEpollHandler { &self.mapping, &self.ext_mapping, &mut self.ext_domain_mapping, + self.msi_iova_space, ) { Ok(len) => len as u32, Err(e) => { @@ -702,6 +705,7 @@ pub struct Iommu { ext_mapping: BTreeMap>, seccomp_action: SeccompAction, exit_evt: EventFd, + msi_iova_space: (u64, u64), } #[derive(Versionize)] @@ -719,6 +723,7 @@ impl Iommu { id: String, seccomp_action: SeccompAction, exit_evt: EventFd, + msi_iova_space: (u64, u64), ) -> io::Result<(Self, Arc)> { let config = VirtioIommuConfig { page_size_mask: VIRTIO_IOMMU_PAGE_SIZE_MASK, @@ -748,6 +753,7 @@ impl Iommu { ext_mapping: BTreeMap::new(), seccomp_action, exit_evt, + msi_iova_space, }, mapping, )) @@ -843,6 +849,7 @@ impl VirtioDevice for Iommu { mapping: self.mapping.clone(), ext_mapping: self.ext_mapping.clone(), ext_domain_mapping: BTreeMap::new(), + msi_iova_space: self.msi_iova_space, }; let paused = self.common.paused.clone(); diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index e2879a2e9..ebd61bc19 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -1135,6 +1135,20 @@ impl DeviceManager { self.device_id_cnt = state.device_id_cnt; } + fn get_msi_iova_space(&mut self) -> (u64, u64) { + #[cfg(target_arch = "aarch64")] + { + let vcpus = self.config.lock().unwrap().cpus.boot_vcpus; + let msi_start = arch::layout::GIC_V3_DIST_START + - arch::layout::GIC_V3_REDIST_SIZE * (vcpus as u64) + - arch::layout::GIC_V3_ITS_SIZE; + let msi_end = msi_start + arch::layout::GIC_V3_ITS_SIZE - 1; + (msi_start, msi_end) + } + #[cfg(target_arch = "x86_64")] + (0xfee0_0000, 0xfeef_ffff) + } + #[cfg(target_arch = "aarch64")] /// Gets the information of the devices registered up to some point in time. pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MmioDeviceInfo> { @@ -1161,6 +1175,7 @@ impl DeviceManager { self.exit_evt .try_clone() .map_err(DeviceManagerError::EventFd)?, + self.get_msi_iova_space(), ) .map_err(DeviceManagerError::CreateVirtioIommu)?; let device = Arc::new(Mutex::new(device));