virtio-devices: iommu: Port to VirtioCommon for feature handling

Signed-off-by: Rob Bradford <robert.bradford@intel.com>
This commit is contained in:
Rob Bradford 2020-09-03 10:37:36 +01:00 committed by Sebastien Boeuf
parent d63dcae233
commit 9fc8b6d242

View File

@ -5,8 +5,8 @@
use super::Error as DeviceError; use super::Error as DeviceError;
use super::{ use super::{
ActivateError, ActivateResult, DescriptorChain, EpollHelper, EpollHelperError, ActivateError, ActivateResult, DescriptorChain, EpollHelper, EpollHelperError,
EpollHelperHandler, Queue, VirtioDevice, VirtioDeviceType, EPOLL_HELPER_EVENT_LAST, EpollHelperHandler, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType,
VIRTIO_F_VERSION_1, EPOLL_HELPER_EVENT_LAST, VIRTIO_F_VERSION_1,
}; };
use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::seccomp_filters::{get_seccomp_filter, Thread};
use crate::{DmaRemapping, VirtioInterrupt, VirtioInterruptType}; use crate::{DmaRemapping, VirtioInterrupt, VirtioInterruptType};
@ -736,11 +736,10 @@ impl DmaRemapping for IommuMapping {
} }
pub struct Iommu { pub struct Iommu {
common: VirtioCommon,
id: String, id: String,
kill_evt: Option<EventFd>, kill_evt: Option<EventFd>,
pause_evt: Option<EventFd>, pause_evt: Option<EventFd>,
avail_features: u64,
acked_features: u64,
config: VirtioIommuConfig, config: VirtioIommuConfig,
config_topo_pci_ranges: Vec<VirtioIommuTopoPciRange>, config_topo_pci_ranges: Vec<VirtioIommuTopoPciRange>,
mapping: Arc<IommuMapping>, mapping: Arc<IommuMapping>,
@ -779,10 +778,12 @@ impl Iommu {
id, id,
kill_evt: None, kill_evt: None,
pause_evt: None, pause_evt: None,
avail_features: 1u64 << VIRTIO_F_VERSION_1 common: VirtioCommon {
| 1u64 << VIRTIO_IOMMU_F_MAP_UNMAP avail_features: 1u64 << VIRTIO_F_VERSION_1
| 1u64 << VIRTIO_IOMMU_F_PROBE, | 1u64 << VIRTIO_IOMMU_F_MAP_UNMAP
acked_features: 0u64, | 1u64 << VIRTIO_IOMMU_F_PROBE,
acked_features: 0u64,
},
config, config,
config_topo_pci_ranges: Vec::new(), config_topo_pci_ranges: Vec::new(),
mapping: mapping.clone(), mapping: mapping.clone(),
@ -800,16 +801,16 @@ impl Iommu {
fn state(&self) -> IommuState { fn state(&self) -> IommuState {
IommuState { IommuState {
avail_features: self.avail_features, avail_features: self.common.avail_features,
acked_features: self.acked_features, acked_features: self.common.acked_features,
endpoints: self.mapping.endpoints.read().unwrap().clone(), endpoints: self.mapping.endpoints.read().unwrap().clone(),
mappings: self.mapping.mappings.read().unwrap().clone(), mappings: self.mapping.mappings.read().unwrap().clone(),
} }
} }
fn set_state(&mut self, state: &IommuState) -> io::Result<()> { fn set_state(&mut self, state: &IommuState) -> io::Result<()> {
self.avail_features = state.avail_features; self.common.avail_features = state.avail_features;
self.acked_features = state.acked_features; self.common.acked_features = state.acked_features;
*(self.mapping.endpoints.write().unwrap()) = state.endpoints.clone(); *(self.mapping.endpoints.write().unwrap()) = state.endpoints.clone();
*(self.mapping.mappings.write().unwrap()) = state.mappings.clone(); *(self.mapping.mappings.write().unwrap()) = state.mappings.clone();
@ -832,7 +833,7 @@ impl Iommu {
// If there is at least one device attached to the virtual IOMMU, we // If there is at least one device attached to the virtual IOMMU, we
// need the topology feature to be enabled. // need the topology feature to be enabled.
self.avail_features |= 1u64 << VIRTIO_IOMMU_F_TOPOLOGY; self.common.avail_features |= 1u64 << VIRTIO_IOMMU_F_TOPOLOGY;
// Update the topology. // Update the topology.
let mut topo_pci_ranges = Vec::new(); let mut topo_pci_ranges = Vec::new();
@ -879,20 +880,11 @@ impl VirtioDevice for Iommu {
} }
fn features(&self) -> u64 { fn features(&self) -> u64 {
self.avail_features self.common.avail_features
} }
fn ack_features(&mut self, value: u64) { fn ack_features(&mut self, value: u64) {
let mut v = value; self.common.ack_features(value)
// Check if the guest is ACK'ing a feature that we didn't claim to have.
let unrequested_features = v & !self.avail_features;
if unrequested_features != 0 {
warn!("Received acknowledge request for unknown feature.");
// Don't count these features as acked.
v &= !unrequested_features;
}
self.acked_features |= v;
} }
fn read_config(&self, offset: u64, data: &mut [u8]) { fn read_config(&self, offset: u64, data: &mut [u8]) {