build: treewide: clippy: collapse nested ifs, use let chains
This bumps the MSRV to 1.88 (also, Rust edition 2024 is mandatory). Signed-off-by: Philipp Schuster <philipp.schuster@cyberus-technology.de> On-behalf-of: SAP philipp.schuster@sap.com
This commit is contained in:
parent
f73a6c8d8e
commit
c995b72384
40 changed files with 574 additions and 608 deletions
|
|
@ -118,12 +118,11 @@ fn parse_http_response(socket: &mut dyn Read) -> Result<Option<String>, Error> {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(body_offset) = body_offset {
|
||||
if let Some(content_length) = content_length {
|
||||
if res.len() >= content_length + body_offset {
|
||||
break;
|
||||
}
|
||||
}
|
||||
if let Some(body_offset) = body_offset
|
||||
&& let Some(content_length) = content_length
|
||||
&& res.len() >= content_length + body_offset
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
let body_string = content_length.and(body_offset.map(|o| String::from(&res[o..])));
|
||||
|
|
|
|||
|
|
@ -999,39 +999,39 @@ fn create_pci_nodes(
|
|||
fdt.property_array_u32("msi-map", &msi_map)?;
|
||||
fdt.property_u32("msi-parent", MSI_PHANDLE)?;
|
||||
|
||||
if pci_device_info_elem.pci_segment_id == 0 {
|
||||
if let Some(virtio_iommu_bdf) = virtio_iommu_bdf {
|
||||
// See kernel document Documentation/devicetree/bindings/pci/pci-iommu.txt
|
||||
// for 'iommu-map' attribute setting.
|
||||
let iommu_map = [
|
||||
0_u32,
|
||||
VIRTIO_IOMMU_PHANDLE,
|
||||
0_u32,
|
||||
virtio_iommu_bdf,
|
||||
virtio_iommu_bdf + 1,
|
||||
VIRTIO_IOMMU_PHANDLE,
|
||||
virtio_iommu_bdf + 1,
|
||||
0xffff - virtio_iommu_bdf,
|
||||
];
|
||||
fdt.property_array_u32("iommu-map", &iommu_map)?;
|
||||
if pci_device_info_elem.pci_segment_id == 0
|
||||
&& let Some(virtio_iommu_bdf) = virtio_iommu_bdf
|
||||
{
|
||||
// See kernel document Documentation/devicetree/bindings/pci/pci-iommu.txt
|
||||
// for 'iommu-map' attribute setting.
|
||||
let iommu_map = [
|
||||
0_u32,
|
||||
VIRTIO_IOMMU_PHANDLE,
|
||||
0_u32,
|
||||
virtio_iommu_bdf,
|
||||
virtio_iommu_bdf + 1,
|
||||
VIRTIO_IOMMU_PHANDLE,
|
||||
virtio_iommu_bdf + 1,
|
||||
0xffff - virtio_iommu_bdf,
|
||||
];
|
||||
fdt.property_array_u32("iommu-map", &iommu_map)?;
|
||||
|
||||
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
|
||||
// for virtio-iommu node settings.
|
||||
let virtio_iommu_node_name = format!("virtio_iommu@{virtio_iommu_bdf:x}");
|
||||
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
|
||||
fdt.property_u32("#iommu-cells", 1)?;
|
||||
fdt.property_string("compatible", "virtio,pci-iommu")?;
|
||||
// See kernel document Documentation/devicetree/bindings/virtio/iommu.txt
|
||||
// for virtio-iommu node settings.
|
||||
let virtio_iommu_node_name = format!("virtio_iommu@{virtio_iommu_bdf:x}");
|
||||
let virtio_iommu_node = fdt.begin_node(&virtio_iommu_node_name)?;
|
||||
fdt.property_u32("#iommu-cells", 1)?;
|
||||
fdt.property_string("compatible", "virtio,pci-iommu")?;
|
||||
|
||||
// 'reg' is a five-cell address encoded as
|
||||
// (phys.hi phys.mid phys.lo size.hi size.lo). phys.hi should contain the
|
||||
// device's BDF as 0b00000000 bbbbbbbb dddddfff 00000000. The other cells
|
||||
// should be zero.
|
||||
let reg = [virtio_iommu_bdf << 8, 0_u32, 0_u32, 0_u32, 0_u32];
|
||||
fdt.property_array_u32("reg", ®)?;
|
||||
fdt.property_u32("phandle", VIRTIO_IOMMU_PHANDLE)?;
|
||||
// 'reg' is a five-cell address encoded as
|
||||
// (phys.hi phys.mid phys.lo size.hi size.lo). phys.hi should contain the
|
||||
// device's BDF as 0b00000000 bbbbbbbb dddddfff 00000000. The other cells
|
||||
// should be zero.
|
||||
let reg = [virtio_iommu_bdf << 8, 0_u32, 0_u32, 0_u32, 0_u32];
|
||||
fdt.property_array_u32("reg", ®)?;
|
||||
fdt.property_u32("phandle", VIRTIO_IOMMU_PHANDLE)?;
|
||||
|
||||
fdt.end_node(virtio_iommu_node)?;
|
||||
}
|
||||
fdt.end_node(virtio_iommu_node)?;
|
||||
}
|
||||
|
||||
fdt.end_node(pci_node)?;
|
||||
|
|
|
|||
|
|
@ -810,31 +810,22 @@ pub fn configure_vcpu(
|
|||
);
|
||||
|
||||
// The TSC frequency CPUID leaf should not be included when running with HyperV emulation
|
||||
if !kvm_hyperv {
|
||||
if let Some(tsc_khz) = vcpu.tsc_khz().map_err(Error::GetTscFrequency)? {
|
||||
// Need to check that the TSC doesn't vary with dynamic frequency
|
||||
// SAFETY: cpuid called with valid leaves
|
||||
if unsafe { std::arch::x86_64::__cpuid(0x8000_0007) }.edx
|
||||
& (1u32 << INVARIANT_TSC_EDX_BIT)
|
||||
> 0
|
||||
{
|
||||
CpuidPatch::set_cpuid_reg(
|
||||
&mut cpuid,
|
||||
0x4000_0000,
|
||||
None,
|
||||
CpuidReg::EAX,
|
||||
0x4000_0010,
|
||||
);
|
||||
cpuid.retain(|c| c.function != 0x4000_0010);
|
||||
cpuid.push(CpuIdEntry {
|
||||
function: 0x4000_0010,
|
||||
eax: tsc_khz,
|
||||
ebx: 1000000, /* LAPIC resolution of 1ns (freq: 1GHz) is hardcoded in KVM's
|
||||
* APIC_BUS_CYCLE_NS */
|
||||
..Default::default()
|
||||
});
|
||||
};
|
||||
}
|
||||
if !kvm_hyperv && let Some(tsc_khz) = vcpu.tsc_khz().map_err(Error::GetTscFrequency)? {
|
||||
// Need to check that the TSC doesn't vary with dynamic frequency
|
||||
// SAFETY: cpuid called with valid leaves
|
||||
if unsafe { std::arch::x86_64::__cpuid(0x8000_0007) }.edx & (1u32 << INVARIANT_TSC_EDX_BIT)
|
||||
> 0
|
||||
{
|
||||
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x4000_0000, None, CpuidReg::EAX, 0x4000_0010);
|
||||
cpuid.retain(|c| c.function != 0x4000_0010);
|
||||
cpuid.push(CpuIdEntry {
|
||||
function: 0x4000_0010,
|
||||
eax: tsc_khz,
|
||||
ebx: 1000000, /* LAPIC resolution of 1ns (freq: 1GHz) is hardcoded in KVM's
|
||||
* APIC_BUS_CYCLE_NS */
|
||||
..Default::default()
|
||||
});
|
||||
};
|
||||
}
|
||||
|
||||
for c in &cpuid {
|
||||
|
|
@ -932,10 +923,10 @@ pub fn configure_system(
|
|||
mptable::setup_mptable(offset, guest_mem, _num_cpus, topology).map_err(Error::MpTableSetup)?;
|
||||
|
||||
// Check that the RAM is not smaller than the RSDP start address
|
||||
if let Some(rsdp_addr) = rsdp_addr {
|
||||
if rsdp_addr.0 > guest_mem.last_addr().0 {
|
||||
return Err(super::Error::RsdpPastRamEnd);
|
||||
}
|
||||
if let Some(rsdp_addr) = rsdp_addr
|
||||
&& rsdp_addr.0 > guest_mem.last_addr().0
|
||||
{
|
||||
return Err(super::Error::RsdpPastRamEnd);
|
||||
}
|
||||
|
||||
match setup_header {
|
||||
|
|
|
|||
|
|
@ -287,11 +287,12 @@ impl QcowHeader {
|
|||
let cluster_bits: u32 = DEFAULT_CLUSTER_BITS;
|
||||
let cluster_size: u32 = 0x01 << cluster_bits;
|
||||
let max_length: usize = (cluster_size - header_size) as usize;
|
||||
if let Some(path) = backing_file {
|
||||
if path.len() > max_length {
|
||||
return Err(Error::BackingFileTooLong(path.len() - max_length));
|
||||
}
|
||||
if let Some(path) = backing_file
|
||||
&& path.len() > max_length
|
||||
{
|
||||
return Err(Error::BackingFileTooLong(path.len() - max_length));
|
||||
}
|
||||
|
||||
// L2 blocks are always one cluster long. They contain cluster_size/sizeof(u64) addresses.
|
||||
let entries_per_cluster: u32 = cluster_size / size_of::<u64>() as u32;
|
||||
let num_clusters: u32 = div_round_up_u64(size, u64::from(cluster_size)) as u32;
|
||||
|
|
@ -589,14 +590,12 @@ impl QcowFile {
|
|||
|
||||
// Check for compressed blocks
|
||||
for l2_addr_disk in l1_table.get_values() {
|
||||
if *l2_addr_disk != 0 {
|
||||
if let Err(e) = Self::read_l2_cluster(&mut raw_file, *l2_addr_disk) {
|
||||
if let Some(os_error) = e.raw_os_error() {
|
||||
if os_error == ENOTSUP {
|
||||
return Err(Error::CompressedBlocksNotSupported);
|
||||
}
|
||||
}
|
||||
}
|
||||
if *l2_addr_disk != 0
|
||||
&& let Err(e) = Self::read_l2_cluster(&mut raw_file, *l2_addr_disk)
|
||||
&& let Some(os_error) = e.raw_os_error()
|
||||
&& os_error == ENOTSUP
|
||||
{
|
||||
return Err(Error::CompressedBlocksNotSupported);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1584,11 +1583,11 @@ impl Seek for QcowFile {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(o) = new_offset {
|
||||
if o <= self.virtual_size() {
|
||||
self.current_offset = o;
|
||||
return Ok(o);
|
||||
}
|
||||
if let Some(o) = new_offset
|
||||
&& o <= self.virtual_size()
|
||||
{
|
||||
self.current_offset = o;
|
||||
return Ok(o);
|
||||
}
|
||||
Err(std::io::Error::from_raw_os_error(EINVAL))
|
||||
}
|
||||
|
|
|
|||
|
|
@ -123,10 +123,10 @@ impl<T: Cacheable> CacheMap<T> {
|
|||
if self.map.len() == self.capacity {
|
||||
// TODO(dgreid) - smarter eviction strategy.
|
||||
let to_evict = *self.map.iter().next().unwrap().0;
|
||||
if let Some(evicted) = self.map.remove(&to_evict) {
|
||||
if evicted.dirty() {
|
||||
write_callback(to_evict, evicted)?;
|
||||
}
|
||||
if let Some(evicted) = self.map.remove(&to_evict)
|
||||
&& evicted.dirty()
|
||||
{
|
||||
write_callback(to_evict, evicted)?;
|
||||
}
|
||||
}
|
||||
self.map.insert(index, block);
|
||||
|
|
|
|||
|
|
@ -187,11 +187,11 @@ impl Seek for Vhdx {
|
|||
}
|
||||
};
|
||||
|
||||
if let Some(o) = new_offset {
|
||||
if o <= self.virtual_disk_size() {
|
||||
self.current_offset = o;
|
||||
return Ok(o);
|
||||
}
|
||||
if let Some(o) = new_offset
|
||||
&& o <= self.virtual_disk_size()
|
||||
{
|
||||
self.current_offset = o;
|
||||
return Ok(o);
|
||||
}
|
||||
|
||||
Err(std::io::Error::new(
|
||||
|
|
|
|||
15
build.rs
15
build.rs
|
|
@ -9,14 +9,13 @@ use std::process::Command;
|
|||
fn main() {
|
||||
let mut version = "v".to_owned() + env!("CARGO_PKG_VERSION");
|
||||
|
||||
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output() {
|
||||
if git_out.status.success() {
|
||||
if let Ok(git_out_str) = String::from_utf8(git_out.stdout) {
|
||||
version = git_out_str;
|
||||
// Pop the trailing newline.
|
||||
version.pop();
|
||||
}
|
||||
}
|
||||
if let Ok(git_out) = Command::new("git").args(["describe", "--dirty"]).output()
|
||||
&& git_out.status.success()
|
||||
&& let Ok(git_out_str) = String::from_utf8(git_out.stdout)
|
||||
{
|
||||
version = git_out_str;
|
||||
// Pop the trailing newline.
|
||||
version.pop();
|
||||
}
|
||||
|
||||
// Append CH_EXTRA_VERSION to version if it is set.
|
||||
|
|
|
|||
|
|
@ -458,10 +458,9 @@ impl BusDevice for Tpm {
|
|||
CRB_CTRL_CANCEL => {
|
||||
if v == CRB_CANCEL_INVOKE
|
||||
&& (self.regs[CRB_CTRL_START as usize] & CRB_START_INVOKE != 0)
|
||||
&& let Err(e) = self.emulator.cancel_cmd()
|
||||
{
|
||||
if let Err(e) = self.emulator.cancel_cmd() {
|
||||
error!("Failed to run cancel command. Error: {:?}", e);
|
||||
}
|
||||
error!("Failed to run cancel command. Error: {:?}", e);
|
||||
}
|
||||
}
|
||||
CRB_CTRL_START => {
|
||||
|
|
|
|||
|
|
@ -624,11 +624,11 @@ impl<T: CpuStateManager> Emulator<'_, T> {
|
|||
last_decoded_ip = decoder.ip();
|
||||
num_insn_emulated += 1;
|
||||
|
||||
if let Some(num_insn) = num_insn {
|
||||
if num_insn_emulated >= num_insn {
|
||||
// Exit the decoding loop, do not decode the next instruction.
|
||||
stop_emulation = true;
|
||||
}
|
||||
if let Some(num_insn) = num_insn
|
||||
&& num_insn_emulated >= num_insn
|
||||
{
|
||||
// Exit the decoding loop, do not decode the next instruction.
|
||||
stop_emulation = true;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -44,12 +44,12 @@ impl MshvEmulatorContext<'_> {
|
|||
gpa
|
||||
);
|
||||
|
||||
if let Some(vm_ops) = &self.vcpu.vm_ops {
|
||||
if vm_ops.guest_mem_read(gpa, data).is_err() {
|
||||
vm_ops
|
||||
.mmio_read(gpa, data)
|
||||
.map_err(|e| PlatformError::MemoryReadFailure(e.into()))?;
|
||||
}
|
||||
if let Some(vm_ops) = &self.vcpu.vm_ops
|
||||
&& vm_ops.guest_mem_read(gpa, data).is_err()
|
||||
{
|
||||
vm_ops
|
||||
.mmio_read(gpa, data)
|
||||
.map_err(|e| PlatformError::MemoryReadFailure(e.into()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -94,12 +94,12 @@ impl MshvEmulatorContext<'_> {
|
|||
gpa
|
||||
);
|
||||
|
||||
if let Some(vm_ops) = &self.vcpu.vm_ops {
|
||||
if vm_ops.guest_mem_write(gpa, data).is_err() {
|
||||
vm_ops
|
||||
.mmio_write(gpa, data)
|
||||
.map_err(|e| PlatformError::MemoryWriteFailure(e.into()))?;
|
||||
}
|
||||
if let Some(vm_ops) = &self.vcpu.vm_ops
|
||||
&& vm_ops.guest_mem_write(gpa, data).is_err()
|
||||
{
|
||||
vm_ops
|
||||
.mmio_write(gpa, data)
|
||||
.map_err(|e| PlatformError::MemoryWriteFailure(e.into()))?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -866,11 +866,11 @@ mod tests {
|
|||
let p = ParsedPkt::new(buf);
|
||||
p.print();
|
||||
|
||||
if let Some(ref udp) = p.udp {
|
||||
if payload == udp.payload() {
|
||||
channel_tx.send(true).unwrap();
|
||||
break;
|
||||
}
|
||||
if let Some(ref udp) = p.udp
|
||||
&& payload == udp.payload()
|
||||
{
|
||||
channel_tx.send(true).unwrap();
|
||||
break;
|
||||
}
|
||||
}
|
||||
});
|
||||
|
|
|
|||
|
|
@ -828,10 +828,10 @@ impl PciConfiguration {
|
|||
|
||||
let mut addr = u64::from(self.bars[bar_num].addr & self.writable_bits[bar_idx]);
|
||||
|
||||
if let Some(bar_type) = self.bars[bar_num].r#type {
|
||||
if bar_type == PciBarRegionType::Memory64BitRegion {
|
||||
addr |= u64::from(self.bars[bar_num + 1].addr) << 32;
|
||||
}
|
||||
if let Some(bar_type) = self.bars[bar_num].r#type
|
||||
&& bar_type == PciBarRegionType::Memory64BitRegion
|
||||
{
|
||||
addr |= u64::from(self.bars[bar_num + 1].addr) << 32;
|
||||
}
|
||||
|
||||
addr
|
||||
|
|
@ -907,19 +907,19 @@ impl PciConfiguration {
|
|||
}
|
||||
|
||||
// Handle potential write to MSI-X message control register
|
||||
if let Some(msix_cap_reg_idx) = self.msix_cap_reg_idx {
|
||||
if let Some(msix_config) = &self.msix_config {
|
||||
if msix_cap_reg_idx == reg_idx && offset == 2 && data.len() == 2 {
|
||||
msix_config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_msg_ctl(LittleEndian::read_u16(data));
|
||||
} else if msix_cap_reg_idx == reg_idx && offset == 0 && data.len() == 4 {
|
||||
msix_config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_msg_ctl((LittleEndian::read_u32(data) >> 16) as u16);
|
||||
}
|
||||
if let Some(msix_cap_reg_idx) = self.msix_cap_reg_idx
|
||||
&& let Some(msix_config) = &self.msix_config
|
||||
{
|
||||
if msix_cap_reg_idx == reg_idx && offset == 2 && data.len() == 2 {
|
||||
msix_config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_msg_ctl(LittleEndian::read_u16(data));
|
||||
} else if msix_cap_reg_idx == reg_idx && offset == 0 && data.len() == 4 {
|
||||
msix_config
|
||||
.lock()
|
||||
.unwrap()
|
||||
.set_msg_ctl((LittleEndian::read_u32(data) >> 16) as u16);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -271,15 +271,11 @@ impl MsiConfig {
|
|||
}
|
||||
}
|
||||
|
||||
if !old_enabled {
|
||||
if let Err(e) = self.interrupt_source_group.enable() {
|
||||
error!("Failed enabling irq_fd: {:?}", e);
|
||||
}
|
||||
}
|
||||
} else if old_enabled {
|
||||
if let Err(e) = self.interrupt_source_group.disable() {
|
||||
error!("Failed disabling irq_fd: {:?}", e);
|
||||
if !old_enabled && let Err(e) = self.interrupt_source_group.enable() {
|
||||
error!("Failed enabling irq_fd: {:?}", e);
|
||||
}
|
||||
} else if old_enabled && let Err(e) = self.interrupt_source_group.disable() {
|
||||
error!("Failed disabling irq_fd: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
180
pci/src/vfio.rs
180
pci/src/vfio.rs
|
|
@ -208,21 +208,20 @@ impl Interrupt {
|
|||
}
|
||||
|
||||
fn accessed(&self, offset: u64) -> Option<(PciCapabilityId, u64)> {
|
||||
if let Some(msi) = &self.msi {
|
||||
if offset >= u64::from(msi.cap_offset)
|
||||
&& offset < u64::from(msi.cap_offset) + msi.cfg.size()
|
||||
{
|
||||
return Some((
|
||||
PciCapabilityId::MessageSignalledInterrupts,
|
||||
u64::from(msi.cap_offset),
|
||||
));
|
||||
}
|
||||
if let Some(msi) = &self.msi
|
||||
&& offset >= u64::from(msi.cap_offset)
|
||||
&& offset < u64::from(msi.cap_offset) + msi.cfg.size()
|
||||
{
|
||||
return Some((
|
||||
PciCapabilityId::MessageSignalledInterrupts,
|
||||
u64::from(msi.cap_offset),
|
||||
));
|
||||
}
|
||||
|
||||
if let Some(msix) = &self.msix {
|
||||
if offset == u64::from(msix.cap_offset) {
|
||||
return Some((PciCapabilityId::MsiX, u64::from(msix.cap_offset)));
|
||||
}
|
||||
if let Some(msix) = &self.msix
|
||||
&& offset == u64::from(msix.cap_offset)
|
||||
{
|
||||
return Some((PciCapabilityId::MsiX, u64::from(msix.cap_offset)));
|
||||
}
|
||||
|
||||
None
|
||||
|
|
@ -603,13 +602,12 @@ impl VfioCommon {
|
|||
type_,
|
||||
..
|
||||
} = resource
|
||||
&& *index == bar_id as usize
|
||||
{
|
||||
if *index == bar_id as usize {
|
||||
restored_bar_addr = Some(GuestAddress(*base));
|
||||
region_size = *size;
|
||||
region_type = PciBarRegionType::from(*type_);
|
||||
break;
|
||||
}
|
||||
restored_bar_addr = Some(GuestAddress(*base));
|
||||
region_size = *size;
|
||||
region_type = PciBarRegionType::from(*type_);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if restored_bar_addr.is_none() {
|
||||
|
|
@ -925,24 +923,23 @@ impl VfioCommon {
|
|||
|
||||
match PciCapabilityId::from(cap_id) {
|
||||
PciCapabilityId::MessageSignalledInterrupts => {
|
||||
if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSI_IRQ_INDEX) {
|
||||
if irq_info.count > 0 {
|
||||
// Parse capability only if the VFIO device
|
||||
// supports MSI.
|
||||
let msg_ctl = self.parse_msi_capabilities(cap_iter);
|
||||
self.initialize_msi(msg_ctl, cap_iter as u32, None);
|
||||
}
|
||||
if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSI_IRQ_INDEX)
|
||||
&& irq_info.count > 0
|
||||
{
|
||||
// Parse capability only if the VFIO device
|
||||
// supports MSI.
|
||||
let msg_ctl = self.parse_msi_capabilities(cap_iter);
|
||||
self.initialize_msi(msg_ctl, cap_iter as u32, None);
|
||||
}
|
||||
}
|
||||
PciCapabilityId::MsiX => {
|
||||
if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_MSIX_IRQ_INDEX)
|
||||
&& irq_info.count > 0
|
||||
{
|
||||
if irq_info.count > 0 {
|
||||
// Parse capability only if the VFIO device
|
||||
// supports MSI-X.
|
||||
let msix_cap = self.parse_msix_capabilities(cap_iter);
|
||||
self.initialize_msix(msix_cap, cap_iter as u32, bdf, None);
|
||||
}
|
||||
// Parse capability only if the VFIO device
|
||||
// supports MSI-X.
|
||||
let msix_cap = self.parse_msix_capabilities(cap_iter);
|
||||
self.initialize_msix(msix_cap, cap_iter as u32, bdf, None);
|
||||
}
|
||||
}
|
||||
PciCapabilityId::PciExpress => pci_express_cap_found = true,
|
||||
|
|
@ -1038,17 +1035,17 @@ impl VfioCommon {
|
|||
}
|
||||
|
||||
pub(crate) fn enable_intx(&mut self) -> Result<(), VfioPciError> {
|
||||
if let Some(intx) = &mut self.interrupt.intx {
|
||||
if !intx.enabled {
|
||||
if let Some(eventfd) = intx.interrupt_source_group.notifier(0) {
|
||||
self.vfio_wrapper
|
||||
.enable_irq(VFIO_PCI_INTX_IRQ_INDEX, vec![&eventfd])
|
||||
.map_err(VfioPciError::EnableIntx)?;
|
||||
if let Some(intx) = &mut self.interrupt.intx
|
||||
&& !intx.enabled
|
||||
{
|
||||
if let Some(eventfd) = intx.interrupt_source_group.notifier(0) {
|
||||
self.vfio_wrapper
|
||||
.enable_irq(VFIO_PCI_INTX_IRQ_INDEX, vec![&eventfd])
|
||||
.map_err(VfioPciError::EnableIntx)?;
|
||||
|
||||
intx.enabled = true;
|
||||
} else {
|
||||
return Err(VfioPciError::MissingNotifier);
|
||||
}
|
||||
intx.enabled = true;
|
||||
} else {
|
||||
return Err(VfioPciError::MissingNotifier);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1056,13 +1053,13 @@ impl VfioCommon {
|
|||
}
|
||||
|
||||
pub(crate) fn disable_intx(&mut self) {
|
||||
if let Some(intx) = &mut self.interrupt.intx {
|
||||
if intx.enabled {
|
||||
if let Err(e) = self.vfio_wrapper.disable_irq(VFIO_PCI_INTX_IRQ_INDEX) {
|
||||
error!("Could not disable INTx: {}", e);
|
||||
} else {
|
||||
intx.enabled = false;
|
||||
}
|
||||
if let Some(intx) = &mut self.interrupt.intx
|
||||
&& intx.enabled
|
||||
{
|
||||
if let Err(e) = self.vfio_wrapper.disable_irq(VFIO_PCI_INTX_IRQ_INDEX) {
|
||||
error!("Could not disable INTx: {}", e);
|
||||
} else {
|
||||
intx.enabled = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1118,12 +1115,12 @@ impl VfioCommon {
|
|||
}
|
||||
|
||||
fn initialize_legacy_interrupt(&mut self) -> Result<(), VfioPciError> {
|
||||
if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_INTX_IRQ_INDEX) {
|
||||
if irq_info.count == 0 {
|
||||
// A count of 0 means the INTx IRQ is not supported, therefore
|
||||
// it shouldn't be initialized.
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(irq_info) = self.vfio_wrapper.get_irq_info(VFIO_PCI_INTX_IRQ_INDEX)
|
||||
&& irq_info.count == 0
|
||||
{
|
||||
// A count of 0 means the INTx IRQ is not supported, therefore
|
||||
// it shouldn't be initialized.
|
||||
return Ok(());
|
||||
}
|
||||
|
||||
if let Some(interrupt_source_group) = self.legacy_interrupt_group.clone() {
|
||||
|
|
@ -1200,10 +1197,10 @@ impl VfioCommon {
|
|||
// INTx EOI
|
||||
// The guest reading from the BAR potentially means the interrupt has
|
||||
// been received and can be acknowledged.
|
||||
if self.interrupt.intx_in_use() {
|
||||
if let Err(e) = self.vfio_wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX) {
|
||||
error!("Failed unmasking INTx IRQ: {}", e);
|
||||
}
|
||||
if self.interrupt.intx_in_use()
|
||||
&& let Err(e) = self.vfio_wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX)
|
||||
{
|
||||
error!("Failed unmasking INTx IRQ: {}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1228,10 +1225,10 @@ impl VfioCommon {
|
|||
// INTx EOI
|
||||
// The guest writing to the BAR potentially means the interrupt has
|
||||
// been received and can be acknowledged.
|
||||
if self.interrupt.intx_in_use() {
|
||||
if let Err(e) = self.vfio_wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX) {
|
||||
error!("Failed unmasking INTx IRQ: {}", e);
|
||||
}
|
||||
if self.interrupt.intx_in_use()
|
||||
&& let Err(e) = self.vfio_wrapper.unmask_irq(VFIO_PCI_INTX_IRQ_INDEX)
|
||||
{
|
||||
error!("Failed unmasking INTx IRQ: {}", e);
|
||||
}
|
||||
|
||||
None
|
||||
|
|
@ -1619,12 +1616,11 @@ impl VfioPciDevice {
|
|||
// Don't try to mmap the region if it contains MSI-X table or
|
||||
// MSI-X PBA subregion, and if we couldn't find MSIX_MAPPABLE
|
||||
// in the list of supported capabilities.
|
||||
if let Some(msix) = self.common.interrupt.msix.as_ref() {
|
||||
if (region.index == msix.cap.table_bir() || region.index == msix.cap.pba_bir())
|
||||
&& !caps.contains(&VfioRegionInfoCap::MsixMappable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
if let Some(msix) = self.common.interrupt.msix.as_ref()
|
||||
&& (region.index == msix.cap.table_bir() || region.index == msix.cap.pba_bir())
|
||||
&& !caps.contains(&VfioRegionInfoCap::MsixMappable)
|
||||
{
|
||||
continue;
|
||||
}
|
||||
|
||||
let mmap_size = self.device.get_region_size(region.index);
|
||||
|
|
@ -1713,18 +1709,17 @@ impl VfioPciDevice {
|
|||
for region in self.common.mmio_regions.iter() {
|
||||
for user_memory_region in region.user_memory_regions.iter() {
|
||||
// Unmap from vfio container
|
||||
if !self.iommu_attached {
|
||||
if let Err(e) = self
|
||||
if !self.iommu_attached
|
||||
&& let Err(e) = self
|
||||
.container
|
||||
.vfio_dma_unmap(user_memory_region.start, user_memory_region.size)
|
||||
.map_err(|e| VfioPciError::DmaUnmap(e, self.device_path.clone(), self.bdf))
|
||||
{
|
||||
error!(
|
||||
"Could not unmap mmio region from vfio container: \
|
||||
{
|
||||
error!(
|
||||
"Could not unmap mmio region from vfio container: \
|
||||
iova 0x{:x}, size 0x{:x}: {}, ",
|
||||
user_memory_region.start, user_memory_region.size, e
|
||||
);
|
||||
}
|
||||
user_memory_region.start, user_memory_region.size, e
|
||||
);
|
||||
}
|
||||
|
||||
// Remove region
|
||||
|
|
@ -1791,16 +1786,16 @@ impl Drop for VfioPciDevice {
|
|||
fn drop(&mut self) {
|
||||
self.unmap_mmio_regions();
|
||||
|
||||
if let Some(msix) = &self.common.interrupt.msix {
|
||||
if msix.bar.enabled() {
|
||||
self.common.disable_msix();
|
||||
}
|
||||
if let Some(msix) = &self.common.interrupt.msix
|
||||
&& msix.bar.enabled()
|
||||
{
|
||||
self.common.disable_msix();
|
||||
}
|
||||
|
||||
if let Some(msi) = &self.common.interrupt.msi {
|
||||
if msi.cfg.enabled() {
|
||||
self.common.disable_msi()
|
||||
}
|
||||
if let Some(msi) = &self.common.interrupt.msi
|
||||
&& msi.cfg.enabled()
|
||||
{
|
||||
self.common.disable_msi()
|
||||
}
|
||||
|
||||
if self.common.interrupt.intx_in_use() {
|
||||
|
|
@ -1898,20 +1893,19 @@ impl PciDevice for VfioPciDevice {
|
|||
|
||||
for user_memory_region in region.user_memory_regions.iter_mut() {
|
||||
// Unmap the old MMIO region from vfio container
|
||||
if !self.iommu_attached {
|
||||
if let Err(e) = self
|
||||
if !self.iommu_attached
|
||||
&& let Err(e) = self
|
||||
.container
|
||||
.vfio_dma_unmap(user_memory_region.start, user_memory_region.size)
|
||||
.map_err(|e| {
|
||||
VfioPciError::DmaUnmap(e, self.device_path.clone(), self.bdf)
|
||||
})
|
||||
{
|
||||
error!(
|
||||
"Could not unmap mmio region from vfio container: \
|
||||
{
|
||||
error!(
|
||||
"Could not unmap mmio region from vfio container: \
|
||||
iova 0x{:x}, size 0x{:x}: {}, ",
|
||||
user_memory_region.start, user_memory_region.size, e
|
||||
);
|
||||
}
|
||||
user_memory_region.start, user_memory_region.size, e
|
||||
);
|
||||
}
|
||||
|
||||
// Remove old region
|
||||
|
|
|
|||
|
|
@ -505,16 +505,16 @@ impl Drop for VfioUserPciDevice {
|
|||
fn drop(&mut self) {
|
||||
self.unmap_mmio_regions();
|
||||
|
||||
if let Some(msix) = &self.common.interrupt.msix {
|
||||
if msix.bar.enabled() {
|
||||
self.common.disable_msix();
|
||||
}
|
||||
if let Some(msix) = &self.common.interrupt.msix
|
||||
&& msix.bar.enabled()
|
||||
{
|
||||
self.common.disable_msix();
|
||||
}
|
||||
|
||||
if let Some(msi) = &self.common.interrupt.msi {
|
||||
if msi.cfg.enabled() {
|
||||
self.common.disable_msi()
|
||||
}
|
||||
if let Some(msi) = &self.common.interrupt.msi
|
||||
&& msi.cfg.enabled()
|
||||
{
|
||||
self.common.disable_msi()
|
||||
}
|
||||
|
||||
if self.common.interrupt.intx_in_use() {
|
||||
|
|
|
|||
|
|
@ -288,10 +288,10 @@ impl Drop for RateLimiterGroup {
|
|||
fn drop(&mut self) {
|
||||
self.kill_evt.write(1).unwrap();
|
||||
|
||||
if let Some(t) = self.epoll_thread.take() {
|
||||
if let Err(e) = t.join() {
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
if let Some(t) = self.epoll_thread.take()
|
||||
&& let Err(e) = t.join()
|
||||
{
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -754,10 +754,10 @@ fn start_vmm(cmd_arguments: ArgMatches) -> Result<Option<String>, Error> {
|
|||
Ok(())
|
||||
})();
|
||||
|
||||
if r.is_err() {
|
||||
if let Err(e) = exit_evt.write(1) {
|
||||
warn!("writing to exit EventFd: {e}");
|
||||
}
|
||||
if r.is_err()
|
||||
&& let Err(e) = exit_evt.write(1)
|
||||
{
|
||||
warn!("writing to exit EventFd: {e}");
|
||||
}
|
||||
|
||||
if landlock_enable {
|
||||
|
|
|
|||
|
|
@ -481,13 +481,14 @@ pub fn rate_limited_copy<P: AsRef<Path>, Q: AsRef<Path>>(from: P, to: Q) -> io::
|
|||
|
||||
match fs::copy(&from, &to) {
|
||||
Err(e) => {
|
||||
if let Some(errno) = e.raw_os_error() {
|
||||
if errno == libc::ENOSPC {
|
||||
eprintln!("Copy returned ENOSPC. Attempt {i} of 10. Sleeping.");
|
||||
thread::sleep(std::time::Duration::new(60, 0));
|
||||
continue;
|
||||
}
|
||||
if let Some(errno) = e.raw_os_error()
|
||||
&& errno == libc::ENOSPC
|
||||
{
|
||||
eprintln!("Copy returned ENOSPC. Attempt {i} of 10. Sleeping.");
|
||||
thread::sleep(std::time::Duration::new(60, 0));
|
||||
continue;
|
||||
}
|
||||
|
||||
return Err(e);
|
||||
}
|
||||
Ok(i) => return Ok(i),
|
||||
|
|
@ -1094,12 +1095,11 @@ impl Guest {
|
|||
let vendors: Vec<&str> = vendors.split('\n').collect();
|
||||
|
||||
for (index, d_id) in devices.iter().enumerate() {
|
||||
if *d_id == device_id {
|
||||
if let Some(v_id) = vendors.get(index) {
|
||||
if *v_id == vendor_id {
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
if *d_id == device_id
|
||||
&& let Some(v_id) = vendors.get(index)
|
||||
&& *v_id == vendor_id
|
||||
{
|
||||
return Ok(true);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -454,12 +454,11 @@ impl EpollHelperHandler for ConsoleEpollHandler {
|
|||
}
|
||||
if self.endpoint.is_pty() {
|
||||
self.file_event_registered = false;
|
||||
if event.events & libc::EPOLLHUP as u32 != 0 {
|
||||
if let Some(pty_write_out) = &self.write_out {
|
||||
if pty_write_out.load(Ordering::Acquire) {
|
||||
pty_write_out.store(false, Ordering::Release);
|
||||
}
|
||||
}
|
||||
if event.events & libc::EPOLLHUP as u32 != 0
|
||||
&& let Some(pty_write_out) = &self.write_out
|
||||
&& pty_write_out.load(Ordering::Acquire)
|
||||
{
|
||||
pty_write_out.store(false, Ordering::Release);
|
||||
} else {
|
||||
// If the EPOLLHUP flag is not up on the associated event, we
|
||||
// can assume the other end of the PTY is connected and therefore
|
||||
|
|
@ -731,10 +730,10 @@ impl VirtioDevice for Console {
|
|||
.acked_features
|
||||
.store(self.common.acked_features, Ordering::Relaxed);
|
||||
|
||||
if self.common.feature_acked(VIRTIO_CONSOLE_F_SIZE) {
|
||||
if let Err(e) = interrupt_cb.trigger(VirtioInterruptType::Config) {
|
||||
error!("Failed to signal console driver: {:?}", e);
|
||||
}
|
||||
if self.common.feature_acked(VIRTIO_CONSOLE_F_SIZE)
|
||||
&& let Err(e) = interrupt_cb.trigger(VirtioInterruptType::Config)
|
||||
{
|
||||
error!("Failed to signal console driver: {:?}", e);
|
||||
}
|
||||
|
||||
let (kill_evt, pause_evt) = self.common.dup_eventfds();
|
||||
|
|
|
|||
|
|
@ -421,13 +421,12 @@ impl Request {
|
|||
// If any other mappings exist in the domain for other containers,
|
||||
// make sure to issue these mappings for the new endpoint/container
|
||||
if let Some(domain_mappings) = &mapping.domains.read().unwrap().get(&domain_id)
|
||||
&& let Some(ext_map) = ext_mapping.get(&endpoint)
|
||||
{
|
||||
if let Some(ext_map) = ext_mapping.get(&endpoint) {
|
||||
for (virt_start, addr_map) in &domain_mappings.mappings {
|
||||
ext_map
|
||||
.map(*virt_start, addr_map.gpa, addr_map.size)
|
||||
.map_err(Error::ExternalUnmapping)?;
|
||||
}
|
||||
for (virt_start, addr_map) in &domain_mappings.mappings {
|
||||
ext_map
|
||||
.map(*virt_start, addr_map.gpa, addr_map.size)
|
||||
.map_err(Error::ExternalUnmapping)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -654,13 +653,13 @@ fn detach_endpoint_from_domain(
|
|||
mapping.endpoints.write().unwrap().remove(&endpoint);
|
||||
|
||||
// Trigger external unmapping for the endpoint if necessary.
|
||||
if let Some(domain_mappings) = &mapping.domains.read().unwrap().get(&domain_id) {
|
||||
if let Some(ext_map) = ext_mapping.get(&endpoint) {
|
||||
for (virt_start, addr_map) in &domain_mappings.mappings {
|
||||
ext_map
|
||||
.unmap(*virt_start, addr_map.size)
|
||||
.map_err(Error::ExternalUnmapping)?;
|
||||
}
|
||||
if let Some(domain_mappings) = &mapping.domains.read().unwrap().get(&domain_id)
|
||||
&& let Some(ext_map) = ext_mapping.get(&endpoint)
|
||||
{
|
||||
for (virt_start, addr_map) in &domain_mappings.mappings {
|
||||
ext_map
|
||||
.unmap(*virt_start, addr_map.size)
|
||||
.map_err(Error::ExternalUnmapping)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -475,11 +475,9 @@ impl MemEpollHandler {
|
|||
return VIRTIO_MEM_RESP_ERROR;
|
||||
}
|
||||
|
||||
if !plug {
|
||||
if let Err(e) = self.discard_memory_range(offset, size) {
|
||||
error!("failed discarding memory range: {:?}", e);
|
||||
return VIRTIO_MEM_RESP_ERROR;
|
||||
}
|
||||
if !plug && let Err(e) = self.discard_memory_range(offset, size) {
|
||||
error!("failed discarding memory range: {:?}", e);
|
||||
return VIRTIO_MEM_RESP_ERROR;
|
||||
}
|
||||
|
||||
self.blocks_state
|
||||
|
|
|
|||
|
|
@ -667,10 +667,10 @@ impl Drop for Net {
|
|||
}
|
||||
// Needed to ensure all references to tap FDs are dropped (#4868)
|
||||
self.common.wait_for_epoll_threads();
|
||||
if let Some(thread) = self.ctrl_queue_epoll_thread.take() {
|
||||
if let Err(e) = thread.join() {
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
if let Some(thread) = self.ctrl_queue_epoll_thread.take()
|
||||
&& let Err(e) = thread.join()
|
||||
{
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -36,12 +36,12 @@ where
|
|||
thread::Builder::new()
|
||||
.name(name.to_string())
|
||||
.spawn(move || {
|
||||
if !seccomp_filter.is_empty() {
|
||||
if let Err(e) = apply_filter(&seccomp_filter) {
|
||||
error!("Error applying seccomp filter: {:?}", e);
|
||||
thread_exit_evt.write(1).ok();
|
||||
return;
|
||||
}
|
||||
if !seccomp_filter.is_empty()
|
||||
&& let Err(e) = apply_filter(&seccomp_filter)
|
||||
{
|
||||
error!("Error applying seccomp filter: {:?}", e);
|
||||
thread_exit_evt.write(1).ok();
|
||||
return;
|
||||
}
|
||||
match std::panic::catch_unwind(AssertUnwindSafe(f)) {
|
||||
Err(_) => {
|
||||
|
|
|
|||
|
|
@ -261,36 +261,28 @@ impl VirtioPciCommonConfig {
|
|||
let ready = value == 1;
|
||||
q.set_ready(ready);
|
||||
// Translate address of descriptor table and vrings.
|
||||
if let Some(access_platform) = &self.access_platform {
|
||||
if ready {
|
||||
let desc_table = access_platform
|
||||
.translate_gva(
|
||||
q.desc_table(),
|
||||
get_vring_size(VringType::Desc, q.size()),
|
||||
)
|
||||
.unwrap();
|
||||
let avail_ring = access_platform
|
||||
.translate_gva(
|
||||
q.avail_ring(),
|
||||
get_vring_size(VringType::Avail, q.size()),
|
||||
)
|
||||
.unwrap();
|
||||
let used_ring = access_platform
|
||||
.translate_gva(q.used_ring(), get_vring_size(VringType::Used, q.size()))
|
||||
.unwrap();
|
||||
q.set_desc_table_address(
|
||||
Some((desc_table & 0xffff_ffff) as u32),
|
||||
Some((desc_table >> 32) as u32),
|
||||
);
|
||||
q.set_avail_ring_address(
|
||||
Some((avail_ring & 0xffff_ffff) as u32),
|
||||
Some((avail_ring >> 32) as u32),
|
||||
);
|
||||
q.set_used_ring_address(
|
||||
Some((used_ring & 0xffff_ffff) as u32),
|
||||
Some((used_ring >> 32) as u32),
|
||||
);
|
||||
}
|
||||
if ready && let Some(access_platform) = &self.access_platform {
|
||||
let desc_table = access_platform
|
||||
.translate_gva(q.desc_table(), get_vring_size(VringType::Desc, q.size()))
|
||||
.unwrap();
|
||||
let avail_ring = access_platform
|
||||
.translate_gva(q.avail_ring(), get_vring_size(VringType::Avail, q.size()))
|
||||
.unwrap();
|
||||
let used_ring = access_platform
|
||||
.translate_gva(q.used_ring(), get_vring_size(VringType::Used, q.size()))
|
||||
.unwrap();
|
||||
q.set_desc_table_address(
|
||||
Some((desc_table & 0xffff_ffff) as u32),
|
||||
Some((desc_table >> 32) as u32),
|
||||
);
|
||||
q.set_avail_ring_address(
|
||||
Some((avail_ring & 0xffff_ffff) as u32),
|
||||
Some((avail_ring >> 32) as u32),
|
||||
);
|
||||
q.set_used_ring_address(
|
||||
Some((used_ring & 0xffff_ffff) as u32),
|
||||
Some((used_ring >> 32) as u32),
|
||||
);
|
||||
}
|
||||
}),
|
||||
_ => {
|
||||
|
|
|
|||
|
|
@ -968,18 +968,17 @@ impl PciDevice for VirtioPciDevice {
|
|||
if let Resource::PciBar {
|
||||
index, base, type_, ..
|
||||
} = resource
|
||||
&& index == VIRTIO_COMMON_BAR_INDEX
|
||||
{
|
||||
if index == VIRTIO_COMMON_BAR_INDEX {
|
||||
settings_bar_addr = Some(GuestAddress(base));
|
||||
use_64bit_bar = match type_ {
|
||||
PciBarType::Io => {
|
||||
return Err(PciDeviceError::InvalidResource(resource));
|
||||
}
|
||||
PciBarType::Mmio32 => false,
|
||||
PciBarType::Mmio64 => true,
|
||||
};
|
||||
break;
|
||||
}
|
||||
settings_bar_addr = Some(GuestAddress(base));
|
||||
use_64bit_bar = match type_ {
|
||||
PciBarType::Io => {
|
||||
return Err(PciDeviceError::InvalidResource(resource));
|
||||
}
|
||||
PciBarType::Mmio32 => false,
|
||||
PciBarType::Mmio64 => true,
|
||||
};
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Error out if no resource was matching the BAR id.
|
||||
|
|
|
|||
|
|
@ -213,16 +213,16 @@ impl Blk {
|
|||
|
||||
impl Drop for Blk {
|
||||
fn drop(&mut self) {
|
||||
if let Some(kill_evt) = self.common.kill_evt.take() {
|
||||
if let Err(e) = kill_evt.write(1) {
|
||||
error!("failed to kill vhost-user-blk: {:?}", e);
|
||||
}
|
||||
if let Some(kill_evt) = self.common.kill_evt.take()
|
||||
&& let Err(e) = kill_evt.write(1)
|
||||
{
|
||||
error!("failed to kill vhost-user-blk: {:?}", e);
|
||||
}
|
||||
self.common.wait_for_epoll_threads();
|
||||
if let Some(thread) = self.epoll_thread.take() {
|
||||
if let Err(e) = thread.join() {
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
if let Some(thread) = self.epoll_thread.take()
|
||||
&& let Err(e) = thread.join()
|
||||
{
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -267,16 +267,15 @@ impl VirtioDevice for Blk {
|
|||
}
|
||||
|
||||
self.config.writeback = data[0];
|
||||
if let Some(vu) = &self.vu_common.vu {
|
||||
if let Err(e) = vu
|
||||
if let Some(vu) = &self.vu_common.vu
|
||||
&& let Err(e) = vu
|
||||
.lock()
|
||||
.unwrap()
|
||||
.socket_handle()
|
||||
.set_config(offset as u32, VhostUserConfigFlags::WRITABLE, data)
|
||||
.map_err(Error::VhostUserSetConfig)
|
||||
{
|
||||
error!("Failed setting vhost-user-blk configuration: {:?}", e);
|
||||
}
|
||||
{
|
||||
error!("Failed setting vhost-user-blk configuration: {:?}", e);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -329,11 +328,11 @@ impl VirtioDevice for Blk {
|
|||
self.common.resume().ok()?;
|
||||
}
|
||||
|
||||
if let Some(vu) = &self.vu_common.vu {
|
||||
if let Err(e) = vu.lock().unwrap().reset_vhost_user() {
|
||||
error!("Failed to reset vhost-user daemon: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
if let Some(vu) = &self.vu_common.vu
|
||||
&& let Err(e) = vu.lock().unwrap().reset_vhost_user()
|
||||
{
|
||||
error!("Failed to reset vhost-user daemon: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(kill_evt) = self.common.kill_evt.take() {
|
||||
|
|
|
|||
|
|
@ -227,10 +227,10 @@ impl Drop for Fs {
|
|||
let _ = kill_evt.write(1);
|
||||
}
|
||||
self.common.wait_for_epoll_threads();
|
||||
if let Some(thread) = self.epoll_thread.take() {
|
||||
if let Err(e) = thread.join() {
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
if let Some(thread) = self.epoll_thread.take()
|
||||
&& let Err(e) = thread.join()
|
||||
{
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -308,11 +308,11 @@ impl VirtioDevice for Fs {
|
|||
self.common.resume().ok()?;
|
||||
}
|
||||
|
||||
if let Some(vu) = &self.vu_common.vu {
|
||||
if let Err(e) = vu.lock().unwrap().reset_vhost_user() {
|
||||
error!("Failed to reset vhost-user daemon: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
if let Some(vu) = &self.vu_common.vu
|
||||
&& let Err(e) = vu.lock().unwrap().reset_vhost_user()
|
||||
{
|
||||
error!("Failed to reset vhost-user daemon: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(kill_evt) = self.common.kill_evt.take() {
|
||||
|
|
|
|||
|
|
@ -243,23 +243,24 @@ impl Net {
|
|||
|
||||
impl Drop for Net {
|
||||
fn drop(&mut self) {
|
||||
if let Some(kill_evt) = self.common.kill_evt.take() {
|
||||
if let Err(e) = kill_evt.write(1) {
|
||||
error!("failed to kill vhost-user-net: {:?}", e);
|
||||
}
|
||||
if let Some(kill_evt) = self.common.kill_evt.take()
|
||||
&& let Err(e) = kill_evt.write(1)
|
||||
{
|
||||
error!("failed to kill vhost-user-net: {:?}", e);
|
||||
}
|
||||
|
||||
self.common.wait_for_epoll_threads();
|
||||
|
||||
if let Some(thread) = self.epoll_thread.take() {
|
||||
if let Err(e) = thread.join() {
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
if let Some(thread) = self.epoll_thread.take()
|
||||
&& let Err(e) = thread.join()
|
||||
{
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
if let Some(thread) = self.ctrl_queue_epoll_thread.take() {
|
||||
if let Err(e) = thread.join() {
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
|
||||
if let Some(thread) = self.ctrl_queue_epoll_thread.take()
|
||||
&& let Err(e) = thread.join()
|
||||
{
|
||||
error!("Error joining thread: {:?}", e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -382,11 +383,11 @@ impl VirtioDevice for Net {
|
|||
self.common.resume().ok()?;
|
||||
}
|
||||
|
||||
if let Some(vu) = &self.vu_common.vu {
|
||||
if let Err(e) = vu.lock().unwrap().reset_vhost_user() {
|
||||
error!("Failed to reset vhost-user daemon: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
if let Some(vu) = &self.vu_common.vu
|
||||
&& let Err(e) = vu.lock().unwrap().reset_vhost_user()
|
||||
{
|
||||
error!("Failed to reset vhost-user daemon: {:?}", e);
|
||||
return None;
|
||||
}
|
||||
|
||||
if let Some(kill_evt) = self.common.kill_evt.take() {
|
||||
|
|
|
|||
|
|
@ -317,17 +317,16 @@ impl VhostUserHandle {
|
|||
.get_features()
|
||||
.map_err(Error::VhostUserGetFeatures)?;
|
||||
|
||||
if acked_features & VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits() != 0 {
|
||||
if let Some(acked_protocol_features) =
|
||||
if acked_features & VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits() != 0
|
||||
&& let Some(acked_protocol_features) =
|
||||
VhostUserProtocolFeatures::from_bits(acked_protocol_features)
|
||||
{
|
||||
self.vu
|
||||
.set_protocol_features(acked_protocol_features)
|
||||
.map_err(Error::VhostUserSetProtocolFeatures)?;
|
||||
{
|
||||
self.vu
|
||||
.set_protocol_features(acked_protocol_features)
|
||||
.map_err(Error::VhostUserSetProtocolFeatures)?;
|
||||
|
||||
if acked_protocol_features.contains(VhostUserProtocolFeatures::REPLY_ACK) {
|
||||
self.vu.set_hdr_flags(VhostUserHeaderFlag::NEED_REPLY);
|
||||
}
|
||||
if acked_protocol_features.contains(VhostUserProtocolFeatures::REPLY_ACK) {
|
||||
self.vu.set_hdr_flags(VhostUserHeaderFlag::NEED_REPLY);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -437,10 +437,10 @@ impl VsockMuxer {
|
|||
if let Some(EpollListener::LocalStream(stream)) = self.listener_map.get_mut(&fd) {
|
||||
let port = Self::read_local_stream_port(&mut self.partial_command_map, stream);
|
||||
|
||||
if let Err(Error::UnixRead(ref e)) = port {
|
||||
if e.kind() == ErrorKind::WouldBlock {
|
||||
return;
|
||||
}
|
||||
if let Err(Error::UnixRead(ref e)) = port
|
||||
&& e.kind() == ErrorKind::WouldBlock
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
let stream = match self.remove_listener(fd) {
|
||||
|
|
|
|||
|
|
@ -111,11 +111,12 @@ impl MuxerKillQ {
|
|||
/// the queue has expired. Otherwise, `None` is returned.
|
||||
///
|
||||
pub fn pop(&mut self) -> Option<ConnMapKey> {
|
||||
if let Some(item) = self.q.front() {
|
||||
if Instant::now() > item.kill_time {
|
||||
return Some(self.q.pop_front().unwrap().key);
|
||||
}
|
||||
if let Some(item) = self.q.front()
|
||||
&& Instant::now() > item.kill_time
|
||||
{
|
||||
return Some(self.q.pop_front().unwrap().key);
|
||||
}
|
||||
|
||||
None
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -196,10 +196,10 @@ impl AddressAllocator {
|
|||
/// Free an already allocated address range.
|
||||
/// We can only free a range if it matches exactly an already allocated range.
|
||||
pub fn free(&mut self, address: GuestAddress, size: GuestUsize) {
|
||||
if let Some(&range_size) = self.ranges.get(&address) {
|
||||
if size == range_size {
|
||||
self.ranges.remove(&address);
|
||||
}
|
||||
if let Some(&range_size) = self.ranges.get(&address)
|
||||
&& size == range_size
|
||||
{
|
||||
self.ranges.remove(&address);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1248,10 +1248,11 @@ impl DiskConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
&& !self.iommu
|
||||
{
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1260,13 +1261,13 @@ impl DiskConfig {
|
|||
}
|
||||
|
||||
// Check Block device serial length
|
||||
if let Some(ref serial) = self.serial {
|
||||
if serial.len() > VIRTIO_BLK_ID_BYTES as usize {
|
||||
return Err(ValidationError::InvalidSerialLength(
|
||||
serial.len(),
|
||||
VIRTIO_BLK_ID_BYTES as usize,
|
||||
));
|
||||
}
|
||||
if let Some(ref serial) = self.serial
|
||||
&& serial.len() > VIRTIO_BLK_ID_BYTES as usize
|
||||
{
|
||||
return Err(ValidationError::InvalidSerialLength(
|
||||
serial.len(),
|
||||
VIRTIO_BLK_ID_BYTES as usize,
|
||||
));
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
|
@ -1496,17 +1497,18 @@ impl NetConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
&& !self.iommu
|
||||
{
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
}
|
||||
|
||||
if let Some(mtu) = self.mtu {
|
||||
if mtu < virtio_devices::net::MIN_MTU {
|
||||
return Err(ValidationError::InvalidMtu(mtu));
|
||||
}
|
||||
if let Some(mtu) = self.mtu
|
||||
&& mtu < virtio_devices::net::MIN_MTU
|
||||
{
|
||||
return Err(ValidationError::InvalidMtu(mtu));
|
||||
}
|
||||
|
||||
if !self.offload_csum && (self.offload_tso || self.offload_ufo) {
|
||||
|
|
@ -1633,12 +1635,12 @@ impl FsConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) {
|
||||
return Err(ValidationError::IommuNotSupportedOnSegment(
|
||||
self.pci_segment,
|
||||
));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
{
|
||||
return Err(ValidationError::IommuNotSupportedOnSegment(
|
||||
self.pci_segment,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1795,10 +1797,11 @@ impl PmemConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
&& !self.iommu
|
||||
{
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -1895,17 +1898,18 @@ impl DebugConsoleConfig {
|
|||
return Err(Error::ParseConsoleInvalidModeGiven);
|
||||
}
|
||||
|
||||
if parser.is_set("iobase") {
|
||||
if let Some(iobase_opt) = parser.get("iobase") {
|
||||
if !iobase_opt.starts_with("0x") {
|
||||
return Err(Error::Validation(ValidationError::InvalidIoPortHex(
|
||||
iobase_opt,
|
||||
)));
|
||||
}
|
||||
iobase = Some(u16::from_str_radix(&iobase_opt[2..], 16).map_err(|_| {
|
||||
if parser.is_set("iobase")
|
||||
&& let Some(iobase_opt) = parser.get("iobase")
|
||||
{
|
||||
if !iobase_opt.starts_with("0x") {
|
||||
return Err(Error::Validation(ValidationError::InvalidIoPortHex(
|
||||
iobase_opt,
|
||||
)));
|
||||
}
|
||||
iobase =
|
||||
Some(u16::from_str_radix(&iobase_opt[2..], 16).map_err(|_| {
|
||||
Error::Validation(ValidationError::InvalidIoPortHex(iobase_opt))
|
||||
})?);
|
||||
}
|
||||
}
|
||||
|
||||
Ok(Self { file, mode, iobase })
|
||||
|
|
@ -1957,10 +1961,11 @@ impl DeviceConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
&& !self.iommu
|
||||
{
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2000,12 +2005,12 @@ impl UserDeviceConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) {
|
||||
return Err(ValidationError::IommuNotSupportedOnSegment(
|
||||
self.pci_segment,
|
||||
));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
{
|
||||
return Err(ValidationError::IommuNotSupportedOnSegment(
|
||||
self.pci_segment,
|
||||
));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2062,10 +2067,11 @@ impl VdpaConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
&& !self.iommu
|
||||
{
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2121,10 +2127,11 @@ impl VsockConfig {
|
|||
return Err(ValidationError::InvalidPciSegment(self.pci_segment));
|
||||
}
|
||||
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
if iommu_segments.contains(&self.pci_segment) && !self.iommu {
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
&& iommu_segments.contains(&self.pci_segment)
|
||||
&& !self.iommu
|
||||
{
|
||||
return Err(ValidationError::OnIommuSegment(self.pci_segment));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -2493,10 +2500,10 @@ impl VmConfig {
|
|||
{
|
||||
let host_data_opt = &self.payload.as_ref().unwrap().host_data;
|
||||
|
||||
if let Some(host_data) = host_data_opt {
|
||||
if host_data.len() != 64 {
|
||||
return Err(ValidationError::InvalidHostData);
|
||||
}
|
||||
if let Some(host_data) = host_data_opt
|
||||
&& host_data.len() != 64
|
||||
{
|
||||
return Err(ValidationError::InvalidHostData);
|
||||
}
|
||||
}
|
||||
// The 'conflict' check is introduced in commit 24438e0390d3
|
||||
|
|
@ -2675,10 +2682,10 @@ impl VmConfig {
|
|||
}
|
||||
}
|
||||
|
||||
if let Some(vsock) = &self.vsock {
|
||||
if [!0, 0, 1, 2].contains(&vsock.cid) {
|
||||
return Err(ValidationError::VsockSpecialCid(vsock.cid));
|
||||
}
|
||||
if let Some(vsock) = &self.vsock
|
||||
&& [!0, 0, 1, 2].contains(&vsock.cid)
|
||||
{
|
||||
return Err(ValidationError::VsockSpecialCid(vsock.cid));
|
||||
}
|
||||
|
||||
if let Some(balloon) = &self.balloon {
|
||||
|
|
@ -3080,11 +3087,11 @@ impl VmConfig {
|
|||
}
|
||||
|
||||
// Remove if vsock device
|
||||
if let Some(vsock) = self.vsock.as_ref() {
|
||||
if vsock.id.as_ref().map(|id| id.as_ref()) == Some(id) {
|
||||
self.vsock = None;
|
||||
removed = true;
|
||||
}
|
||||
if let Some(vsock) = self.vsock.as_ref()
|
||||
&& vsock.id.as_ref().map(|id| id.as_ref()) == Some(id)
|
||||
{
|
||||
self.vsock = None;
|
||||
removed = true;
|
||||
}
|
||||
|
||||
removed
|
||||
|
|
|
|||
|
|
@ -601,10 +601,10 @@ impl BusDevice for CpuManager {
|
|||
state.removing = false;
|
||||
}
|
||||
// Trigger removal of vCPU
|
||||
if data[0] & (1 << CPU_EJECT_FLAG) == 1 << CPU_EJECT_FLAG {
|
||||
if let Err(e) = self.remove_vcpu(self.selected_cpu as u32) {
|
||||
error!("Error removing vCPU: {:?}", e);
|
||||
}
|
||||
if data[0] & (1 << CPU_EJECT_FLAG) == 1 << CPU_EJECT_FLAG
|
||||
&& let Err(e) = self.remove_vcpu(self.selected_cpu as u32)
|
||||
{
|
||||
error!("Error removing vCPU: {:?}", e);
|
||||
}
|
||||
} else {
|
||||
warn!("Out of range vCPU id: {}", self.selected_cpu);
|
||||
|
|
@ -1059,14 +1059,13 @@ impl CpuManager {
|
|||
}
|
||||
|
||||
// Apply seccomp filter for vcpu thread.
|
||||
if !vcpu_seccomp_filter.is_empty() {
|
||||
if let Err(e) =
|
||||
if !vcpu_seccomp_filter.is_empty() && let Err(e) =
|
||||
apply_filter(&vcpu_seccomp_filter).map_err(Error::ApplySeccompFilter)
|
||||
{
|
||||
error!("Error applying seccomp filter: {:?}", e);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
extern "C" fn handle_signal(_: i32, _: *mut siginfo_t, _: *mut c_void) {}
|
||||
// This uses an async signal safe handler to kill the vcpu handles.
|
||||
register_signal_handler(SIGRTMIN(), handle_signal)
|
||||
|
|
|
|||
|
|
@ -772,12 +772,13 @@ impl DeviceRelocation for AddressManager {
|
|||
if let Some(node) = self.device_tree.lock().unwrap().get_mut(&id) {
|
||||
let mut resource_updated = false;
|
||||
for resource in node.resources.iter_mut() {
|
||||
if let Resource::PciBar { base, type_, .. } = resource {
|
||||
if PciBarRegionType::from(*type_) == region_type && *base == old_base {
|
||||
*base = new_base;
|
||||
resource_updated = true;
|
||||
break;
|
||||
}
|
||||
if let Resource::PciBar { base, type_, .. } = resource
|
||||
&& PciBarRegionType::from(*type_) == region_type
|
||||
&& *base == old_base
|
||||
{
|
||||
*base = new_base;
|
||||
resource_updated = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -814,43 +815,41 @@ impl DeviceRelocation for AddressManager {
|
|||
} else {
|
||||
let virtio_dev = virtio_pci_dev.virtio_device();
|
||||
let mut virtio_dev = virtio_dev.lock().unwrap();
|
||||
if let Some(mut shm_regions) = virtio_dev.get_shm_regions() {
|
||||
if shm_regions.addr.raw_value() == old_base {
|
||||
let mem_region = self.vm.make_user_memory_region(
|
||||
shm_regions.mem_slot,
|
||||
old_base,
|
||||
shm_regions.len,
|
||||
shm_regions.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
if let Some(mut shm_regions) = virtio_dev.get_shm_regions()
|
||||
&& shm_regions.addr.raw_value() == old_base
|
||||
{
|
||||
let mem_region = self.vm.make_user_memory_region(
|
||||
shm_regions.mem_slot,
|
||||
old_base,
|
||||
shm_regions.len,
|
||||
shm_regions.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
self.vm.remove_user_memory_region(mem_region).map_err(|e| {
|
||||
io::Error::other(format!("failed to remove user memory region: {e:?}"))
|
||||
})?;
|
||||
self.vm.remove_user_memory_region(mem_region).map_err(|e| {
|
||||
io::Error::other(format!("failed to remove user memory region: {e:?}"))
|
||||
})?;
|
||||
|
||||
// Create new mapping by inserting new region to KVM.
|
||||
let mem_region = self.vm.make_user_memory_region(
|
||||
shm_regions.mem_slot,
|
||||
new_base,
|
||||
shm_regions.len,
|
||||
shm_regions.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
// Create new mapping by inserting new region to KVM.
|
||||
let mem_region = self.vm.make_user_memory_region(
|
||||
shm_regions.mem_slot,
|
||||
new_base,
|
||||
shm_regions.len,
|
||||
shm_regions.host_addr,
|
||||
false,
|
||||
false,
|
||||
);
|
||||
|
||||
self.vm.create_user_memory_region(mem_region).map_err(|e| {
|
||||
io::Error::other(format!("failed to create user memory regions: {e:?}"))
|
||||
})?;
|
||||
self.vm.create_user_memory_region(mem_region).map_err(|e| {
|
||||
io::Error::other(format!("failed to create user memory regions: {e:?}"))
|
||||
})?;
|
||||
|
||||
// Update shared memory regions to reflect the new mapping.
|
||||
shm_regions.addr = GuestAddress(new_base);
|
||||
virtio_dev.set_shm_regions(shm_regions).map_err(|e| {
|
||||
io::Error::other(format!(
|
||||
"failed to update shared memory regions: {e:?}"
|
||||
))
|
||||
})?;
|
||||
}
|
||||
// Update shared memory regions to reflect the new mapping.
|
||||
shm_regions.addr = GuestAddress(new_base);
|
||||
virtio_dev.set_shm_regions(shm_regions).map_err(|e| {
|
||||
io::Error::other(format!("failed to update shared memory regions: {e:?}"))
|
||||
})?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -1655,14 +1654,14 @@ impl DeviceManager {
|
|||
iommu_attached_devices.append(&mut vfio_user_iommu_device_ids);
|
||||
|
||||
// Add all devices from forced iommu segments
|
||||
if let Some(platform_config) = self.config.lock().unwrap().platform.as_ref() {
|
||||
if let Some(iommu_segments) = platform_config.iommu_segments.as_ref() {
|
||||
for segment in iommu_segments {
|
||||
for device in 0..32 {
|
||||
let bdf = PciBdf::new(*segment, 0, device, 0);
|
||||
if !iommu_attached_devices.contains(&bdf) {
|
||||
iommu_attached_devices.push(bdf);
|
||||
}
|
||||
if let Some(platform_config) = self.config.lock().unwrap().platform.as_ref()
|
||||
&& let Some(iommu_segments) = platform_config.iommu_segments.as_ref()
|
||||
{
|
||||
for segment in iommu_segments {
|
||||
for device in 0..32 {
|
||||
let bdf = PciBdf::new(*segment, 0, device, 0);
|
||||
if !iommu_attached_devices.contains(&bdf) {
|
||||
iommu_attached_devices.push(bdf);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -4350,14 +4349,14 @@ impl DeviceManager {
|
|||
.add_memory_region(new_region)
|
||||
.map_err(DeviceManagerError::UpdateMemoryForVirtioDevice)?;
|
||||
|
||||
if let Some(dma_handler) = &handle.dma_handler {
|
||||
if !handle.iommu {
|
||||
let gpa = new_region.start_addr().0;
|
||||
let size = new_region.len();
|
||||
dma_handler
|
||||
.map(gpa, gpa, size)
|
||||
.map_err(DeviceManagerError::VirtioDmaMap)?;
|
||||
}
|
||||
if let Some(dma_handler) = &handle.dma_handler
|
||||
&& !handle.iommu
|
||||
{
|
||||
let gpa = new_region.start_addr().0;
|
||||
let size = new_region.len();
|
||||
dma_handler
|
||||
.map(gpa, gpa, size)
|
||||
.map_err(DeviceManagerError::VirtioDmaMap)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -4576,10 +4575,10 @@ impl DeviceManager {
|
|||
};
|
||||
|
||||
let mut iommu_attached = false;
|
||||
if let Some((_, iommu_attached_devices)) = &self.iommu_attached_devices {
|
||||
if iommu_attached_devices.contains(&pci_device_bdf) {
|
||||
iommu_attached = true;
|
||||
}
|
||||
if let Some((_, iommu_attached_devices)) = &self.iommu_attached_devices
|
||||
&& iommu_attached_devices.contains(&pci_device_bdf)
|
||||
{
|
||||
iommu_attached = true;
|
||||
}
|
||||
|
||||
let (pci_device, bus_device, virtio_device, remove_dma_handler) = match pci_device_handle {
|
||||
|
|
@ -4610,16 +4609,16 @@ impl DeviceManager {
|
|||
.map_err(|e| DeviceManagerError::UnRegisterIoevent(e.into()))?;
|
||||
}
|
||||
|
||||
if let Some(dma_handler) = dev.dma_handler() {
|
||||
if !iommu_attached {
|
||||
for (_, zone) in self.memory_manager.lock().unwrap().memory_zones().iter() {
|
||||
for region in zone.regions() {
|
||||
let iova = region.start_addr().0;
|
||||
let size = region.len();
|
||||
dma_handler
|
||||
.unmap(iova, size)
|
||||
.map_err(DeviceManagerError::VirtioDmaUnmap)?;
|
||||
}
|
||||
if let Some(dma_handler) = dev.dma_handler()
|
||||
&& !iommu_attached
|
||||
{
|
||||
for (_, zone) in self.memory_manager.lock().unwrap().memory_zones().iter() {
|
||||
for region in zone.regions() {
|
||||
let iova = region.start_addr().0;
|
||||
let size = region.len();
|
||||
dma_handler
|
||||
.unmap(iova, size)
|
||||
.map_err(DeviceManagerError::VirtioDmaUnmap)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -428,11 +428,11 @@ pub fn load_igvm(
|
|||
let gpas_grouped = gpas
|
||||
.iter()
|
||||
.fold(Vec::<Vec<GpaPages>>::new(), |mut acc, gpa| {
|
||||
if let Some(last_vec) = acc.last_mut() {
|
||||
if last_vec[0].page_type == gpa.page_type {
|
||||
last_vec.push(*gpa);
|
||||
return acc;
|
||||
}
|
||||
if let Some(last_vec) = acc.last_mut()
|
||||
&& last_vec[0].page_type == gpa.page_type
|
||||
{
|
||||
last_vec.push(*gpa);
|
||||
return acc;
|
||||
}
|
||||
acc.push(vec![*gpa]);
|
||||
acc
|
||||
|
|
|
|||
|
|
@ -729,15 +729,14 @@ impl Vmm {
|
|||
thread::Builder::new()
|
||||
.name("vmm_signal_handler".to_string())
|
||||
.spawn(move || {
|
||||
if !signal_handler_seccomp_filter.is_empty() {
|
||||
if let Err(e) = apply_filter(&signal_handler_seccomp_filter)
|
||||
if !signal_handler_seccomp_filter.is_empty() && let Err(e) = apply_filter(&signal_handler_seccomp_filter)
|
||||
.map_err(Error::ApplySeccompFilter)
|
||||
{
|
||||
error!("Error applying seccomp filter: {:?}", e);
|
||||
exit_evt.write(1).ok();
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if landlock_enable{
|
||||
match Landlock::new() {
|
||||
Ok(landlock) => {
|
||||
|
|
@ -1834,10 +1833,10 @@ impl RequestHandler for Vmm {
|
|||
if let Some(desired_ram) = desired_ram {
|
||||
config.memory.size = desired_ram;
|
||||
}
|
||||
if let Some(desired_balloon) = desired_balloon {
|
||||
if let Some(balloon_config) = &mut config.balloon {
|
||||
balloon_config.size = desired_balloon;
|
||||
}
|
||||
if let Some(desired_balloon) = desired_balloon
|
||||
&& let Some(balloon_config) = &mut config.balloon
|
||||
{
|
||||
balloon_config.size = desired_balloon;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
|
|
@ -2306,16 +2305,16 @@ impl RequestHandler for Vmm {
|
|||
error!("Migration failed: {:?}", migration_err);
|
||||
|
||||
// Stop logging dirty pages only for non-local migrations
|
||||
if !send_data_migration.local {
|
||||
if let Err(e) = vm.stop_dirty_log() {
|
||||
return e;
|
||||
}
|
||||
if !send_data_migration.local
|
||||
&& let Err(e) = vm.stop_dirty_log()
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
if vm.get_state().unwrap() == VmState::Paused {
|
||||
if let Err(e) = vm.resume() {
|
||||
return e;
|
||||
}
|
||||
if vm.get_state().unwrap() == VmState::Paused
|
||||
&& let Err(e) = vm.resume()
|
||||
{
|
||||
return e;
|
||||
}
|
||||
|
||||
migration_err
|
||||
|
|
|
|||
|
|
@ -1959,23 +1959,21 @@ impl MemoryManager {
|
|||
}
|
||||
|
||||
for region in memory_zone.regions() {
|
||||
if snapshot {
|
||||
if let Some(file_offset) = region.file_offset() {
|
||||
if (region.flags() & libc::MAP_SHARED == libc::MAP_SHARED)
|
||||
&& Self::is_hardlink(file_offset.file())
|
||||
{
|
||||
// In this very specific case, we know the memory
|
||||
// region is backed by a file on the host filesystem
|
||||
// that can be accessed by the user, and additionally
|
||||
// the mapping is shared, which means that modifications
|
||||
// to the content are written to the actual file.
|
||||
// When meeting these conditions, we can skip the
|
||||
// copy of the memory content for this specific region,
|
||||
// as we can assume the user will have it saved through
|
||||
// the backing file already.
|
||||
continue;
|
||||
}
|
||||
}
|
||||
if snapshot
|
||||
&& let Some(file_offset) = region.file_offset()
|
||||
&& (region.flags() & libc::MAP_SHARED == libc::MAP_SHARED)
|
||||
&& Self::is_hardlink(file_offset.file())
|
||||
{
|
||||
// In this very specific case, we know the memory
|
||||
// region is backed by a file on the host filesystem
|
||||
// that can be accessed by the user, and additionally
|
||||
// the mapping is shared, which means that modifications
|
||||
// to the content are written to the actual file.
|
||||
// When meeting these conditions, we can skip the
|
||||
// copy of the memory content for this specific region,
|
||||
// as we can assume the user will have it saved through
|
||||
// the backing file already.
|
||||
continue;
|
||||
}
|
||||
|
||||
table.push(MemoryRange {
|
||||
|
|
|
|||
|
|
@ -432,12 +432,12 @@ impl Drop for SerialManager {
|
|||
if let Some(handle) = self.handle.take() {
|
||||
handle.join().ok();
|
||||
}
|
||||
if let ConsoleOutput::Socket(_) = self.in_file {
|
||||
if let Some(socket_path) = self.socket_path.as_ref() {
|
||||
std::fs::remove_file(socket_path.as_os_str())
|
||||
.map_err(Error::RemoveUnixSocket)
|
||||
.ok();
|
||||
}
|
||||
if let ConsoleOutput::Socket(_) = self.in_file
|
||||
&& let Some(socket_path) = self.socket_path.as_ref()
|
||||
{
|
||||
std::fs::remove_file(socket_path.as_os_str())
|
||||
.map_err(Error::RemoveUnixSocket)
|
||||
.ok();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -3123,12 +3123,12 @@ impl GuestDebuggable for Vm {
|
|||
|
||||
#[cfg(feature = "tdx")]
|
||||
{
|
||||
if let Some(ref platform) = self.config.lock().unwrap().platform {
|
||||
if platform.tdx {
|
||||
return Err(GuestDebuggableError::Coredump(anyhow!(
|
||||
"Coredump not possible with TDX VM"
|
||||
)));
|
||||
}
|
||||
if let Some(ref platform) = self.config.lock().unwrap().platform
|
||||
&& platform.tdx
|
||||
{
|
||||
return Err(GuestDebuggableError::Coredump(anyhow!(
|
||||
"Coredump not possible with TDX VM"
|
||||
)));
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue