diff --git a/.github/workflows/cross-build.yaml b/.github/workflows/cross-build.yaml index ec5627d48..48407b82b 100644 --- a/.github/workflows/cross-build.yaml +++ b/.github/workflows/cross-build.yaml @@ -25,7 +25,7 @@ jobs: - name: Install arm64 libfdt run: wget http://ftp.us.debian.org/debian/pool/main/d/device-tree-compiler/libfdt-dev_1.6.0-1_arm64.deb && dpkg-deb -xv libfdt-dev_1.6.0-1_arm64.deb ./tlibfdtdev && sudo mkdir /tmmmp && mkdir target && mkdir target/debug && mkdir target/debug/deps && sudo cp ./tlibfdtdev/usr/lib/aarch64-linux-gnu/libfdt.a target/debug/deps/libfdt.a && echo "libfdt installed" - name: Disable "with-serde" in kvm-bindings - run: sed -i 's/"with-serde",\ //g' vmm/Cargo.toml + run: sed -i 's/"with-serde",\ //g' vmm/Cargo.toml && sed -i 's/"with-serde",\ //g' hypervisor/Cargo.toml - name: Build uses: actions-rs/cargo@v1 with: diff --git a/Cargo.lock b/Cargo.lock index 9d9233ef6..89457b7c6 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -57,8 +57,10 @@ name = "arch" version = "0.1.0" dependencies = [ "acpi_tables", + "anyhow", "arch_gen", "byteorder", + "hypervisor", "kvm-bindings", "kvm-ioctls", "libc", @@ -716,8 +718,7 @@ dependencies = [ "anyhow", "byteorder", "devices", - "kvm-bindings", - "kvm-ioctls", + "hypervisor", "libc", "log 0.4.8", "serde", @@ -1574,8 +1575,7 @@ dependencies = [ "credibility", "devices", "epoll", - "kvm-bindings", - "kvm-ioctls", + "hypervisor", "lazy_static", "libc", "linux-loader", diff --git a/arch/Cargo.toml b/arch/Cargo.toml index d6b800bb4..bd63bce2e 100644 --- a/arch/Cargo.toml +++ b/arch/Cargo.toml @@ -8,7 +8,9 @@ default = [] acpi = ["acpi_tables"] [dependencies] +anyhow = "1.0" byteorder = "1.3.4" +hypervisor = { path = "../hypervisor" } kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch" } kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" } libc = "0.2.71" diff --git a/arch/src/aarch64/gic.rs b/arch/src/aarch64/gic.rs index ded6d769c..04ba1ad84 100644 --- a/arch/src/aarch64/gic.rs +++ b/arch/src/aarch64/gic.rs @@ -1,9 +1,9 @@ // Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved. // SPDX-License-Identifier: Apache-2.0 -use std::{boxed::Box, result}; - use kvm_ioctls::{DeviceFd, VmFd}; +use std::sync::Arc; +use std::{boxed::Box, result}; use super::gicv2::GICv2; use super::gicv3::GICv3; @@ -12,7 +12,7 @@ use super::gicv3::GICv3; #[derive(Debug)] pub enum Error { /// Error while calling KVM ioctl for setting up the global interrupt controller. - CreateGIC(kvm_ioctls::Error), + CreateGIC(hypervisor::HypervisorVmError), /// Error while setting device attributes for the GIC. SetDeviceAttribute(kvm_ioctls::Error), } @@ -51,7 +51,7 @@ pub trait GICDevice: Send + Sync { Self: Sized; /// Initialize a GIC device - fn init_device(vm: &VmFd) -> Result + fn init_device(vm: &Arc) -> Result where Self: Sized, { @@ -120,7 +120,7 @@ pub trait GICDevice: Send + Sync { } /// Method to initialize the GIC device - fn new(vm: &VmFd, vcpu_count: u64) -> Result> + fn new(vm: &Arc, vcpu_count: u64) -> Result> where Self: Sized, { @@ -140,7 +140,7 @@ pub trait GICDevice: Send + Sync { /// /// It will try to create by default a GICv3 device. If that fails it will try /// to fall-back to a GICv2 device. -pub fn create_gic(vm: &VmFd, vcpu_count: u64) -> Result> { +pub fn create_gic(vm: &Arc, vcpu_count: u64) -> Result> { GICv3::new(vm, vcpu_count).or_else(|_| GICv2::new(vm, vcpu_count)) } diff --git a/arch/src/aarch64/mod.rs b/arch/src/aarch64/mod.rs index e4b4eba68..47b662aaa 100644 --- a/arch/src/aarch64/mod.rs +++ b/arch/src/aarch64/mod.rs @@ -20,6 +20,7 @@ use kvm_ioctls::*; use std::collections::HashMap; use std::ffi::CStr; use std::fmt::Debug; +use std::sync::Arc; use vm_memory::{ Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryMmap, GuestUsize, @@ -41,10 +42,10 @@ pub enum Error { REGSConfiguration(regs::Error), /// Error fetching prefered target - VcpuArmPreferredTarget(kvm_ioctls::Error), + VcpuArmPreferredTarget(hypervisor::HypervisorVmError), /// Error doing Vcpu Init on Arm. - VcpuArmInit(kvm_ioctls::Error), + VcpuArmInit(hypervisor::HypervisorCpuError), } impl From for super::Error { @@ -63,9 +64,9 @@ pub struct EntryPoint { /// Configure the specified VCPU, and return its MPIDR. pub fn configure_vcpu( - fd: &VcpuFd, + fd: &Arc, id: u8, - vm_fd: &VmFd, + vm_fd: &Arc, kernel_entry_point: Option, vm_memory: &GuestMemoryAtomic, ) -> super::Result { @@ -138,7 +139,7 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region #[allow(clippy::too_many_arguments)] #[allow(unused_variables)] pub fn configure_system( - vm_fd: &VmFd, + vm_fd: &Arc, guest_mem: &GuestMemoryMmap, cmdline_cstring: &CStr, vcpu_count: u64, @@ -200,13 +201,6 @@ pub fn get_host_cpu_phys_bits() -> u8 { 40 } -pub fn check_required_kvm_extensions(kvm: &Kvm) -> super::Result<()> { - if !kvm.check_extension(Cap::SignalMsi) { - return Err(super::Error::CapabilityMissing(Cap::SignalMsi)); - } - Ok(()) -} - #[cfg(test)] mod tests { use super::*; diff --git a/arch/src/aarch64/regs.rs b/arch/src/aarch64/regs.rs index dac3b6430..8356e2b5a 100644 --- a/arch/src/aarch64/regs.rs +++ b/arch/src/aarch64/regs.rs @@ -5,8 +5,6 @@ // Use of this source code is governed by a BSD-style license that can be // found in the THIRD-PARTY file. -use std::{mem, result}; - use super::get_fdt_addr; use kvm_bindings::{ user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK, @@ -16,16 +14,17 @@ use kvm_bindings::{ KVM_REG_ARM_CORE, KVM_REG_SIZE_U64, }; use kvm_ioctls::VcpuFd; - +use std::sync::Arc; +use std::{mem, result}; use vm_memory::GuestMemoryMmap; /// Errors thrown while setting aarch64 registers. #[derive(Debug)] pub enum Error { /// Failed to set core register (PC, PSTATE or general purpose ones). - SetCoreRegister(kvm_ioctls::Error), + SetCoreRegister(hypervisor::HypervisorCpuError), /// Failed to get a system register. - GetSysRegister(kvm_ioctls::Error), + GetSysRegister(hypervisor::HypervisorCpuError), } type Result = result::Result; @@ -122,7 +121,12 @@ arm64_sys_reg!(MPIDR_EL1, 3, 0, 0, 0, 5); /// * `cpu_id` - Index of current vcpu. /// * `boot_ip` - Starting instruction pointer. /// * `mem` - Reserved DRAM for current VM. -pub fn setup_regs(vcpu: &VcpuFd, cpu_id: u8, boot_ip: u64, mem: &GuestMemoryMmap) -> Result<()> { +pub fn setup_regs( + vcpu: &Arc, + cpu_id: u8, + boot_ip: u64, + mem: &GuestMemoryMmap, +) -> Result<()> { // Get the register index of the PSTATE (Processor State) register. vcpu.set_one_reg(arm64_core_reg!(pstate), PSTATE_FAULT_BITS_64) .map_err(Error::SetCoreRegister)?; @@ -148,7 +152,7 @@ pub fn setup_regs(vcpu: &VcpuFd, cpu_id: u8, boot_ip: u64, mem: &GuestMemoryMmap /// # Arguments /// /// * `vcpu` - Structure for the VCPU that holds the VCPU's fd. -pub fn read_mpidr(vcpu: &VcpuFd) -> Result { +pub fn read_mpidr(vcpu: &Arc) -> Result { vcpu.get_one_reg(MPIDR_EL1).map_err(Error::GetSysRegister) } diff --git a/arch/src/lib.rs b/arch/src/lib.rs index 2204b05be..66fdf899f 100644 --- a/arch/src/lib.rs +++ b/arch/src/lib.rs @@ -15,6 +15,7 @@ )] extern crate byteorder; +extern crate hypervisor; extern crate kvm_bindings; extern crate kvm_ioctls; extern crate libc; @@ -26,7 +27,6 @@ extern crate acpi_tables; extern crate arch_gen; extern crate linux_loader; -use kvm_ioctls::*; use std::fmt; use std::result; @@ -57,8 +57,6 @@ pub enum Error { ModlistSetup(vm_memory::GuestMemoryError), /// RSDP Beyond Guest Memory RSDPPastRamEnd, - /// Capability missing - CapabilityMissing(Cap), } /// Type for returning public functions outcome. @@ -89,9 +87,9 @@ pub mod aarch64; #[cfg(target_arch = "aarch64")] pub use aarch64::{ - arch_memory_regions, check_required_kvm_extensions, configure_system, configure_vcpu, - fdt::DeviceInfoForFDT, get_host_cpu_phys_bits, get_kernel_start, layout, - layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint, + arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFDT, + get_host_cpu_phys_bits, get_kernel_start, layout, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, + layout::IRQ_MAX, EntryPoint, }; #[cfg(target_arch = "x86_64")] @@ -99,9 +97,9 @@ pub mod x86_64; #[cfg(target_arch = "x86_64")] pub use x86_64::{ - arch_memory_regions, check_required_kvm_extensions, configure_system, configure_vcpu, - get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, - layout::CMDLINE_START, regs, BootProtocol, CpuidPatch, CpuidReg, EntryPoint, + arch_memory_regions, configure_system, configure_vcpu, get_host_cpu_phys_bits, + initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs, + BootProtocol, CpuidPatch, CpuidReg, EntryPoint, }; /// Safe wrapper for `sysconf(_SC_PAGESIZE)`. diff --git a/arch/src/x86_64/gdt.rs b/arch/src/x86_64/gdt.rs index 71ee6ca2d..4d36cea8e 100644 --- a/arch/src/x86_64/gdt.rs +++ b/arch/src/x86_64/gdt.rs @@ -8,8 +8,7 @@ // found in the LICENSE-BSD-3-Clause file. // For GDT details see arch/x86/include/asm/segment.h - -use kvm_bindings::kvm_segment; +use hypervisor::x86_64::SegmentRegister; /// Constructor for a conventional segment GDT (or LDT) entry. Derived from the kernel's segment.h. pub fn gdt_entry(flags: u16, base: u32, limit: u32) -> u64 { @@ -88,14 +87,14 @@ fn get_type(entry: u64) -> u8 { ((entry & 0x00000F0000000000) >> 40) as u8 } -/// Automatically build the kvm struct for SET_SREGS from the kernel bit fields. +/// Automatically build the struct for SET_SREGS from the kernel bit fields. /// /// # Arguments /// /// * `entry` - The gdt entry. /// * `table_index` - Index of the entry in the gdt table. -pub fn kvm_segment_from_gdt(entry: u64, table_index: u8) -> kvm_segment { - kvm_segment { +pub fn segment_from_gdt(entry: u64, table_index: u8) -> SegmentRegister { + SegmentRegister { base: get_base(entry), limit: get_limit(entry), selector: (table_index * 8) as u16, @@ -122,7 +121,7 @@ mod tests { #[test] fn field_parse() { let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff); - let seg = kvm_segment_from_gdt(gdt, 0); + let seg = segment_from_gdt(gdt, 0); // 0xA09B // 'A' assert_eq!(0x1, seg.g); diff --git a/arch/src/x86_64/interrupts.rs b/arch/src/x86_64/interrupts.rs index 1d016c872..b6ee8e4c2 100644 --- a/arch/src/x86_64/interrupts.rs +++ b/arch/src/x86_64/interrupts.rs @@ -8,19 +8,19 @@ use std::io::Cursor; use std::mem; use std::result; +use std::sync::Arc; use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt}; -use kvm_bindings::kvm_lapic_state; -use kvm_ioctls; +use hypervisor::x86_64::LapicState; #[derive(Debug)] pub enum Error { - GetLapic(kvm_ioctls::Error), - SetLapic(kvm_ioctls::Error), + GetLapic(anyhow::Error), + SetLapic(anyhow::Error), } -pub type Result = result::Result; +pub type Result = result::Result; // Defines poached from apicdef.h kernel header. const APIC_LVT0: usize = 0x350; @@ -28,7 +28,7 @@ const APIC_LVT1: usize = 0x360; const APIC_MODE_NMI: u32 = 0x4; const APIC_MODE_EXTINT: u32 = 0x7; -fn get_klapic_reg(klapic: &kvm_lapic_state, reg_offset: usize) -> u32 { +fn get_klapic_reg(klapic: &LapicState, reg_offset: usize) -> u32 { let sliceu8 = unsafe { // This array is only accessed as parts of a u32 word, so interpret it as a u8 array. // Cursors are only readable on arrays of u8, not i8(c_char). @@ -41,7 +41,7 @@ fn get_klapic_reg(klapic: &kvm_lapic_state, reg_offset: usize) -> u32 { .expect("Failed to read klapic register") } -fn set_klapic_reg(klapic: &mut kvm_lapic_state, reg_offset: usize, value: u32) { +fn set_klapic_reg(klapic: &mut LapicState, reg_offset: usize, value: u32) { let sliceu8 = unsafe { // This array is only accessed as parts of a u32 word, so interpret it as a u8 array. // Cursors are only readable on arrays of u8, not i8(c_char). @@ -62,8 +62,8 @@ fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 { /// /// # Arguments /// * `vcpu` - The VCPU object to configure. -pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> { - let mut klapic = vcpu.get_lapic().map_err(Error::GetLapic)?; +pub fn set_lint(vcpu: &Arc) -> Result<()> { + let mut klapic = vcpu.get_lapic()?; let lvt_lint0 = get_klapic_reg(&klapic, APIC_LVT0); set_klapic_reg( @@ -78,24 +78,23 @@ pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> { set_apic_delivery_mode(lvt_lint1, APIC_MODE_NMI), ); - vcpu.set_lapic(&klapic).map_err(Error::SetLapic) + vcpu.set_lapic(&klapic) } #[cfg(test)] mod tests { - extern crate kvm_ioctls; + extern crate rand; use self::rand::Rng; use super::*; - use kvm_ioctls::Kvm; const KVM_APIC_REG_SIZE: usize = 0x400; #[test] fn test_set_and_get_klapic_reg() { let reg_offset = 0x340; - let mut klapic = kvm_lapic_state::default(); + let mut klapic = LapicState::default(); set_klapic_reg(&mut klapic, reg_offset, 3); let value = get_klapic_reg(&klapic, reg_offset); assert_eq!(value, 3); @@ -105,7 +104,7 @@ mod tests { #[should_panic] fn test_set_and_get_klapic_out_of_bounds() { let reg_offset = KVM_APIC_REG_SIZE + 10; - let mut klapic = kvm_lapic_state::default(); + let mut klapic = LapicState::default(); set_klapic_reg(&mut klapic, reg_offset, 3); } @@ -122,13 +121,14 @@ mod tests { #[test] fn test_setlint() { - let kvm = kvm_ioctls::Kvm::new().unwrap(); - assert!(kvm.check_extension(kvm_ioctls::Cap::Irqchip)); - let vm = kvm.create_vm().unwrap(); - //the get_lapic ioctl will fail if there is no irqchip created beforehand. + let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap(); + let hv: Arc = Arc::new(kvm); + let vm = hv.create_vm().expect("new VM fd creation failed"); + assert!(hv.check_capability(hypervisor::kvm::Cap::Irqchip)); + // Calling get_lapic will fail if there is no irqchip before hand. assert!(vm.create_irq_chip().is_ok()); let vcpu = vm.create_vcpu(0).unwrap(); - let klapic_before: kvm_lapic_state = vcpu.get_lapic().unwrap(); + let klapic_before: LapicState = vcpu.get_lapic().unwrap(); // Compute the value that is expected to represent LVT0 and LVT1. let lint0 = get_klapic_reg(&klapic_before, APIC_LVT0); @@ -139,20 +139,10 @@ mod tests { set_lint(&vcpu).unwrap(); // Compute the value that represents LVT0 and LVT1 after set_lint. - let klapic_actual: kvm_lapic_state = vcpu.get_lapic().unwrap(); + let klapic_actual: LapicState = vcpu.get_lapic().unwrap(); let lint0_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT0); let lint1_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT1); assert_eq!(lint0_mode_expected, lint0_mode_actual); assert_eq!(lint1_mode_expected, lint1_mode_actual); } - - #[test] - fn test_setlint_fails() { - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); - let vcpu = vm.create_vcpu(0).unwrap(); - // 'get_lapic' ioctl triggered by the 'set_lint' function will fail if there is no - // irqchip created beforehand. - assert!(set_lint(&vcpu).is_err()); - } } diff --git a/arch/src/x86_64/mod.rs b/arch/src/x86_64/mod.rs index 1e1ad9346..63a0eb68d 100644 --- a/arch/src/x86_64/mod.rs +++ b/arch/src/x86_64/mod.rs @@ -6,7 +6,7 @@ // 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 // found in the LICENSE-BSD-3-Clause file. - +use std::sync::Arc; mod gdt; pub mod interrupts; pub mod layout; @@ -15,8 +15,7 @@ mod mptable; pub mod regs; use crate::InitramfsConfig; use crate::RegionType; -use kvm_bindings::CpuId; -use kvm_ioctls::*; +use hypervisor::CpuId; use linux_loader::loader::bootparam::{boot_params, setup_header}; use linux_loader::loader::elf::start_info::{ hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info, @@ -111,10 +110,10 @@ pub enum Error { MSRSConfiguration(regs::Error), /// The call to KVM_SET_CPUID2 failed. - SetSupportedCpusFailed(kvm_ioctls::Error), + SetSupportedCpusFailed(anyhow::Error), /// Cannot set the local interruption due to bad configuration. - LocalIntConfiguration(interrupts::Error), + LocalIntConfiguration(anyhow::Error), } impl From for super::Error { @@ -200,7 +199,7 @@ impl CpuidPatch { } pub fn configure_vcpu( - fd: &VcpuFd, + fd: &Arc, id: u8, kernel_entry_point: Option, vm_memory: &GuestMemoryAtomic, @@ -210,7 +209,7 @@ pub fn configure_vcpu( CpuidPatch::set_cpuid_reg(&mut cpuid, 0xb, None, CpuidReg::EDX, u32::from(id)); CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id)); fd.set_cpuid2(&cpuid) - .map_err(Error::SetSupportedCpusFailed)?; + .map_err(|e| Error::SetSupportedCpusFailed(e.into()))?; regs::setup_msrs(fd).map_err(Error::MSRSConfiguration)?; if let Some(kernel_entry_point) = kernel_entry_point { @@ -227,7 +226,7 @@ pub fn configure_vcpu( regs::setup_sregs(&vm_memory.memory(), fd, kernel_entry_point.protocol) .map_err(Error::SREGSConfiguration)?; } - interrupts::set_lint(fd).map_err(Error::LocalIntConfiguration)?; + interrupts::set_lint(fd).map_err(|e| Error::LocalIntConfiguration(e.into()))?; Ok(()) } @@ -616,19 +615,6 @@ pub fn get_host_cpu_phys_bits() -> u8 { } } -pub fn check_required_kvm_extensions(kvm: &Kvm) -> super::Result<()> { - if !kvm.check_extension(Cap::SignalMsi) { - return Err(super::Error::CapabilityMissing(Cap::SignalMsi)); - } - if !kvm.check_extension(Cap::TscDeadlineTimer) { - return Err(super::Error::CapabilityMissing(Cap::TscDeadlineTimer)); - } - if !kvm.check_extension(Cap::SplitIrqchip) { - return Err(super::Error::CapabilityMissing(Cap::SplitIrqchip)); - } - Ok(()) -} - pub fn update_cpuid_topology( cpuid: &mut CpuId, threads_per_core: u8, diff --git a/arch/src/x86_64/regs.rs b/arch/src/x86_64/regs.rs index 302740762..6a45293b3 100644 --- a/arch/src/x86_64/regs.rs +++ b/arch/src/x86_64/regs.rs @@ -6,35 +6,29 @@ // 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 // found in the LICENSE-BSD-3-Clause file. - +use std::sync::Arc; use std::{mem, result}; -use super::gdt::{gdt_entry, kvm_segment_from_gdt}; +use super::gdt::{gdt_entry, segment_from_gdt}; use super::BootProtocol; -use arch_gen::x86::msr_index; -use kvm_bindings::{kvm_fpu, kvm_msr_entry, kvm_regs, kvm_sregs, Msrs}; -use kvm_ioctls::VcpuFd; +use hypervisor::x86_64::{FpuState, SpecialRegisters, StandardRegisters}; use layout::{ BOOT_GDT_START, BOOT_IDT_START, PDE_START, PDPTE_START, PML4_START, PML5_START, PVH_INFO_START, }; use vm_memory::{Address, Bytes, GuestMemory, GuestMemoryError, GuestMemoryMmap}; -// MTRR constants -const MTRR_ENABLE: u64 = 0x800; // IA32_MTRR_DEF_TYPE MSR: E (MTRRs enabled) flag, bit 11 -const MTRR_MEM_TYPE_WB: u64 = 0x6; - #[derive(Debug)] pub enum Error { /// Failed to get SREGs for this CPU. - GetStatusRegisters(kvm_ioctls::Error), + GetStatusRegisters(hypervisor::HypervisorCpuError), /// Failed to set base registers for this CPU. - SetBaseRegisters(kvm_ioctls::Error), + SetBaseRegisters(hypervisor::HypervisorCpuError), /// Failed to configure the FPU. - SetFPURegisters(kvm_ioctls::Error), + SetFPURegisters(hypervisor::HypervisorCpuError), /// Setting up MSRs failed. - SetModelSpecificRegisters(kvm_ioctls::Error), + SetModelSpecificRegisters(hypervisor::HypervisorCpuError), /// Failed to set SREGs for this CPU. - SetStatusRegisters(kvm_ioctls::Error), + SetStatusRegisters(hypervisor::HypervisorCpuError), /// Checking the GDT address failed. CheckGDTAddr, /// Writing the GDT to RAM failed. @@ -58,8 +52,8 @@ pub type Result = result::Result; /// # Arguments /// /// * `vcpu` - Structure for the VCPU that holds the VCPU's fd. -pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> { - let fpu: kvm_fpu = kvm_fpu { +pub fn setup_fpu(vcpu: &Arc) -> Result<()> { + let fpu: FpuState = FpuState { fcw: 0x37f, mxcsr: 0x1f80, ..Default::default() @@ -73,8 +67,8 @@ pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> { /// # Arguments /// /// * `vcpu` - Structure for the VCPU that holds the VCPU's fd. -pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> { - vcpu.set_msrs(&boot_msr_entries()) +pub fn setup_msrs(vcpu: &Arc) -> Result<()> { + vcpu.set_msrs(&hypervisor::kvm::x86_64::boot_msr_entries()) .map_err(Error::SetModelSpecificRegisters)?; Ok(()) @@ -89,22 +83,22 @@ pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> { /// * `boot_sp` - Starting stack pointer. /// * `boot_si` - Must point to zero page address per Linux ABI. pub fn setup_regs( - vcpu: &VcpuFd, + vcpu: &Arc, boot_ip: u64, boot_sp: u64, boot_si: u64, boot_prot: BootProtocol, ) -> Result<()> { - let regs: kvm_regs = match boot_prot { + let regs: StandardRegisters = match boot_prot { // Configure regs as required by PVH boot protocol. - BootProtocol::PvhBoot => kvm_regs { + BootProtocol::PvhBoot => StandardRegisters { rflags: 0x0000000000000002u64, rbx: PVH_INFO_START.raw_value(), rip: boot_ip, ..Default::default() }, // Configure regs as required by Linux 64-bit boot protocol. - BootProtocol::LinuxBoot => kvm_regs { + BootProtocol::LinuxBoot => StandardRegisters { rflags: 0x0000000000000002u64, rip: boot_ip, rsp: boot_sp, @@ -122,8 +116,12 @@ pub fn setup_regs( /// /// * `mem` - The memory that will be passed to the guest. /// * `vcpu` - Structure for the VCPU that holds the VCPU's fd. -pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &VcpuFd, boot_prot: BootProtocol) -> Result<()> { - let mut sregs: kvm_sregs = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?; +pub fn setup_sregs( + mem: &GuestMemoryMmap, + vcpu: &Arc, + boot_prot: BootProtocol, +) -> Result<()> { + let mut sregs: SpecialRegisters = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?; configure_segments_and_sregs(mem, &mut sregs, boot_prot)?; @@ -164,7 +162,7 @@ fn write_idt_value(val: u64, guest_mem: &GuestMemoryMmap) -> Result<()> { fn configure_segments_and_sregs( mem: &GuestMemoryMmap, - sregs: &mut kvm_sregs, + sregs: &mut SpecialRegisters, boot_prot: BootProtocol, ) -> Result<()> { let gdt_table: [u64; BOOT_GDT_MAX as usize] = match boot_prot { @@ -188,9 +186,9 @@ fn configure_segments_and_sregs( } }; - let code_seg = kvm_segment_from_gdt(gdt_table[1], 1); - let data_seg = kvm_segment_from_gdt(gdt_table[2], 2); - let tss_seg = kvm_segment_from_gdt(gdt_table[3], 3); + let code_seg = segment_from_gdt(gdt_table[1], 1); + let data_seg = segment_from_gdt(gdt_table[2], 2); + let tss_seg = segment_from_gdt(gdt_table[3], 3); // Write segments write_gdt_table(&gdt_table[..], mem)?; @@ -224,9 +222,8 @@ fn configure_segments_and_sregs( Ok(()) } -fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> { +fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut SpecialRegisters) -> Result<()> { // Puts PML5 or PML4 right after zero page but aligned to 4k. - if unsafe { std::arch::x86_64::__cpuid(7).ecx } & (1 << 16) != 0 { // Entry covering VA [0..256TB) mem.write_obj(PML4_START.raw_value() | 0x03, PML5_START) @@ -259,52 +256,12 @@ fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> Ok(()) } -macro_rules! kvm_msr { - ($msr:expr) => { - kvm_msr_entry { - index: $msr, - data: 0x0, - ..Default::default() - } - }; -} - -macro_rules! kvm_msr_data { - ($msr:expr, $data:expr) => { - kvm_msr_entry { - index: $msr, - data: $data, - ..Default::default() - } - }; -} - -pub fn boot_msr_entries() -> Msrs { - Msrs::from_entries(&[ - kvm_msr!(msr_index::MSR_IA32_SYSENTER_CS), - kvm_msr!(msr_index::MSR_IA32_SYSENTER_ESP), - kvm_msr!(msr_index::MSR_IA32_SYSENTER_EIP), - kvm_msr!(msr_index::MSR_STAR), - kvm_msr!(msr_index::MSR_CSTAR), - kvm_msr!(msr_index::MSR_LSTAR), - kvm_msr!(msr_index::MSR_KERNEL_GS_BASE), - kvm_msr!(msr_index::MSR_SYSCALL_MASK), - kvm_msr!(msr_index::MSR_IA32_TSC), - kvm_msr_data!( - msr_index::MSR_IA32_MISC_ENABLE, - msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64 - ), - kvm_msr_data!(msr_index::MSR_MTRRdefType, MTRR_ENABLE | MTRR_MEM_TYPE_WB), - ]) -} - #[cfg(test)] mod tests { extern crate kvm_ioctls; extern crate vm_memory; use super::*; - use kvm_ioctls::Kvm; use vm_memory::{GuestAddress, GuestMemoryMmap}; fn create_guest_mem() -> GuestMemoryMmap { @@ -317,7 +274,7 @@ mod tests { #[test] fn segments_and_sregs() { - let mut sregs: kvm_sregs = Default::default(); + let mut sregs: SpecialRegisters = Default::default(); let gm = create_guest_mem(); configure_segments_and_sregs(&gm, &mut sregs, BootProtocol::LinuxBoot).unwrap(); @@ -381,7 +338,7 @@ mod tests { #[test] fn page_tables() { - let mut sregs: kvm_sregs = Default::default(); + let mut sregs: SpecialRegisters = Default::default(); let gm = create_guest_mem(); setup_page_tables(&gm, &mut sregs).unwrap(); @@ -408,20 +365,21 @@ mod tests { #[test] fn test_setup_fpu() { - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); + let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap(); + let hv: Arc = Arc::new(kvm); + let vm = hv.create_vm().expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0).unwrap(); setup_fpu(&vcpu).unwrap(); - let expected_fpu: kvm_fpu = kvm_fpu { + let expected_fpu: FpuState = FpuState { fcw: 0x37f, mxcsr: 0x1f80, ..Default::default() }; - let actual_fpu: kvm_fpu = vcpu.get_fpu().unwrap(); + let actual_fpu: FpuState = vcpu.get_fpu().unwrap(); // TODO: auto-generate kvm related structures with PartialEq on. assert_eq!(expected_fpu.fcw, actual_fpu.fcw); - // Setting the mxcsr register from kvm_fpu inside setup_fpu does not influence anything. + // Setting the mxcsr register from FpuState inside setup_fpu does not influence anything. // See 'kvm_arch_vcpu_ioctl_set_fpu' from arch/x86/kvm/x86.c. // The mxcsr will stay 0 and the assert below fails. Decide whether or not we should // remove it at all. @@ -430,14 +388,18 @@ mod tests { #[test] fn test_setup_msrs() { - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); + use hypervisor::arch::x86::msr_index; + use hypervisor::x86_64::{MsrEntries, MsrEntry}; + + let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap(); + let hv: Arc = Arc::new(kvm); + let vm = hv.create_vm().expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0).unwrap(); setup_msrs(&vcpu).unwrap(); // This test will check against the last MSR entry configured (the tenth one). // See create_msr_entries for details. - let mut msrs = Msrs::from_entries(&[kvm_msr_entry { + let mut msrs = MsrEntries::from_entries(&[MsrEntry { index: msr_index::MSR_IA32_MISC_ENABLE, ..Default::default() }]); @@ -450,17 +412,18 @@ mod tests { // Official entries that were setup when we did setup_msrs. We need to assert that the // tenth one (i.e the one with index msr_index::MSR_IA32_MISC_ENABLE has the data we // expect. - let entry_vec = boot_msr_entries(); + let entry_vec = hypervisor::x86_64::boot_msr_entries(); assert_eq!(entry_vec.as_slice()[9], msrs.as_slice()[0]); } #[test] fn test_setup_regs() { - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); + let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap(); + let hv: Arc = Arc::new(kvm); + let vm = hv.create_vm().expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0).unwrap(); - let expected_regs: kvm_regs = kvm_regs { + let expected_regs: StandardRegisters = StandardRegisters { rflags: 0x0000000000000002u64, rip: 1, rsp: 2, @@ -478,23 +441,24 @@ mod tests { ) .unwrap(); - let actual_regs: kvm_regs = vcpu.get_regs().unwrap(); + let actual_regs: StandardRegisters = vcpu.get_regs().unwrap(); assert_eq!(actual_regs, expected_regs); } #[test] fn test_setup_sregs() { - let kvm = Kvm::new().unwrap(); - let vm = kvm.create_vm().unwrap(); + let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap(); + let hv: Arc = Arc::new(kvm); + let vm = hv.create_vm().expect("new VM fd creation failed"); let vcpu = vm.create_vcpu(0).unwrap(); - let mut expected_sregs: kvm_sregs = vcpu.get_sregs().unwrap(); + let mut expected_sregs: SpecialRegisters = vcpu.get_sregs().unwrap(); let gm = create_guest_mem(); configure_segments_and_sregs(&gm, &mut expected_sregs, BootProtocol::LinuxBoot).unwrap(); setup_page_tables(&gm, &mut expected_sregs).unwrap(); setup_sregs(&gm, &vcpu, BootProtocol::LinuxBoot).unwrap(); - let actual_sregs: kvm_sregs = vcpu.get_sregs().unwrap(); + let actual_sregs: SpecialRegisters = vcpu.get_sregs().unwrap(); assert_eq!(expected_sregs, actual_sregs); } } diff --git a/arch_gen/src/x86/mod.rs b/arch_gen/src/x86/mod.rs index 5fa21e5e1..e6d153186 100644 --- a/arch_gen/src/x86/mod.rs +++ b/arch_gen/src/x86/mod.rs @@ -20,6 +20,3 @@ #[allow(non_upper_case_globals)] #[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)] pub mod mpspec; -#[allow(non_upper_case_globals)] -#[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)] -pub mod msr_index; diff --git a/arch_gen/src/x86/msr_index.rs b/arch_gen/src/x86/msr_index.rs deleted file mode 100644 index 81a7b06a0..000000000 --- a/arch_gen/src/x86/msr_index.rs +++ /dev/null @@ -1,543 +0,0 @@ -// Copyright 2017 The Chromium OS Authors. All rights reserved. -// Use of this source code is governed by a BSD-style license that can be -// found in the LICENSE-BSD-3-Clause file. - -/* - * automatically generated by rust-bindgen - * From upstream linux msr-index.h at commit: - * 806276b7f07a39a1cc3f38bb1ef5c573d4594a38 - */ - -pub const MSR_EFER: ::std::os::raw::c_uint = 0xc0000080; -pub const MSR_STAR: ::std::os::raw::c_uint = 0xc0000081; -pub const MSR_LSTAR: ::std::os::raw::c_uint = 0xc0000082; -pub const MSR_CSTAR: ::std::os::raw::c_uint = 0xc0000083; -pub const MSR_SYSCALL_MASK: ::std::os::raw::c_uint = 0xc0000084; -pub const MSR_FS_BASE: ::std::os::raw::c_uint = 0xc0000100; -pub const MSR_GS_BASE: ::std::os::raw::c_uint = 0xc0000101; -pub const MSR_KERNEL_GS_BASE: ::std::os::raw::c_uint = 0xc0000102; -pub const MSR_TSC_AUX: ::std::os::raw::c_uint = 0xc0000103; -pub const _EFER_SCE: ::std::os::raw::c_uint = 0x00000000; -pub const _EFER_LME: ::std::os::raw::c_uint = 0x00000008; -pub const _EFER_LMA: ::std::os::raw::c_uint = 0x0000000a; -pub const _EFER_NX: ::std::os::raw::c_uint = 0x0000000b; -pub const _EFER_SVME: ::std::os::raw::c_uint = 0x0000000c; -pub const _EFER_LMSLE: ::std::os::raw::c_uint = 0x0000000d; -pub const _EFER_FFXSR: ::std::os::raw::c_uint = 0x0000000e; -pub const EFER_SCE: ::std::os::raw::c_uint = 0x00000001; -pub const EFER_LME: ::std::os::raw::c_uint = 0x00000100; -pub const EFER_LMA: ::std::os::raw::c_uint = 0x00000400; -pub const EFER_NX: ::std::os::raw::c_uint = 0x00000800; -pub const EFER_SVME: ::std::os::raw::c_uint = 0x00001000; -pub const EFER_LMSLE: ::std::os::raw::c_uint = 0x00002000; -pub const EFER_FFXSR: ::std::os::raw::c_uint = 0x00004000; -pub const MSR_PPIN_CTL: ::std::os::raw::c_uint = 0x0000004e; -pub const MSR_PPIN: ::std::os::raw::c_uint = 0x0000004f; -pub const MSR_IA32_PERFCTR0: ::std::os::raw::c_uint = 0x000000c1; -pub const MSR_IA32_PERFCTR1: ::std::os::raw::c_uint = 0x000000c2; -pub const MSR_FSB_FREQ: ::std::os::raw::c_uint = 0x000000cd; -pub const MSR_PLATFORM_INFO: ::std::os::raw::c_uint = 0x000000ce; -pub const MSR_PKG_CST_CONFIG_CONTROL: ::std::os::raw::c_uint = 0x000000e2; -pub const NHM_C3_AUTO_DEMOTE: ::std::os::raw::c_uint = 0x02000000; -pub const NHM_C1_AUTO_DEMOTE: ::std::os::raw::c_uint = 0x04000000; -pub const ATM_LNC_C6_AUTO_DEMOTE: ::std::os::raw::c_uint = 0x02000000; -pub const SNB_C1_AUTO_UNDEMOTE: ::std::os::raw::c_uint = 0x08000000; -pub const SNB_C3_AUTO_UNDEMOTE: ::std::os::raw::c_uint = 0x10000000; -pub const MSR_MTRRcap: ::std::os::raw::c_uint = 0x000000fe; -pub const MSR_IA32_BBL_CR_CTL: ::std::os::raw::c_uint = 0x00000119; -pub const MSR_IA32_BBL_CR_CTL3: ::std::os::raw::c_uint = 0x0000011e; -pub const MSR_IA32_SYSENTER_CS: ::std::os::raw::c_uint = 0x00000174; -pub const MSR_IA32_SYSENTER_ESP: ::std::os::raw::c_uint = 0x00000175; -pub const MSR_IA32_SYSENTER_EIP: ::std::os::raw::c_uint = 0x00000176; -pub const MSR_IA32_MCG_CAP: ::std::os::raw::c_uint = 0x00000179; -pub const MSR_IA32_MCG_STATUS: ::std::os::raw::c_uint = 0x0000017a; -pub const MSR_IA32_MCG_CTL: ::std::os::raw::c_uint = 0x0000017b; -pub const MSR_IA32_MCG_EXT_CTL: ::std::os::raw::c_uint = 0x000004d0; -pub const MSR_OFFCORE_RSP_0: ::std::os::raw::c_uint = 0x000001a6; -pub const MSR_OFFCORE_RSP_1: ::std::os::raw::c_uint = 0x000001a7; -pub const MSR_TURBO_RATIO_LIMIT: ::std::os::raw::c_uint = 0x000001ad; -pub const MSR_TURBO_RATIO_LIMIT1: ::std::os::raw::c_uint = 0x000001ae; -pub const MSR_TURBO_RATIO_LIMIT2: ::std::os::raw::c_uint = 0x000001af; -pub const MSR_LBR_SELECT: ::std::os::raw::c_uint = 0x000001c8; -pub const MSR_LBR_TOS: ::std::os::raw::c_uint = 0x000001c9; -pub const MSR_LBR_NHM_FROM: ::std::os::raw::c_uint = 0x00000680; -pub const MSR_LBR_NHM_TO: ::std::os::raw::c_uint = 0x000006c0; -pub const MSR_LBR_CORE_FROM: ::std::os::raw::c_uint = 0x00000040; -pub const MSR_LBR_CORE_TO: ::std::os::raw::c_uint = 0x00000060; -pub const MSR_LBR_INFO_0: ::std::os::raw::c_uint = 0x00000dc0; -pub const LBR_INFO_CYCLES: ::std::os::raw::c_uint = 0x0000ffff; -pub const MSR_IA32_PEBS_ENABLE: ::std::os::raw::c_uint = 0x000003f1; -pub const MSR_IA32_DS_AREA: ::std::os::raw::c_uint = 0x00000600; -pub const MSR_IA32_PERF_CAPABILITIES: ::std::os::raw::c_uint = 0x00000345; -pub const MSR_PEBS_LD_LAT_THRESHOLD: ::std::os::raw::c_uint = 0x000003f6; -pub const MSR_IA32_RTIT_CTL: ::std::os::raw::c_uint = 0x00000570; -pub const MSR_IA32_RTIT_STATUS: ::std::os::raw::c_uint = 0x00000571; -pub const MSR_IA32_RTIT_ADDR0_A: ::std::os::raw::c_uint = 0x00000580; -pub const MSR_IA32_RTIT_ADDR0_B: ::std::os::raw::c_uint = 0x00000581; -pub const MSR_IA32_RTIT_ADDR1_A: ::std::os::raw::c_uint = 0x00000582; -pub const MSR_IA32_RTIT_ADDR1_B: ::std::os::raw::c_uint = 0x00000583; -pub const MSR_IA32_RTIT_ADDR2_A: ::std::os::raw::c_uint = 0x00000584; -pub const MSR_IA32_RTIT_ADDR2_B: ::std::os::raw::c_uint = 0x00000585; -pub const MSR_IA32_RTIT_ADDR3_A: ::std::os::raw::c_uint = 0x00000586; -pub const MSR_IA32_RTIT_ADDR3_B: ::std::os::raw::c_uint = 0x00000587; -pub const MSR_IA32_RTIT_CR3_MATCH: ::std::os::raw::c_uint = 0x00000572; -pub const MSR_IA32_RTIT_OUTPUT_BASE: ::std::os::raw::c_uint = 0x00000560; -pub const MSR_IA32_RTIT_OUTPUT_MASK: ::std::os::raw::c_uint = 0x00000561; -pub const MSR_MTRRfix64K_00000: ::std::os::raw::c_uint = 0x00000250; -pub const MSR_MTRRfix16K_80000: ::std::os::raw::c_uint = 0x00000258; -pub const MSR_MTRRfix16K_A0000: ::std::os::raw::c_uint = 0x00000259; -pub const MSR_MTRRfix4K_C0000: ::std::os::raw::c_uint = 0x00000268; -pub const MSR_MTRRfix4K_C8000: ::std::os::raw::c_uint = 0x00000269; -pub const MSR_MTRRfix4K_D0000: ::std::os::raw::c_uint = 0x0000026a; -pub const MSR_MTRRfix4K_D8000: ::std::os::raw::c_uint = 0x0000026b; -pub const MSR_MTRRfix4K_E0000: ::std::os::raw::c_uint = 0x0000026c; -pub const MSR_MTRRfix4K_E8000: ::std::os::raw::c_uint = 0x0000026d; -pub const MSR_MTRRfix4K_F0000: ::std::os::raw::c_uint = 0x0000026e; -pub const MSR_MTRRfix4K_F8000: ::std::os::raw::c_uint = 0x0000026f; -pub const MSR_MTRRdefType: ::std::os::raw::c_uint = 0x000002ff; -pub const MSR_IA32_CR_PAT: ::std::os::raw::c_uint = 0x00000277; -pub const MSR_IA32_DEBUGCTLMSR: ::std::os::raw::c_uint = 0x000001d9; -pub const MSR_IA32_LASTBRANCHFROMIP: ::std::os::raw::c_uint = 0x000001db; -pub const MSR_IA32_LASTBRANCHTOIP: ::std::os::raw::c_uint = 0x000001dc; -pub const MSR_IA32_LASTINTFROMIP: ::std::os::raw::c_uint = 0x000001dd; -pub const MSR_IA32_LASTINTTOIP: ::std::os::raw::c_uint = 0x000001de; -pub const DEBUGCTLMSR_LBR: ::std::os::raw::c_uint = 0x00000001; -pub const DEBUGCTLMSR_BTF: ::std::os::raw::c_uint = 0x00000002; -pub const DEBUGCTLMSR_TR: ::std::os::raw::c_uint = 0x00000040; -pub const DEBUGCTLMSR_BTS: ::std::os::raw::c_uint = 0x00000080; -pub const DEBUGCTLMSR_BTINT: ::std::os::raw::c_uint = 0x00000100; -pub const DEBUGCTLMSR_BTS_OFF_OS: ::std::os::raw::c_uint = 0x00000200; -pub const DEBUGCTLMSR_BTS_OFF_USR: ::std::os::raw::c_uint = 0x00000400; -pub const DEBUGCTLMSR_FREEZE_LBRS_ON_PMI: ::std::os::raw::c_uint = 0x00000800; -pub const MSR_PEBS_FRONTEND: ::std::os::raw::c_uint = 0x000003f7; -pub const MSR_IA32_POWER_CTL: ::std::os::raw::c_uint = 0x000001fc; -pub const MSR_IA32_MC0_CTL: ::std::os::raw::c_uint = 0x00000400; -pub const MSR_IA32_MC0_STATUS: ::std::os::raw::c_uint = 0x00000401; -pub const MSR_IA32_MC0_ADDR: ::std::os::raw::c_uint = 0x00000402; -pub const MSR_IA32_MC0_MISC: ::std::os::raw::c_uint = 0x00000403; -pub const MSR_PKG_C3_RESIDENCY: ::std::os::raw::c_uint = 0x000003f8; -pub const MSR_PKG_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003f9; -pub const MSR_ATOM_PKG_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003fa; -pub const MSR_PKG_C7_RESIDENCY: ::std::os::raw::c_uint = 0x000003fa; -pub const MSR_CORE_C3_RESIDENCY: ::std::os::raw::c_uint = 0x000003fc; -pub const MSR_CORE_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003fd; -pub const MSR_CORE_C7_RESIDENCY: ::std::os::raw::c_uint = 0x000003fe; -pub const MSR_KNL_CORE_C6_RESIDENCY: ::std::os::raw::c_uint = 0x000003ff; -pub const MSR_PKG_C2_RESIDENCY: ::std::os::raw::c_uint = 0x0000060d; -pub const MSR_PKG_C8_RESIDENCY: ::std::os::raw::c_uint = 0x00000630; -pub const MSR_PKG_C9_RESIDENCY: ::std::os::raw::c_uint = 0x00000631; -pub const MSR_PKG_C10_RESIDENCY: ::std::os::raw::c_uint = 0x00000632; -pub const MSR_PKGC3_IRTL: ::std::os::raw::c_uint = 0x0000060a; -pub const MSR_PKGC6_IRTL: ::std::os::raw::c_uint = 0x0000060b; -pub const MSR_PKGC7_IRTL: ::std::os::raw::c_uint = 0x0000060c; -pub const MSR_PKGC8_IRTL: ::std::os::raw::c_uint = 0x00000633; -pub const MSR_PKGC9_IRTL: ::std::os::raw::c_uint = 0x00000634; -pub const MSR_PKGC10_IRTL: ::std::os::raw::c_uint = 0x00000635; -pub const MSR_RAPL_POWER_UNIT: ::std::os::raw::c_uint = 0x00000606; -pub const MSR_PKG_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000610; -pub const MSR_PKG_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000611; -pub const MSR_PKG_PERF_STATUS: ::std::os::raw::c_uint = 0x00000613; -pub const MSR_PKG_POWER_INFO: ::std::os::raw::c_uint = 0x00000614; -pub const MSR_DRAM_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000618; -pub const MSR_DRAM_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000619; -pub const MSR_DRAM_PERF_STATUS: ::std::os::raw::c_uint = 0x0000061b; -pub const MSR_DRAM_POWER_INFO: ::std::os::raw::c_uint = 0x0000061c; -pub const MSR_PP0_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000638; -pub const MSR_PP0_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000639; -pub const MSR_PP0_POLICY: ::std::os::raw::c_uint = 0x0000063a; -pub const MSR_PP0_PERF_STATUS: ::std::os::raw::c_uint = 0x0000063b; -pub const MSR_PP1_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000640; -pub const MSR_PP1_ENERGY_STATUS: ::std::os::raw::c_uint = 0x00000641; -pub const MSR_PP1_POLICY: ::std::os::raw::c_uint = 0x00000642; -pub const MSR_CONFIG_TDP_NOMINAL: ::std::os::raw::c_uint = 0x00000648; -pub const MSR_CONFIG_TDP_LEVEL_1: ::std::os::raw::c_uint = 0x00000649; -pub const MSR_CONFIG_TDP_LEVEL_2: ::std::os::raw::c_uint = 0x0000064a; -pub const MSR_CONFIG_TDP_CONTROL: ::std::os::raw::c_uint = 0x0000064b; -pub const MSR_TURBO_ACTIVATION_RATIO: ::std::os::raw::c_uint = 0x0000064c; -pub const MSR_PLATFORM_ENERGY_STATUS: ::std::os::raw::c_uint = 0x0000064d; -pub const MSR_PKG_WEIGHTED_CORE_C0_RES: ::std::os::raw::c_uint = 0x00000658; -pub const MSR_PKG_ANY_CORE_C0_RES: ::std::os::raw::c_uint = 0x00000659; -pub const MSR_PKG_ANY_GFXE_C0_RES: ::std::os::raw::c_uint = 0x0000065a; -pub const MSR_PKG_BOTH_CORE_GFXE_C0_RES: ::std::os::raw::c_uint = 0x0000065b; -pub const MSR_CORE_C1_RES: ::std::os::raw::c_uint = 0x00000660; -pub const MSR_MODULE_C6_RES_MS: ::std::os::raw::c_uint = 0x00000664; -pub const MSR_CC6_DEMOTION_POLICY_CONFIG: ::std::os::raw::c_uint = 0x00000668; -pub const MSR_MC6_DEMOTION_POLICY_CONFIG: ::std::os::raw::c_uint = 0x00000669; -pub const MSR_ATOM_CORE_RATIOS: ::std::os::raw::c_uint = 0x0000066a; -pub const MSR_ATOM_CORE_VIDS: ::std::os::raw::c_uint = 0x0000066b; -pub const MSR_ATOM_CORE_TURBO_RATIOS: ::std::os::raw::c_uint = 0x0000066c; -pub const MSR_ATOM_CORE_TURBO_VIDS: ::std::os::raw::c_uint = 0x0000066d; -pub const MSR_CORE_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x00000690; -pub const MSR_GFX_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x000006b0; -pub const MSR_RING_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x000006b1; -pub const MSR_PPERF: ::std::os::raw::c_uint = 0x0000064e; -pub const MSR_PERF_LIMIT_REASONS: ::std::os::raw::c_uint = 0x0000064f; -pub const MSR_PM_ENABLE: ::std::os::raw::c_uint = 0x00000770; -pub const MSR_HWP_CAPABILITIES: ::std::os::raw::c_uint = 0x00000771; -pub const MSR_HWP_REQUEST_PKG: ::std::os::raw::c_uint = 0x00000772; -pub const MSR_HWP_INTERRUPT: ::std::os::raw::c_uint = 0x00000773; -pub const MSR_HWP_REQUEST: ::std::os::raw::c_uint = 0x00000774; -pub const MSR_HWP_STATUS: ::std::os::raw::c_uint = 0x00000777; -pub const HWP_BASE_BIT: ::std::os::raw::c_uint = 0x00000080; -pub const HWP_NOTIFICATIONS_BIT: ::std::os::raw::c_uint = 0x00000100; -pub const HWP_ACTIVITY_WINDOW_BIT: ::std::os::raw::c_uint = 0x00000200; -pub const HWP_ENERGY_PERF_PREFERENCE_BIT: ::std::os::raw::c_uint = 0x00000400; -pub const HWP_PACKAGE_LEVEL_REQUEST_BIT: ::std::os::raw::c_uint = 0x00000800; -pub const MSR_AMD64_MC0_MASK: ::std::os::raw::c_uint = 0xc0010044; -pub const MSR_IA32_MC0_CTL2: ::std::os::raw::c_uint = 0x00000280; -pub const MSR_P6_PERFCTR0: ::std::os::raw::c_uint = 0x000000c1; -pub const MSR_P6_PERFCTR1: ::std::os::raw::c_uint = 0x000000c2; -pub const MSR_P6_EVNTSEL0: ::std::os::raw::c_uint = 0x00000186; -pub const MSR_P6_EVNTSEL1: ::std::os::raw::c_uint = 0x00000187; -pub const MSR_KNC_PERFCTR0: ::std::os::raw::c_uint = 0x00000020; -pub const MSR_KNC_PERFCTR1: ::std::os::raw::c_uint = 0x00000021; -pub const MSR_KNC_EVNTSEL0: ::std::os::raw::c_uint = 0x00000028; -pub const MSR_KNC_EVNTSEL1: ::std::os::raw::c_uint = 0x00000029; -pub const MSR_IA32_PMC0: ::std::os::raw::c_uint = 0x000004c1; -pub const MSR_AMD64_PATCH_LEVEL: ::std::os::raw::c_uint = 0x0000008b; -pub const MSR_AMD64_TSC_RATIO: ::std::os::raw::c_uint = 0xc0000104; -pub const MSR_AMD64_NB_CFG: ::std::os::raw::c_uint = 0xc001001f; -pub const MSR_AMD64_PATCH_LOADER: ::std::os::raw::c_uint = 0xc0010020; -pub const MSR_AMD64_OSVW_ID_LENGTH: ::std::os::raw::c_uint = 0xc0010140; -pub const MSR_AMD64_OSVW_STATUS: ::std::os::raw::c_uint = 0xc0010141; -pub const MSR_AMD64_LS_CFG: ::std::os::raw::c_uint = 0xc0011020; -pub const MSR_AMD64_DC_CFG: ::std::os::raw::c_uint = 0xc0011022; -pub const MSR_AMD64_BU_CFG2: ::std::os::raw::c_uint = 0xc001102a; -pub const MSR_AMD64_IBSFETCHCTL: ::std::os::raw::c_uint = 0xc0011030; -pub const MSR_AMD64_IBSFETCHLINAD: ::std::os::raw::c_uint = 0xc0011031; -pub const MSR_AMD64_IBSFETCHPHYSAD: ::std::os::raw::c_uint = 0xc0011032; -pub const MSR_AMD64_IBSFETCH_REG_COUNT: ::std::os::raw::c_uint = 0x00000003; -pub const MSR_AMD64_IBSFETCH_REG_MASK: ::std::os::raw::c_uint = 0x00000007; -pub const MSR_AMD64_IBSOPCTL: ::std::os::raw::c_uint = 0xc0011033; -pub const MSR_AMD64_IBSOPRIP: ::std::os::raw::c_uint = 0xc0011034; -pub const MSR_AMD64_IBSOPDATA: ::std::os::raw::c_uint = 0xc0011035; -pub const MSR_AMD64_IBSOPDATA2: ::std::os::raw::c_uint = 0xc0011036; -pub const MSR_AMD64_IBSOPDATA3: ::std::os::raw::c_uint = 0xc0011037; -pub const MSR_AMD64_IBSDCLINAD: ::std::os::raw::c_uint = 0xc0011038; -pub const MSR_AMD64_IBSDCPHYSAD: ::std::os::raw::c_uint = 0xc0011039; -pub const MSR_AMD64_IBSOP_REG_COUNT: ::std::os::raw::c_uint = 0x00000007; -pub const MSR_AMD64_IBSOP_REG_MASK: ::std::os::raw::c_uint = 0x0000007f; -pub const MSR_AMD64_IBSCTL: ::std::os::raw::c_uint = 0xc001103a; -pub const MSR_AMD64_IBSBRTARGET: ::std::os::raw::c_uint = 0xc001103b; -pub const MSR_AMD64_IBSOPDATA4: ::std::os::raw::c_uint = 0xc001103d; -pub const MSR_AMD64_IBS_REG_COUNT_MAX: ::std::os::raw::c_uint = 0x00000008; -pub const MSR_F17H_IRPERF: ::std::os::raw::c_uint = 0xc00000e9; -pub const MSR_F16H_L2I_PERF_CTL: ::std::os::raw::c_uint = 0xc0010230; -pub const MSR_F16H_L2I_PERF_CTR: ::std::os::raw::c_uint = 0xc0010231; -pub const MSR_F16H_DR1_ADDR_MASK: ::std::os::raw::c_uint = 0xc0011019; -pub const MSR_F16H_DR2_ADDR_MASK: ::std::os::raw::c_uint = 0xc001101a; -pub const MSR_F16H_DR3_ADDR_MASK: ::std::os::raw::c_uint = 0xc001101b; -pub const MSR_F16H_DR0_ADDR_MASK: ::std::os::raw::c_uint = 0xc0011027; -pub const MSR_F15H_PERF_CTL: ::std::os::raw::c_uint = 0xc0010200; -pub const MSR_F15H_PERF_CTR: ::std::os::raw::c_uint = 0xc0010201; -pub const MSR_F15H_NB_PERF_CTL: ::std::os::raw::c_uint = 0xc0010240; -pub const MSR_F15H_NB_PERF_CTR: ::std::os::raw::c_uint = 0xc0010241; -pub const MSR_F15H_PTSC: ::std::os::raw::c_uint = 0xc0010280; -pub const MSR_F15H_IC_CFG: ::std::os::raw::c_uint = 0xc0011021; -pub const MSR_FAM10H_MMIO_CONF_BASE: ::std::os::raw::c_uint = 0xc0010058; -pub const FAM10H_MMIO_CONF_ENABLE: ::std::os::raw::c_uint = 0x00000001; -pub const FAM10H_MMIO_CONF_BUSRANGE_MASK: ::std::os::raw::c_uint = 0x0000000f; -pub const FAM10H_MMIO_CONF_BUSRANGE_SHIFT: ::std::os::raw::c_uint = 0x00000002; -pub const FAM10H_MMIO_CONF_BASE_MASK: ::std::os::raw::c_uint = 0x0fffffff; -pub const FAM10H_MMIO_CONF_BASE_SHIFT: ::std::os::raw::c_uint = 0x00000014; -pub const MSR_FAM10H_NODE_ID: ::std::os::raw::c_uint = 0xc001100c; -pub const MSR_K8_TOP_MEM1: ::std::os::raw::c_uint = 0xc001001a; -pub const MSR_K8_TOP_MEM2: ::std::os::raw::c_uint = 0xc001001d; -pub const MSR_K8_SYSCFG: ::std::os::raw::c_uint = 0xc0010010; -pub const MSR_K8_INT_PENDING_MSG: ::std::os::raw::c_uint = 0xc0010055; -pub const K8_INTP_C1E_ACTIVE_MASK: ::std::os::raw::c_uint = 0x18000000; -pub const MSR_K8_TSEG_ADDR: ::std::os::raw::c_uint = 0xc0010112; -pub const MSR_K8_TSEG_MASK: ::std::os::raw::c_uint = 0xc0010113; -pub const K8_MTRRFIXRANGE_DRAM_ENABLE: ::std::os::raw::c_uint = 0x00040000; -pub const K8_MTRRFIXRANGE_DRAM_MODIFY: ::std::os::raw::c_uint = 0x00080000; -pub const K8_MTRR_RDMEM_WRMEM_MASK: ::std::os::raw::c_uint = 0x18181818; -pub const MSR_K7_EVNTSEL0: ::std::os::raw::c_uint = 0xc0010000; -pub const MSR_K7_PERFCTR0: ::std::os::raw::c_uint = 0xc0010004; -pub const MSR_K7_EVNTSEL1: ::std::os::raw::c_uint = 0xc0010001; -pub const MSR_K7_PERFCTR1: ::std::os::raw::c_uint = 0xc0010005; -pub const MSR_K7_EVNTSEL2: ::std::os::raw::c_uint = 0xc0010002; -pub const MSR_K7_PERFCTR2: ::std::os::raw::c_uint = 0xc0010006; -pub const MSR_K7_EVNTSEL3: ::std::os::raw::c_uint = 0xc0010003; -pub const MSR_K7_PERFCTR3: ::std::os::raw::c_uint = 0xc0010007; -pub const MSR_K7_CLK_CTL: ::std::os::raw::c_uint = 0xc001001b; -pub const MSR_K7_HWCR: ::std::os::raw::c_uint = 0xc0010015; -pub const MSR_K7_FID_VID_CTL: ::std::os::raw::c_uint = 0xc0010041; -pub const MSR_K7_FID_VID_STATUS: ::std::os::raw::c_uint = 0xc0010042; -pub const MSR_K6_WHCR: ::std::os::raw::c_uint = 0xc0000082; -pub const MSR_K6_UWCCR: ::std::os::raw::c_uint = 0xc0000085; -pub const MSR_K6_EPMR: ::std::os::raw::c_uint = 0xc0000086; -pub const MSR_K6_PSOR: ::std::os::raw::c_uint = 0xc0000087; -pub const MSR_K6_PFIR: ::std::os::raw::c_uint = 0xc0000088; -pub const MSR_IDT_FCR1: ::std::os::raw::c_uint = 0x00000107; -pub const MSR_IDT_FCR2: ::std::os::raw::c_uint = 0x00000108; -pub const MSR_IDT_FCR3: ::std::os::raw::c_uint = 0x00000109; -pub const MSR_IDT_FCR4: ::std::os::raw::c_uint = 0x0000010a; -pub const MSR_IDT_MCR0: ::std::os::raw::c_uint = 0x00000110; -pub const MSR_IDT_MCR1: ::std::os::raw::c_uint = 0x00000111; -pub const MSR_IDT_MCR2: ::std::os::raw::c_uint = 0x00000112; -pub const MSR_IDT_MCR3: ::std::os::raw::c_uint = 0x00000113; -pub const MSR_IDT_MCR4: ::std::os::raw::c_uint = 0x00000114; -pub const MSR_IDT_MCR5: ::std::os::raw::c_uint = 0x00000115; -pub const MSR_IDT_MCR6: ::std::os::raw::c_uint = 0x00000116; -pub const MSR_IDT_MCR7: ::std::os::raw::c_uint = 0x00000117; -pub const MSR_IDT_MCR_CTRL: ::std::os::raw::c_uint = 0x00000120; -pub const MSR_VIA_FCR: ::std::os::raw::c_uint = 0x00001107; -pub const MSR_VIA_LONGHAUL: ::std::os::raw::c_uint = 0x0000110a; -pub const MSR_VIA_RNG: ::std::os::raw::c_uint = 0x0000110b; -pub const MSR_VIA_BCR2: ::std::os::raw::c_uint = 0x00001147; -pub const MSR_TMTA_LONGRUN_CTRL: ::std::os::raw::c_uint = 0x80868010; -pub const MSR_TMTA_LONGRUN_FLAGS: ::std::os::raw::c_uint = 0x80868011; -pub const MSR_TMTA_LRTI_READOUT: ::std::os::raw::c_uint = 0x80868018; -pub const MSR_TMTA_LRTI_VOLT_MHZ: ::std::os::raw::c_uint = 0x8086801a; -pub const MSR_IA32_P5_MC_ADDR: ::std::os::raw::c_uint = 0x00000000; -pub const MSR_IA32_P5_MC_TYPE: ::std::os::raw::c_uint = 0x00000001; -pub const MSR_IA32_TSC: ::std::os::raw::c_uint = 0x00000010; -pub const MSR_IA32_PLATFORM_ID: ::std::os::raw::c_uint = 0x00000017; -pub const MSR_IA32_EBL_CR_POWERON: ::std::os::raw::c_uint = 0x0000002a; -pub const MSR_EBC_FREQUENCY_ID: ::std::os::raw::c_uint = 0x0000002c; -pub const MSR_SMI_COUNT: ::std::os::raw::c_uint = 0x00000034; -pub const MSR_IA32_FEATURE_CONTROL: ::std::os::raw::c_uint = 0x0000003a; -pub const MSR_IA32_TSC_ADJUST: ::std::os::raw::c_uint = 0x0000003b; -pub const MSR_IA32_BNDCFGS: ::std::os::raw::c_uint = 0x00000d90; -pub const MSR_IA32_XSS: ::std::os::raw::c_uint = 0x00000da0; -pub const FEATURE_CONTROL_LOCKED: ::std::os::raw::c_uint = 0x00000001; -pub const FEATURE_CONTROL_VMXON_ENABLED_INSIDE_SMX: ::std::os::raw::c_uint = 0x00000002; -pub const FEATURE_CONTROL_VMXON_ENABLED_OUTSIDE_SMX: ::std::os::raw::c_uint = 0x00000004; -pub const FEATURE_CONTROL_LMCE: ::std::os::raw::c_uint = 0x00100000; -pub const MSR_IA32_APICBASE: ::std::os::raw::c_uint = 0x0000001b; -pub const MSR_IA32_APICBASE_BSP: ::std::os::raw::c_uint = 0x00000100; -pub const MSR_IA32_APICBASE_ENABLE: ::std::os::raw::c_uint = 0x00000800; -pub const MSR_IA32_APICBASE_BASE: ::std::os::raw::c_uint = 0xfffff000; -pub const MSR_IA32_TSCDEADLINE: ::std::os::raw::c_uint = 0x000006e0; -pub const MSR_IA32_UCODE_WRITE: ::std::os::raw::c_uint = 0x00000079; -pub const MSR_IA32_UCODE_REV: ::std::os::raw::c_uint = 0x0000008b; -pub const MSR_IA32_SMM_MONITOR_CTL: ::std::os::raw::c_uint = 0x0000009b; -pub const MSR_IA32_SMBASE: ::std::os::raw::c_uint = 0x0000009e; -pub const MSR_IA32_PERF_STATUS: ::std::os::raw::c_uint = 0x00000198; -pub const MSR_IA32_PERF_CTL: ::std::os::raw::c_uint = 0x00000199; -pub const INTEL_PERF_CTL_MASK: ::std::os::raw::c_uint = 0x0000ffff; -pub const MSR_AMD_PSTATE_DEF_BASE: ::std::os::raw::c_uint = 0xc0010064; -pub const MSR_AMD_PERF_STATUS: ::std::os::raw::c_uint = 0xc0010063; -pub const MSR_AMD_PERF_CTL: ::std::os::raw::c_uint = 0xc0010062; -pub const MSR_IA32_MPERF: ::std::os::raw::c_uint = 0x000000e7; -pub const MSR_IA32_APERF: ::std::os::raw::c_uint = 0x000000e8; -pub const MSR_IA32_THERM_CONTROL: ::std::os::raw::c_uint = 0x0000019a; -pub const MSR_IA32_THERM_INTERRUPT: ::std::os::raw::c_uint = 0x0000019b; -pub const THERM_INT_HIGH_ENABLE: ::std::os::raw::c_uint = 0x00000001; -pub const THERM_INT_LOW_ENABLE: ::std::os::raw::c_uint = 0x00000002; -pub const THERM_INT_PLN_ENABLE: ::std::os::raw::c_uint = 0x01000000; -pub const MSR_IA32_THERM_STATUS: ::std::os::raw::c_uint = 0x0000019c; -pub const THERM_STATUS_PROCHOT: ::std::os::raw::c_uint = 0x00000001; -pub const THERM_STATUS_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000400; -pub const MSR_THERM2_CTL: ::std::os::raw::c_uint = 0x0000019d; -pub const MSR_THERM2_CTL_TM_SELECT: ::std::os::raw::c_uint = 0x00010000; -pub const MSR_IA32_MISC_ENABLE: ::std::os::raw::c_uint = 0x000001a0; -pub const MSR_IA32_TEMPERATURE_TARGET: ::std::os::raw::c_uint = 0x000001a2; -pub const MSR_MISC_FEATURE_CONTROL: ::std::os::raw::c_uint = 0x000001a4; -pub const MSR_MISC_PWR_MGMT: ::std::os::raw::c_uint = 0x000001aa; -pub const MSR_IA32_ENERGY_PERF_BIAS: ::std::os::raw::c_uint = 0x000001b0; -pub const ENERGY_PERF_BIAS_PERFORMANCE: ::std::os::raw::c_uint = 0x00000000; -pub const ENERGY_PERF_BIAS_NORMAL: ::std::os::raw::c_uint = 0x00000006; -pub const ENERGY_PERF_BIAS_POWERSAVE: ::std::os::raw::c_uint = 0x0000000f; -pub const MSR_IA32_PACKAGE_THERM_STATUS: ::std::os::raw::c_uint = 0x000001b1; -pub const PACKAGE_THERM_STATUS_PROCHOT: ::std::os::raw::c_uint = 0x00000001; -pub const PACKAGE_THERM_STATUS_POWER_LIMIT: ::std::os::raw::c_uint = 0x00000400; -pub const MSR_IA32_PACKAGE_THERM_INTERRUPT: ::std::os::raw::c_uint = 0x000001b2; -pub const PACKAGE_THERM_INT_HIGH_ENABLE: ::std::os::raw::c_uint = 0x00000001; -pub const PACKAGE_THERM_INT_LOW_ENABLE: ::std::os::raw::c_uint = 0x00000002; -pub const PACKAGE_THERM_INT_PLN_ENABLE: ::std::os::raw::c_uint = 0x01000000; -pub const THERM_INT_THRESHOLD0_ENABLE: ::std::os::raw::c_uint = 0x00008000; -pub const THERM_SHIFT_THRESHOLD0: ::std::os::raw::c_uint = 0x00000008; -pub const THERM_MASK_THRESHOLD0: ::std::os::raw::c_uint = 0x00007f00; -pub const THERM_INT_THRESHOLD1_ENABLE: ::std::os::raw::c_uint = 0x00800000; -pub const THERM_SHIFT_THRESHOLD1: ::std::os::raw::c_uint = 0x00000010; -pub const THERM_MASK_THRESHOLD1: ::std::os::raw::c_uint = 0x007f0000; -pub const THERM_STATUS_THRESHOLD0: ::std::os::raw::c_uint = 0x00000040; -pub const THERM_LOG_THRESHOLD0: ::std::os::raw::c_uint = 0x00000080; -pub const THERM_STATUS_THRESHOLD1: ::std::os::raw::c_uint = 0x00000100; -pub const THERM_LOG_THRESHOLD1: ::std::os::raw::c_uint = 0x00000200; -pub const MSR_IA32_MISC_ENABLE_FAST_STRING_BIT: ::std::os::raw::c_uint = 0x00000000; -pub const MSR_IA32_MISC_ENABLE_FAST_STRING: ::std::os::raw::c_uint = 0x00000001; -pub const MSR_IA32_MISC_ENABLE_TCC_BIT: ::std::os::raw::c_uint = 0x00000001; -pub const MSR_IA32_MISC_ENABLE_TCC: ::std::os::raw::c_uint = 0x00000002; -pub const MSR_IA32_MISC_ENABLE_EMON_BIT: ::std::os::raw::c_uint = 0x00000007; -pub const MSR_IA32_MISC_ENABLE_EMON: ::std::os::raw::c_uint = 0x00000080; -pub const MSR_IA32_MISC_ENABLE_BTS_UNAVAIL_BIT: ::std::os::raw::c_uint = 0x0000000b; -pub const MSR_IA32_MISC_ENABLE_BTS_UNAVAIL: ::std::os::raw::c_uint = 0x00000800; -pub const MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL_BIT: ::std::os::raw::c_uint = 0x0000000c; -pub const MSR_IA32_MISC_ENABLE_PEBS_UNAVAIL: ::std::os::raw::c_uint = 0x00001000; -pub const MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP_BIT: ::std::os::raw::c_uint = 0x00000010; -pub const MSR_IA32_MISC_ENABLE_ENHANCED_SPEEDSTEP: ::std::os::raw::c_uint = 0x00010000; -pub const MSR_IA32_MISC_ENABLE_MWAIT_BIT: ::std::os::raw::c_uint = 0x00000012; -pub const MSR_IA32_MISC_ENABLE_MWAIT: ::std::os::raw::c_uint = 0x00040000; -pub const MSR_IA32_MISC_ENABLE_LIMIT_CPUID_BIT: ::std::os::raw::c_uint = 0x00000016; -pub const MSR_IA32_MISC_ENABLE_LIMIT_CPUID: ::std::os::raw::c_uint = 0x00400000; -pub const MSR_IA32_MISC_ENABLE_XTPR_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000017; -pub const MSR_IA32_MISC_ENABLE_XTPR_DISABLE: ::std::os::raw::c_uint = 0x00800000; -pub const MSR_IA32_MISC_ENABLE_XD_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000022; -pub const MSR_IA32_MISC_ENABLE_XD_DISABLE: ::std::os::raw::c_ulonglong = 0x400000000; -pub const MSR_IA32_MISC_ENABLE_X87_COMPAT_BIT: ::std::os::raw::c_uint = 0x00000002; -pub const MSR_IA32_MISC_ENABLE_X87_COMPAT: ::std::os::raw::c_uint = 0x00000004; -pub const MSR_IA32_MISC_ENABLE_TM1_BIT: ::std::os::raw::c_uint = 0x00000003; -pub const MSR_IA32_MISC_ENABLE_TM1: ::std::os::raw::c_uint = 0x00000008; -pub const MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000004; -pub const MSR_IA32_MISC_ENABLE_SPLIT_LOCK_DISABLE: ::std::os::raw::c_uint = 0x00000010; -pub const MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000006; -pub const MSR_IA32_MISC_ENABLE_L3CACHE_DISABLE: ::std::os::raw::c_uint = 0x00000040; -pub const MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK_BIT: ::std::os::raw::c_uint = 0x00000008; -pub const MSR_IA32_MISC_ENABLE_SUPPRESS_LOCK: ::std::os::raw::c_uint = 0x00000100; -pub const MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000009; -pub const MSR_IA32_MISC_ENABLE_PREFETCH_DISABLE: ::std::os::raw::c_uint = 0x00000200; -pub const MSR_IA32_MISC_ENABLE_FERR_BIT: ::std::os::raw::c_uint = 0x0000000a; -pub const MSR_IA32_MISC_ENABLE_FERR: ::std::os::raw::c_uint = 0x00000400; -pub const MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX_BIT: ::std::os::raw::c_uint = 0x0000000a; -pub const MSR_IA32_MISC_ENABLE_FERR_MULTIPLEX: ::std::os::raw::c_uint = 0x00000400; -pub const MSR_IA32_MISC_ENABLE_TM2_BIT: ::std::os::raw::c_uint = 0x0000000d; -pub const MSR_IA32_MISC_ENABLE_TM2: ::std::os::raw::c_uint = 0x00002000; -pub const MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000013; -pub const MSR_IA32_MISC_ENABLE_ADJ_PREF_DISABLE: ::std::os::raw::c_uint = 0x00080000; -pub const MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK_BIT: ::std::os::raw::c_uint = 0x00000014; -pub const MSR_IA32_MISC_ENABLE_SPEEDSTEP_LOCK: ::std::os::raw::c_uint = 0x00100000; -pub const MSR_IA32_MISC_ENABLE_L1D_CONTEXT_BIT: ::std::os::raw::c_uint = 0x00000018; -pub const MSR_IA32_MISC_ENABLE_L1D_CONTEXT: ::std::os::raw::c_uint = 0x01000000; -pub const MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000025; -pub const MSR_IA32_MISC_ENABLE_DCU_PREF_DISABLE: ::std::os::raw::c_ulonglong = 0x2000000000; -pub const MSR_IA32_MISC_ENABLE_TURBO_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000026; -pub const MSR_IA32_MISC_ENABLE_TURBO_DISABLE: ::std::os::raw::c_ulonglong = 0x4000000000; -pub const MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE_BIT: ::std::os::raw::c_uint = 0x00000027; -pub const MSR_IA32_MISC_ENABLE_IP_PREF_DISABLE: ::std::os::raw::c_ulonglong = 0x8000000000; -pub const MSR_MISC_FEATURE_ENABLES: ::std::os::raw::c_uint = 0x00000140; -pub const MSR_MISC_FEATURE_ENABLES_RING3MWAIT_BIT: ::std::os::raw::c_uint = 0x00000001; -pub const MSR_IA32_TSC_DEADLINE: ::std::os::raw::c_uint = 0x000006e0; -pub const MSR_IA32_MCG_EAX: ::std::os::raw::c_uint = 0x00000180; -pub const MSR_IA32_MCG_EBX: ::std::os::raw::c_uint = 0x00000181; -pub const MSR_IA32_MCG_ECX: ::std::os::raw::c_uint = 0x00000182; -pub const MSR_IA32_MCG_EDX: ::std::os::raw::c_uint = 0x00000183; -pub const MSR_IA32_MCG_ESI: ::std::os::raw::c_uint = 0x00000184; -pub const MSR_IA32_MCG_EDI: ::std::os::raw::c_uint = 0x00000185; -pub const MSR_IA32_MCG_EBP: ::std::os::raw::c_uint = 0x00000186; -pub const MSR_IA32_MCG_ESP: ::std::os::raw::c_uint = 0x00000187; -pub const MSR_IA32_MCG_EFLAGS: ::std::os::raw::c_uint = 0x00000188; -pub const MSR_IA32_MCG_EIP: ::std::os::raw::c_uint = 0x00000189; -pub const MSR_IA32_MCG_RESERVED: ::std::os::raw::c_uint = 0x0000018a; -pub const MSR_P4_BPU_PERFCTR0: ::std::os::raw::c_uint = 0x00000300; -pub const MSR_P4_BPU_PERFCTR1: ::std::os::raw::c_uint = 0x00000301; -pub const MSR_P4_BPU_PERFCTR2: ::std::os::raw::c_uint = 0x00000302; -pub const MSR_P4_BPU_PERFCTR3: ::std::os::raw::c_uint = 0x00000303; -pub const MSR_P4_MS_PERFCTR0: ::std::os::raw::c_uint = 0x00000304; -pub const MSR_P4_MS_PERFCTR1: ::std::os::raw::c_uint = 0x00000305; -pub const MSR_P4_MS_PERFCTR2: ::std::os::raw::c_uint = 0x00000306; -pub const MSR_P4_MS_PERFCTR3: ::std::os::raw::c_uint = 0x00000307; -pub const MSR_P4_FLAME_PERFCTR0: ::std::os::raw::c_uint = 0x00000308; -pub const MSR_P4_FLAME_PERFCTR1: ::std::os::raw::c_uint = 0x00000309; -pub const MSR_P4_FLAME_PERFCTR2: ::std::os::raw::c_uint = 0x0000030a; -pub const MSR_P4_FLAME_PERFCTR3: ::std::os::raw::c_uint = 0x0000030b; -pub const MSR_P4_IQ_PERFCTR0: ::std::os::raw::c_uint = 0x0000030c; -pub const MSR_P4_IQ_PERFCTR1: ::std::os::raw::c_uint = 0x0000030d; -pub const MSR_P4_IQ_PERFCTR2: ::std::os::raw::c_uint = 0x0000030e; -pub const MSR_P4_IQ_PERFCTR3: ::std::os::raw::c_uint = 0x0000030f; -pub const MSR_P4_IQ_PERFCTR4: ::std::os::raw::c_uint = 0x00000310; -pub const MSR_P4_IQ_PERFCTR5: ::std::os::raw::c_uint = 0x00000311; -pub const MSR_P4_BPU_CCCR0: ::std::os::raw::c_uint = 0x00000360; -pub const MSR_P4_BPU_CCCR1: ::std::os::raw::c_uint = 0x00000361; -pub const MSR_P4_BPU_CCCR2: ::std::os::raw::c_uint = 0x00000362; -pub const MSR_P4_BPU_CCCR3: ::std::os::raw::c_uint = 0x00000363; -pub const MSR_P4_MS_CCCR0: ::std::os::raw::c_uint = 0x00000364; -pub const MSR_P4_MS_CCCR1: ::std::os::raw::c_uint = 0x00000365; -pub const MSR_P4_MS_CCCR2: ::std::os::raw::c_uint = 0x00000366; -pub const MSR_P4_MS_CCCR3: ::std::os::raw::c_uint = 0x00000367; -pub const MSR_P4_FLAME_CCCR0: ::std::os::raw::c_uint = 0x00000368; -pub const MSR_P4_FLAME_CCCR1: ::std::os::raw::c_uint = 0x00000369; -pub const MSR_P4_FLAME_CCCR2: ::std::os::raw::c_uint = 0x0000036a; -pub const MSR_P4_FLAME_CCCR3: ::std::os::raw::c_uint = 0x0000036b; -pub const MSR_P4_IQ_CCCR0: ::std::os::raw::c_uint = 0x0000036c; -pub const MSR_P4_IQ_CCCR1: ::std::os::raw::c_uint = 0x0000036d; -pub const MSR_P4_IQ_CCCR2: ::std::os::raw::c_uint = 0x0000036e; -pub const MSR_P4_IQ_CCCR3: ::std::os::raw::c_uint = 0x0000036f; -pub const MSR_P4_IQ_CCCR4: ::std::os::raw::c_uint = 0x00000370; -pub const MSR_P4_IQ_CCCR5: ::std::os::raw::c_uint = 0x00000371; -pub const MSR_P4_ALF_ESCR0: ::std::os::raw::c_uint = 0x000003ca; -pub const MSR_P4_ALF_ESCR1: ::std::os::raw::c_uint = 0x000003cb; -pub const MSR_P4_BPU_ESCR0: ::std::os::raw::c_uint = 0x000003b2; -pub const MSR_P4_BPU_ESCR1: ::std::os::raw::c_uint = 0x000003b3; -pub const MSR_P4_BSU_ESCR0: ::std::os::raw::c_uint = 0x000003a0; -pub const MSR_P4_BSU_ESCR1: ::std::os::raw::c_uint = 0x000003a1; -pub const MSR_P4_CRU_ESCR0: ::std::os::raw::c_uint = 0x000003b8; -pub const MSR_P4_CRU_ESCR1: ::std::os::raw::c_uint = 0x000003b9; -pub const MSR_P4_CRU_ESCR2: ::std::os::raw::c_uint = 0x000003cc; -pub const MSR_P4_CRU_ESCR3: ::std::os::raw::c_uint = 0x000003cd; -pub const MSR_P4_CRU_ESCR4: ::std::os::raw::c_uint = 0x000003e0; -pub const MSR_P4_CRU_ESCR5: ::std::os::raw::c_uint = 0x000003e1; -pub const MSR_P4_DAC_ESCR0: ::std::os::raw::c_uint = 0x000003a8; -pub const MSR_P4_DAC_ESCR1: ::std::os::raw::c_uint = 0x000003a9; -pub const MSR_P4_FIRM_ESCR0: ::std::os::raw::c_uint = 0x000003a4; -pub const MSR_P4_FIRM_ESCR1: ::std::os::raw::c_uint = 0x000003a5; -pub const MSR_P4_FLAME_ESCR0: ::std::os::raw::c_uint = 0x000003a6; -pub const MSR_P4_FLAME_ESCR1: ::std::os::raw::c_uint = 0x000003a7; -pub const MSR_P4_FSB_ESCR0: ::std::os::raw::c_uint = 0x000003a2; -pub const MSR_P4_FSB_ESCR1: ::std::os::raw::c_uint = 0x000003a3; -pub const MSR_P4_IQ_ESCR0: ::std::os::raw::c_uint = 0x000003ba; -pub const MSR_P4_IQ_ESCR1: ::std::os::raw::c_uint = 0x000003bb; -pub const MSR_P4_IS_ESCR0: ::std::os::raw::c_uint = 0x000003b4; -pub const MSR_P4_IS_ESCR1: ::std::os::raw::c_uint = 0x000003b5; -pub const MSR_P4_ITLB_ESCR0: ::std::os::raw::c_uint = 0x000003b6; -pub const MSR_P4_ITLB_ESCR1: ::std::os::raw::c_uint = 0x000003b7; -pub const MSR_P4_IX_ESCR0: ::std::os::raw::c_uint = 0x000003c8; -pub const MSR_P4_IX_ESCR1: ::std::os::raw::c_uint = 0x000003c9; -pub const MSR_P4_MOB_ESCR0: ::std::os::raw::c_uint = 0x000003aa; -pub const MSR_P4_MOB_ESCR1: ::std::os::raw::c_uint = 0x000003ab; -pub const MSR_P4_MS_ESCR0: ::std::os::raw::c_uint = 0x000003c0; -pub const MSR_P4_MS_ESCR1: ::std::os::raw::c_uint = 0x000003c1; -pub const MSR_P4_PMH_ESCR0: ::std::os::raw::c_uint = 0x000003ac; -pub const MSR_P4_PMH_ESCR1: ::std::os::raw::c_uint = 0x000003ad; -pub const MSR_P4_RAT_ESCR0: ::std::os::raw::c_uint = 0x000003bc; -pub const MSR_P4_RAT_ESCR1: ::std::os::raw::c_uint = 0x000003bd; -pub const MSR_P4_SAAT_ESCR0: ::std::os::raw::c_uint = 0x000003ae; -pub const MSR_P4_SAAT_ESCR1: ::std::os::raw::c_uint = 0x000003af; -pub const MSR_P4_SSU_ESCR0: ::std::os::raw::c_uint = 0x000003be; -pub const MSR_P4_SSU_ESCR1: ::std::os::raw::c_uint = 0x000003bf; -pub const MSR_P4_TBPU_ESCR0: ::std::os::raw::c_uint = 0x000003c2; -pub const MSR_P4_TBPU_ESCR1: ::std::os::raw::c_uint = 0x000003c3; -pub const MSR_P4_TC_ESCR0: ::std::os::raw::c_uint = 0x000003c4; -pub const MSR_P4_TC_ESCR1: ::std::os::raw::c_uint = 0x000003c5; -pub const MSR_P4_U2L_ESCR0: ::std::os::raw::c_uint = 0x000003b0; -pub const MSR_P4_U2L_ESCR1: ::std::os::raw::c_uint = 0x000003b1; -pub const MSR_P4_PEBS_MATRIX_VERT: ::std::os::raw::c_uint = 0x000003f2; -pub const MSR_CORE_PERF_FIXED_CTR0: ::std::os::raw::c_uint = 0x00000309; -pub const MSR_CORE_PERF_FIXED_CTR1: ::std::os::raw::c_uint = 0x0000030a; -pub const MSR_CORE_PERF_FIXED_CTR2: ::std::os::raw::c_uint = 0x0000030b; -pub const MSR_CORE_PERF_FIXED_CTR_CTRL: ::std::os::raw::c_uint = 0x0000038d; -pub const MSR_CORE_PERF_GLOBAL_STATUS: ::std::os::raw::c_uint = 0x0000038e; -pub const MSR_CORE_PERF_GLOBAL_CTRL: ::std::os::raw::c_uint = 0x0000038f; -pub const MSR_CORE_PERF_GLOBAL_OVF_CTRL: ::std::os::raw::c_uint = 0x00000390; -pub const MSR_GEODE_BUSCONT_CONF0: ::std::os::raw::c_uint = 0x00001900; -pub const MSR_IA32_VMX_BASIC: ::std::os::raw::c_uint = 0x00000480; -pub const MSR_IA32_VMX_PINBASED_CTLS: ::std::os::raw::c_uint = 0x00000481; -pub const MSR_IA32_VMX_PROCBASED_CTLS: ::std::os::raw::c_uint = 0x00000482; -pub const MSR_IA32_VMX_EXIT_CTLS: ::std::os::raw::c_uint = 0x00000483; -pub const MSR_IA32_VMX_ENTRY_CTLS: ::std::os::raw::c_uint = 0x00000484; -pub const MSR_IA32_VMX_MISC: ::std::os::raw::c_uint = 0x00000485; -pub const MSR_IA32_VMX_CR0_FIXED0: ::std::os::raw::c_uint = 0x00000486; -pub const MSR_IA32_VMX_CR0_FIXED1: ::std::os::raw::c_uint = 0x00000487; -pub const MSR_IA32_VMX_CR4_FIXED0: ::std::os::raw::c_uint = 0x00000488; -pub const MSR_IA32_VMX_CR4_FIXED1: ::std::os::raw::c_uint = 0x00000489; -pub const MSR_IA32_VMX_VMCS_ENUM: ::std::os::raw::c_uint = 0x0000048a; -pub const MSR_IA32_VMX_PROCBASED_CTLS2: ::std::os::raw::c_uint = 0x0000048b; -pub const MSR_IA32_VMX_EPT_VPID_CAP: ::std::os::raw::c_uint = 0x0000048c; -pub const MSR_IA32_VMX_TRUE_PINBASED_CTLS: ::std::os::raw::c_uint = 0x0000048d; -pub const MSR_IA32_VMX_TRUE_PROCBASED_CTLS: ::std::os::raw::c_uint = 0x0000048e; -pub const MSR_IA32_VMX_TRUE_EXIT_CTLS: ::std::os::raw::c_uint = 0x0000048f; -pub const MSR_IA32_VMX_TRUE_ENTRY_CTLS: ::std::os::raw::c_uint = 0x00000490; -pub const MSR_IA32_VMX_VMFUNC: ::std::os::raw::c_uint = 0x00000491; -pub const VMX_BASIC_VMCS_SIZE_SHIFT: ::std::os::raw::c_uint = 0x00000020; -pub const VMX_BASIC_TRUE_CTLS: ::std::os::raw::c_ulonglong = 0x80000000000000; -pub const VMX_BASIC_64: ::std::os::raw::c_ulonglong = 0x1000000000000; -pub const VMX_BASIC_MEM_TYPE_SHIFT: ::std::os::raw::c_uint = 0x00000032; -pub const VMX_BASIC_MEM_TYPE_MASK: ::std::os::raw::c_ulonglong = 0x3c000000000000; -pub const VMX_BASIC_MEM_TYPE_WB: ::std::os::raw::c_uint = 0x00000006; -pub const VMX_BASIC_INOUT: ::std::os::raw::c_ulonglong = 0x40000000000000; -pub const MSR_IA32_VMX_MISC_VMWRITE_SHADOW_RO_FIELDS: ::std::os::raw::c_uint = 0x20000000; -pub const MSR_IA32_VMX_MISC_PREEMPTION_TIMER_SCALE: ::std::os::raw::c_uint = 0x0000001f; -pub const MSR_VM_CR: ::std::os::raw::c_uint = 0xc0010114; -pub const MSR_VM_IGNNE: ::std::os::raw::c_uint = 0xc0010115; -pub const MSR_VM_HSAVE_PA: ::std::os::raw::c_uint = 0xc0010117; diff --git a/pci/Cargo.toml b/pci/Cargo.toml index 9c6955c7e..93b377380 100644 --- a/pci/Cargo.toml +++ b/pci/Cargo.toml @@ -8,8 +8,7 @@ edition = "2018" anyhow = "1.0" byteorder = "1.3.4" devices = { path = "../devices" } -kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch" } -kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" } +hypervisor = { path = "../hypervisor" } vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" } vmm-sys-util = ">=0.3.1" libc = "0.2.71" diff --git a/pci/src/lib.rs b/pci/src/lib.rs index 05725638b..20cc879b2 100644 --- a/pci/src/lib.rs +++ b/pci/src/lib.rs @@ -6,6 +6,7 @@ #[macro_use] extern crate log; extern crate devices; +extern crate hypervisor; extern crate serde; #[macro_use] extern crate serde_derive; diff --git a/pci/src/vfio.rs b/pci/src/vfio.rs index dca217311..a43e66378 100644 --- a/pci/src/vfio.rs +++ b/pci/src/vfio.rs @@ -13,8 +13,7 @@ use crate::{ }; use byteorder::{ByteOrder, LittleEndian}; use devices::BusDevice; -use kvm_bindings::kvm_userspace_memory_region; -use kvm_ioctls::*; +use hypervisor::kvm::kvm_userspace_memory_region; use std::any::Any; use std::ops::Deref; use std::os::unix::io::AsRawFd; @@ -38,10 +37,10 @@ pub enum VfioPciError { AllocateGsi, EventFd(io::Error), InterruptSourceGroupCreate(io::Error), - IrqFd(kvm_ioctls::Error), + IrqFd(hypervisor::HypervisorVmError), NewVfioPciDevice, - MapRegionGuest(kvm_ioctls::Error), - SetGsiRouting(kvm_ioctls::Error), + MapRegionGuest(anyhow::Error), + SetGsiRouting(hypervisor::HypervisorVmError), MsiNotConfigured, MsixNotConfigured, UpdateMemory(VfioError), @@ -281,7 +280,7 @@ impl VfioPciConfig { /// The VMM creates a VfioDevice, then assigns it to a VfioPciDevice, /// which then gets added to the PCI bus. pub struct VfioPciDevice { - vm_fd: Arc, + vm_fd: Arc, device: Arc, vfio_pci_configuration: VfioPciConfig, configuration: PciConfiguration, @@ -293,7 +292,7 @@ pub struct VfioPciDevice { impl VfioPciDevice { /// Constructs a new Vfio Pci device for the given Vfio device pub fn new( - vm_fd: &Arc, + vm_fd: &Arc, device: VfioDevice, interrupt_manager: &Arc>, mem: GuestMemoryAtomic, @@ -512,7 +511,7 @@ impl VfioPciDevice { /// # Return value /// /// This function returns the updated KVM memory slot id. - pub fn map_mmio_regions(&mut self, vm: &Arc, mem_slot: F) -> Result<()> + pub fn map_mmio_regions(&mut self, vm: &Arc, mem_slot: F) -> Result<()> where F: Fn() -> u32, { @@ -569,11 +568,8 @@ impl VfioPciDevice { flags: 0, }; - // Safe because the guest regions are guaranteed not to overlap. - unsafe { - vm.set_user_memory_region(mem_region) - .map_err(VfioPciError::MapRegionGuest)?; - } + vm.set_user_memory_region(mem_region) + .map_err(|e| VfioPciError::MapRegionGuest(e.into()))?; // Update the region with memory mapped info. region.mem_slot = Some(slot); @@ -600,8 +596,8 @@ impl VfioPciDevice { userspace_addr: host_addr, flags: 0, }; - // Safe because the guest regions are guaranteed not to overlap. - if let Err(e) = unsafe { self.vm_fd.set_user_memory_region(kvm_region) } { + + if let Err(e) = self.vm_fd.set_user_memory_region(kvm_region) { error!( "Could not remove the userspace memory region from KVM: {}", e @@ -1028,12 +1024,10 @@ impl PciDevice for VfioPciDevice { userspace_addr: host_addr, flags: 0, }; - // Safe because the guest regions are guaranteed not to overlap. - unsafe { - self.vm_fd - .set_user_memory_region(old_mem_region) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; - } + + self.vm_fd + .set_user_memory_region(old_mem_region) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; // Insert new region to KVM let new_mem_region = kvm_userspace_memory_region { @@ -1043,12 +1037,10 @@ impl PciDevice for VfioPciDevice { userspace_addr: host_addr, flags: 0, }; - // Safe because the guest regions are guaranteed not to overlap. - unsafe { - self.vm_fd - .set_user_memory_region(new_mem_region) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; - } + + self.vm_fd + .set_user_memory_region(new_mem_region) + .map_err(|e| io::Error::new(io::ErrorKind::Other, e))?; } } } diff --git a/src/main.rs b/src/main.rs index 991e4d0bd..84497010a 100644 --- a/src/main.rs +++ b/src/main.rs @@ -10,6 +10,7 @@ extern crate vmm_sys_util; extern crate clap; use clap::{App, Arg, ArgGroup, ArgMatches}; +use hypervisor::kvm::KvmHyperVisor as Hypervisor; use libc::EFD_NONBLOCK; use log::LevelFilter; use seccomp::SeccompLevel; @@ -282,7 +283,7 @@ fn start_vmm(cmd_arguments: ArgMatches) { } else { SeccompLevel::Advanced }; - + let hypervisor = Hypervisor::new().unwrap(); let vmm_thread = match vmm::start_vmm_thread( env!("CARGO_PKG_VERSION").to_string(), api_socket_path, @@ -290,6 +291,7 @@ fn start_vmm(cmd_arguments: ArgMatches) { http_sender, api_request_receiver, &seccomp_level, + Arc::new(hypervisor), ) { Ok(t) => t, Err(e) => { diff --git a/vmm/Cargo.toml b/vmm/Cargo.toml index 58cde6158..21a3a397d 100644 --- a/vmm/Cargo.toml +++ b/vmm/Cargo.toml @@ -20,8 +20,7 @@ anyhow = "1.0" arch = { path = "../arch" } devices = { path = "../devices" } epoll = ">=4.0.1" -kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch", features = ["with-serde", "fam-wrappers"] } -kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" } +hypervisor = { path = "../hypervisor" } lazy_static = "1.4.0" libc = "0.2.71" log = "0.4.8" @@ -44,6 +43,7 @@ vmm-sys-util = { version = ">=0.5.0", features = ["with-serde"] } signal-hook = "0.1.15" tempfile = "3.1.0" + [dependencies.linux-loader] git = "https://github.com/rust-vmm/linux-loader" features = ["elf", "bzimage", "pe"] diff --git a/vmm/src/cpu.rs b/vmm/src/cpu.rs index edbeef563..28456491e 100644 --- a/vmm/src/cpu.rs +++ b/vmm/src/cpu.rs @@ -24,15 +24,13 @@ use arch::EntryPoint; use arch::{CpuidPatch, CpuidReg}; use devices::{interrupt_controller::InterruptController, BusDevice}; #[cfg(target_arch = "aarch64")] -use kvm_bindings::KVM_SYSTEM_EVENT_SHUTDOWN; +use hypervisor::kvm::kvm_bindings::KVM_SYSTEM_EVENT_SHUTDOWN; #[cfg(target_arch = "x86_64")] -use kvm_bindings::{ - kvm_fpu, kvm_lapic_state, kvm_mp_state, kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs, - kvm_xsave, CpuId, Msrs, -}; -use kvm_ioctls::*; +use hypervisor::CpuId; +use hypervisor::VcpuExit; + use libc::{c_void, siginfo_t}; -use serde_derive::{Deserialize, Serialize}; + #[cfg(target_arch = "x86_64")] use std::fmt; use std::os::unix::thread::JoinHandleExt; @@ -103,23 +101,23 @@ impl fmt::Display for DebugIoPortRange { #[derive(Debug)] pub enum Error { /// Cannot open the VCPU file descriptor. - VcpuFd(kvm_ioctls::Error), + VcpuFd(anyhow::Error), /// Cannot run the VCPUs. - VcpuRun(kvm_ioctls::Error), + VcpuRun(anyhow::Error), /// Cannot spawn a new vCPU thread. VcpuSpawn(io::Error), /// Cannot patch the CPU ID - PatchCpuId(kvm_ioctls::Error), + PatchCpuId(anyhow::Error), /// The call to KVM_SET_CPUID2 failed. - SetSupportedCpusFailed(kvm_ioctls::Error), + SetSupportedCpusFailed(anyhow::Error), #[cfg(target_arch = "x86_64")] /// Cannot set the local interruption due to bad configuration. - LocalIntConfiguration(arch::x86_64::interrupts::Error), + LocalIntConfiguration(anyhow::Error), /// Error configuring VCPU VcpuConfiguration(arch::Error), @@ -140,58 +138,58 @@ pub enum Error { DesiredVCPUCountExceedsMax, /// Failed to get KVM vcpu lapic. - VcpuGetLapic(kvm_ioctls::Error), + VcpuGetLapic(anyhow::Error), /// Failed to set KVM vcpu lapic. - VcpuSetLapic(kvm_ioctls::Error), + VcpuSetLapic(anyhow::Error), /// Failed to get KVM vcpu MP state. - VcpuGetMpState(kvm_ioctls::Error), + VcpuGetMpState(anyhow::Error), /// Failed to set KVM vcpu MP state. - VcpuSetMpState(kvm_ioctls::Error), + VcpuSetMpState(anyhow::Error), /// Failed to get KVM vcpu msrs. - VcpuGetMsrs(kvm_ioctls::Error), + VcpuGetMsrs(anyhow::Error), /// Failed to set KVM vcpu msrs. - VcpuSetMsrs(kvm_ioctls::Error), + VcpuSetMsrs(anyhow::Error), /// Failed to get KVM vcpu regs. - VcpuGetRegs(kvm_ioctls::Error), + VcpuGetRegs(anyhow::Error), /// Failed to set KVM vcpu regs. - VcpuSetRegs(kvm_ioctls::Error), + VcpuSetRegs(anyhow::Error), /// Failed to get KVM vcpu sregs. - VcpuGetSregs(kvm_ioctls::Error), + VcpuGetSregs(anyhow::Error), /// Failed to set KVM vcpu sregs. - VcpuSetSregs(kvm_ioctls::Error), + VcpuSetSregs(anyhow::Error), /// Failed to get KVM vcpu events. - VcpuGetVcpuEvents(kvm_ioctls::Error), + VcpuGetVcpuEvents(anyhow::Error), /// Failed to set KVM vcpu events. - VcpuSetVcpuEvents(kvm_ioctls::Error), + VcpuSetVcpuEvents(anyhow::Error), /// Failed to get KVM vcpu FPU. - VcpuGetFpu(kvm_ioctls::Error), + VcpuGetFpu(anyhow::Error), /// Failed to set KVM vcpu FPU. - VcpuSetFpu(kvm_ioctls::Error), + VcpuSetFpu(anyhow::Error), /// Failed to get KVM vcpu XSAVE. - VcpuGetXsave(kvm_ioctls::Error), + VcpuGetXsave(anyhow::Error), /// Failed to set KVM vcpu XSAVE. - VcpuSetXsave(kvm_ioctls::Error), + VcpuSetXsave(anyhow::Error), /// Failed to get KVM vcpu XCRS. - VcpuGetXcrs(kvm_ioctls::Error), + VcpuGetXcrs(anyhow::Error), /// Failed to set KVM vcpu XCRS. - VcpuSetXcrs(kvm_ioctls::Error), + VcpuSetXcrs(anyhow::Error), /// Error resuming vCPU on shutdown ResumeOnShutdown(MigratableError), @@ -232,7 +230,7 @@ struct InterruptSourceOverride { /// A wrapper around creating and using a kvm-based VCPU. pub struct Vcpu { - fd: VcpuFd, + fd: Arc, id: u8, #[cfg(target_arch = "x86_64")] io_bus: Arc, @@ -245,24 +243,6 @@ pub struct Vcpu { mpidr: u64, } -#[cfg(target_arch = "x86_64")] -#[derive(Clone, Serialize, Deserialize)] -pub struct VcpuKvmState { - msrs: Msrs, - vcpu_events: kvm_vcpu_events, - regs: kvm_regs, - sregs: kvm_sregs, - fpu: kvm_fpu, - lapic_state: kvm_lapic_state, - xsave: kvm_xsave, - xcrs: kvm_xcrs, - mp_state: kvm_mp_state, -} - -#[cfg(target_arch = "aarch64")] -#[derive(Clone, Serialize, Deserialize)] -pub struct VcpuKvmState {} - impl Vcpu { /// Constructs a new VCPU for `vm`. /// @@ -272,13 +252,13 @@ impl Vcpu { /// * `vm` - The virtual machine this vcpu will get attached to. pub fn new( id: u8, - fd: &Arc, + fd: &Arc, #[cfg(target_arch = "x86_64")] io_bus: Arc, mmio_bus: Arc, interrupt_controller: Option>>, creation_ts: std::time::Instant, ) -> Result>> { - let kvm_vcpu = fd.create_vcpu(id).map_err(Error::VcpuFd)?; + let kvm_vcpu = fd.create_vcpu(id).map_err(|e| Error::VcpuFd(e.into()))?; // Initially the cpuid per vCPU is the one supported by this VM. Ok(Arc::new(Mutex::new(Vcpu { fd: kvm_vcpu, @@ -303,7 +283,7 @@ impl Vcpu { /// * `cpuid` - (x86_64) CpuId, wrapper over the `kvm_cpuid2` structure. pub fn configure( &mut self, - #[cfg(target_arch = "aarch64")] vm_fd: &VmFd, + #[cfg(target_arch = "aarch64")] vm_fd: &Arc, kernel_entry_point: Option, vm_memory: &GuestMemoryAtomic, #[cfg(target_arch = "x86_64")] cpuid: CpuId, @@ -413,75 +393,6 @@ impl Vcpu { ts.as_micros() ); } - - #[cfg(target_arch = "x86_64")] - fn kvm_state(&self) -> Result { - let mut msrs = arch::x86_64::regs::boot_msr_entries(); - self.fd.get_msrs(&mut msrs).map_err(Error::VcpuGetMsrs)?; - - let vcpu_events = self - .fd - .get_vcpu_events() - .map_err(Error::VcpuGetVcpuEvents)?; - let regs = self.fd.get_regs().map_err(Error::VcpuGetRegs)?; - let sregs = self.fd.get_sregs().map_err(Error::VcpuGetSregs)?; - let lapic_state = self.fd.get_lapic().map_err(Error::VcpuGetLapic)?; - let fpu = self.fd.get_fpu().map_err(Error::VcpuGetFpu)?; - let xsave = self.fd.get_xsave().map_err(Error::VcpuGetXsave)?; - let xcrs = self.fd.get_xcrs().map_err(Error::VcpuGetXsave)?; - let mp_state = self.fd.get_mp_state().map_err(Error::VcpuGetMpState)?; - - Ok(VcpuKvmState { - msrs, - vcpu_events, - regs, - sregs, - fpu, - lapic_state, - xsave, - xcrs, - mp_state, - }) - } - - #[cfg(target_arch = "x86_64")] - fn set_kvm_state(&mut self, state: &VcpuKvmState) -> Result<()> { - self.fd.set_regs(&state.regs).map_err(Error::VcpuSetRegs)?; - - self.fd.set_fpu(&state.fpu).map_err(Error::VcpuSetFpu)?; - - self.fd - .set_xsave(&state.xsave) - .map_err(Error::VcpuSetXsave)?; - - self.fd - .set_sregs(&state.sregs) - .map_err(Error::VcpuSetSregs)?; - - self.fd.set_xcrs(&state.xcrs).map_err(Error::VcpuSetXcrs)?; - - self.fd.set_msrs(&state.msrs).map_err(Error::VcpuSetMsrs)?; - - self.fd - .set_lapic(&state.lapic_state) - .map_err(Error::VcpuSetLapic)?; - - self.fd - .set_mp_state(state.mp_state) - .map_err(Error::VcpuSetMpState)?; - - Ok(()) - } - - #[cfg(target_arch = "aarch64")] - fn kvm_state(&self) -> Result { - unimplemented!(); - } - - #[cfg(target_arch = "aarch64")] - fn set_kvm_state(&mut self, _state: &VcpuKvmState) -> Result<()> { - Ok(()) - } } const VCPU_SNAPSHOT_ID: &str = "vcpu"; @@ -492,7 +403,7 @@ impl Snapshottable for Vcpu { } fn snapshot(&self) -> std::result::Result { - let snapshot = serde_json::to_vec(&self.kvm_state().map_err(|e| { + let snapshot = serde_json::to_vec(&self.fd.cpu_state().map_err(|e| { MigratableError::Snapshot(anyhow!("Could not get vCPU KVM state {:?}", e)) })?) .map_err(|e| MigratableError::Snapshot(e.into()))?; @@ -521,7 +432,7 @@ impl Snapshottable for Vcpu { } }; - self.set_kvm_state(&vcpu_state).map_err(|e| { + self.fd.set_cpu_state(&vcpu_state).map_err(|e| { MigratableError::Restore(anyhow!("Could not set the vCPU KVM state {:?}", e)) })?; @@ -547,7 +458,7 @@ pub struct CpuManager { #[cfg(target_arch = "x86_64")] cpuid: CpuId, #[cfg_attr(target_arch = "aarch64", allow(dead_code))] - fd: Arc, + fd: Arc, vcpus_kill_signalled: Arc, vcpus_pause_signalled: Arc, #[cfg_attr(target_arch = "aarch64", allow(dead_code))] @@ -677,16 +588,16 @@ impl CpuManager { config: &CpusConfig, device_manager: &Arc>, guest_memory: GuestMemoryAtomic, - #[cfg_attr(target_arch = "aarch64", allow(unused_variables))] kvm: &Kvm, - fd: Arc, + fd: Arc, reset_evt: EventFd, + hypervisor: Arc, ) -> Result>> { let mut vcpu_states = Vec::with_capacity(usize::from(config.max_vcpus)); vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default); let device_manager = device_manager.lock().unwrap(); #[cfg(target_arch = "x86_64")] - let cpuid = CpuManager::patch_cpuid(kvm, &config.topology)?; + let cpuid = CpuManager::patch_cpuid(hypervisor, &config.topology)?; let cpu_manager = Arc::new(Mutex::new(CpuManager { config: config.clone(), #[cfg(target_arch = "x86_64")] @@ -725,7 +636,10 @@ impl CpuManager { } #[cfg(target_arch = "x86_64")] - fn patch_cpuid(kvm: &Kvm, topology: &Option) -> Result { + fn patch_cpuid( + hypervisor: Arc, + topology: &Option, + ) -> Result { let mut cpuid_patches = Vec::new(); // Patch tsc deadline timer bit @@ -751,9 +665,9 @@ impl CpuManager { }); // Supported CPUID - let mut cpuid = kvm - .get_supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES) - .map_err(Error::PatchCpuId)?; + let mut cpuid = hypervisor + .get_cpuid() + .map_err(|e| Error::PatchCpuId(e.into()))?; CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches); @@ -804,7 +718,7 @@ impl CpuManager { .unwrap() .fd .set_cpuid2(&cpuid) - .map_err(Error::SetSupportedCpusFailed)?; + .map_err(|e| Error::SetSupportedCpusFailed(e.into()))?; } vcpu.lock() .unwrap() diff --git a/vmm/src/device_manager.rs b/vmm/src/device_manager.rs index d635da503..3e8c53315 100644 --- a/vmm/src/device_manager.rs +++ b/vmm/src/device_manager.rs @@ -40,7 +40,10 @@ use devices::{ interrupt_controller, interrupt_controller::InterruptController, legacy::Serial, BusDevice, HotPlugNotificationFlags, }; -use kvm_ioctls::*; +use hypervisor::kvm_ioctls; +use hypervisor::kvm_ioctls::*; +#[cfg(feature = "mmio_support")] +use hypervisor::vm::DataMatch; use libc::TIOCGWINSZ; use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE}; #[cfg(feature = "pci_support")] @@ -186,10 +189,10 @@ pub enum DeviceManagerError { FreePciBars(pci::PciDeviceError), /// Cannot register ioevent. - RegisterIoevent(kvm_ioctls::Error), + RegisterIoevent(anyhow::Error), /// Cannot unregister ioevent. - UnRegisterIoevent(kvm_ioctls::Error), + UnRegisterIoevent(anyhow::Error), /// Cannot create virtio device VirtioDevice(vmm_sys_util::errno::Error), @@ -229,7 +232,7 @@ pub enum DeviceManagerError { VfioMapRegion(pci::VfioPciError), /// Failed to create the KVM device. - CreateKvmDevice(kvm_ioctls::Error), + CreateKvmDevice(anyhow::Error), /// Failed to memory map. Mmap(io::Error), @@ -430,7 +433,7 @@ struct AddressManager { #[cfg(target_arch = "x86_64")] io_bus: Arc, mmio_bus: Arc, - vm_fd: Arc, + vm_fd: Arc, #[cfg(feature = "pci_support")] device_tree: Arc>, } @@ -561,15 +564,16 @@ impl DeviceRelocation for AddressManager { if bar_addr == new_base { for (event, addr) in virtio_pci_dev.ioeventfds(old_base) { let io_addr = IoEventAddress::Mmio(addr); - self.vm_fd - .unregister_ioevent(event, &io_addr) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; + self.vm_fd.unregister_ioevent(event, &io_addr).unwrap(); + /* + map_err(io::Error::from_raw_os_error( + hypervisor::HypervisorVmError::UnregisterIoEvent, + ))?; */ } for (event, addr) in virtio_pci_dev.ioeventfds(new_base) { let io_addr = IoEventAddress::Mmio(addr); - self.vm_fd - .register_ioevent(event, &io_addr, NoDatamatch) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; + self.vm_fd.register_ioevent(event, &io_addr, None).unwrap(); + //.map_err(|e| io::Error::from_raw_os_error(e.errno()))?; } } else { let virtio_dev = virtio_pci_dev.virtio_device(); @@ -577,7 +581,7 @@ impl DeviceRelocation for AddressManager { if let Some(mut shm_regions) = virtio_dev.get_shm_regions() { if shm_regions.addr.raw_value() == old_base { // Remove old region from KVM by passing a size of 0. - let mut mem_region = kvm_bindings::kvm_userspace_memory_region { + let mut mem_region = hypervisor::kvm::kvm_userspace_memory_region { slot: shm_regions.mem_slot, guest_phys_addr: old_base, memory_size: 0, @@ -585,23 +589,19 @@ impl DeviceRelocation for AddressManager { flags: 0, }; - // Safe because removing an existing guest region. - unsafe { - self.vm_fd - .set_user_memory_region(mem_region) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; - } + self.vm_fd.set_user_memory_region(mem_region).unwrap(); + //.map_err(|e| io::Error::from_raw_os_error(e.errno()))?; // Create new mapping by inserting new region to KVM. mem_region.guest_phys_addr = new_base; mem_region.memory_size = shm_regions.len; - // Safe because the guest regions are guaranteed not to overlap. - unsafe { - self.vm_fd - .set_user_memory_region(mem_region) - .map_err(|e| io::Error::from_raw_os_error(e.errno()))?; - } + self.vm_fd.set_user_memory_region(mem_region).map_err(|e| { + io::Error::new( + io::ErrorKind::Other, + format!("failed to set user memory regions: {:?}", e), + ) + })?; // Update shared memory regions to reflect the new mapping. shm_regions.addr = GuestAddress(new_base); @@ -753,7 +753,7 @@ pub struct DeviceManager { impl DeviceManager { pub fn new( - vm_fd: Arc, + vm_fd: Arc, config: Arc>, memory_manager: Arc>, _exit_evt: &EventFd, @@ -2291,15 +2291,15 @@ impl DeviceManager { } #[cfg(feature = "pci_support")] - fn create_kvm_device(vm: &Arc) -> DeviceManagerResult { - let mut vfio_dev = kvm_bindings::kvm_create_device { - type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_VFIO, + fn create_kvm_device(vm: &Arc) -> DeviceManagerResult { + let mut vfio_dev = hypervisor::kvm::kvm_create_device { + type_: hypervisor::kvm::kvm_device_type_KVM_DEV_TYPE_VFIO, fd: 0, flags: 0, }; vm.create_device(&mut vfio_dev) - .map_err(DeviceManagerError::CreateKvmDevice) + .map_err(|e| DeviceManagerError::CreateKvmDevice(e.into())) } #[cfg(not(feature = "pci_support"))] @@ -2582,8 +2582,8 @@ impl DeviceManager { let io_addr = IoEventAddress::Mmio(addr); self.address_manager .vm_fd - .register_ioevent(event, &io_addr, NoDatamatch) - .map_err(DeviceManagerError::RegisterIoevent)?; + .register_ioevent(event, &io_addr, None) + .map_err(|e| DeviceManagerError::RegisterIoevent(e.into()))?; } let virtio_pci_device = Arc::new(Mutex::new(virtio_pci_device)); @@ -2739,8 +2739,8 @@ impl DeviceManager { let io_addr = IoEventAddress::Mmio(*addr); self.address_manager .vm_fd - .register_ioevent(event, &io_addr, i as u32) - .map_err(DeviceManagerError::RegisterIoevent)?; + .register_ioevent(event, &io_addr, Some(DataMatch::DataMatch32(i as u32))) + .map_err(|e| DeviceManagerError::RegisterIoevent(e.into()))?; } let interrupt_group = interrupt_manager @@ -2979,7 +2979,7 @@ impl DeviceManager { self.address_manager .vm_fd .unregister_ioevent(event, &io_addr) - .map_err(DeviceManagerError::UnRegisterIoevent)?; + .map_err(|e| DeviceManagerError::UnRegisterIoevent(e.into()))?; } ( diff --git a/vmm/src/interrupt.rs b/vmm/src/interrupt.rs index f3934e33d..fc668f871 100644 --- a/vmm/src/interrupt.rs +++ b/vmm/src/interrupt.rs @@ -4,8 +4,8 @@ // use devices::interrupt_controller::InterruptController; -use kvm_bindings::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI}; -use kvm_ioctls::VmFd; +use hypervisor::kvm::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI}; + use std::collections::HashMap; use std::io; use std::mem::size_of; @@ -70,7 +70,7 @@ impl InterruptRoute { }) } - pub fn enable(&self, vm: &Arc) -> Result<()> { + pub fn enable(&self, vm: &Arc) -> Result<()> { if !self.registered.load(Ordering::SeqCst) { vm.register_irqfd(&self.irq_fd, self.gsi).map_err(|e| { io::Error::new( @@ -86,7 +86,7 @@ impl InterruptRoute { Ok(()) } - pub fn disable(&self, vm: &Arc) -> Result<()> { + pub fn disable(&self, vm: &Arc) -> Result<()> { if self.registered.load(Ordering::SeqCst) { vm.unregister_irqfd(&self.irq_fd, self.gsi).map_err(|e| { io::Error::new( @@ -109,14 +109,14 @@ pub struct KvmRoutingEntry { } pub struct MsiInterruptGroup { - vm_fd: Arc, + vm_fd: Arc, gsi_msi_routes: Arc>>, irq_routes: HashMap, } impl MsiInterruptGroup { fn new( - vm_fd: Arc, + vm_fd: Arc, gsi_msi_routes: Arc>>, irq_routes: HashMap, ) -> Self { @@ -316,7 +316,7 @@ pub struct KvmLegacyUserspaceInterruptManager { pub struct KvmMsiInterruptManager { allocator: Arc>, - vm_fd: Arc, + vm_fd: Arc, gsi_msi_routes: Arc>>, } @@ -329,7 +329,7 @@ impl KvmLegacyUserspaceInterruptManager { impl KvmMsiInterruptManager { pub fn new( allocator: Arc>, - vm_fd: Arc, + vm_fd: Arc, gsi_msi_routes: Arc>>, ) -> Self { KvmMsiInterruptManager { diff --git a/vmm/src/lib.rs b/vmm/src/lib.rs index 689b3f836..f4b696754 100644 --- a/vmm/src/lib.rs +++ b/vmm/src/lib.rs @@ -5,6 +5,7 @@ extern crate anyhow; extern crate arc_swap; +extern crate hypervisor; #[macro_use] extern crate lazy_static; #[macro_use] @@ -213,6 +214,7 @@ pub fn start_vmm_thread( api_sender: Sender, api_receiver: Receiver, seccomp_level: &SeccompLevel, + hypervisor: Arc, ) -> Result>> { let http_api_event = api_event.try_clone().map_err(Error::EventFdClone)?; @@ -232,7 +234,7 @@ pub fn start_vmm_thread( // Apply seccomp filter for VMM thread. SeccompFilter::apply(vmm_seccomp_filter).map_err(Error::ApplySeccompFilter)?; - let mut vmm = Vmm::new(vmm_version.to_string(), api_event, vmm_path)?; + let mut vmm = Vmm::new(vmm_version.to_string(), api_event, vmm_path, hypervisor)?; vmm.control_loop(Arc::new(api_receiver)) }) @@ -253,10 +255,16 @@ pub struct Vmm { vm: Option, vm_config: Option>>, vmm_path: PathBuf, + hypervisor: Arc, } impl Vmm { - fn new(vmm_version: String, api_evt: EventFd, vmm_path: PathBuf) -> Result { + fn new( + vmm_version: String, + api_evt: EventFd, + vmm_path: PathBuf, + hypervisor: Arc, + ) -> Result { let mut epoll = EpollContext::new().map_err(Error::Epoll)?; let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?; let reset_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?; @@ -286,6 +294,7 @@ impl Vmm { vm: None, vm_config: None, vmm_path, + hypervisor, }) } @@ -301,6 +310,7 @@ impl Vmm { exit_evt, reset_evt, self.vmm_path.clone(), + self.hypervisor.clone(), )?; self.vm = Some(vm); } @@ -370,6 +380,7 @@ impl Vmm { self.vmm_path.clone(), source_url, restore_cfg.prefault, + self.hypervisor.clone(), )?; self.vm = Some(vm); @@ -413,7 +424,13 @@ impl Vmm { if self.reset_evt.read().is_ok() { warn!("Spurious second reset event received. Ignoring."); } - self.vm = Some(Vm::new(config, exit_evt, reset_evt, self.vmm_path.clone())?); + self.vm = Some(Vm::new( + config, + exit_evt, + reset_evt, + self.vmm_path.clone(), + self.hypervisor.clone(), + )?); } // Then we start the new VM. diff --git a/vmm/src/memory_manager.rs b/vmm/src/memory_manager.rs index e64236b8f..14b1bb95e 100644 --- a/vmm/src/memory_manager.rs +++ b/vmm/src/memory_manager.rs @@ -2,7 +2,7 @@ // // SPDX-License-Identifier: Apache-2.0 // - +extern crate hypervisor; use crate::config::{HotplugMethod, MemoryConfig}; use crate::MEMORY_MANAGER_SNAPSHOT_ID; #[cfg(feature = "acpi")] @@ -12,8 +12,9 @@ use arch::{get_host_cpu_phys_bits, layout, RegionType}; #[cfg(target_arch = "x86_64")] use devices::ioapic; use devices::BusDevice; -use kvm_bindings::{kvm_userspace_memory_region, KVM_MEM_READONLY}; -use kvm_ioctls::*; + +use hypervisor::kvm::{kvm_userspace_memory_region, KVM_MEM_READONLY}; + use std::convert::TryInto; use std::ffi; use std::fs::{File, OpenOptions}; @@ -56,7 +57,7 @@ pub struct MemoryManager { next_kvm_memory_slot: u32, start_of_device_area: GuestAddress, end_of_device_area: GuestAddress, - pub fd: Arc, + pub fd: Arc, hotplug_slots: Vec, selected_slot: usize, backing_file: Option, @@ -103,7 +104,7 @@ pub enum Error { InvalidSize, /// Failed to set the user memory region. - SetUserMemoryRegion(kvm_ioctls::Error), + SetUserMemoryRegion(hypervisor::HypervisorVmError), /// Failed to EventFd. EventFdFail(io::Error), @@ -214,7 +215,7 @@ impl BusDevice for MemoryManager { impl MemoryManager { pub fn new( - fd: Arc, + fd: Arc, config: &MemoryConfig, ext_regions: Option>, prefault: bool, @@ -381,7 +382,7 @@ impl MemoryManager { pub fn new_from_snapshot( snapshot: &Snapshot, - fd: Arc, + fd: Arc, config: &MemoryConfig, source_url: &str, prefault: bool, @@ -685,8 +686,8 @@ impl MemoryManager { flags: if readonly { KVM_MEM_READONLY } else { 0 }, }; - // Safe because the guest regions are guaranteed not to overlap. - unsafe { self.fd.set_user_memory_region(mem_region) } + self.fd + .set_user_memory_region(mem_region) .map_err(Error::SetUserMemoryRegion)?; // Mark the pages as mergeable if explicitly asked for. @@ -738,8 +739,8 @@ impl MemoryManager { flags: 0, }; - // Safe to remove because we know the region exist. - unsafe { self.fd.set_user_memory_region(mem_region) } + self.fd + .set_user_memory_region(mem_region) .map_err(Error::SetUserMemoryRegion)?; // Mark the pages as unmergeable if there were previously marked as diff --git a/vmm/src/vm.rs b/vmm/src/vm.rs index a646136f9..5875ffa88 100644 --- a/vmm/src/vm.rs +++ b/vmm/src/vm.rs @@ -14,7 +14,7 @@ extern crate arch; extern crate devices; extern crate epoll; -extern crate kvm_ioctls; +extern crate hypervisor; extern crate libc; extern crate linux_loader; extern crate net_util; @@ -38,17 +38,13 @@ use crate::{ use anyhow::anyhow; #[cfg(target_arch = "x86_64")] use arch::BootProtocol; -use arch::{check_required_kvm_extensions, EntryPoint}; -#[cfg(target_arch = "x86_64")] -use devices::ioapic; +use arch::EntryPoint; use devices::HotPlugNotificationFlags; -#[cfg(target_arch = "x86_64")] -use kvm_bindings::{kvm_enable_cap, KVM_CAP_SPLIT_IRQCHIP}; -use kvm_ioctls::*; use linux_loader::cmdline::Cmdline; #[cfg(target_arch = "x86_64")] use linux_loader::loader::elf::Error::InvalidElfMagicNumber; use linux_loader::loader::KernelLoader; + use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH}; #[cfg(target_arch = "x86_64")] use std::convert::TryInto; @@ -82,12 +78,6 @@ pub enum Error { /// Cannot open the VM file descriptor. VmFd(io::Error), - /// Cannot create the KVM instance - VmCreate(kvm_ioctls::Error), - - /// Cannot set the VM up - VmSetup(kvm_ioctls::Error), - /// Cannot open the kernel image KernelFile(io::Error), @@ -144,9 +134,6 @@ pub enum Error { /// Failed to join on vCPU threads ThreadCleanup(std::boxed::Box), - /// Failed to create a new KVM instance - KvmNew(kvm_ioctls::Error), - /// VM is not created VmNotCreated, @@ -272,57 +259,14 @@ pub struct Vm { } impl Vm { - fn kvm_new() -> Result<(Kvm, Arc)> { - let kvm = Kvm::new().map_err(Error::KvmNew)?; - - check_required_kvm_extensions(&kvm).expect("Missing KVM capabilities"); - - let fd: VmFd; - loop { - match kvm.create_vm() { - Ok(res) => fd = res, - Err(e) => { - if e.errno() == libc::EINTR { - // If the error returned is EINTR, which means the - // ioctl has been interrupted, we have to retry as - // this can't be considered as a regular error. - continue; - } else { - return Err(Error::VmCreate(e)); - } - } - } - break; - } - let fd = Arc::new(fd); - - // Set TSS - #[cfg(target_arch = "x86_64")] - fd.set_tss_address(arch::x86_64::layout::KVM_TSS_ADDRESS.raw_value() as usize) - .map_err(Error::VmSetup)?; - - #[cfg(target_arch = "x86_64")] - { - // Create split irqchip - // Only the local APIC is emulated in kernel, both PICs and IOAPIC - // are not. - let mut cap: kvm_enable_cap = Default::default(); - cap.cap = KVM_CAP_SPLIT_IRQCHIP; - cap.args[0] = ioapic::NUM_IOAPIC_PINS as u64; - fd.enable_cap(&cap).map_err(Error::VmSetup)?; - } - - Ok((kvm, fd)) - } - fn new_from_memory_manager( config: Arc>, memory_manager: Arc>, - fd: Arc, - kvm: Kvm, + fd: Arc, exit_evt: EventFd, reset_evt: EventFd, vmm_path: PathBuf, + hypervisor: Arc, ) -> Result { config .lock() @@ -344,9 +288,9 @@ impl Vm { &config.lock().unwrap().cpus.clone(), &device_manager, memory_manager.lock().unwrap().guest_memory(), - &kvm, fd, reset_evt, + hypervisor, ) .map_err(Error::CpuManager)?; @@ -382,8 +326,13 @@ impl Vm { exit_evt: EventFd, reset_evt: EventFd, vmm_path: PathBuf, + hypervisor: Arc, ) -> Result { - let (kvm, fd) = Vm::kvm_new()?; + #[cfg(target_arch = "x86_64")] + hypervisor.check_required_extensions().unwrap(); + let fd = hypervisor.create_vm().unwrap(); + #[cfg(target_arch = "x86_64")] + fd.enable_split_irq().unwrap(); let memory_manager = MemoryManager::new( fd.clone(), &config.lock().unwrap().memory.clone(), @@ -396,10 +345,10 @@ impl Vm { config, memory_manager, fd, - kvm, exit_evt, reset_evt, vmm_path, + hypervisor, )?; // The device manager must create the devices from here as it is part @@ -420,8 +369,13 @@ impl Vm { vmm_path: PathBuf, source_url: &str, prefault: bool, + hypervisor: Arc, ) -> Result { - let (kvm, fd) = Vm::kvm_new()?; + #[cfg(target_arch = "x86_64")] + hypervisor.check_required_extensions().unwrap(); + let fd = hypervisor.create_vm().unwrap(); + #[cfg(target_arch = "x86_64")] + fd.enable_split_irq().unwrap(); let config = vm_config_from_snapshot(snapshot).map_err(Error::Restore)?; let memory_manager = if let Some(memory_manager_snapshot) = @@ -445,10 +399,10 @@ impl Vm { config, memory_manager, fd, - kvm, exit_evt, reset_evt, vmm_path, + hypervisor, ) } @@ -1432,9 +1386,8 @@ mod tests { #[cfg(target_arch = "x86_64")] #[test] pub fn test_vm() { - use kvm_bindings::kvm_userspace_memory_region; + use hypervisor::VcpuExit; use vm_memory::{GuestMemory, GuestMemoryRegion}; - // This example based on https://lwn.net/Articles/658511/ let code = [ 0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */ @@ -1450,11 +1403,12 @@ pub fn test_vm() { let load_addr = GuestAddress(0x1000); let mem = GuestMemoryMmap::from_ranges(&[(load_addr, mem_size)]).unwrap(); - let kvm = Kvm::new().expect("new KVM instance creation failed"); - let vm_fd = kvm.create_vm().expect("new VM fd creation failed"); + let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap(); + let hv: Arc = Arc::new(kvm); + let vm_fd = hv.create_vm().expect("new VM fd creation failed"); mem.with_regions(|index, region| { - let mem_region = kvm_userspace_memory_region { + let mem_region = hypervisor::kvm_userspace_memory_region { slot: index as u32, guest_phys_addr: region.start_addr().raw_value(), memory_size: region.len() as u64, @@ -1463,7 +1417,7 @@ pub fn test_vm() { }; // Safe because the guest regions are guaranteed not to overlap. - unsafe { vm_fd.set_user_memory_region(mem_region) } + vm_fd.set_user_memory_region(mem_region) }) .expect("Cannot configure guest memory"); mem.write_slice(&code, load_addr)