2019-04-18 17:24:06 +00:00
|
|
|
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
|
|
|
//
|
|
|
|
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
|
|
|
// Use of this source code is governed by a BSD-style license that can be
|
2019-05-08 10:22:53 +00:00
|
|
|
// found in the LICENSE-BSD-3-Clause file.
|
|
|
|
//
|
|
|
|
// Copyright © 2019 Intel Corporation
|
|
|
|
//
|
|
|
|
// SPDX-License-Identifier: Apache-2.0 AND BSD-3-Clause
|
2019-04-18 17:24:06 +00:00
|
|
|
|
|
|
|
//! Implements virtio devices, queues, and transport mechanisms.
|
2019-12-31 10:49:11 +00:00
|
|
|
|
|
|
|
extern crate arc_swap;
|
2019-04-18 17:24:06 +00:00
|
|
|
extern crate epoll;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate log;
|
2019-09-11 16:07:33 +00:00
|
|
|
#[cfg(feature = "pci_support")]
|
2019-04-18 17:24:06 +00:00
|
|
|
extern crate pci;
|
2020-04-08 01:53:12 +00:00
|
|
|
extern crate serde;
|
|
|
|
#[macro_use]
|
|
|
|
extern crate serde_derive;
|
|
|
|
extern crate serde_json;
|
2019-08-28 09:50:48 +00:00
|
|
|
extern crate vhost_rs;
|
2019-04-18 17:24:06 +00:00
|
|
|
extern crate virtio_bindings;
|
2019-11-19 00:42:31 +00:00
|
|
|
extern crate vm_device;
|
2019-04-18 17:24:06 +00:00
|
|
|
extern crate vm_memory;
|
|
|
|
|
|
|
|
use std::fmt;
|
|
|
|
use std::io;
|
|
|
|
|
2019-11-19 00:42:31 +00:00
|
|
|
#[macro_use]
|
|
|
|
mod device;
|
2019-10-24 05:30:44 +00:00
|
|
|
pub mod block;
|
2019-07-22 18:50:56 +00:00
|
|
|
mod console;
|
2019-09-17 18:40:14 +00:00
|
|
|
mod iommu;
|
2020-03-04 02:12:22 +00:00
|
|
|
pub mod mem;
|
2019-05-08 00:26:37 +00:00
|
|
|
pub mod net;
|
2020-01-09 11:54:40 +00:00
|
|
|
pub mod net_util;
|
2019-06-18 21:40:57 +00:00
|
|
|
mod pmem;
|
2020-02-21 10:34:51 +00:00
|
|
|
pub mod queue;
|
2019-05-09 05:01:48 +00:00
|
|
|
mod rng;
|
2019-09-04 21:19:16 +00:00
|
|
|
pub mod vsock;
|
2019-04-18 17:24:06 +00:00
|
|
|
|
2019-04-18 17:32:41 +00:00
|
|
|
pub mod transport;
|
2019-08-28 09:50:48 +00:00
|
|
|
pub mod vhost_user;
|
2019-04-18 17:32:41 +00:00
|
|
|
|
2019-05-06 17:27:40 +00:00
|
|
|
pub use self::block::*;
|
2019-07-22 18:50:56 +00:00
|
|
|
pub use self::console::*;
|
2019-04-18 17:24:06 +00:00
|
|
|
pub use self::device::*;
|
2019-09-17 18:40:14 +00:00
|
|
|
pub use self::iommu::*;
|
2020-03-04 02:12:22 +00:00
|
|
|
pub use self::mem::*;
|
2019-05-08 00:26:37 +00:00
|
|
|
pub use self::net::*;
|
2020-01-09 11:54:40 +00:00
|
|
|
pub use self::net_util::*;
|
2019-06-18 21:40:57 +00:00
|
|
|
pub use self::pmem::*;
|
2019-04-18 17:24:06 +00:00
|
|
|
pub use self::queue::*;
|
2019-05-09 05:01:48 +00:00
|
|
|
pub use self::rng::*;
|
2019-09-03 22:12:58 +00:00
|
|
|
pub use self::vsock::*;
|
2019-04-18 17:24:06 +00:00
|
|
|
|
|
|
|
const DEVICE_INIT: u32 = 0x00;
|
|
|
|
const DEVICE_ACKNOWLEDGE: u32 = 0x01;
|
|
|
|
const DEVICE_DRIVER: u32 = 0x02;
|
|
|
|
const DEVICE_DRIVER_OK: u32 = 0x04;
|
|
|
|
const DEVICE_FEATURES_OK: u32 = 0x08;
|
|
|
|
const DEVICE_FAILED: u32 = 0x80;
|
|
|
|
|
|
|
|
const VIRTIO_F_VERSION_1: u32 = 32;
|
2019-10-04 17:32:26 +00:00
|
|
|
const VIRTIO_F_IOMMU_PLATFORM: u32 = 33;
|
2019-09-04 21:19:16 +00:00
|
|
|
const VIRTIO_F_IN_ORDER: u32 = 35;
|
2019-04-18 17:24:06 +00:00
|
|
|
|
|
|
|
// Types taken from linux/virtio_ids.h
|
2020-01-09 17:29:00 +00:00
|
|
|
#[derive(Copy, Clone)]
|
2019-04-18 17:24:06 +00:00
|
|
|
#[allow(dead_code)]
|
|
|
|
#[allow(non_camel_case_types)]
|
|
|
|
#[repr(C)]
|
|
|
|
enum VirtioDeviceType {
|
|
|
|
TYPE_NET = 1,
|
|
|
|
TYPE_BLOCK = 2,
|
2019-07-22 18:50:56 +00:00
|
|
|
TYPE_CONSOLE = 3,
|
2019-04-18 17:24:06 +00:00
|
|
|
TYPE_RNG = 4,
|
|
|
|
TYPE_BALLOON = 5,
|
|
|
|
TYPE_9P = 9,
|
|
|
|
TYPE_GPU = 16,
|
|
|
|
TYPE_INPUT = 18,
|
|
|
|
TYPE_VSOCK = 19,
|
2019-09-17 18:40:14 +00:00
|
|
|
TYPE_IOMMU = 23,
|
2020-03-04 02:12:22 +00:00
|
|
|
TYPE_MEM = 24,
|
2019-05-21 18:54:53 +00:00
|
|
|
TYPE_FS = 26,
|
2019-06-18 21:40:57 +00:00
|
|
|
TYPE_PMEM = 27,
|
2019-07-02 15:11:09 +00:00
|
|
|
TYPE_UNKNOWN = 0xFF,
|
|
|
|
}
|
|
|
|
|
|
|
|
impl From<u32> for VirtioDeviceType {
|
|
|
|
fn from(t: u32) -> Self {
|
|
|
|
match t {
|
|
|
|
1 => VirtioDeviceType::TYPE_NET,
|
|
|
|
2 => VirtioDeviceType::TYPE_BLOCK,
|
2020-01-09 13:50:15 +00:00
|
|
|
3 => VirtioDeviceType::TYPE_CONSOLE,
|
2019-07-02 15:11:09 +00:00
|
|
|
4 => VirtioDeviceType::TYPE_RNG,
|
|
|
|
5 => VirtioDeviceType::TYPE_BALLOON,
|
|
|
|
9 => VirtioDeviceType::TYPE_9P,
|
|
|
|
16 => VirtioDeviceType::TYPE_GPU,
|
|
|
|
18 => VirtioDeviceType::TYPE_INPUT,
|
|
|
|
19 => VirtioDeviceType::TYPE_VSOCK,
|
2019-09-17 18:40:14 +00:00
|
|
|
23 => VirtioDeviceType::TYPE_IOMMU,
|
2020-03-04 02:12:22 +00:00
|
|
|
24 => VirtioDeviceType::TYPE_MEM,
|
2019-07-02 15:11:09 +00:00
|
|
|
26 => VirtioDeviceType::TYPE_FS,
|
|
|
|
27 => VirtioDeviceType::TYPE_PMEM,
|
|
|
|
_ => VirtioDeviceType::TYPE_UNKNOWN,
|
|
|
|
}
|
|
|
|
}
|
2019-04-18 17:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// In order to use the `{}` marker, the trait `fmt::Display` must be implemented
|
|
|
|
// manually for the type VirtioDeviceType.
|
|
|
|
impl fmt::Display for VirtioDeviceType {
|
|
|
|
// This trait requires `fmt` with this exact signature.
|
|
|
|
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
|
|
|
|
let output = match *self {
|
|
|
|
VirtioDeviceType::TYPE_NET => "net",
|
|
|
|
VirtioDeviceType::TYPE_BLOCK => "block",
|
2020-01-09 13:50:15 +00:00
|
|
|
VirtioDeviceType::TYPE_CONSOLE => "console",
|
2019-04-18 17:24:06 +00:00
|
|
|
VirtioDeviceType::TYPE_RNG => "rng",
|
|
|
|
VirtioDeviceType::TYPE_BALLOON => "balloon",
|
|
|
|
VirtioDeviceType::TYPE_GPU => "gpu",
|
|
|
|
VirtioDeviceType::TYPE_9P => "9p",
|
2020-01-09 13:50:15 +00:00
|
|
|
VirtioDeviceType::TYPE_INPUT => "input",
|
2019-04-18 17:24:06 +00:00
|
|
|
VirtioDeviceType::TYPE_VSOCK => "vsock",
|
2020-01-09 13:50:15 +00:00
|
|
|
VirtioDeviceType::TYPE_IOMMU => "iommu",
|
2020-03-04 02:12:22 +00:00
|
|
|
VirtioDeviceType::TYPE_MEM => "mem",
|
2019-05-21 18:54:53 +00:00
|
|
|
VirtioDeviceType::TYPE_FS => "fs",
|
2019-06-18 21:40:57 +00:00
|
|
|
VirtioDeviceType::TYPE_PMEM => "pmem",
|
2020-01-09 13:50:15 +00:00
|
|
|
VirtioDeviceType::TYPE_UNKNOWN => "UNKNOWN",
|
2019-04-18 17:24:06 +00:00
|
|
|
};
|
|
|
|
write!(f, "{}", output)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
#[allow(dead_code)]
|
|
|
|
const INTERRUPT_STATUS_USED_RING: u32 = 0x1;
|
|
|
|
#[allow(dead_code)]
|
|
|
|
const INTERRUPT_STATUS_CONFIG_CHANGED: u32 = 0x2;
|
2020-01-21 08:32:50 +00:00
|
|
|
#[cfg(feature = "pci_support")]
|
2019-12-11 08:09:16 +00:00
|
|
|
const VIRTIO_MSI_NO_VECTOR: u16 = 0xffff;
|
2019-04-18 17:24:06 +00:00
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum ActivateError {
|
|
|
|
EpollCtl(std::io::Error),
|
|
|
|
BadActivate,
|
2019-08-28 09:50:48 +00:00
|
|
|
/// Queue number is not correct
|
|
|
|
BadQueueNum,
|
|
|
|
/// Failed to clone Kill event
|
|
|
|
CloneKillEventFd,
|
|
|
|
/// Failed to create Vhost-user interrupt eventfd
|
|
|
|
VhostIrqCreate,
|
2019-05-21 18:54:53 +00:00
|
|
|
/// Failed to setup vhost-user daemon.
|
2019-08-30 17:40:33 +00:00
|
|
|
VhostUserSetup(vhost_user::Error),
|
2019-08-28 09:50:48 +00:00
|
|
|
/// Failed to setup vhost-user daemon.
|
|
|
|
VhostUserNetSetup(vhost_user::Error),
|
2019-09-02 11:00:35 +00:00
|
|
|
/// Failed to setup vhost-user daemon.
|
|
|
|
VhostUserBlkSetup(vhost_user::Error),
|
2019-09-19 16:14:55 +00:00
|
|
|
/// Failed to reset vhost-user daemon.
|
|
|
|
VhostUserReset(vhost_user::Error),
|
2019-04-18 17:24:06 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
pub type ActivateResult = std::result::Result<(), ActivateError>;
|
|
|
|
|
|
|
|
pub type DeviceEventT = u16;
|
|
|
|
|
|
|
|
#[derive(Debug)]
|
|
|
|
pub enum Error {
|
|
|
|
FailedReadingQueue {
|
|
|
|
event_type: &'static str,
|
|
|
|
underlying: io::Error,
|
|
|
|
},
|
|
|
|
FailedReadTap,
|
|
|
|
FailedSignalingUsedQueue(io::Error),
|
|
|
|
PayloadExpected,
|
|
|
|
UnknownEvent {
|
|
|
|
device: &'static str,
|
|
|
|
event: DeviceEventT,
|
|
|
|
},
|
|
|
|
IoError(io::Error),
|
2019-05-06 17:27:40 +00:00
|
|
|
EpollCreateFd(io::Error),
|
|
|
|
EpollCtl(io::Error),
|
|
|
|
EpollWait(io::Error),
|
vm-virtio: Implement console size config feature
One of the features of the virtio console device is its size can be
configured and updated. Our first iteration of the console device
implementation is lack of this feature. As a result, it had a
default fixed size which could not be changed. This commit implements
the console config feature and lets us change the console size from
the vmm side.
During the activation of the device, vmm reads the current terminal
size, sets the console configuration accordinly, and lets the driver
know about this configuration by sending an interrupt. Later, if
someone changes the terminal size, the vmm detects the corresponding
event, updates the configuration, and sends interrupt as before. As a
result, the console device driver, in the guest, updates the console
size.
Signed-off-by: A K M Fazla Mehrab <fazla.mehrab.akm@intel.com>
2019-07-23 19:18:20 +00:00
|
|
|
FailedSignalingDriver(io::Error),
|
2020-03-23 10:07:17 +00:00
|
|
|
VhostUserUpdateMemory(vhost_user::Error),
|
2020-03-04 02:12:22 +00:00
|
|
|
EventfdError(io::Error),
|
2020-04-17 17:30:33 +00:00
|
|
|
SetShmRegionsNotSupported,
|
2019-04-18 17:24:06 +00:00
|
|
|
}
|