From 92c2101f7cdb2efabffc69689001c5960a97e968 Mon Sep 17 00:00:00 2001 From: Sebastien Boeuf Date: Fri, 21 May 2021 18:26:00 +0200 Subject: [PATCH] virtio-devices: vhost_user: Enable most virtio reserved features A lot of the VIRTIO reserved features should be supported or not by the vhost-user backend. That means on the VMM side, these features should be available, so that they don't get lost during the negotiation. Signed-off-by: Sebastien Boeuf --- Cargo.lock | 1 + virtio-devices/src/lib.rs | 7 +++++ virtio-devices/src/vhost_user/blk.rs | 24 ++++++++++------ virtio-devices/src/vhost_user/fs.rs | 12 ++------ virtio-devices/src/vhost_user/mod.rs | 14 +++++++++ virtio-devices/src/vhost_user/net.rs | 43 ++++++++++++++-------------- 6 files changed, 63 insertions(+), 38 deletions(-) diff --git a/Cargo.lock b/Cargo.lock index d7c3ac065..bd735c248 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -241,6 +241,7 @@ version = "0.1.0" dependencies = [ "acpi_tables", "anyhow", + "arch", "bitflags", "byteorder", "epoll", diff --git a/virtio-devices/src/lib.rs b/virtio-devices/src/lib.rs index bdac027df..cf6b74247 100644 --- a/virtio-devices/src/lib.rs +++ b/virtio-devices/src/lib.rs @@ -59,9 +59,16 @@ const DEVICE_DRIVER_OK: u32 = 0x04; const DEVICE_FEATURES_OK: u32 = 0x08; const DEVICE_FAILED: u32 = 0x80; +const VIRTIO_F_RING_INDIRECT_DESC: u32 = 28; +const VIRTIO_F_RING_EVENT_IDX: u32 = 29; const VIRTIO_F_VERSION_1: u32 = 32; const VIRTIO_F_IOMMU_PLATFORM: u32 = 33; +const VIRTIO_F_RING_PACKED: u32 = 34; const VIRTIO_F_IN_ORDER: u32 = 35; +const VIRTIO_F_ORDER_PLATFORM: u32 = 36; +#[allow(dead_code)] +const VIRTIO_F_SR_IOV: u32 = 37; +const VIRTIO_F_NOTIFICATION_DATA: u32 = 38; #[derive(Debug)] pub enum ActivateError { diff --git a/virtio-devices/src/vhost_user/blk.rs b/virtio-devices/src/vhost_user/blk.rs index ba0779c49..6ddcb41b8 100644 --- a/virtio-devices/src/vhost_user/blk.rs +++ b/virtio-devices/src/vhost_user/blk.rs @@ -4,8 +4,11 @@ use super::super::{ ActivateError, ActivateResult, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType, }; -use super::vu_common_ctrl::*; -use super::{Error, Result}; +use super::vu_common_ctrl::{ + add_memory_region, negotiate_features_vhost_user, reset_vhost_user, setup_vhost_user, + update_mem_table, VhostUserConfig, +}; +use super::{Error, Result, DEFAULT_VIRTIO_FEATURES}; use crate::VirtioInterrupt; use block_util::VirtioBlockConfig; use std::mem; @@ -19,8 +22,11 @@ use vhost::vhost_user::message::VHOST_USER_CONFIG_OFFSET; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; use vhost::VhostBackend; -use virtio_bindings::bindings::virtio_blk::*; -use virtio_bindings::bindings::virtio_ring::VIRTIO_RING_F_EVENT_IDX; +use virtio_bindings::bindings::virtio_blk::{ + VIRTIO_BLK_F_BLK_SIZE, VIRTIO_BLK_F_CONFIG_WCE, VIRTIO_BLK_F_DISCARD, VIRTIO_BLK_F_FLUSH, + VIRTIO_BLK_F_GEOMETRY, VIRTIO_BLK_F_MQ, VIRTIO_BLK_F_RO, VIRTIO_BLK_F_SEG_MAX, + VIRTIO_BLK_F_SIZE_MAX, VIRTIO_BLK_F_TOPOLOGY, VIRTIO_BLK_F_WRITE_ZEROES, +}; use vm_memory::{ ByteValued, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap, GuestRegionMmap, }; @@ -50,15 +56,17 @@ impl Blk { .map_err(Error::VhostUserCreateMaster)?; // Filling device and vring features VMM supports. - let mut avail_features = 1 << VIRTIO_BLK_F_SEG_MAX + let mut avail_features = 1 << VIRTIO_BLK_F_SIZE_MAX + | 1 << VIRTIO_BLK_F_SEG_MAX + | 1 << VIRTIO_BLK_F_GEOMETRY | 1 << VIRTIO_BLK_F_RO | 1 << VIRTIO_BLK_F_BLK_SIZE | 1 << VIRTIO_BLK_F_FLUSH | 1 << VIRTIO_BLK_F_TOPOLOGY - | 1 << VIRTIO_RING_F_EVENT_IDX | 1 << VIRTIO_BLK_F_CONFIG_WCE - | 1 << VIRTIO_F_VERSION_1 - | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits(); + | 1 << VIRTIO_BLK_F_DISCARD + | 1 << VIRTIO_BLK_F_WRITE_ZEROES + | DEFAULT_VIRTIO_FEATURES; if num_queues > 1 { avail_features |= 1 << VIRTIO_BLK_F_MQ; diff --git a/virtio-devices/src/vhost_user/fs.rs b/virtio-devices/src/vhost_user/fs.rs index 8d37b1f5a..c15b21d3e 100644 --- a/virtio-devices/src/vhost_user/fs.rs +++ b/virtio-devices/src/vhost_user/fs.rs @@ -5,12 +5,12 @@ use super::vu_common_ctrl::{ add_memory_region, negotiate_features_vhost_user, reset_vhost_user, setup_vhost_user, update_mem_table, }; -use super::{Error, Result}; +use super::{Error, Result, DEFAULT_VIRTIO_FEATURES}; use crate::seccomp_filters::{get_seccomp_filter, Thread}; use crate::vhost_user::handler::{VhostUserEpollConfig, VhostUserEpollHandler}; use crate::{ ActivateError, ActivateResult, Queue, UserspaceMapping, VirtioCommon, VirtioDevice, - VirtioDeviceType, VirtioInterrupt, VirtioSharedMemoryList, VIRTIO_F_VERSION_1, + VirtioDeviceType, VirtioInterrupt, VirtioSharedMemoryList, }; use libc::{self, c_void, off64_t, pread64, pwrite64}; use seccomp::{SeccompAction, SeccompFilter}; @@ -27,9 +27,6 @@ use vhost::vhost_user::message::{ use vhost::vhost_user::{ HandlerResult, Master, MasterReqHandler, VhostUserMaster, VhostUserMasterReqHandler, }; -use virtio_bindings::bindings::virtio_ring::{ - VIRTIO_RING_F_EVENT_IDX, VIRTIO_RING_F_INDIRECT_DESC, -}; use vm_memory::{ Address, ByteValued, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryMmap, GuestRegionMmap, MmapRegion, @@ -307,10 +304,7 @@ impl Fs { Master::connect(path, num_queues as u64).map_err(Error::VhostUserCreateMaster)?; // Filling device and vring features VMM supports. - let avail_features = 1 << VIRTIO_F_VERSION_1 - | 1 << VIRTIO_RING_F_EVENT_IDX - | 1 << VIRTIO_RING_F_INDIRECT_DESC - | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits(); + let avail_features = DEFAULT_VIRTIO_FEATURES; let mut avail_protocol_features = VhostUserProtocolFeatures::MQ | VhostUserProtocolFeatures::CONFIGURE_MEM_SLOTS diff --git a/virtio-devices/src/vhost_user/mod.rs b/virtio-devices/src/vhost_user/mod.rs index 3374f0907..5e65766ba 100644 --- a/virtio-devices/src/vhost_user/mod.rs +++ b/virtio-devices/src/vhost_user/mod.rs @@ -1,7 +1,12 @@ // Copyright 2019 Intel Corporation. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 +use crate::{ + VIRTIO_F_IN_ORDER, VIRTIO_F_NOTIFICATION_DATA, VIRTIO_F_ORDER_PLATFORM, + VIRTIO_F_RING_EVENT_IDX, VIRTIO_F_RING_INDIRECT_DESC, VIRTIO_F_RING_PACKED, VIRTIO_F_VERSION_1, +}; use std::io; +use vhost::vhost_user::message::VhostUserVirtioFeatures; use vhost::Error as VhostError; use vm_memory::Error as MmapError; @@ -98,3 +103,12 @@ pub enum Error { MissingIrqFd, } type Result = std::result::Result; + +pub const DEFAULT_VIRTIO_FEATURES: u64 = 1 << VIRTIO_F_RING_INDIRECT_DESC + | 1 << VIRTIO_F_RING_EVENT_IDX + | 1 << VIRTIO_F_VERSION_1 + | 1 << VIRTIO_F_RING_PACKED + | 1 << VIRTIO_F_IN_ORDER + | 1 << VIRTIO_F_ORDER_PLATFORM + | 1 << VIRTIO_F_NOTIFICATION_DATA + | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits(); diff --git a/virtio-devices/src/vhost_user/net.rs b/virtio-devices/src/vhost_user/net.rs index 45f896f2d..98b5bdc07 100644 --- a/virtio-devices/src/vhost_user/net.rs +++ b/virtio-devices/src/vhost_user/net.rs @@ -5,7 +5,7 @@ use super::super::{ ActivateError, ActivateResult, Queue, VirtioCommon, VirtioDevice, VirtioDeviceType, }; use super::vu_common_ctrl::*; -use super::{Error, Result}; +use super::{Error, Result, DEFAULT_VIRTIO_FEATURES}; use crate::VirtioInterrupt; use net_util::{build_net_config_space, MacAddr, VirtioNetConfig}; use std::ops::Deref; @@ -17,8 +17,12 @@ use std::vec::Vec; use vhost::vhost_user::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures}; use vhost::vhost_user::{Master, VhostUserMaster, VhostUserMasterReqHandler}; use vhost::VhostBackend; -use virtio_bindings::bindings::virtio_net; -use virtio_bindings::bindings::virtio_ring; +use virtio_bindings::bindings::virtio_net::{ + VIRTIO_NET_F_CSUM, VIRTIO_NET_F_CTRL_VQ, VIRTIO_NET_F_GUEST_CSUM, VIRTIO_NET_F_GUEST_ECN, + VIRTIO_NET_F_GUEST_TSO4, VIRTIO_NET_F_GUEST_TSO6, VIRTIO_NET_F_GUEST_UFO, + VIRTIO_NET_F_HOST_ECN, VIRTIO_NET_F_HOST_TSO4, VIRTIO_NET_F_HOST_TSO6, VIRTIO_NET_F_HOST_UFO, + VIRTIO_NET_F_MRG_RXBUF, +}; use vm_memory::{ ByteValued, GuestAddressSpace, GuestMemoryAtomic, GuestMemoryMmap, GuestRegionMmap, }; @@ -53,22 +57,19 @@ impl Net { let mut num_queues = vu_cfg.num_queues; // Filling device and vring features VMM supports. - let mut avail_features = 1 << virtio_net::VIRTIO_NET_F_GUEST_CSUM - | 1 << virtio_net::VIRTIO_NET_F_CSUM - | 1 << virtio_net::VIRTIO_NET_F_GUEST_TSO4 - | 1 << virtio_net::VIRTIO_NET_F_GUEST_TSO6 - | 1 << virtio_net::VIRTIO_NET_F_GUEST_ECN - | 1 << virtio_net::VIRTIO_NET_F_GUEST_UFO - | 1 << virtio_net::VIRTIO_NET_F_HOST_TSO4 - | 1 << virtio_net::VIRTIO_NET_F_HOST_TSO6 - | 1 << virtio_net::VIRTIO_NET_F_HOST_ECN - | 1 << virtio_net::VIRTIO_NET_F_HOST_UFO - | 1 << virtio_net::VIRTIO_NET_F_MRG_RXBUF - | 1 << virtio_net::VIRTIO_NET_F_CTRL_VQ - | 1 << virtio_net::VIRTIO_F_NOTIFY_ON_EMPTY - | 1 << virtio_net::VIRTIO_F_VERSION_1 - | 1 << virtio_ring::VIRTIO_RING_F_EVENT_IDX - | VhostUserVirtioFeatures::PROTOCOL_FEATURES.bits(); + let mut avail_features = 1 << VIRTIO_NET_F_CSUM + | 1 << VIRTIO_NET_F_GUEST_CSUM + | 1 << VIRTIO_NET_F_GUEST_TSO4 + | 1 << VIRTIO_NET_F_GUEST_TSO6 + | 1 << VIRTIO_NET_F_GUEST_ECN + | 1 << VIRTIO_NET_F_GUEST_UFO + | 1 << VIRTIO_NET_F_HOST_TSO4 + | 1 << VIRTIO_NET_F_HOST_TSO6 + | 1 << VIRTIO_NET_F_HOST_ECN + | 1 << VIRTIO_NET_F_HOST_UFO + | 1 << VIRTIO_NET_F_MRG_RXBUF + | 1 << VIRTIO_NET_F_CTRL_VQ + | DEFAULT_VIRTIO_FEATURES; let mut config = VirtioNetConfig::default(); build_net_config_space(&mut config, mac_addr, num_queues, &mut avail_features); @@ -102,7 +103,7 @@ impl Net { // If the control queue feature has not been negotiated, let's decrease // the number of queues. - if acked_features & (1 << virtio_net::VIRTIO_NET_F_CTRL_VQ) == 0 { + if acked_features & (1 << VIRTIO_NET_F_CTRL_VQ) == 0 { num_queues -= 1; } @@ -111,7 +112,7 @@ impl Net { vhost_user_net .get_queue_num() .map_err(Error::VhostUserGetQueueMaxNum)? as usize - } else if acked_features & (1 << virtio_net::VIRTIO_NET_F_CTRL_VQ) != 0 { + } else if acked_features & (1 << VIRTIO_NET_F_CTRL_VQ) != 0 { DEFAULT_QUEUE_NUMBER + 1 } else { DEFAULT_QUEUE_NUMBER