mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2024-10-05 21:15:45 +00:00
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 <michael.zhao@arm.com>
This commit is contained in:
parent
b30ddc0837
commit
b3fa56544c
@ -54,8 +54,6 @@ const EVENT_Q_EVENT: u16 = EPOLL_HELPER_EVENT_LAST + 2;
|
|||||||
/// will conflict with x86.
|
/// will conflict with x86.
|
||||||
const PROBE_PROP_SIZE: u32 =
|
const PROBE_PROP_SIZE: u32 =
|
||||||
(size_of::<VirtioIommuProbeProperty>() + size_of::<VirtioIommuProbeResvMem>()) as u32;
|
(size_of::<VirtioIommuProbeProperty>() + size_of::<VirtioIommuProbeResvMem>()) as u32;
|
||||||
const MSI_IOVA_START: u64 = 0xfee0_0000;
|
|
||||||
const MSI_IOVA_END: u64 = 0xfeef_ffff;
|
|
||||||
|
|
||||||
/// Virtio IOMMU features
|
/// Virtio IOMMU features
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
@ -352,6 +350,7 @@ impl Request {
|
|||||||
mapping: &Arc<IommuMapping>,
|
mapping: &Arc<IommuMapping>,
|
||||||
ext_mapping: &BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
ext_mapping: &BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
||||||
ext_domain_mapping: &mut BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
ext_domain_mapping: &mut BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
||||||
|
msi_iova_space: (u64, u64),
|
||||||
) -> result::Result<usize, Error> {
|
) -> result::Result<usize, Error> {
|
||||||
// The head contains the request type which MUST be readable.
|
// The head contains the request type which MUST be readable.
|
||||||
if avail_desc.is_write_only() {
|
if avail_desc.is_write_only() {
|
||||||
@ -372,6 +371,8 @@ impl Request {
|
|||||||
return Err(Error::InvalidRequest);
|
return Err(Error::InvalidRequest);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
let (msi_iova_start, msi_iova_end) = msi_iova_space;
|
||||||
|
|
||||||
// Create the reply
|
// Create the reply
|
||||||
let mut reply: Vec<u8> = Vec::new();
|
let mut reply: Vec<u8> = Vec::new();
|
||||||
|
|
||||||
@ -515,8 +516,8 @@ impl Request {
|
|||||||
|
|
||||||
let resv_mem = VirtioIommuProbeResvMem {
|
let resv_mem = VirtioIommuProbeResvMem {
|
||||||
subtype: VIRTIO_IOMMU_RESV_MEM_T_MSI,
|
subtype: VIRTIO_IOMMU_RESV_MEM_T_MSI,
|
||||||
start: MSI_IOVA_START,
|
start: msi_iova_start,
|
||||||
end: MSI_IOVA_END,
|
end: msi_iova_end,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
};
|
};
|
||||||
reply.extend_from_slice(resv_mem.as_slice());
|
reply.extend_from_slice(resv_mem.as_slice());
|
||||||
@ -562,6 +563,7 @@ struct IommuEpollHandler {
|
|||||||
mapping: Arc<IommuMapping>,
|
mapping: Arc<IommuMapping>,
|
||||||
ext_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
ext_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
||||||
ext_domain_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
ext_domain_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
||||||
|
msi_iova_space: (u64, u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl IommuEpollHandler {
|
impl IommuEpollHandler {
|
||||||
@ -576,6 +578,7 @@ impl IommuEpollHandler {
|
|||||||
&self.mapping,
|
&self.mapping,
|
||||||
&self.ext_mapping,
|
&self.ext_mapping,
|
||||||
&mut self.ext_domain_mapping,
|
&mut self.ext_domain_mapping,
|
||||||
|
self.msi_iova_space,
|
||||||
) {
|
) {
|
||||||
Ok(len) => len as u32,
|
Ok(len) => len as u32,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
@ -702,6 +705,7 @@ pub struct Iommu {
|
|||||||
ext_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
ext_mapping: BTreeMap<u32, Arc<dyn ExternalDmaMapping>>,
|
||||||
seccomp_action: SeccompAction,
|
seccomp_action: SeccompAction,
|
||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
|
msi_iova_space: (u64, u64),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Versionize)]
|
#[derive(Versionize)]
|
||||||
@ -719,6 +723,7 @@ impl Iommu {
|
|||||||
id: String,
|
id: String,
|
||||||
seccomp_action: SeccompAction,
|
seccomp_action: SeccompAction,
|
||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
|
msi_iova_space: (u64, u64),
|
||||||
) -> io::Result<(Self, Arc<IommuMapping>)> {
|
) -> io::Result<(Self, Arc<IommuMapping>)> {
|
||||||
let config = VirtioIommuConfig {
|
let config = VirtioIommuConfig {
|
||||||
page_size_mask: VIRTIO_IOMMU_PAGE_SIZE_MASK,
|
page_size_mask: VIRTIO_IOMMU_PAGE_SIZE_MASK,
|
||||||
@ -748,6 +753,7 @@ impl Iommu {
|
|||||||
ext_mapping: BTreeMap::new(),
|
ext_mapping: BTreeMap::new(),
|
||||||
seccomp_action,
|
seccomp_action,
|
||||||
exit_evt,
|
exit_evt,
|
||||||
|
msi_iova_space,
|
||||||
},
|
},
|
||||||
mapping,
|
mapping,
|
||||||
))
|
))
|
||||||
@ -843,6 +849,7 @@ impl VirtioDevice for Iommu {
|
|||||||
mapping: self.mapping.clone(),
|
mapping: self.mapping.clone(),
|
||||||
ext_mapping: self.ext_mapping.clone(),
|
ext_mapping: self.ext_mapping.clone(),
|
||||||
ext_domain_mapping: BTreeMap::new(),
|
ext_domain_mapping: BTreeMap::new(),
|
||||||
|
msi_iova_space: self.msi_iova_space,
|
||||||
};
|
};
|
||||||
|
|
||||||
let paused = self.common.paused.clone();
|
let paused = self.common.paused.clone();
|
||||||
|
@ -1135,6 +1135,20 @@ impl DeviceManager {
|
|||||||
self.device_id_cnt = state.device_id_cnt;
|
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")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
/// Gets the information of the devices registered up to some point in time.
|
/// Gets the information of the devices registered up to some point in time.
|
||||||
pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MmioDeviceInfo> {
|
pub fn get_device_info(&self) -> &HashMap<(DeviceType, String), MmioDeviceInfo> {
|
||||||
@ -1161,6 +1175,7 @@ impl DeviceManager {
|
|||||||
self.exit_evt
|
self.exit_evt
|
||||||
.try_clone()
|
.try_clone()
|
||||||
.map_err(DeviceManagerError::EventFd)?,
|
.map_err(DeviceManagerError::EventFd)?,
|
||||||
|
self.get_msi_iova_space(),
|
||||||
)
|
)
|
||||||
.map_err(DeviceManagerError::CreateVirtioIommu)?;
|
.map_err(DeviceManagerError::CreateVirtioIommu)?;
|
||||||
let device = Arc::new(Mutex::new(device));
|
let device = Arc::new(Mutex::new(device));
|
||||||
|
Loading…
Reference in New Issue
Block a user