mirror of
https://chromium.googlesource.com/crosvm/crosvm
synced 2025-02-05 10:10:41 +00:00
Update to the latest pKVM ABI.
This involves two main changes: * Protected VMs must be created with KVM_VM_TYPE_ARM_PROTECTED. * pVM firmware is now loaded by IPA rather than memslot ID. There are also a lot of trivial changes because the ProtectionType enum was moved from the devices crate to the hypervisor crate. BUG=b:209794844 TEST=Will tested manually with patched kernel and dummy firmware Change-Id: I1dd75e20063ca4736f155292ca5f70b94664fdd9 Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/crosvm/+/3330204 Auto-Submit: Andrew Walbran <qwandor@google.com> Tested-by: kokoro <noreply+kokoro@google.com> Reviewed-by: Daniel Verkamp <dverkamp@chromium.org> Commit-Queue: Daniel Verkamp <dverkamp@chromium.org>
This commit is contained in:
parent
7df3a323f7
commit
00f1c9fd46
34 changed files with 171 additions and 134 deletions
|
@ -12,9 +12,10 @@ use base::{Event, MemoryMappingBuilder};
|
|||
use devices::serial_device::{SerialHardware, SerialParameters};
|
||||
use devices::{
|
||||
Bus, BusDeviceObj, BusError, IrqChip, IrqChipAArch64, PciAddress, PciConfigMmio, PciDevice,
|
||||
ProtectionType,
|
||||
};
|
||||
use hypervisor::{DeviceKind, Hypervisor, HypervisorCap, VcpuAArch64, VcpuFeature, VmAArch64};
|
||||
use hypervisor::{
|
||||
DeviceKind, Hypervisor, HypervisorCap, ProtectionType, VcpuAArch64, VcpuFeature, VmAArch64,
|
||||
};
|
||||
use minijail::Minijail;
|
||||
use remain::sorted;
|
||||
use resources::SystemAllocator;
|
||||
|
@ -351,7 +352,7 @@ impl arch::LinuxArch for AArch64 {
|
|||
}
|
||||
|
||||
if components.protected_vm == ProtectionType::Protected {
|
||||
vm.enable_protected_vm(
|
||||
vm.load_protected_vm_firmware(
|
||||
GuestAddress(AARCH64_PROTECTED_VM_FW_START),
|
||||
AARCH64_PROTECTED_VM_FW_MAX_SIZE,
|
||||
)
|
||||
|
|
|
@ -20,10 +20,10 @@ use base::{syslog, AsRawDescriptor, AsRawDescriptors, Event, Tube};
|
|||
use devices::virtio::VirtioDevice;
|
||||
use devices::{
|
||||
Bus, BusDevice, BusDeviceObj, BusError, BusResumeDevice, HotPlugBus, IrqChip, PciAddress,
|
||||
PciDevice, PciDeviceError, PciInterruptPin, PciRoot, ProtectionType, ProxyDevice,
|
||||
SerialHardware, SerialParameters, VfioPlatformDevice,
|
||||
PciDevice, PciDeviceError, PciInterruptPin, PciRoot, ProxyDevice, SerialHardware,
|
||||
SerialParameters, VfioPlatformDevice,
|
||||
};
|
||||
use hypervisor::{IoEventAddress, Vm};
|
||||
use hypervisor::{IoEventAddress, ProtectionType, Vm};
|
||||
use minijail::Minijail;
|
||||
use remain::sorted;
|
||||
use resources::{MmioType, SystemAllocator};
|
||||
|
|
|
@ -7,7 +7,8 @@ use std::sync::Arc;
|
|||
|
||||
use base::Event;
|
||||
use devices::serial_device::{SerialHardware, SerialParameters, SerialType};
|
||||
use devices::{Bus, ProtectionType, ProxyDevice, Serial};
|
||||
use devices::{Bus, ProxyDevice, Serial};
|
||||
use hypervisor::ProtectionType;
|
||||
use minijail::Minijail;
|
||||
use remain::sorted;
|
||||
use sync::Mutex;
|
||||
|
|
|
@ -12,7 +12,7 @@ use std::sync::Arc;
|
|||
use base::Event;
|
||||
use cros_fuzz::fuzz_target;
|
||||
use devices::virtio::{base_features, Block, Interrupt, Queue, VirtioDevice};
|
||||
use devices::ProtectionType;
|
||||
use hypervisor::ProtectionType;
|
||||
use tempfile;
|
||||
use vm_memory::{GuestAddress, GuestMemory};
|
||||
|
||||
|
|
|
@ -180,9 +180,8 @@ impl IrqChip for KvmKernelIrqChip {
|
|||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
|
||||
use hypervisor::kvm::{Kvm, KvmVm};
|
||||
use hypervisor::{MPState, Vm};
|
||||
use hypervisor::{MPState, ProtectionType, Vm};
|
||||
use vm_memory::GuestMemory;
|
||||
|
||||
use crate::irqchip::{IrqChip, KvmKernelIrqChip};
|
||||
|
@ -196,7 +195,8 @@ mod tests {
|
|||
fn create_kvm_kernel_irqchip() {
|
||||
let kvm = Kvm::new().expect("failed to instantiate Kvm");
|
||||
let mem = GuestMemory::new(&[]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, mem).expect("failed to instantiate vm");
|
||||
let vm =
|
||||
KvmVm::new(&kvm, mem, ProtectionType::Unprotected).expect("failed to instantiate vm");
|
||||
|
||||
let mut chip = KvmKernelIrqChip::new(vm.try_clone().expect("failed to clone vm"), 1)
|
||||
.expect("failed to instantiate KvmKernelIrqChip");
|
||||
|
@ -210,7 +210,8 @@ mod tests {
|
|||
fn mp_state() {
|
||||
let kvm = Kvm::new().expect("failed to instantiate Kvm");
|
||||
let mem = GuestMemory::new(&[]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, mem).expect("failed to instantiate vm");
|
||||
let vm =
|
||||
KvmVm::new(&kvm, mem, ProtectionType::Unprotected).expect("failed to instantiate vm");
|
||||
|
||||
let mut chip = KvmKernelIrqChip::new(vm.try_clone().expect("failed to clone vm"), 1)
|
||||
.expect("failed to instantiate KvmKernelIrqChip");
|
||||
|
|
|
@ -723,7 +723,9 @@ mod tests {
|
|||
use hypervisor::kvm::Kvm;
|
||||
use vm_memory::GuestMemory;
|
||||
|
||||
use hypervisor::{IoapicRedirectionTableEntry, PitRWMode, TriggerMode, Vm, VmX86_64};
|
||||
use hypervisor::{
|
||||
IoapicRedirectionTableEntry, PitRWMode, ProtectionType, TriggerMode, Vm, VmX86_64,
|
||||
};
|
||||
|
||||
use super::super::super::tests::*;
|
||||
use crate::IrqChip;
|
||||
|
@ -732,7 +734,8 @@ mod tests {
|
|||
fn get_kernel_chip() -> KvmKernelIrqChip {
|
||||
let kvm = Kvm::new().expect("failed to instantiate Kvm");
|
||||
let mem = GuestMemory::new(&[]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, mem).expect("failed tso instantiate vm");
|
||||
let vm =
|
||||
KvmVm::new(&kvm, mem, ProtectionType::Unprotected).expect("failed tso instantiate vm");
|
||||
|
||||
let mut chip = KvmKernelIrqChip::new(vm.try_clone().expect("failed to clone vm"), 1)
|
||||
.expect("failed to instantiate KvmKernelIrqChip");
|
||||
|
@ -748,7 +751,8 @@ mod tests {
|
|||
fn get_split_chip() -> KvmSplitIrqChip {
|
||||
let kvm = Kvm::new().expect("failed to instantiate Kvm");
|
||||
let mem = GuestMemory::new(&[]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, mem).expect("failed tso instantiate vm");
|
||||
let vm =
|
||||
KvmVm::new(&kvm, mem, ProtectionType::Unprotected).expect("failed tso instantiate vm");
|
||||
|
||||
let (_, device_tube) = Tube::pair().expect("failed to create irq tube");
|
||||
|
||||
|
|
|
@ -68,12 +68,3 @@ pub use self::usb::host_backend::host_backend_device_provider::HostBackendDevice
|
|||
pub use self::usb::xhci::xhci_controller::XhciController;
|
||||
pub use self::vfio::{VfioContainer, VfioDevice};
|
||||
pub use self::virtio::VirtioPciDevice;
|
||||
|
||||
/// Whether the VM should be run in protected mode or not.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum ProtectionType {
|
||||
/// The VM should be run in the unprotected mode, where the host has access to its memory.
|
||||
Unprotected,
|
||||
/// The VM should be run in protected mode, so the host cannot access its memory directly.
|
||||
Protected,
|
||||
}
|
||||
|
|
|
@ -10,9 +10,10 @@ use std::sync::Arc;
|
|||
use std::thread::{self};
|
||||
|
||||
use base::{error, Event, RawDescriptor, Result};
|
||||
use hypervisor::ProtectionType;
|
||||
|
||||
use crate::bus::BusAccessInfo;
|
||||
use crate::{BusDevice, ProtectionType, SerialDevice};
|
||||
use crate::{BusDevice, SerialDevice};
|
||||
|
||||
const LOOP_SIZE: usize = 0x40;
|
||||
|
||||
|
|
|
@ -16,12 +16,11 @@ use base::{
|
|||
error, info, read_raw_stdin, safe_descriptor_from_path, syslog, AsRawDescriptor, Event,
|
||||
RawDescriptor,
|
||||
};
|
||||
use hypervisor::ProtectionType;
|
||||
use minijail::Minijail;
|
||||
use remain::sorted;
|
||||
use thiserror::Error as ThisError;
|
||||
|
||||
use crate::ProtectionType;
|
||||
|
||||
#[sorted]
|
||||
#[derive(ThisError, Debug)]
|
||||
pub enum Error {
|
||||
|
|
|
@ -847,13 +847,13 @@ mod tests {
|
|||
|
||||
use data_model::{Le32, Le64};
|
||||
use disk::SingleFileDisk;
|
||||
use hypervisor::ProtectionType;
|
||||
use tempfile::TempDir;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use crate::virtio::base_features;
|
||||
use crate::virtio::block::common::*;
|
||||
use crate::virtio::descriptor_utils::{create_descriptor_chain, DescriptorType};
|
||||
use crate::ProtectionType;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -698,13 +698,13 @@ mod tests {
|
|||
use std::mem::size_of_val;
|
||||
|
||||
use data_model::{Le32, Le64};
|
||||
use hypervisor::ProtectionType;
|
||||
use tempfile::tempfile;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use crate::virtio::base_features;
|
||||
use crate::virtio::block::common::*;
|
||||
use crate::virtio::descriptor_utils::{create_descriptor_chain, DescriptorType};
|
||||
use crate::ProtectionType;
|
||||
|
||||
use super::*;
|
||||
|
||||
|
|
|
@ -11,6 +11,7 @@ use std::thread;
|
|||
|
||||
use base::{error, Event, PollToken, RawDescriptor, WaitContext};
|
||||
use data_model::{DataInit, Le16, Le32};
|
||||
use hypervisor::ProtectionType;
|
||||
use remain::sorted;
|
||||
use sync::Mutex;
|
||||
use thiserror::Error as ThisError;
|
||||
|
@ -20,7 +21,7 @@ use super::{
|
|||
base_features, copy_config, Interrupt, Queue, Reader, SignalableInterrupt, VirtioDevice,
|
||||
Writer, TYPE_CONSOLE,
|
||||
};
|
||||
use crate::{ProtectionType, SerialDevice};
|
||||
use crate::SerialDevice;
|
||||
|
||||
pub(crate) const QUEUE_SIZE: u16 = 256;
|
||||
|
||||
|
|
|
@ -59,10 +59,10 @@ pub use self::virtio_device::*;
|
|||
pub use self::virtio_pci_device::*;
|
||||
pub use self::wl::*;
|
||||
|
||||
use crate::ProtectionType;
|
||||
use std::cmp;
|
||||
use std::convert::TryFrom;
|
||||
|
||||
use hypervisor::ProtectionType;
|
||||
use virtio_sys::virtio_ring::VIRTIO_RING_F_EVENT_IDX;
|
||||
|
||||
const DEVICE_RESET: u32 = 0x0;
|
||||
|
|
|
@ -355,7 +355,7 @@ pub mod tests {
|
|||
use super::*;
|
||||
use crate::virtio::base_features;
|
||||
use crate::virtio::VIRTIO_MSI_NO_VECTOR;
|
||||
use crate::ProtectionType;
|
||||
use hypervisor::ProtectionType;
|
||||
use net_util::fakes::FakeTap;
|
||||
use std::path::PathBuf;
|
||||
use std::result;
|
||||
|
|
|
@ -19,6 +19,7 @@ use base::{error, iov_max, warn, Event, Timer};
|
|||
use cros_async::{sync::Mutex as AsyncMutex, EventAsync, Executor, TimerAsync};
|
||||
use data_model::DataInit;
|
||||
use disk::create_async_disk_file;
|
||||
use hypervisor::ProtectionType;
|
||||
use vm_memory::GuestMemory;
|
||||
|
||||
use crate::virtio::block::asynchronous::{flush_disk, process_one_chain};
|
||||
|
@ -27,7 +28,6 @@ use crate::virtio::vhost::user::device::handler::{
|
|||
CallEvent, DeviceRequestHandler, VhostUserBackend,
|
||||
};
|
||||
use crate::virtio::{self, base_features, copy_config, Queue};
|
||||
use crate::ProtectionType;
|
||||
|
||||
static BLOCK_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ use data_model::DataInit;
|
|||
|
||||
use futures::future::{AbortHandle, Abortable};
|
||||
use getopts::Options;
|
||||
use hypervisor::ProtectionType;
|
||||
use once_cell::sync::OnceCell;
|
||||
use sync::Mutex;
|
||||
use vm_memory::GuestMemory;
|
||||
|
@ -28,7 +29,6 @@ use crate::virtio::vhost::user::device::handler::{
|
|||
CallEvent, DeviceRequestHandler, VhostUserBackend,
|
||||
};
|
||||
use crate::virtio::{self, copy_config};
|
||||
use crate::ProtectionType;
|
||||
|
||||
static CONSOLE_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
||||
|
|
|
@ -15,6 +15,7 @@ use data_model::{DataInit, Le32};
|
|||
use fuse::Server;
|
||||
use futures::future::{AbortHandle, Abortable};
|
||||
use getopts::Options;
|
||||
use hypervisor::ProtectionType;
|
||||
use minijail::{self, Minijail};
|
||||
use once_cell::sync::OnceCell;
|
||||
use sync::Mutex;
|
||||
|
@ -28,7 +29,6 @@ use crate::virtio::fs::{process_fs_queue, virtio_fs_config, FS_MAX_TAG_LEN};
|
|||
use crate::virtio::vhost::user::device::handler::{
|
||||
CallEvent, DeviceRequestHandler, VhostUserBackend,
|
||||
};
|
||||
use crate::ProtectionType;
|
||||
|
||||
static FS_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
||||
|
|
|
@ -17,19 +17,16 @@ use futures::{
|
|||
pin_mut,
|
||||
};
|
||||
use getopts::Options;
|
||||
use hypervisor::ProtectionType;
|
||||
use once_cell::sync::OnceCell;
|
||||
use sync::Mutex;
|
||||
use vm_memory::GuestMemory;
|
||||
use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
|
||||
|
||||
use crate::{
|
||||
virtio::{
|
||||
self, gpu,
|
||||
vhost::user::device::handler::{CallEvent, DeviceRequestHandler, VhostUserBackend},
|
||||
DescriptorChain, Gpu, GpuDisplayParameters, GpuParameters, Queue, QueueReader,
|
||||
VirtioDevice,
|
||||
},
|
||||
ProtectionType,
|
||||
use crate::virtio::{
|
||||
self, gpu,
|
||||
vhost::user::device::handler::{CallEvent, DeviceRequestHandler, VhostUserBackend},
|
||||
DescriptorChain, Gpu, GpuDisplayParameters, GpuParameters, Queue, QueueReader, VirtioDevice,
|
||||
};
|
||||
|
||||
static GPU_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
|
|
@ -13,6 +13,7 @@ use cros_async::{EventAsync, Executor, IoSourceExt};
|
|||
use data_model::DataInit;
|
||||
use futures::future::{AbortHandle, Abortable};
|
||||
use getopts::Options;
|
||||
use hypervisor::ProtectionType;
|
||||
use net_util::{MacAddress, Tap, TapT};
|
||||
use once_cell::sync::OnceCell;
|
||||
use sync::Mutex;
|
||||
|
@ -20,6 +21,7 @@ use virtio_sys::virtio_net;
|
|||
use vm_memory::GuestMemory;
|
||||
use vmm_vhost::message::{VhostUserProtocolFeatures, VhostUserVirtioFeatures};
|
||||
|
||||
use crate::virtio;
|
||||
use crate::virtio::net::{
|
||||
build_config, process_ctrl, process_rx, process_tx, validate_and_configure_tap,
|
||||
virtio_features_to_tap_offload, NetError,
|
||||
|
@ -27,7 +29,6 @@ use crate::virtio::net::{
|
|||
use crate::virtio::vhost::user::device::handler::{
|
||||
CallEvent, DeviceRequestHandler, VhostUserBackend,
|
||||
};
|
||||
use crate::{virtio, ProtectionType};
|
||||
|
||||
thread_local! {
|
||||
static NET_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
|
|
@ -22,6 +22,7 @@ use base::{
|
|||
use cros_async::{AsyncWrapper, Executor};
|
||||
use data_model::{DataInit, Le64};
|
||||
use getopts::Options;
|
||||
use hypervisor::ProtectionType;
|
||||
use once_cell::sync::OnceCell;
|
||||
use vhost::{self, Vhost, Vsock};
|
||||
use vm_memory::GuestMemory;
|
||||
|
@ -34,16 +35,13 @@ use vmm_vhost::{
|
|||
Error, Result, SlaveReqHandler, VhostUserSlaveReqHandlerMut,
|
||||
};
|
||||
|
||||
use crate::{
|
||||
virtio::{
|
||||
base_features,
|
||||
vhost::{
|
||||
user::device::handler::{create_guest_memory, vmm_va_to_gpa, MappingInfo},
|
||||
vsock,
|
||||
},
|
||||
Queue,
|
||||
use crate::virtio::{
|
||||
base_features,
|
||||
vhost::{
|
||||
user::device::handler::{create_guest_memory, vmm_va_to_gpa, MappingInfo},
|
||||
vsock,
|
||||
},
|
||||
ProtectionType,
|
||||
Queue,
|
||||
};
|
||||
|
||||
static VSOCK_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
|
|
@ -19,6 +19,7 @@ use base::{
|
|||
use cros_async::{AsyncWrapper, EventAsync, Executor, IoSourceExt};
|
||||
use futures::future::{AbortHandle, Abortable};
|
||||
use getopts::Options;
|
||||
use hypervisor::ProtectionType;
|
||||
use once_cell::sync::OnceCell;
|
||||
use sync::Mutex;
|
||||
use vm_memory::GuestMemory;
|
||||
|
@ -28,7 +29,6 @@ use crate::virtio::vhost::user::device::handler::{
|
|||
CallEvent, DeviceRequestHandler, VhostUserBackend,
|
||||
};
|
||||
use crate::virtio::{base_features, wl, Queue};
|
||||
use crate::ProtectionType;
|
||||
|
||||
static WL_EXECUTOR: OnceCell<Executor> = OnceCell::new();
|
||||
|
||||
|
|
|
@ -19,9 +19,11 @@ pub trait VmAArch64: Vm {
|
|||
/// Gets the `Hypervisor` that created this VM.
|
||||
fn get_hypervisor(&self) -> &dyn Hypervisor;
|
||||
|
||||
/// Enables protected mode for the VM, creating a memslot for the firmware as needed.
|
||||
/// Only works on VMs that support `VmCap::Protected`.
|
||||
fn enable_protected_vm(&mut self, fw_addr: GuestAddress, fw_max_size: u64) -> Result<()>;
|
||||
/// Load pVM firmware for the VM, creating a memslot for it as needed.
|
||||
///
|
||||
/// Only works on protected VMs (i.e. those that support `VmCap::Protected`).
|
||||
fn load_protected_vm_firmware(&mut self, fw_addr: GuestAddress, fw_max_size: u64)
|
||||
-> Result<()>;
|
||||
|
||||
/// Create a Vcpu with the specified Vcpu ID.
|
||||
fn create_vcpu(&self, id: usize) -> Result<Box<dyn VcpuAArch64>>;
|
||||
|
|
|
@ -9,13 +9,12 @@ use base::{
|
|||
MemoryMappingBuilder, Result,
|
||||
};
|
||||
use kvm_sys::*;
|
||||
use std::os::raw::c_ulong;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use super::{Kvm, KvmCap, KvmVcpu, KvmVm};
|
||||
use crate::{
|
||||
ClockState, DeviceKind, Hypervisor, IrqSourceChip, PsciVersion, VcpuAArch64, VcpuFeature, Vm,
|
||||
VmAArch64, VmCap,
|
||||
ClockState, DeviceKind, Hypervisor, IrqSourceChip, ProtectionType, PsciVersion, VcpuAArch64,
|
||||
VcpuFeature, Vm, VmAArch64, VmCap,
|
||||
};
|
||||
|
||||
impl Kvm {
|
||||
|
@ -23,15 +22,21 @@ impl Kvm {
|
|||
// Ideally, this would take a description of the memory map and return
|
||||
// the closest machine type for this VM. Here, we just return the maximum
|
||||
// the kernel support.
|
||||
pub fn get_vm_type(&self) -> c_ulong {
|
||||
pub fn get_vm_type(&self, protection_type: ProtectionType) -> Result<u32> {
|
||||
// Safe because we know self is a real kvm fd
|
||||
match unsafe { ioctl_with_val(self, KVM_CHECK_EXTENSION(), KVM_CAP_ARM_VM_IPA_SIZE.into()) }
|
||||
{
|
||||
let ipa_size = match unsafe {
|
||||
ioctl_with_val(self, KVM_CHECK_EXTENSION(), KVM_CAP_ARM_VM_IPA_SIZE.into())
|
||||
} {
|
||||
// Not supported? Use 0 as the machine type, which implies 40bit IPA
|
||||
ret if ret < 0 => 0,
|
||||
// Use the lower 8 bits representing the IPA space as the machine type
|
||||
ipa => (ipa & 0xff) as c_ulong,
|
||||
}
|
||||
ipa => ipa as u32,
|
||||
};
|
||||
let protection_flag = match protection_type {
|
||||
ProtectionType::Unprotected => 0,
|
||||
ProtectionType::Protected => KVM_VM_TYPE_ARM_PROTECTED,
|
||||
};
|
||||
// Use the lower 8 bits representing the IPA space as the machine type
|
||||
Ok((ipa_size & KVM_VM_TYPE_ARM_IPA_SIZE_MASK) | protection_flag)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -86,6 +91,17 @@ impl KvmVm {
|
|||
}?;
|
||||
Ok(info)
|
||||
}
|
||||
|
||||
fn set_protected_vm_firmware_ipa(&self, fw_addr: GuestAddress) -> Result<()> {
|
||||
// Safe because none of the args are pointers.
|
||||
unsafe {
|
||||
self.enable_raw_capability(
|
||||
KvmCap::ArmProtectedVm,
|
||||
KVM_CAP_ARM_PROTECTED_VM_FLAGS_SET_FW_IPA,
|
||||
&[fw_addr.0, 0, 0, 0],
|
||||
)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[repr(C)]
|
||||
|
@ -99,13 +115,17 @@ impl VmAArch64 for KvmVm {
|
|||
&self.kvm
|
||||
}
|
||||
|
||||
fn enable_protected_vm(&mut self, fw_addr: GuestAddress, fw_max_size: u64) -> Result<()> {
|
||||
fn load_protected_vm_firmware(
|
||||
&mut self,
|
||||
fw_addr: GuestAddress,
|
||||
fw_max_size: u64,
|
||||
) -> Result<()> {
|
||||
if !self.check_capability(VmCap::Protected) {
|
||||
return Err(Error::new(ENOSYS));
|
||||
}
|
||||
let info = self.get_protected_vm_info()?;
|
||||
let memslot = if info.firmware_size == 0 {
|
||||
u64::MAX
|
||||
if info.firmware_size == 0 {
|
||||
Err(Error::new(EINVAL))
|
||||
} else {
|
||||
if info.firmware_size > fw_max_size {
|
||||
return Err(Error::new(ENOMEM));
|
||||
|
@ -113,15 +133,8 @@ impl VmAArch64 for KvmVm {
|
|||
let mem = MemoryMappingBuilder::new(info.firmware_size as usize)
|
||||
.build()
|
||||
.map_err(|_| Error::new(EINVAL))?;
|
||||
self.add_memory_region(fw_addr, Box::new(mem), false, false)? as u64
|
||||
};
|
||||
// Safe because none of the args are pointers.
|
||||
unsafe {
|
||||
self.enable_raw_capability(
|
||||
KvmCap::ArmProtectedVm,
|
||||
KVM_CAP_ARM_PROTECTED_VM_FLAGS_ENABLE,
|
||||
&[memslot, 0, 0, 0],
|
||||
)
|
||||
self.add_memory_region(fw_addr, Box::new(mem), false, false)?;
|
||||
self.set_protected_vm_firmware_ipa(fw_addr)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -333,7 +346,7 @@ mod tests {
|
|||
fn set_gsi_routing() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.create_irq_chip().unwrap();
|
||||
vm.set_gsi_routing(&[]).unwrap();
|
||||
vm.set_gsi_routing(&[IrqRoute {
|
||||
|
|
|
@ -42,7 +42,7 @@ use vm_memory::{GuestAddress, GuestMemory};
|
|||
|
||||
use crate::{
|
||||
ClockState, Datamatch, DeviceKind, Hypervisor, HypervisorCap, IoEventAddress, IrqRoute,
|
||||
IrqSource, MPState, MemSlot, Vcpu, VcpuExit, VcpuRunHandle, Vm, VmCap,
|
||||
IrqSource, MPState, MemSlot, ProtectionType, Vcpu, VcpuExit, VcpuRunHandle, Vm, VmCap,
|
||||
};
|
||||
|
||||
// Wrapper around KVM_SET_USER_MEMORY_REGION ioctl, which creates, modifies, or deletes a mapping
|
||||
|
@ -163,10 +163,20 @@ pub struct KvmVm {
|
|||
|
||||
impl KvmVm {
|
||||
/// Constructs a new `KvmVm` using the given `Kvm` instance.
|
||||
pub fn new(kvm: &Kvm, guest_mem: GuestMemory) -> Result<KvmVm> {
|
||||
pub fn new(
|
||||
kvm: &Kvm,
|
||||
guest_mem: GuestMemory,
|
||||
protection_type: ProtectionType,
|
||||
) -> Result<KvmVm> {
|
||||
// Safe because we know kvm is a real kvm fd as this module is the only one that can make
|
||||
// Kvm objects.
|
||||
let ret = unsafe { ioctl_with_val(kvm, KVM_CREATE_VM(), kvm.get_vm_type()) };
|
||||
let ret = unsafe {
|
||||
ioctl_with_val(
|
||||
kvm,
|
||||
KVM_CREATE_VM(),
|
||||
kvm.get_vm_type(protection_type)? as c_ulong,
|
||||
)
|
||||
};
|
||||
if ret < 0 {
|
||||
return errno_result();
|
||||
}
|
||||
|
@ -1194,14 +1204,14 @@ mod tests {
|
|||
fn create_vm() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
KvmVm::new(&kvm, gm).unwrap();
|
||||
KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn clone_vm() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.try_clone().unwrap();
|
||||
}
|
||||
|
||||
|
@ -1209,7 +1219,7 @@ mod tests {
|
|||
fn send_vm() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
thread::spawn(move || {
|
||||
let _vm = vm;
|
||||
})
|
||||
|
@ -1221,7 +1231,7 @@ mod tests {
|
|||
fn check_vm_capability() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
assert!(vm.check_raw_capability(KvmCap::UserMemory));
|
||||
// I assume nobody is testing this on s390
|
||||
assert!(!vm.check_raw_capability(KvmCap::S390UserSigp));
|
||||
|
@ -1231,7 +1241,7 @@ mod tests {
|
|||
fn create_vcpu() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.create_vcpu(0).unwrap();
|
||||
}
|
||||
|
||||
|
@ -1239,7 +1249,7 @@ mod tests {
|
|||
fn get_memory() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let obj_addr = GuestAddress(0xf0);
|
||||
vm.get_memory().write_obj_at_addr(67u8, obj_addr).unwrap();
|
||||
let read_val: u8 = vm.get_memory().read_obj_from_addr(obj_addr).unwrap();
|
||||
|
@ -1251,7 +1261,7 @@ mod tests {
|
|||
let kvm = Kvm::new().unwrap();
|
||||
let gm =
|
||||
GuestMemory::new(&[(GuestAddress(0), 0x1000), (GuestAddress(0x5000), 0x5000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let mem_size = 0x1000;
|
||||
let mem = MemoryMappingBuilder::new(mem_size).build().unwrap();
|
||||
vm.add_memory_region(GuestAddress(0x1000), Box::new(mem), false, false)
|
||||
|
@ -1265,7 +1275,7 @@ mod tests {
|
|||
fn add_memory_ro() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let mem_size = 0x1000;
|
||||
let mem = MemoryMappingBuilder::new(mem_size).build().unwrap();
|
||||
vm.add_memory_region(GuestAddress(0x1000), Box::new(mem), true, false)
|
||||
|
@ -1276,7 +1286,7 @@ mod tests {
|
|||
fn remove_memory() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let mem_size = 0x1000;
|
||||
let mem = MemoryMappingBuilder::new(mem_size).build().unwrap();
|
||||
let mem_ptr = mem.as_ptr();
|
||||
|
@ -1292,7 +1302,7 @@ mod tests {
|
|||
fn remove_invalid_memory() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
assert!(vm.remove_memory_region(0).is_err());
|
||||
}
|
||||
|
||||
|
@ -1300,7 +1310,7 @@ mod tests {
|
|||
fn overlap_memory() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let mem_size = 0x2000;
|
||||
let mem = MemoryMappingBuilder::new(mem_size).build().unwrap();
|
||||
assert!(vm
|
||||
|
@ -1313,7 +1323,7 @@ mod tests {
|
|||
let kvm = Kvm::new().unwrap();
|
||||
let gm =
|
||||
GuestMemory::new(&[(GuestAddress(0), 0x1000), (GuestAddress(0x5000), 0x5000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let mem_size = 0x1000;
|
||||
let mem = MemoryMappingArena::new(mem_size).unwrap();
|
||||
let slot = vm
|
||||
|
@ -1328,7 +1338,7 @@ mod tests {
|
|||
fn register_irqfd() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let evtfd1 = Event::new().unwrap();
|
||||
let evtfd2 = Event::new().unwrap();
|
||||
let evtfd3 = Event::new().unwrap();
|
||||
|
@ -1343,7 +1353,7 @@ mod tests {
|
|||
fn unregister_irqfd() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let evtfd1 = Event::new().unwrap();
|
||||
let evtfd2 = Event::new().unwrap();
|
||||
let evtfd3 = Event::new().unwrap();
|
||||
|
@ -1360,7 +1370,7 @@ mod tests {
|
|||
fn irqfd_resample() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let evtfd1 = Event::new().unwrap();
|
||||
let evtfd2 = Event::new().unwrap();
|
||||
vm.create_irq_chip().unwrap();
|
||||
|
@ -1375,7 +1385,7 @@ mod tests {
|
|||
fn set_signal_mask() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
vcpu.set_signal_mask(&[base::SIGRTMIN() + 0]).unwrap();
|
||||
}
|
||||
|
@ -1393,7 +1403,7 @@ mod tests {
|
|||
fn register_ioevent() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let evtfd = Event::new().unwrap();
|
||||
vm.register_ioevent(&evtfd, IoEventAddress::Pio(0xf4), Datamatch::AnyLength)
|
||||
.unwrap();
|
||||
|
@ -1429,7 +1439,7 @@ mod tests {
|
|||
fn unregister_ioevent() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let mut vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let evtfd = Event::new().unwrap();
|
||||
vm.register_ioevent(&evtfd, IoEventAddress::Pio(0xf4), Datamatch::AnyLength)
|
||||
.unwrap();
|
||||
|
|
|
@ -12,15 +12,14 @@ use base::{
|
|||
};
|
||||
use data_model::vec_with_array_field;
|
||||
use kvm_sys::*;
|
||||
use std::os::raw::c_ulong;
|
||||
use vm_memory::GuestAddress;
|
||||
|
||||
use super::{Kvm, KvmVcpu, KvmVm};
|
||||
use crate::{
|
||||
ClockState, CpuId, CpuIdEntry, DebugRegs, DescriptorTable, DeviceKind, Fpu, HypervisorX86_64,
|
||||
IoapicRedirectionTableEntry, IoapicState, IrqSourceChip, LapicState, PicSelect, PicState,
|
||||
PitChannelState, PitState, Register, Regs, Segment, Sregs, VcpuX86_64, VmCap, VmX86_64,
|
||||
MAX_IOAPIC_PINS, NUM_IOAPIC_PINS,
|
||||
PitChannelState, PitState, ProtectionType, Register, Regs, Segment, Sregs, VcpuX86_64, VmCap,
|
||||
VmX86_64, MAX_IOAPIC_PINS, NUM_IOAPIC_PINS,
|
||||
};
|
||||
|
||||
type KvmCpuId = kvm::CpuId;
|
||||
|
@ -66,9 +65,14 @@ impl Kvm {
|
|||
get_cpuid_with_initial_capacity(self, kind, KVM_MAX_ENTRIES)
|
||||
}
|
||||
|
||||
// The x86 machine type is always 0
|
||||
pub fn get_vm_type(&self) -> c_ulong {
|
||||
0
|
||||
// The x86 machine type is always 0. Protected VMs are not supported.
|
||||
pub fn get_vm_type(&self, protection_type: ProtectionType) -> Result<u32> {
|
||||
if protection_type == ProtectionType::Unprotected {
|
||||
Ok(0)
|
||||
} else {
|
||||
error!("Protected mode is not supported on x86_64.");
|
||||
Err(Error::new(libc::EINVAL))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1250,7 +1254,7 @@ mod tests {
|
|||
fn check_vm_arch_capability() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x1000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
assert!(vm.check_capability(VmCap::PvClock));
|
||||
}
|
||||
|
||||
|
@ -1426,7 +1430,7 @@ mod tests {
|
|||
fn clock_handling() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let mut clock_data = vm.get_pvclock().unwrap();
|
||||
clock_data.clock += 1000;
|
||||
vm.set_pvclock(&clock_data).unwrap();
|
||||
|
@ -1436,7 +1440,7 @@ mod tests {
|
|||
fn set_gsi_routing() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.create_irq_chip().unwrap();
|
||||
vm.set_gsi_routing(&[]).unwrap();
|
||||
vm.set_gsi_routing(&[IrqRoute {
|
||||
|
@ -1478,7 +1482,7 @@ mod tests {
|
|||
fn set_identity_map_addr() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.set_identity_map_addr(GuestAddress(0x20000)).unwrap();
|
||||
}
|
||||
|
||||
|
@ -1486,7 +1490,7 @@ mod tests {
|
|||
fn mp_state() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.create_irq_chip().unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
let state = vcpu.get_mp_state().unwrap();
|
||||
|
@ -1497,7 +1501,7 @@ mod tests {
|
|||
fn enable_feature() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
vm.create_irq_chip().unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
unsafe { vcpu.enable_raw_capability(kvm_sys::KVM_CAP_HYPERV_SYNIC, &[0; 4]) }.unwrap();
|
||||
|
@ -1522,7 +1526,7 @@ mod tests {
|
|||
fn debugregs() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
let mut dregs = vcpu.get_debugregs().unwrap();
|
||||
dregs.dr7 = 13;
|
||||
|
@ -1539,7 +1543,7 @@ mod tests {
|
|||
}
|
||||
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
let mut xcrs = vcpu.get_xcrs().unwrap();
|
||||
xcrs[0].value = 1;
|
||||
|
@ -1552,7 +1556,7 @@ mod tests {
|
|||
fn get_msrs() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
let mut msrs = vec![
|
||||
// This one should succeed
|
||||
|
@ -1574,7 +1578,7 @@ mod tests {
|
|||
fn set_msrs() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
|
||||
const MSR_TSC_AUX: u32 = 0xc0000103;
|
||||
|
@ -1595,7 +1599,7 @@ mod tests {
|
|||
fn get_hyperv_cpuid() {
|
||||
let kvm = Kvm::new().unwrap();
|
||||
let gm = GuestMemory::new(&[(GuestAddress(0), 0x10000)]).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm).unwrap();
|
||||
let vm = KvmVm::new(&kvm, gm, ProtectionType::Unprotected).unwrap();
|
||||
let vcpu = vm.create_vcpu(0).unwrap();
|
||||
let cpuid = vcpu.get_hyperv_cpuid();
|
||||
// Older kernels don't support so tolerate this kind of failure.
|
||||
|
|
|
@ -439,3 +439,12 @@ pub enum MPState {
|
|||
/// the vcpu is stopped (arm/arm64)
|
||||
Stopped,
|
||||
}
|
||||
|
||||
/// Whether the VM should be run in protected mode or not.
|
||||
#[derive(Copy, Clone, Debug, Eq, PartialEq)]
|
||||
pub enum ProtectionType {
|
||||
/// The VM should be run in the unprotected mode, where the host has access to its memory.
|
||||
Unprotected,
|
||||
/// The VM should be run in protected mode, so the host cannot access its memory directly.
|
||||
Protected,
|
||||
}
|
||||
|
|
|
@ -481,7 +481,8 @@ pub const KVM_VM_MIPS_AUTO: u32 = 0;
|
|||
pub const KVM_VM_MIPS_VZ: u32 = 1;
|
||||
pub const KVM_VM_MIPS_TE: u32 = 2;
|
||||
pub const KVM_S390_SIE_PAGE_OFFSET: u32 = 1;
|
||||
pub const KVM_VM_TYPE_ARM_IPA_SIZE_MASK: u32 = 255;
|
||||
pub const KVM_VM_TYPE_ARM_IPA_SIZE_MASK: u32 = 0xff;
|
||||
pub const KVM_VM_TYPE_ARM_PROTECTED: u32 = 0x100;
|
||||
pub const KVM_CAP_IRQCHIP: u32 = 0;
|
||||
pub const KVM_CAP_HLT: u32 = 1;
|
||||
pub const KVM_CAP_MMU_SHADOW_CACHE_CONTROL: u32 = 2;
|
||||
|
@ -663,7 +664,7 @@ pub const KVM_CAP_ENFORCE_PV_FEATURE_CPUID: u32 = 190;
|
|||
pub const KVM_CAP_IOAPIC_NUM_PINS: u32 = 8191;
|
||||
// TODO(qwandor): Update this once the pKVM patches are merged upstream with a stable capability ID.
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM: u32 = 0xffbadab1;
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM_FLAGS_ENABLE: u32 = 0;
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM_FLAGS_SET_FW_IPA: u32 = 0;
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM_FLAGS_INFO: u32 = 1;
|
||||
pub const KVM_IRQ_ROUTING_IRQCHIP: u32 = 1;
|
||||
pub const KVM_IRQ_ROUTING_MSI: u32 = 2;
|
||||
|
|
|
@ -397,7 +397,8 @@ pub const KVM_VM_MIPS_AUTO: u32 = 0;
|
|||
pub const KVM_VM_MIPS_VZ: u32 = 1;
|
||||
pub const KVM_VM_MIPS_TE: u32 = 2;
|
||||
pub const KVM_S390_SIE_PAGE_OFFSET: u32 = 1;
|
||||
pub const KVM_VM_TYPE_ARM_IPA_SIZE_MASK: u32 = 255;
|
||||
pub const KVM_VM_TYPE_ARM_IPA_SIZE_MASK: u32 = 0xff;
|
||||
pub const KVM_VM_TYPE_ARM_PROTECTED: u32 = 0x100;
|
||||
pub const KVM_CAP_IRQCHIP: u32 = 0;
|
||||
pub const KVM_CAP_HLT: u32 = 1;
|
||||
pub const KVM_CAP_MMU_SHADOW_CACHE_CONTROL: u32 = 2;
|
||||
|
@ -572,7 +573,7 @@ pub const KVM_CAP_HYPERV_DIRECT_TLBFLUSH: u32 = 175;
|
|||
pub const KVM_CAP_IOAPIC_NUM_PINS: u32 = 8191;
|
||||
// TODO(qwandor): Update this once the pKVM patches are merged upstream with a stable capability ID.
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM: u32 = 0xffbadab1;
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM_FLAGS_ENABLE: u32 = 0;
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM_FLAGS_SET_FW_IPA: u32 = 0;
|
||||
pub const KVM_CAP_ARM_PROTECTED_VM_FLAGS_INFO: u32 = 1;
|
||||
pub const KVM_IRQ_ROUTING_IRQCHIP: u32 = 1;
|
||||
pub const KVM_IRQ_ROUTING_MSI: u32 = 2;
|
||||
|
|
|
@ -33,8 +33,8 @@ use devices::virtio::VideoBackendType;
|
|||
use devices::Ac97Parameters;
|
||||
#[cfg(feature = "direct")]
|
||||
use devices::BusRange;
|
||||
use devices::ProtectionType;
|
||||
use devices::StubPciParameters;
|
||||
use hypervisor::ProtectionType;
|
||||
use libc::{getegid, geteuid};
|
||||
use vm_control::BatteryType;
|
||||
|
||||
|
|
|
@ -50,7 +50,6 @@ use devices::virtio::{
|
|||
};
|
||||
#[cfg(feature = "audio")]
|
||||
use devices::Ac97Dev;
|
||||
use devices::ProtectionType;
|
||||
use devices::{
|
||||
self, BusDeviceObj, HostHotPlugKey, HotPlugBus, IrqChip, IrqEventIndex, KvmKernelIrqChip,
|
||||
PciAddress, PciBridge, PciDevice, PcieRootPort, StubPciDevice, VcpuRunState, VfioContainer,
|
||||
|
@ -59,7 +58,7 @@ use devices::{
|
|||
#[cfg(feature = "usb")]
|
||||
use devices::{HostBackendDeviceProvider, XhciController};
|
||||
use hypervisor::kvm::{Kvm, KvmVcpu, KvmVm};
|
||||
use hypervisor::{HypervisorCap, Vcpu, VcpuExit, VcpuRunHandle, Vm, VmCap};
|
||||
use hypervisor::{HypervisorCap, ProtectionType, Vcpu, VcpuExit, VcpuRunHandle, Vm, VmCap};
|
||||
use minijail::{self, Minijail};
|
||||
use net_util::{MacAddress, Tap};
|
||||
use resources::{Alloc, MmioType, SystemAllocator};
|
||||
|
@ -2581,7 +2580,7 @@ pub fn run_config(cfg: Config) -> Result<ExitState> {
|
|||
}
|
||||
guest_mem.set_memory_policy(mem_policy);
|
||||
let kvm = Kvm::new_with_path(&cfg.kvm_device_path).context("failed to create kvm")?;
|
||||
let vm = KvmVm::new(&kvm, guest_mem).context("failed to create vm")?;
|
||||
let vm = KvmVm::new(&kvm, guest_mem, components.protected_vm).context("failed to create vm")?;
|
||||
let vm_clone = vm.try_clone().context("failed to clone vm")?;
|
||||
|
||||
enum KvmIrqChip {
|
||||
|
|
|
@ -49,12 +49,13 @@ use devices::virtio::{
|
|||
use devices::BusRange;
|
||||
#[cfg(feature = "audio")]
|
||||
use devices::{Ac97Backend, Ac97Parameters};
|
||||
use devices::{PciAddress, PciClassCode, ProtectionType, StubPciParameters};
|
||||
use devices::{PciAddress, PciClassCode, StubPciParameters};
|
||||
use disk::{self, QcowFile};
|
||||
#[cfg(feature = "composite-disk")]
|
||||
use disk::{
|
||||
create_composite_disk, create_disk_file, create_zero_filler, ImagePartitionType, PartitionInfo,
|
||||
};
|
||||
use hypervisor::ProtectionType;
|
||||
use vm_control::{
|
||||
client::{
|
||||
do_modify_battery, do_usb_attach, do_usb_detach, do_usb_list, handle_request, vms_request,
|
||||
|
|
|
@ -230,7 +230,7 @@ pub fn phy_max_address_bits() -> u32 {
|
|||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use hypervisor::CpuIdEntry;
|
||||
use hypervisor::{CpuIdEntry, ProtectionType};
|
||||
|
||||
#[test]
|
||||
fn feature_and_vendor_name() {
|
||||
|
@ -238,7 +238,7 @@ mod tests {
|
|||
let guest_mem =
|
||||
vm_memory::GuestMemory::new(&[(vm_memory::GuestAddress(0), 0x10000)]).unwrap();
|
||||
let kvm = hypervisor::kvm::Kvm::new().unwrap();
|
||||
let vm = hypervisor::kvm::KvmVm::new(&kvm, guest_mem).unwrap();
|
||||
let vm = hypervisor::kvm::KvmVm::new(&kvm, guest_mem, ProtectionType::Unprotected).unwrap();
|
||||
let irq_chip = devices::KvmKernelIrqChip::new(vm, 1).unwrap();
|
||||
|
||||
let entries = &mut cpuid.cpu_id_entries;
|
||||
|
|
|
@ -60,9 +60,9 @@ use base::Event;
|
|||
use devices::serial_device::{SerialHardware, SerialParameters};
|
||||
use devices::{
|
||||
BusDeviceObj, BusResumeDevice, IrqChip, IrqChipX86_64, PciAddress, PciConfigIo, PciConfigMmio,
|
||||
PciDevice, ProtectionType,
|
||||
PciDevice,
|
||||
};
|
||||
use hypervisor::{HypervisorX86_64, VcpuX86_64, VmX86_64};
|
||||
use hypervisor::{HypervisorX86_64, ProtectionType, VcpuX86_64, VmX86_64};
|
||||
use minijail::Minijail;
|
||||
use remain::sorted;
|
||||
use resources::SystemAllocator;
|
||||
|
|
|
@ -5,8 +5,8 @@
|
|||
#![cfg(any(target_arch = "x86", target_arch = "x86_64"))]
|
||||
|
||||
use arch::LinuxArch;
|
||||
use devices::{IrqChipX86_64, ProtectionType};
|
||||
use hypervisor::{HypervisorX86_64, VcpuExit, VcpuX86_64, VmX86_64};
|
||||
use devices::IrqChipX86_64;
|
||||
use hypervisor::{HypervisorX86_64, ProtectionType, VcpuExit, VcpuX86_64, VmX86_64};
|
||||
use vm_memory::{GuestAddress, GuestMemory};
|
||||
|
||||
use super::cpuid::setup_cpuid;
|
||||
|
@ -41,7 +41,8 @@ fn simple_kvm_kernel_irqchip_test() {
|
|||
simple_vm_test::<_, _, KvmVcpu, _, _, _>(
|
||||
|guest_mem| {
|
||||
let kvm = Kvm::new().expect("failed to create kvm");
|
||||
let vm = KvmVm::new(&kvm, guest_mem).expect("failed to create kvm vm");
|
||||
let vm = KvmVm::new(&kvm, guest_mem, ProtectionType::Unprotected)
|
||||
.expect("failed to create kvm vm");
|
||||
(kvm, vm)
|
||||
},
|
||||
|vm, vcpu_count, _| {
|
||||
|
@ -57,7 +58,8 @@ fn simple_kvm_split_irqchip_test() {
|
|||
simple_vm_test::<_, _, KvmVcpu, _, _, _>(
|
||||
|guest_mem| {
|
||||
let kvm = Kvm::new().expect("failed to create kvm");
|
||||
let vm = KvmVm::new(&kvm, guest_mem).expect("failed to create kvm vm");
|
||||
let vm = KvmVm::new(&kvm, guest_mem, ProtectionType::Unprotected)
|
||||
.expect("failed to create kvm vm");
|
||||
(kvm, vm)
|
||||
},
|
||||
|vm, vcpu_count, device_tube| {
|
||||
|
|
Loading…
Reference in a new issue