From 00f1c9fd468dca09c16f2f1267e6a1a0466579c3 Mon Sep 17 00:00:00 2001 From: Andrew Walbran Date: Fri, 10 Dec 2021 17:13:08 +0000 Subject: [PATCH] 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 Tested-by: kokoro Reviewed-by: Daniel Verkamp Commit-Queue: Daniel Verkamp --- aarch64/src/lib.rs | 7 ++- arch/src/lib.rs | 6 +- arch/src/serial.rs | 3 +- crosvm-fuzz/block_fuzzer.rs | 2 +- devices/src/irqchip/kvm/mod.rs | 9 +-- devices/src/irqchip/kvm/x86_64.rs | 10 +++- devices/src/lib.rs | 9 --- devices/src/serial.rs | 3 +- devices/src/serial_device.rs | 3 +- devices/src/virtio/block/asynchronous.rs | 2 +- devices/src/virtio/block/block.rs | 2 +- devices/src/virtio/console.rs | 3 +- devices/src/virtio/mod.rs | 2 +- devices/src/virtio/vhost/net.rs | 2 +- devices/src/virtio/vhost/user/device/block.rs | 2 +- .../src/virtio/vhost/user/device/console.rs | 2 +- devices/src/virtio/vhost/user/device/fs.rs | 2 +- devices/src/virtio/vhost/user/device/gpu.rs | 13 ++--- devices/src/virtio/vhost/user/device/net.rs | 3 +- devices/src/virtio/vhost/user/device/vsock.rs | 16 +++--- devices/src/virtio/vhost/user/device/wl.rs | 2 +- hypervisor/src/aarch64.rs | 8 ++- hypervisor/src/kvm/aarch64.rs | 57 ++++++++++++------- hypervisor/src/kvm/mod.rs | 52 ++++++++++------- hypervisor/src/kvm/x86_64.rs | 38 +++++++------ hypervisor/src/lib.rs | 9 +++ kvm_sys/src/aarch64/bindings.rs | 5 +- kvm_sys/src/x86/bindings.rs | 5 +- src/crosvm.rs | 2 +- src/linux.rs | 5 +- src/main.rs | 3 +- x86_64/src/cpuid.rs | 4 +- x86_64/src/lib.rs | 4 +- x86_64/src/test_integration.rs | 10 ++-- 34 files changed, 171 insertions(+), 134 deletions(-) diff --git a/aarch64/src/lib.rs b/aarch64/src/lib.rs index 1cb8af0419..e5f8f6587c 100644 --- a/aarch64/src/lib.rs +++ b/aarch64/src/lib.rs @@ -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, ) diff --git a/arch/src/lib.rs b/arch/src/lib.rs index 79e88f4d98..811c379a98 100644 --- a/arch/src/lib.rs +++ b/arch/src/lib.rs @@ -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}; diff --git a/arch/src/serial.rs b/arch/src/serial.rs index 29ac2f02a2..683b51121d 100644 --- a/arch/src/serial.rs +++ b/arch/src/serial.rs @@ -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; diff --git a/crosvm-fuzz/block_fuzzer.rs b/crosvm-fuzz/block_fuzzer.rs index 124dcacce9..6976fb3cd8 100644 --- a/crosvm-fuzz/block_fuzzer.rs +++ b/crosvm-fuzz/block_fuzzer.rs @@ -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}; diff --git a/devices/src/irqchip/kvm/mod.rs b/devices/src/irqchip/kvm/mod.rs index 595224f85d..fb43a9637d 100644 --- a/devices/src/irqchip/kvm/mod.rs +++ b/devices/src/irqchip/kvm/mod.rs @@ -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"); diff --git a/devices/src/irqchip/kvm/x86_64.rs b/devices/src/irqchip/kvm/x86_64.rs index 66b304cbd1..b22ff54cc1 100644 --- a/devices/src/irqchip/kvm/x86_64.rs +++ b/devices/src/irqchip/kvm/x86_64.rs @@ -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"); diff --git a/devices/src/lib.rs b/devices/src/lib.rs index 349af11176..30749e47d2 100644 --- a/devices/src/lib.rs +++ b/devices/src/lib.rs @@ -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, -} diff --git a/devices/src/serial.rs b/devices/src/serial.rs index 710f300027..3ce0d90f78 100644 --- a/devices/src/serial.rs +++ b/devices/src/serial.rs @@ -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; diff --git a/devices/src/serial_device.rs b/devices/src/serial_device.rs index a446f59f32..3a93a7a887 100644 --- a/devices/src/serial_device.rs +++ b/devices/src/serial_device.rs @@ -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 { diff --git a/devices/src/virtio/block/asynchronous.rs b/devices/src/virtio/block/asynchronous.rs index d6529d9648..fdaa69b114 100644 --- a/devices/src/virtio/block/asynchronous.rs +++ b/devices/src/virtio/block/asynchronous.rs @@ -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::*; diff --git a/devices/src/virtio/block/block.rs b/devices/src/virtio/block/block.rs index c97e2e8e92..4623e6ea02 100644 --- a/devices/src/virtio/block/block.rs +++ b/devices/src/virtio/block/block.rs @@ -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::*; diff --git a/devices/src/virtio/console.rs b/devices/src/virtio/console.rs index 2f4f24bb6d..cb74fb4ea1 100644 --- a/devices/src/virtio/console.rs +++ b/devices/src/virtio/console.rs @@ -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; diff --git a/devices/src/virtio/mod.rs b/devices/src/virtio/mod.rs index cfbbaf782c..b45e1f6ba4 100644 --- a/devices/src/virtio/mod.rs +++ b/devices/src/virtio/mod.rs @@ -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; diff --git a/devices/src/virtio/vhost/net.rs b/devices/src/virtio/vhost/net.rs index e0b77e88ef..78af0f5aaf 100644 --- a/devices/src/virtio/vhost/net.rs +++ b/devices/src/virtio/vhost/net.rs @@ -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; diff --git a/devices/src/virtio/vhost/user/device/block.rs b/devices/src/virtio/vhost/user/device/block.rs index b36cd42408..0a7f365a35 100644 --- a/devices/src/virtio/vhost/user/device/block.rs +++ b/devices/src/virtio/vhost/user/device/block.rs @@ -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 = OnceCell::new(); diff --git a/devices/src/virtio/vhost/user/device/console.rs b/devices/src/virtio/vhost/user/device/console.rs index bb20e5732b..3840e9e75f 100644 --- a/devices/src/virtio/vhost/user/device/console.rs +++ b/devices/src/virtio/vhost/user/device/console.rs @@ -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 = OnceCell::new(); diff --git a/devices/src/virtio/vhost/user/device/fs.rs b/devices/src/virtio/vhost/user/device/fs.rs index 2d927bc1f2..4d4604fbab 100644 --- a/devices/src/virtio/vhost/user/device/fs.rs +++ b/devices/src/virtio/vhost/user/device/fs.rs @@ -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 = OnceCell::new(); diff --git a/devices/src/virtio/vhost/user/device/gpu.rs b/devices/src/virtio/vhost/user/device/gpu.rs index c42569cc35..0828c73ba4 100644 --- a/devices/src/virtio/vhost/user/device/gpu.rs +++ b/devices/src/virtio/vhost/user/device/gpu.rs @@ -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 = OnceCell::new(); diff --git a/devices/src/virtio/vhost/user/device/net.rs b/devices/src/virtio/vhost/user/device/net.rs index af5bbabff7..7914174760 100644 --- a/devices/src/virtio/vhost/user/device/net.rs +++ b/devices/src/virtio/vhost/user/device/net.rs @@ -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 = OnceCell::new(); diff --git a/devices/src/virtio/vhost/user/device/vsock.rs b/devices/src/virtio/vhost/user/device/vsock.rs index 2879c520d8..74459c1221 100644 --- a/devices/src/virtio/vhost/user/device/vsock.rs +++ b/devices/src/virtio/vhost/user/device/vsock.rs @@ -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 = OnceCell::new(); diff --git a/devices/src/virtio/vhost/user/device/wl.rs b/devices/src/virtio/vhost/user/device/wl.rs index bd3bafcba7..9980bd82bc 100644 --- a/devices/src/virtio/vhost/user/device/wl.rs +++ b/devices/src/virtio/vhost/user/device/wl.rs @@ -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 = OnceCell::new(); diff --git a/hypervisor/src/aarch64.rs b/hypervisor/src/aarch64.rs index 55c1710cd6..b5c85e9925 100644 --- a/hypervisor/src/aarch64.rs +++ b/hypervisor/src/aarch64.rs @@ -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>; diff --git a/hypervisor/src/kvm/aarch64.rs b/hypervisor/src/kvm/aarch64.rs index ed93be526d..b825b4e2e4 100644 --- a/hypervisor/src/kvm/aarch64.rs +++ b/hypervisor/src/kvm/aarch64.rs @@ -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 { // 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 { diff --git a/hypervisor/src/kvm/mod.rs b/hypervisor/src/kvm/mod.rs index 1117d57b0c..b5b61198ff 100644 --- a/hypervisor/src/kvm/mod.rs +++ b/hypervisor/src/kvm/mod.rs @@ -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 { + pub fn new( + kvm: &Kvm, + guest_mem: GuestMemory, + protection_type: ProtectionType, + ) -> Result { // 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(); diff --git a/hypervisor/src/kvm/x86_64.rs b/hypervisor/src/kvm/x86_64.rs index ab486c3406..fec0f4d9c6 100644 --- a/hypervisor/src/kvm/x86_64.rs +++ b/hypervisor/src/kvm/x86_64.rs @@ -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 { + 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. diff --git a/hypervisor/src/lib.rs b/hypervisor/src/lib.rs index ac3642b798..c0ab404d85 100644 --- a/hypervisor/src/lib.rs +++ b/hypervisor/src/lib.rs @@ -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, +} diff --git a/kvm_sys/src/aarch64/bindings.rs b/kvm_sys/src/aarch64/bindings.rs index df8238ace8..a6350aad96 100644 --- a/kvm_sys/src/aarch64/bindings.rs +++ b/kvm_sys/src/aarch64/bindings.rs @@ -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; diff --git a/kvm_sys/src/x86/bindings.rs b/kvm_sys/src/x86/bindings.rs index a3d33ac893..0177e38349 100644 --- a/kvm_sys/src/x86/bindings.rs +++ b/kvm_sys/src/x86/bindings.rs @@ -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; diff --git a/src/crosvm.rs b/src/crosvm.rs index 093cf7138e..6279450c92 100644 --- a/src/crosvm.rs +++ b/src/crosvm.rs @@ -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; diff --git a/src/linux.rs b/src/linux.rs index d012b33a18..22ec840a73 100644 --- a/src/linux.rs +++ b/src/linux.rs @@ -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 { } 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 { diff --git a/src/main.rs b/src/main.rs index 756f63ac8f..f5cbcdf72e 100644 --- a/src/main.rs +++ b/src/main.rs @@ -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, diff --git a/x86_64/src/cpuid.rs b/x86_64/src/cpuid.rs index 3e49d03252..5eabc8f34f 100644 --- a/x86_64/src/cpuid.rs +++ b/x86_64/src/cpuid.rs @@ -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; diff --git a/x86_64/src/lib.rs b/x86_64/src/lib.rs index b0e201918f..f111054596 100644 --- a/x86_64/src/lib.rs +++ b/x86_64/src/lib.rs @@ -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; diff --git a/x86_64/src/test_integration.rs b/x86_64/src/test_integration.rs index 863eb830ca..758544711a 100644 --- a/x86_64/src/test_integration.rs +++ b/x86_64/src/test_integration.rs @@ -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| {