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 <sebastien.boeuf@intel.com>
This commit is contained in:
Sebastien Boeuf 2021-05-21 18:26:00 +02:00
parent ff46fb69d0
commit 92c2101f7c
6 changed files with 63 additions and 38 deletions

1
Cargo.lock generated
View File

@ -241,6 +241,7 @@ version = "0.1.0"
dependencies = [
"acpi_tables",
"anyhow",
"arch",
"bitflags",
"byteorder",
"epoll",

View File

@ -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 {

View File

@ -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;

View File

@ -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

View File

@ -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<T> = std::result::Result<T, Error>;
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();

View File

@ -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