mirror of
https://github.com/cloud-hypervisor/cloud-hypervisor.git
synced 2025-01-22 04:25:21 +00:00
arch, pci, vmm: Initial switch to the hypervisor crate
Start moving the vmm, arch and pci crates to being hypervisor agnostic by using the hypervisor trait and abstractions. This is not a complete switch and there are still some remaining KVM dependencies. Signed-off-by: Muminul Islam <muislam@microsoft.com> Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
parent
c48d0c1a67
commit
e4dee57e81
2
.github/workflows/cross-build.yaml
vendored
2
.github/workflows/cross-build.yaml
vendored
@ -25,7 +25,7 @@ jobs:
|
|||||||
- name: Install arm64 libfdt
|
- 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"
|
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
|
- 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
|
- name: Build
|
||||||
uses: actions-rs/cargo@v1
|
uses: actions-rs/cargo@v1
|
||||||
with:
|
with:
|
||||||
|
8
Cargo.lock
generated
8
Cargo.lock
generated
@ -57,8 +57,10 @@ name = "arch"
|
|||||||
version = "0.1.0"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"acpi_tables",
|
"acpi_tables",
|
||||||
|
"anyhow",
|
||||||
"arch_gen",
|
"arch_gen",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
|
"hypervisor",
|
||||||
"kvm-bindings",
|
"kvm-bindings",
|
||||||
"kvm-ioctls",
|
"kvm-ioctls",
|
||||||
"libc",
|
"libc",
|
||||||
@ -716,8 +718,7 @@ dependencies = [
|
|||||||
"anyhow",
|
"anyhow",
|
||||||
"byteorder",
|
"byteorder",
|
||||||
"devices",
|
"devices",
|
||||||
"kvm-bindings",
|
"hypervisor",
|
||||||
"kvm-ioctls",
|
|
||||||
"libc",
|
"libc",
|
||||||
"log 0.4.8",
|
"log 0.4.8",
|
||||||
"serde",
|
"serde",
|
||||||
@ -1574,8 +1575,7 @@ dependencies = [
|
|||||||
"credibility",
|
"credibility",
|
||||||
"devices",
|
"devices",
|
||||||
"epoll",
|
"epoll",
|
||||||
"kvm-bindings",
|
"hypervisor",
|
||||||
"kvm-ioctls",
|
|
||||||
"lazy_static",
|
"lazy_static",
|
||||||
"libc",
|
"libc",
|
||||||
"linux-loader",
|
"linux-loader",
|
||||||
|
@ -8,7 +8,9 @@ default = []
|
|||||||
acpi = ["acpi_tables"]
|
acpi = ["acpi_tables"]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
anyhow = "1.0"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
|
hypervisor = { path = "../hypervisor" }
|
||||||
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch" }
|
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch" }
|
||||||
kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" }
|
kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" }
|
||||||
libc = "0.2.71"
|
libc = "0.2.71"
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
|
|
||||||
use std::{boxed::Box, result};
|
|
||||||
|
|
||||||
use kvm_ioctls::{DeviceFd, VmFd};
|
use kvm_ioctls::{DeviceFd, VmFd};
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::{boxed::Box, result};
|
||||||
|
|
||||||
use super::gicv2::GICv2;
|
use super::gicv2::GICv2;
|
||||||
use super::gicv3::GICv3;
|
use super::gicv3::GICv3;
|
||||||
@ -12,7 +12,7 @@ use super::gicv3::GICv3;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Error while calling KVM ioctl for setting up the global interrupt controller.
|
/// 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.
|
/// Error while setting device attributes for the GIC.
|
||||||
SetDeviceAttribute(kvm_ioctls::Error),
|
SetDeviceAttribute(kvm_ioctls::Error),
|
||||||
}
|
}
|
||||||
@ -51,7 +51,7 @@ pub trait GICDevice: Send + Sync {
|
|||||||
Self: Sized;
|
Self: Sized;
|
||||||
|
|
||||||
/// Initialize a GIC device
|
/// Initialize a GIC device
|
||||||
fn init_device(vm: &VmFd) -> Result<DeviceFd>
|
fn init_device(vm: &Arc<dyn hypervisor::Vm>) -> Result<DeviceFd>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
Self: Sized,
|
||||||
{
|
{
|
||||||
@ -120,7 +120,7 @@ pub trait GICDevice: Send + Sync {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Method to initialize the GIC device
|
/// Method to initialize the GIC device
|
||||||
fn new(vm: &VmFd, vcpu_count: u64) -> Result<Box<dyn GICDevice>>
|
fn new(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GICDevice>>
|
||||||
where
|
where
|
||||||
Self: Sized,
|
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
|
/// It will try to create by default a GICv3 device. If that fails it will try
|
||||||
/// to fall-back to a GICv2 device.
|
/// to fall-back to a GICv2 device.
|
||||||
pub fn create_gic(vm: &VmFd, vcpu_count: u64) -> Result<Box<dyn GICDevice>> {
|
pub fn create_gic(vm: &Arc<dyn hypervisor::Vm>, vcpu_count: u64) -> Result<Box<dyn GICDevice>> {
|
||||||
GICv3::new(vm, vcpu_count).or_else(|_| GICv2::new(vm, vcpu_count))
|
GICv3::new(vm, vcpu_count).or_else(|_| GICv2::new(vm, vcpu_count))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,6 +20,7 @@ use kvm_ioctls::*;
|
|||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::ffi::CStr;
|
use std::ffi::CStr;
|
||||||
use std::fmt::Debug;
|
use std::fmt::Debug;
|
||||||
|
use std::sync::Arc;
|
||||||
use vm_memory::{
|
use vm_memory::{
|
||||||
Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryMmap,
|
Address, GuestAddress, GuestAddressSpace, GuestMemory, GuestMemoryAtomic, GuestMemoryMmap,
|
||||||
GuestUsize,
|
GuestUsize,
|
||||||
@ -41,10 +42,10 @@ pub enum Error {
|
|||||||
REGSConfiguration(regs::Error),
|
REGSConfiguration(regs::Error),
|
||||||
|
|
||||||
/// Error fetching prefered target
|
/// Error fetching prefered target
|
||||||
VcpuArmPreferredTarget(kvm_ioctls::Error),
|
VcpuArmPreferredTarget(hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
/// Error doing Vcpu Init on Arm.
|
/// Error doing Vcpu Init on Arm.
|
||||||
VcpuArmInit(kvm_ioctls::Error),
|
VcpuArmInit(hypervisor::HypervisorCpuError),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for super::Error {
|
impl From<Error> for super::Error {
|
||||||
@ -63,9 +64,9 @@ pub struct EntryPoint {
|
|||||||
|
|
||||||
/// Configure the specified VCPU, and return its MPIDR.
|
/// Configure the specified VCPU, and return its MPIDR.
|
||||||
pub fn configure_vcpu(
|
pub fn configure_vcpu(
|
||||||
fd: &VcpuFd,
|
fd: &Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u8,
|
||||||
vm_fd: &VmFd,
|
vm_fd: &Arc<dyn hypervisor::Vm>,
|
||||||
kernel_entry_point: Option<EntryPoint>,
|
kernel_entry_point: Option<EntryPoint>,
|
||||||
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
) -> super::Result<u64> {
|
) -> super::Result<u64> {
|
||||||
@ -138,7 +139,7 @@ pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize, Region
|
|||||||
#[allow(clippy::too_many_arguments)]
|
#[allow(clippy::too_many_arguments)]
|
||||||
#[allow(unused_variables)]
|
#[allow(unused_variables)]
|
||||||
pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
|
pub fn configure_system<T: DeviceInfoForFDT + Clone + Debug>(
|
||||||
vm_fd: &VmFd,
|
vm_fd: &Arc<dyn hypervisor::Vm>,
|
||||||
guest_mem: &GuestMemoryMmap,
|
guest_mem: &GuestMemoryMmap,
|
||||||
cmdline_cstring: &CStr,
|
cmdline_cstring: &CStr,
|
||||||
vcpu_count: u64,
|
vcpu_count: u64,
|
||||||
@ -200,13 +201,6 @@ pub fn get_host_cpu_phys_bits() -> u8 {
|
|||||||
40
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
@ -5,8 +5,6 @@
|
|||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the THIRD-PARTY file.
|
// found in the THIRD-PARTY file.
|
||||||
|
|
||||||
use std::{mem, result};
|
|
||||||
|
|
||||||
use super::get_fdt_addr;
|
use super::get_fdt_addr;
|
||||||
use kvm_bindings::{
|
use kvm_bindings::{
|
||||||
user_pt_regs, KVM_REG_ARM64, KVM_REG_ARM64_SYSREG, KVM_REG_ARM64_SYSREG_CRM_MASK,
|
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,
|
KVM_REG_ARM_CORE, KVM_REG_SIZE_U64,
|
||||||
};
|
};
|
||||||
use kvm_ioctls::VcpuFd;
|
use kvm_ioctls::VcpuFd;
|
||||||
|
use std::sync::Arc;
|
||||||
|
use std::{mem, result};
|
||||||
use vm_memory::GuestMemoryMmap;
|
use vm_memory::GuestMemoryMmap;
|
||||||
|
|
||||||
/// Errors thrown while setting aarch64 registers.
|
/// Errors thrown while setting aarch64 registers.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Failed to set core register (PC, PSTATE or general purpose ones).
|
/// Failed to set core register (PC, PSTATE or general purpose ones).
|
||||||
SetCoreRegister(kvm_ioctls::Error),
|
SetCoreRegister(hypervisor::HypervisorCpuError),
|
||||||
/// Failed to get a system register.
|
/// Failed to get a system register.
|
||||||
GetSysRegister(kvm_ioctls::Error),
|
GetSysRegister(hypervisor::HypervisorCpuError),
|
||||||
}
|
}
|
||||||
type Result<T> = result::Result<T, Error>;
|
type Result<T> = result::Result<T, Error>;
|
||||||
|
|
||||||
@ -122,7 +121,12 @@ arm64_sys_reg!(MPIDR_EL1, 3, 0, 0, 0, 5);
|
|||||||
/// * `cpu_id` - Index of current vcpu.
|
/// * `cpu_id` - Index of current vcpu.
|
||||||
/// * `boot_ip` - Starting instruction pointer.
|
/// * `boot_ip` - Starting instruction pointer.
|
||||||
/// * `mem` - Reserved DRAM for current VM.
|
/// * `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<dyn hypervisor::Vcpu>,
|
||||||
|
cpu_id: u8,
|
||||||
|
boot_ip: u64,
|
||||||
|
mem: &GuestMemoryMmap,
|
||||||
|
) -> Result<()> {
|
||||||
// Get the register index of the PSTATE (Processor State) register.
|
// Get the register index of the PSTATE (Processor State) register.
|
||||||
vcpu.set_one_reg(arm64_core_reg!(pstate), PSTATE_FAULT_BITS_64)
|
vcpu.set_one_reg(arm64_core_reg!(pstate), PSTATE_FAULT_BITS_64)
|
||||||
.map_err(Error::SetCoreRegister)?;
|
.map_err(Error::SetCoreRegister)?;
|
||||||
@ -148,7 +152,7 @@ pub fn setup_regs(vcpu: &VcpuFd, cpu_id: u8, boot_ip: u64, mem: &GuestMemoryMmap
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
pub fn read_mpidr(vcpu: &VcpuFd) -> Result<u64> {
|
pub fn read_mpidr(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<u64> {
|
||||||
vcpu.get_one_reg(MPIDR_EL1).map_err(Error::GetSysRegister)
|
vcpu.get_one_reg(MPIDR_EL1).map_err(Error::GetSysRegister)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -15,6 +15,7 @@
|
|||||||
)]
|
)]
|
||||||
|
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
extern crate hypervisor;
|
||||||
extern crate kvm_bindings;
|
extern crate kvm_bindings;
|
||||||
extern crate kvm_ioctls;
|
extern crate kvm_ioctls;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
@ -26,7 +27,6 @@ extern crate acpi_tables;
|
|||||||
extern crate arch_gen;
|
extern crate arch_gen;
|
||||||
extern crate linux_loader;
|
extern crate linux_loader;
|
||||||
|
|
||||||
use kvm_ioctls::*;
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::result;
|
use std::result;
|
||||||
|
|
||||||
@ -57,8 +57,6 @@ pub enum Error {
|
|||||||
ModlistSetup(vm_memory::GuestMemoryError),
|
ModlistSetup(vm_memory::GuestMemoryError),
|
||||||
/// RSDP Beyond Guest Memory
|
/// RSDP Beyond Guest Memory
|
||||||
RSDPPastRamEnd,
|
RSDPPastRamEnd,
|
||||||
/// Capability missing
|
|
||||||
CapabilityMissing(Cap),
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Type for returning public functions outcome.
|
/// Type for returning public functions outcome.
|
||||||
@ -89,9 +87,9 @@ pub mod aarch64;
|
|||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[cfg(target_arch = "aarch64")]
|
||||||
pub use aarch64::{
|
pub use aarch64::{
|
||||||
arch_memory_regions, check_required_kvm_extensions, configure_system, configure_vcpu,
|
arch_memory_regions, configure_system, configure_vcpu, fdt::DeviceInfoForFDT,
|
||||||
fdt::DeviceInfoForFDT, get_host_cpu_phys_bits, get_kernel_start, layout,
|
get_host_cpu_phys_bits, get_kernel_start, layout, layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE,
|
||||||
layout::CMDLINE_MAX_SIZE, layout::IRQ_BASE, layout::IRQ_MAX, EntryPoint,
|
layout::IRQ_MAX, EntryPoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -99,9 +97,9 @@ pub mod x86_64;
|
|||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
pub use x86_64::{
|
pub use x86_64::{
|
||||||
arch_memory_regions, check_required_kvm_extensions, configure_system, configure_vcpu,
|
arch_memory_regions, configure_system, configure_vcpu, get_host_cpu_phys_bits,
|
||||||
get_host_cpu_phys_bits, initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE,
|
initramfs_load_addr, layout, layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START, regs,
|
||||||
layout::CMDLINE_START, regs, BootProtocol, CpuidPatch, CpuidReg, EntryPoint,
|
BootProtocol, CpuidPatch, CpuidReg, EntryPoint,
|
||||||
};
|
};
|
||||||
|
|
||||||
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
|
/// Safe wrapper for `sysconf(_SC_PAGESIZE)`.
|
||||||
|
@ -8,8 +8,7 @@
|
|||||||
// found in the LICENSE-BSD-3-Clause file.
|
// found in the LICENSE-BSD-3-Clause file.
|
||||||
|
|
||||||
// For GDT details see arch/x86/include/asm/segment.h
|
// For GDT details see arch/x86/include/asm/segment.h
|
||||||
|
use hypervisor::x86_64::SegmentRegister;
|
||||||
use kvm_bindings::kvm_segment;
|
|
||||||
|
|
||||||
/// Constructor for a conventional segment GDT (or LDT) entry. Derived from the kernel's segment.h.
|
/// 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 {
|
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
|
((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
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `entry` - The gdt entry.
|
/// * `entry` - The gdt entry.
|
||||||
/// * `table_index` - Index of the entry in the gdt table.
|
/// * `table_index` - Index of the entry in the gdt table.
|
||||||
pub fn kvm_segment_from_gdt(entry: u64, table_index: u8) -> kvm_segment {
|
pub fn segment_from_gdt(entry: u64, table_index: u8) -> SegmentRegister {
|
||||||
kvm_segment {
|
SegmentRegister {
|
||||||
base: get_base(entry),
|
base: get_base(entry),
|
||||||
limit: get_limit(entry),
|
limit: get_limit(entry),
|
||||||
selector: (table_index * 8) as u16,
|
selector: (table_index * 8) as u16,
|
||||||
@ -122,7 +121,7 @@ mod tests {
|
|||||||
#[test]
|
#[test]
|
||||||
fn field_parse() {
|
fn field_parse() {
|
||||||
let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
|
let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
|
||||||
let seg = kvm_segment_from_gdt(gdt, 0);
|
let seg = segment_from_gdt(gdt, 0);
|
||||||
// 0xA09B
|
// 0xA09B
|
||||||
// 'A'
|
// 'A'
|
||||||
assert_eq!(0x1, seg.g);
|
assert_eq!(0x1, seg.g);
|
||||||
|
@ -8,19 +8,19 @@
|
|||||||
use std::io::Cursor;
|
use std::io::Cursor;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::result;
|
use std::result;
|
||||||
|
use std::sync::Arc;
|
||||||
|
|
||||||
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
|
||||||
use kvm_bindings::kvm_lapic_state;
|
use hypervisor::x86_64::LapicState;
|
||||||
use kvm_ioctls;
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
GetLapic(kvm_ioctls::Error),
|
GetLapic(anyhow::Error),
|
||||||
SetLapic(kvm_ioctls::Error),
|
SetLapic(anyhow::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub type Result<T> = result::Result<T, Error>;
|
pub type Result<T> = result::Result<T, hypervisor::HypervisorCpuError>;
|
||||||
|
|
||||||
// Defines poached from apicdef.h kernel header.
|
// Defines poached from apicdef.h kernel header.
|
||||||
const APIC_LVT0: usize = 0x350;
|
const APIC_LVT0: usize = 0x350;
|
||||||
@ -28,7 +28,7 @@ const APIC_LVT1: usize = 0x360;
|
|||||||
const APIC_MODE_NMI: u32 = 0x4;
|
const APIC_MODE_NMI: u32 = 0x4;
|
||||||
const APIC_MODE_EXTINT: u32 = 0x7;
|
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 {
|
let sliceu8 = unsafe {
|
||||||
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
|
// 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).
|
// 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")
|
.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 {
|
let sliceu8 = unsafe {
|
||||||
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
|
// 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).
|
// 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
|
/// # Arguments
|
||||||
/// * `vcpu` - The VCPU object to configure.
|
/// * `vcpu` - The VCPU object to configure.
|
||||||
pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> {
|
pub fn set_lint(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
|
||||||
let mut klapic = vcpu.get_lapic().map_err(Error::GetLapic)?;
|
let mut klapic = vcpu.get_lapic()?;
|
||||||
|
|
||||||
let lvt_lint0 = get_klapic_reg(&klapic, APIC_LVT0);
|
let lvt_lint0 = get_klapic_reg(&klapic, APIC_LVT0);
|
||||||
set_klapic_reg(
|
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),
|
set_apic_delivery_mode(lvt_lint1, APIC_MODE_NMI),
|
||||||
);
|
);
|
||||||
|
|
||||||
vcpu.set_lapic(&klapic).map_err(Error::SetLapic)
|
vcpu.set_lapic(&klapic)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
extern crate kvm_ioctls;
|
|
||||||
extern crate rand;
|
extern crate rand;
|
||||||
use self::rand::Rng;
|
use self::rand::Rng;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use kvm_ioctls::Kvm;
|
|
||||||
|
|
||||||
const KVM_APIC_REG_SIZE: usize = 0x400;
|
const KVM_APIC_REG_SIZE: usize = 0x400;
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_set_and_get_klapic_reg() {
|
fn test_set_and_get_klapic_reg() {
|
||||||
let reg_offset = 0x340;
|
let reg_offset = 0x340;
|
||||||
let mut klapic = kvm_lapic_state::default();
|
let mut klapic = LapicState::default();
|
||||||
set_klapic_reg(&mut klapic, reg_offset, 3);
|
set_klapic_reg(&mut klapic, reg_offset, 3);
|
||||||
let value = get_klapic_reg(&klapic, reg_offset);
|
let value = get_klapic_reg(&klapic, reg_offset);
|
||||||
assert_eq!(value, 3);
|
assert_eq!(value, 3);
|
||||||
@ -105,7 +104,7 @@ mod tests {
|
|||||||
#[should_panic]
|
#[should_panic]
|
||||||
fn test_set_and_get_klapic_out_of_bounds() {
|
fn test_set_and_get_klapic_out_of_bounds() {
|
||||||
let reg_offset = KVM_APIC_REG_SIZE + 10;
|
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);
|
set_klapic_reg(&mut klapic, reg_offset, 3);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,13 +121,14 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setlint() {
|
fn test_setlint() {
|
||||||
let kvm = kvm_ioctls::Kvm::new().unwrap();
|
let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap();
|
||||||
assert!(kvm.check_extension(kvm_ioctls::Cap::Irqchip));
|
let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
|
||||||
let vm = kvm.create_vm().unwrap();
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
//the get_lapic ioctl will fail if there is no irqchip created beforehand.
|
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());
|
assert!(vm.create_irq_chip().is_ok());
|
||||||
let vcpu = vm.create_vcpu(0).unwrap();
|
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.
|
// Compute the value that is expected to represent LVT0 and LVT1.
|
||||||
let lint0 = get_klapic_reg(&klapic_before, APIC_LVT0);
|
let lint0 = get_klapic_reg(&klapic_before, APIC_LVT0);
|
||||||
@ -139,20 +139,10 @@ mod tests {
|
|||||||
set_lint(&vcpu).unwrap();
|
set_lint(&vcpu).unwrap();
|
||||||
|
|
||||||
// Compute the value that represents LVT0 and LVT1 after set_lint.
|
// 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 lint0_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT0);
|
||||||
let lint1_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT1);
|
let lint1_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT1);
|
||||||
assert_eq!(lint0_mode_expected, lint0_mode_actual);
|
assert_eq!(lint0_mode_expected, lint0_mode_actual);
|
||||||
assert_eq!(lint1_mode_expected, lint1_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());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
@ -6,7 +6,7 @@
|
|||||||
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE-BSD-3-Clause file.
|
// found in the LICENSE-BSD-3-Clause file.
|
||||||
|
use std::sync::Arc;
|
||||||
mod gdt;
|
mod gdt;
|
||||||
pub mod interrupts;
|
pub mod interrupts;
|
||||||
pub mod layout;
|
pub mod layout;
|
||||||
@ -15,8 +15,7 @@ mod mptable;
|
|||||||
pub mod regs;
|
pub mod regs;
|
||||||
use crate::InitramfsConfig;
|
use crate::InitramfsConfig;
|
||||||
use crate::RegionType;
|
use crate::RegionType;
|
||||||
use kvm_bindings::CpuId;
|
use hypervisor::CpuId;
|
||||||
use kvm_ioctls::*;
|
|
||||||
use linux_loader::loader::bootparam::{boot_params, setup_header};
|
use linux_loader::loader::bootparam::{boot_params, setup_header};
|
||||||
use linux_loader::loader::elf::start_info::{
|
use linux_loader::loader::elf::start_info::{
|
||||||
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
|
hvm_memmap_table_entry, hvm_modlist_entry, hvm_start_info,
|
||||||
@ -111,10 +110,10 @@ pub enum Error {
|
|||||||
MSRSConfiguration(regs::Error),
|
MSRSConfiguration(regs::Error),
|
||||||
|
|
||||||
/// The call to KVM_SET_CPUID2 failed.
|
/// The call to KVM_SET_CPUID2 failed.
|
||||||
SetSupportedCpusFailed(kvm_ioctls::Error),
|
SetSupportedCpusFailed(anyhow::Error),
|
||||||
|
|
||||||
/// Cannot set the local interruption due to bad configuration.
|
/// Cannot set the local interruption due to bad configuration.
|
||||||
LocalIntConfiguration(interrupts::Error),
|
LocalIntConfiguration(anyhow::Error),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<Error> for super::Error {
|
impl From<Error> for super::Error {
|
||||||
@ -200,7 +199,7 @@ impl CpuidPatch {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn configure_vcpu(
|
pub fn configure_vcpu(
|
||||||
fd: &VcpuFd,
|
fd: &Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u8,
|
||||||
kernel_entry_point: Option<EntryPoint>,
|
kernel_entry_point: Option<EntryPoint>,
|
||||||
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
@ -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, 0xb, None, CpuidReg::EDX, u32::from(id));
|
||||||
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id));
|
CpuidPatch::set_cpuid_reg(&mut cpuid, 0x1f, None, CpuidReg::EDX, u32::from(id));
|
||||||
fd.set_cpuid2(&cpuid)
|
fd.set_cpuid2(&cpuid)
|
||||||
.map_err(Error::SetSupportedCpusFailed)?;
|
.map_err(|e| Error::SetSupportedCpusFailed(e.into()))?;
|
||||||
|
|
||||||
regs::setup_msrs(fd).map_err(Error::MSRSConfiguration)?;
|
regs::setup_msrs(fd).map_err(Error::MSRSConfiguration)?;
|
||||||
if let Some(kernel_entry_point) = kernel_entry_point {
|
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)
|
regs::setup_sregs(&vm_memory.memory(), fd, kernel_entry_point.protocol)
|
||||||
.map_err(Error::SREGSConfiguration)?;
|
.map_err(Error::SREGSConfiguration)?;
|
||||||
}
|
}
|
||||||
interrupts::set_lint(fd).map_err(Error::LocalIntConfiguration)?;
|
interrupts::set_lint(fd).map_err(|e| Error::LocalIntConfiguration(e.into()))?;
|
||||||
Ok(())
|
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(
|
pub fn update_cpuid_topology(
|
||||||
cpuid: &mut CpuId,
|
cpuid: &mut CpuId,
|
||||||
threads_per_core: u8,
|
threads_per_core: u8,
|
||||||
|
@ -6,35 +6,29 @@
|
|||||||
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
|
||||||
// Use of this source code is governed by a BSD-style license that can be
|
// Use of this source code is governed by a BSD-style license that can be
|
||||||
// found in the LICENSE-BSD-3-Clause file.
|
// found in the LICENSE-BSD-3-Clause file.
|
||||||
|
use std::sync::Arc;
|
||||||
use std::{mem, result};
|
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 super::BootProtocol;
|
||||||
use arch_gen::x86::msr_index;
|
use hypervisor::x86_64::{FpuState, SpecialRegisters, StandardRegisters};
|
||||||
use kvm_bindings::{kvm_fpu, kvm_msr_entry, kvm_regs, kvm_sregs, Msrs};
|
|
||||||
use kvm_ioctls::VcpuFd;
|
|
||||||
use layout::{
|
use layout::{
|
||||||
BOOT_GDT_START, BOOT_IDT_START, PDE_START, PDPTE_START, PML4_START, PML5_START, PVH_INFO_START,
|
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};
|
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)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Failed to get SREGs for this CPU.
|
/// Failed to get SREGs for this CPU.
|
||||||
GetStatusRegisters(kvm_ioctls::Error),
|
GetStatusRegisters(hypervisor::HypervisorCpuError),
|
||||||
/// Failed to set base registers for this CPU.
|
/// Failed to set base registers for this CPU.
|
||||||
SetBaseRegisters(kvm_ioctls::Error),
|
SetBaseRegisters(hypervisor::HypervisorCpuError),
|
||||||
/// Failed to configure the FPU.
|
/// Failed to configure the FPU.
|
||||||
SetFPURegisters(kvm_ioctls::Error),
|
SetFPURegisters(hypervisor::HypervisorCpuError),
|
||||||
/// Setting up MSRs failed.
|
/// Setting up MSRs failed.
|
||||||
SetModelSpecificRegisters(kvm_ioctls::Error),
|
SetModelSpecificRegisters(hypervisor::HypervisorCpuError),
|
||||||
/// Failed to set SREGs for this CPU.
|
/// Failed to set SREGs for this CPU.
|
||||||
SetStatusRegisters(kvm_ioctls::Error),
|
SetStatusRegisters(hypervisor::HypervisorCpuError),
|
||||||
/// Checking the GDT address failed.
|
/// Checking the GDT address failed.
|
||||||
CheckGDTAddr,
|
CheckGDTAddr,
|
||||||
/// Writing the GDT to RAM failed.
|
/// Writing the GDT to RAM failed.
|
||||||
@ -58,8 +52,8 @@ pub type Result<T> = result::Result<T, Error>;
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
|
pub fn setup_fpu(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
|
||||||
let fpu: kvm_fpu = kvm_fpu {
|
let fpu: FpuState = FpuState {
|
||||||
fcw: 0x37f,
|
fcw: 0x37f,
|
||||||
mxcsr: 0x1f80,
|
mxcsr: 0x1f80,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
@ -73,8 +67,8 @@ pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
|
|||||||
/// # Arguments
|
/// # Arguments
|
||||||
///
|
///
|
||||||
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> {
|
pub fn setup_msrs(vcpu: &Arc<dyn hypervisor::Vcpu>) -> Result<()> {
|
||||||
vcpu.set_msrs(&boot_msr_entries())
|
vcpu.set_msrs(&hypervisor::kvm::x86_64::boot_msr_entries())
|
||||||
.map_err(Error::SetModelSpecificRegisters)?;
|
.map_err(Error::SetModelSpecificRegisters)?;
|
||||||
|
|
||||||
Ok(())
|
Ok(())
|
||||||
@ -89,22 +83,22 @@ pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> {
|
|||||||
/// * `boot_sp` - Starting stack pointer.
|
/// * `boot_sp` - Starting stack pointer.
|
||||||
/// * `boot_si` - Must point to zero page address per Linux ABI.
|
/// * `boot_si` - Must point to zero page address per Linux ABI.
|
||||||
pub fn setup_regs(
|
pub fn setup_regs(
|
||||||
vcpu: &VcpuFd,
|
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
||||||
boot_ip: u64,
|
boot_ip: u64,
|
||||||
boot_sp: u64,
|
boot_sp: u64,
|
||||||
boot_si: u64,
|
boot_si: u64,
|
||||||
boot_prot: BootProtocol,
|
boot_prot: BootProtocol,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let regs: kvm_regs = match boot_prot {
|
let regs: StandardRegisters = match boot_prot {
|
||||||
// Configure regs as required by PVH boot protocol.
|
// Configure regs as required by PVH boot protocol.
|
||||||
BootProtocol::PvhBoot => kvm_regs {
|
BootProtocol::PvhBoot => StandardRegisters {
|
||||||
rflags: 0x0000000000000002u64,
|
rflags: 0x0000000000000002u64,
|
||||||
rbx: PVH_INFO_START.raw_value(),
|
rbx: PVH_INFO_START.raw_value(),
|
||||||
rip: boot_ip,
|
rip: boot_ip,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
},
|
},
|
||||||
// Configure regs as required by Linux 64-bit boot protocol.
|
// Configure regs as required by Linux 64-bit boot protocol.
|
||||||
BootProtocol::LinuxBoot => kvm_regs {
|
BootProtocol::LinuxBoot => StandardRegisters {
|
||||||
rflags: 0x0000000000000002u64,
|
rflags: 0x0000000000000002u64,
|
||||||
rip: boot_ip,
|
rip: boot_ip,
|
||||||
rsp: boot_sp,
|
rsp: boot_sp,
|
||||||
@ -122,8 +116,12 @@ pub fn setup_regs(
|
|||||||
///
|
///
|
||||||
/// * `mem` - The memory that will be passed to the guest.
|
/// * `mem` - The memory that will be passed to the guest.
|
||||||
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
|
||||||
pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &VcpuFd, boot_prot: BootProtocol) -> Result<()> {
|
pub fn setup_sregs(
|
||||||
let mut sregs: kvm_sregs = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
|
mem: &GuestMemoryMmap,
|
||||||
|
vcpu: &Arc<dyn hypervisor::Vcpu>,
|
||||||
|
boot_prot: BootProtocol,
|
||||||
|
) -> Result<()> {
|
||||||
|
let mut sregs: SpecialRegisters = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
|
||||||
|
|
||||||
configure_segments_and_sregs(mem, &mut sregs, boot_prot)?;
|
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(
|
fn configure_segments_and_sregs(
|
||||||
mem: &GuestMemoryMmap,
|
mem: &GuestMemoryMmap,
|
||||||
sregs: &mut kvm_sregs,
|
sregs: &mut SpecialRegisters,
|
||||||
boot_prot: BootProtocol,
|
boot_prot: BootProtocol,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let gdt_table: [u64; BOOT_GDT_MAX as usize] = match boot_prot {
|
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 code_seg = segment_from_gdt(gdt_table[1], 1);
|
||||||
let data_seg = kvm_segment_from_gdt(gdt_table[2], 2);
|
let data_seg = segment_from_gdt(gdt_table[2], 2);
|
||||||
let tss_seg = kvm_segment_from_gdt(gdt_table[3], 3);
|
let tss_seg = segment_from_gdt(gdt_table[3], 3);
|
||||||
|
|
||||||
// Write segments
|
// Write segments
|
||||||
write_gdt_table(&gdt_table[..], mem)?;
|
write_gdt_table(&gdt_table[..], mem)?;
|
||||||
@ -224,9 +222,8 @@ fn configure_segments_and_sregs(
|
|||||||
Ok(())
|
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.
|
// Puts PML5 or PML4 right after zero page but aligned to 4k.
|
||||||
|
|
||||||
if unsafe { std::arch::x86_64::__cpuid(7).ecx } & (1 << 16) != 0 {
|
if unsafe { std::arch::x86_64::__cpuid(7).ecx } & (1 << 16) != 0 {
|
||||||
// Entry covering VA [0..256TB)
|
// Entry covering VA [0..256TB)
|
||||||
mem.write_obj(PML4_START.raw_value() | 0x03, PML5_START)
|
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(())
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
extern crate kvm_ioctls;
|
extern crate kvm_ioctls;
|
||||||
extern crate vm_memory;
|
extern crate vm_memory;
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
use kvm_ioctls::Kvm;
|
|
||||||
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
use vm_memory::{GuestAddress, GuestMemoryMmap};
|
||||||
|
|
||||||
fn create_guest_mem() -> GuestMemoryMmap {
|
fn create_guest_mem() -> GuestMemoryMmap {
|
||||||
@ -317,7 +274,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn segments_and_sregs() {
|
fn segments_and_sregs() {
|
||||||
let mut sregs: kvm_sregs = Default::default();
|
let mut sregs: SpecialRegisters = Default::default();
|
||||||
let gm = create_guest_mem();
|
let gm = create_guest_mem();
|
||||||
configure_segments_and_sregs(&gm, &mut sregs, BootProtocol::LinuxBoot).unwrap();
|
configure_segments_and_sregs(&gm, &mut sregs, BootProtocol::LinuxBoot).unwrap();
|
||||||
|
|
||||||
@ -381,7 +338,7 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn page_tables() {
|
fn page_tables() {
|
||||||
let mut sregs: kvm_sregs = Default::default();
|
let mut sregs: SpecialRegisters = Default::default();
|
||||||
let gm = create_guest_mem();
|
let gm = create_guest_mem();
|
||||||
setup_page_tables(&gm, &mut sregs).unwrap();
|
setup_page_tables(&gm, &mut sregs).unwrap();
|
||||||
|
|
||||||
@ -408,20 +365,21 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_fpu() {
|
fn test_setup_fpu() {
|
||||||
let kvm = Kvm::new().unwrap();
|
let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap();
|
||||||
let vm = kvm.create_vm().unwrap();
|
let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
|
||||||
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
let vcpu = vm.create_vcpu(0).unwrap();
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
setup_fpu(&vcpu).unwrap();
|
setup_fpu(&vcpu).unwrap();
|
||||||
|
|
||||||
let expected_fpu: kvm_fpu = kvm_fpu {
|
let expected_fpu: FpuState = FpuState {
|
||||||
fcw: 0x37f,
|
fcw: 0x37f,
|
||||||
mxcsr: 0x1f80,
|
mxcsr: 0x1f80,
|
||||||
..Default::default()
|
..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.
|
// TODO: auto-generate kvm related structures with PartialEq on.
|
||||||
assert_eq!(expected_fpu.fcw, actual_fpu.fcw);
|
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.
|
// 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
|
// The mxcsr will stay 0 and the assert below fails. Decide whether or not we should
|
||||||
// remove it at all.
|
// remove it at all.
|
||||||
@ -430,14 +388,18 @@ mod tests {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_msrs() {
|
fn test_setup_msrs() {
|
||||||
let kvm = Kvm::new().unwrap();
|
use hypervisor::arch::x86::msr_index;
|
||||||
let vm = kvm.create_vm().unwrap();
|
use hypervisor::x86_64::{MsrEntries, MsrEntry};
|
||||||
|
|
||||||
|
let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap();
|
||||||
|
let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
|
||||||
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
let vcpu = vm.create_vcpu(0).unwrap();
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
setup_msrs(&vcpu).unwrap();
|
setup_msrs(&vcpu).unwrap();
|
||||||
|
|
||||||
// This test will check against the last MSR entry configured (the tenth one).
|
// This test will check against the last MSR entry configured (the tenth one).
|
||||||
// See create_msr_entries for details.
|
// 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,
|
index: msr_index::MSR_IA32_MISC_ENABLE,
|
||||||
..Default::default()
|
..Default::default()
|
||||||
}]);
|
}]);
|
||||||
@ -450,17 +412,18 @@ mod tests {
|
|||||||
// Official entries that were setup when we did setup_msrs. We need to assert that the
|
// 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
|
// tenth one (i.e the one with index msr_index::MSR_IA32_MISC_ENABLE has the data we
|
||||||
// expect.
|
// 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]);
|
assert_eq!(entry_vec.as_slice()[9], msrs.as_slice()[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_regs() {
|
fn test_setup_regs() {
|
||||||
let kvm = Kvm::new().unwrap();
|
let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap();
|
||||||
let vm = kvm.create_vm().unwrap();
|
let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
|
||||||
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
let vcpu = vm.create_vcpu(0).unwrap();
|
let vcpu = vm.create_vcpu(0).unwrap();
|
||||||
|
|
||||||
let expected_regs: kvm_regs = kvm_regs {
|
let expected_regs: StandardRegisters = StandardRegisters {
|
||||||
rflags: 0x0000000000000002u64,
|
rflags: 0x0000000000000002u64,
|
||||||
rip: 1,
|
rip: 1,
|
||||||
rsp: 2,
|
rsp: 2,
|
||||||
@ -478,23 +441,24 @@ mod tests {
|
|||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
||||||
let actual_regs: kvm_regs = vcpu.get_regs().unwrap();
|
let actual_regs: StandardRegisters = vcpu.get_regs().unwrap();
|
||||||
assert_eq!(actual_regs, expected_regs);
|
assert_eq!(actual_regs, expected_regs);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_setup_sregs() {
|
fn test_setup_sregs() {
|
||||||
let kvm = Kvm::new().unwrap();
|
let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap();
|
||||||
let vm = kvm.create_vm().unwrap();
|
let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
|
||||||
|
let vm = hv.create_vm().expect("new VM fd creation failed");
|
||||||
let vcpu = vm.create_vcpu(0).unwrap();
|
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();
|
let gm = create_guest_mem();
|
||||||
configure_segments_and_sregs(&gm, &mut expected_sregs, BootProtocol::LinuxBoot).unwrap();
|
configure_segments_and_sregs(&gm, &mut expected_sregs, BootProtocol::LinuxBoot).unwrap();
|
||||||
setup_page_tables(&gm, &mut expected_sregs).unwrap();
|
setup_page_tables(&gm, &mut expected_sregs).unwrap();
|
||||||
|
|
||||||
setup_sregs(&gm, &vcpu, BootProtocol::LinuxBoot).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);
|
assert_eq!(expected_sregs, actual_sregs);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -20,6 +20,3 @@
|
|||||||
#[allow(non_upper_case_globals)]
|
#[allow(non_upper_case_globals)]
|
||||||
#[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)]
|
#[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)]
|
||||||
pub mod mpspec;
|
pub mod mpspec;
|
||||||
#[allow(non_upper_case_globals)]
|
|
||||||
#[allow(clippy::unreadable_literal, clippy::redundant_static_lifetimes)]
|
|
||||||
pub mod msr_index;
|
|
||||||
|
@ -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;
|
|
@ -8,8 +8,7 @@ edition = "2018"
|
|||||||
anyhow = "1.0"
|
anyhow = "1.0"
|
||||||
byteorder = "1.3.4"
|
byteorder = "1.3.4"
|
||||||
devices = { path = "../devices" }
|
devices = { path = "../devices" }
|
||||||
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch" }
|
hypervisor = { path = "../hypervisor" }
|
||||||
kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" }
|
|
||||||
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
|
vfio-ioctls = { git = "https://github.com/cloud-hypervisor/vfio-ioctls", branch = "ch" }
|
||||||
vmm-sys-util = ">=0.3.1"
|
vmm-sys-util = ">=0.3.1"
|
||||||
libc = "0.2.71"
|
libc = "0.2.71"
|
||||||
|
@ -6,6 +6,7 @@
|
|||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate log;
|
extern crate log;
|
||||||
extern crate devices;
|
extern crate devices;
|
||||||
|
extern crate hypervisor;
|
||||||
extern crate serde;
|
extern crate serde;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate serde_derive;
|
extern crate serde_derive;
|
||||||
|
@ -13,8 +13,7 @@ use crate::{
|
|||||||
};
|
};
|
||||||
use byteorder::{ByteOrder, LittleEndian};
|
use byteorder::{ByteOrder, LittleEndian};
|
||||||
use devices::BusDevice;
|
use devices::BusDevice;
|
||||||
use kvm_bindings::kvm_userspace_memory_region;
|
use hypervisor::kvm::kvm_userspace_memory_region;
|
||||||
use kvm_ioctls::*;
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::ops::Deref;
|
use std::ops::Deref;
|
||||||
use std::os::unix::io::AsRawFd;
|
use std::os::unix::io::AsRawFd;
|
||||||
@ -38,10 +37,10 @@ pub enum VfioPciError {
|
|||||||
AllocateGsi,
|
AllocateGsi,
|
||||||
EventFd(io::Error),
|
EventFd(io::Error),
|
||||||
InterruptSourceGroupCreate(io::Error),
|
InterruptSourceGroupCreate(io::Error),
|
||||||
IrqFd(kvm_ioctls::Error),
|
IrqFd(hypervisor::HypervisorVmError),
|
||||||
NewVfioPciDevice,
|
NewVfioPciDevice,
|
||||||
MapRegionGuest(kvm_ioctls::Error),
|
MapRegionGuest(anyhow::Error),
|
||||||
SetGsiRouting(kvm_ioctls::Error),
|
SetGsiRouting(hypervisor::HypervisorVmError),
|
||||||
MsiNotConfigured,
|
MsiNotConfigured,
|
||||||
MsixNotConfigured,
|
MsixNotConfigured,
|
||||||
UpdateMemory(VfioError),
|
UpdateMemory(VfioError),
|
||||||
@ -281,7 +280,7 @@ impl VfioPciConfig {
|
|||||||
/// The VMM creates a VfioDevice, then assigns it to a VfioPciDevice,
|
/// The VMM creates a VfioDevice, then assigns it to a VfioPciDevice,
|
||||||
/// which then gets added to the PCI bus.
|
/// which then gets added to the PCI bus.
|
||||||
pub struct VfioPciDevice {
|
pub struct VfioPciDevice {
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
device: Arc<VfioDevice>,
|
device: Arc<VfioDevice>,
|
||||||
vfio_pci_configuration: VfioPciConfig,
|
vfio_pci_configuration: VfioPciConfig,
|
||||||
configuration: PciConfiguration,
|
configuration: PciConfiguration,
|
||||||
@ -293,7 +292,7 @@ pub struct VfioPciDevice {
|
|||||||
impl VfioPciDevice {
|
impl VfioPciDevice {
|
||||||
/// Constructs a new Vfio Pci device for the given Vfio device
|
/// Constructs a new Vfio Pci device for the given Vfio device
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vm_fd: &Arc<VmFd>,
|
vm_fd: &Arc<dyn hypervisor::Vm>,
|
||||||
device: VfioDevice,
|
device: VfioDevice,
|
||||||
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
|
interrupt_manager: &Arc<dyn InterruptManager<GroupConfig = MsiIrqGroupConfig>>,
|
||||||
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
mem: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
@ -512,7 +511,7 @@ impl VfioPciDevice {
|
|||||||
/// # Return value
|
/// # Return value
|
||||||
///
|
///
|
||||||
/// This function returns the updated KVM memory slot id.
|
/// This function returns the updated KVM memory slot id.
|
||||||
pub fn map_mmio_regions<F>(&mut self, vm: &Arc<VmFd>, mem_slot: F) -> Result<()>
|
pub fn map_mmio_regions<F>(&mut self, vm: &Arc<dyn hypervisor::Vm>, mem_slot: F) -> Result<()>
|
||||||
where
|
where
|
||||||
F: Fn() -> u32,
|
F: Fn() -> u32,
|
||||||
{
|
{
|
||||||
@ -569,11 +568,8 @@ impl VfioPciDevice {
|
|||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Safe because the guest regions are guaranteed not to overlap.
|
vm.set_user_memory_region(mem_region)
|
||||||
unsafe {
|
.map_err(|e| VfioPciError::MapRegionGuest(e.into()))?;
|
||||||
vm.set_user_memory_region(mem_region)
|
|
||||||
.map_err(VfioPciError::MapRegionGuest)?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update the region with memory mapped info.
|
// Update the region with memory mapped info.
|
||||||
region.mem_slot = Some(slot);
|
region.mem_slot = Some(slot);
|
||||||
@ -600,8 +596,8 @@ impl VfioPciDevice {
|
|||||||
userspace_addr: host_addr,
|
userspace_addr: host_addr,
|
||||||
flags: 0,
|
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!(
|
error!(
|
||||||
"Could not remove the userspace memory region from KVM: {}",
|
"Could not remove the userspace memory region from KVM: {}",
|
||||||
e
|
e
|
||||||
@ -1028,12 +1024,10 @@ impl PciDevice for VfioPciDevice {
|
|||||||
userspace_addr: host_addr,
|
userspace_addr: host_addr,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
// Safe because the guest regions are guaranteed not to overlap.
|
|
||||||
unsafe {
|
self.vm_fd
|
||||||
self.vm_fd
|
.set_user_memory_region(old_mem_region)
|
||||||
.set_user_memory_region(old_mem_region)
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
||||||
.map_err(|e| io::Error::from_raw_os_error(e.errno()))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Insert new region to KVM
|
// Insert new region to KVM
|
||||||
let new_mem_region = kvm_userspace_memory_region {
|
let new_mem_region = kvm_userspace_memory_region {
|
||||||
@ -1043,12 +1037,10 @@ impl PciDevice for VfioPciDevice {
|
|||||||
userspace_addr: host_addr,
|
userspace_addr: host_addr,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
// Safe because the guest regions are guaranteed not to overlap.
|
|
||||||
unsafe {
|
self.vm_fd
|
||||||
self.vm_fd
|
.set_user_memory_region(new_mem_region)
|
||||||
.set_user_memory_region(new_mem_region)
|
.map_err(|e| io::Error::new(io::ErrorKind::Other, e))?;
|
||||||
.map_err(|e| io::Error::from_raw_os_error(e.errno()))?;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ extern crate vmm_sys_util;
|
|||||||
extern crate clap;
|
extern crate clap;
|
||||||
|
|
||||||
use clap::{App, Arg, ArgGroup, ArgMatches};
|
use clap::{App, Arg, ArgGroup, ArgMatches};
|
||||||
|
use hypervisor::kvm::KvmHyperVisor as Hypervisor;
|
||||||
use libc::EFD_NONBLOCK;
|
use libc::EFD_NONBLOCK;
|
||||||
use log::LevelFilter;
|
use log::LevelFilter;
|
||||||
use seccomp::SeccompLevel;
|
use seccomp::SeccompLevel;
|
||||||
@ -282,7 +283,7 @@ fn start_vmm(cmd_arguments: ArgMatches) {
|
|||||||
} else {
|
} else {
|
||||||
SeccompLevel::Advanced
|
SeccompLevel::Advanced
|
||||||
};
|
};
|
||||||
|
let hypervisor = Hypervisor::new().unwrap();
|
||||||
let vmm_thread = match vmm::start_vmm_thread(
|
let vmm_thread = match vmm::start_vmm_thread(
|
||||||
env!("CARGO_PKG_VERSION").to_string(),
|
env!("CARGO_PKG_VERSION").to_string(),
|
||||||
api_socket_path,
|
api_socket_path,
|
||||||
@ -290,6 +291,7 @@ fn start_vmm(cmd_arguments: ArgMatches) {
|
|||||||
http_sender,
|
http_sender,
|
||||||
api_request_receiver,
|
api_request_receiver,
|
||||||
&seccomp_level,
|
&seccomp_level,
|
||||||
|
Arc::new(hypervisor),
|
||||||
) {
|
) {
|
||||||
Ok(t) => t,
|
Ok(t) => t,
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
@ -20,8 +20,7 @@ anyhow = "1.0"
|
|||||||
arch = { path = "../arch" }
|
arch = { path = "../arch" }
|
||||||
devices = { path = "../devices" }
|
devices = { path = "../devices" }
|
||||||
epoll = ">=4.0.1"
|
epoll = ">=4.0.1"
|
||||||
kvm-bindings = { git = "https://github.com/cloud-hypervisor/kvm-bindings", branch = "ch", features = ["with-serde", "fam-wrappers"] }
|
hypervisor = { path = "../hypervisor" }
|
||||||
kvm-ioctls = { git = "https://github.com/cloud-hypervisor/kvm-ioctls", branch = "ch" }
|
|
||||||
lazy_static = "1.4.0"
|
lazy_static = "1.4.0"
|
||||||
libc = "0.2.71"
|
libc = "0.2.71"
|
||||||
log = "0.4.8"
|
log = "0.4.8"
|
||||||
@ -44,6 +43,7 @@ vmm-sys-util = { version = ">=0.5.0", features = ["with-serde"] }
|
|||||||
signal-hook = "0.1.15"
|
signal-hook = "0.1.15"
|
||||||
tempfile = "3.1.0"
|
tempfile = "3.1.0"
|
||||||
|
|
||||||
|
|
||||||
[dependencies.linux-loader]
|
[dependencies.linux-loader]
|
||||||
git = "https://github.com/rust-vmm/linux-loader"
|
git = "https://github.com/rust-vmm/linux-loader"
|
||||||
features = ["elf", "bzimage", "pe"]
|
features = ["elf", "bzimage", "pe"]
|
||||||
|
178
vmm/src/cpu.rs
178
vmm/src/cpu.rs
@ -24,15 +24,13 @@ use arch::EntryPoint;
|
|||||||
use arch::{CpuidPatch, CpuidReg};
|
use arch::{CpuidPatch, CpuidReg};
|
||||||
use devices::{interrupt_controller::InterruptController, BusDevice};
|
use devices::{interrupt_controller::InterruptController, BusDevice};
|
||||||
#[cfg(target_arch = "aarch64")]
|
#[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")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use kvm_bindings::{
|
use hypervisor::CpuId;
|
||||||
kvm_fpu, kvm_lapic_state, kvm_mp_state, kvm_regs, kvm_sregs, kvm_vcpu_events, kvm_xcrs,
|
use hypervisor::VcpuExit;
|
||||||
kvm_xsave, CpuId, Msrs,
|
|
||||||
};
|
|
||||||
use kvm_ioctls::*;
|
|
||||||
use libc::{c_void, siginfo_t};
|
use libc::{c_void, siginfo_t};
|
||||||
use serde_derive::{Deserialize, Serialize};
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::os::unix::thread::JoinHandleExt;
|
use std::os::unix::thread::JoinHandleExt;
|
||||||
@ -103,23 +101,23 @@ impl fmt::Display for DebugIoPortRange {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub enum Error {
|
pub enum Error {
|
||||||
/// Cannot open the VCPU file descriptor.
|
/// Cannot open the VCPU file descriptor.
|
||||||
VcpuFd(kvm_ioctls::Error),
|
VcpuFd(anyhow::Error),
|
||||||
|
|
||||||
/// Cannot run the VCPUs.
|
/// Cannot run the VCPUs.
|
||||||
VcpuRun(kvm_ioctls::Error),
|
VcpuRun(anyhow::Error),
|
||||||
|
|
||||||
/// Cannot spawn a new vCPU thread.
|
/// Cannot spawn a new vCPU thread.
|
||||||
VcpuSpawn(io::Error),
|
VcpuSpawn(io::Error),
|
||||||
|
|
||||||
/// Cannot patch the CPU ID
|
/// Cannot patch the CPU ID
|
||||||
PatchCpuId(kvm_ioctls::Error),
|
PatchCpuId(anyhow::Error),
|
||||||
|
|
||||||
/// The call to KVM_SET_CPUID2 failed.
|
/// The call to KVM_SET_CPUID2 failed.
|
||||||
SetSupportedCpusFailed(kvm_ioctls::Error),
|
SetSupportedCpusFailed(anyhow::Error),
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
/// Cannot set the local interruption due to bad configuration.
|
/// Cannot set the local interruption due to bad configuration.
|
||||||
LocalIntConfiguration(arch::x86_64::interrupts::Error),
|
LocalIntConfiguration(anyhow::Error),
|
||||||
|
|
||||||
/// Error configuring VCPU
|
/// Error configuring VCPU
|
||||||
VcpuConfiguration(arch::Error),
|
VcpuConfiguration(arch::Error),
|
||||||
@ -140,58 +138,58 @@ pub enum Error {
|
|||||||
DesiredVCPUCountExceedsMax,
|
DesiredVCPUCountExceedsMax,
|
||||||
|
|
||||||
/// Failed to get KVM vcpu lapic.
|
/// Failed to get KVM vcpu lapic.
|
||||||
VcpuGetLapic(kvm_ioctls::Error),
|
VcpuGetLapic(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu lapic.
|
/// Failed to set KVM vcpu lapic.
|
||||||
VcpuSetLapic(kvm_ioctls::Error),
|
VcpuSetLapic(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu MP state.
|
/// Failed to get KVM vcpu MP state.
|
||||||
VcpuGetMpState(kvm_ioctls::Error),
|
VcpuGetMpState(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu MP state.
|
/// Failed to set KVM vcpu MP state.
|
||||||
VcpuSetMpState(kvm_ioctls::Error),
|
VcpuSetMpState(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu msrs.
|
/// Failed to get KVM vcpu msrs.
|
||||||
VcpuGetMsrs(kvm_ioctls::Error),
|
VcpuGetMsrs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu msrs.
|
/// Failed to set KVM vcpu msrs.
|
||||||
VcpuSetMsrs(kvm_ioctls::Error),
|
VcpuSetMsrs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu regs.
|
/// Failed to get KVM vcpu regs.
|
||||||
VcpuGetRegs(kvm_ioctls::Error),
|
VcpuGetRegs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu regs.
|
/// Failed to set KVM vcpu regs.
|
||||||
VcpuSetRegs(kvm_ioctls::Error),
|
VcpuSetRegs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu sregs.
|
/// Failed to get KVM vcpu sregs.
|
||||||
VcpuGetSregs(kvm_ioctls::Error),
|
VcpuGetSregs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu sregs.
|
/// Failed to set KVM vcpu sregs.
|
||||||
VcpuSetSregs(kvm_ioctls::Error),
|
VcpuSetSregs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu events.
|
/// Failed to get KVM vcpu events.
|
||||||
VcpuGetVcpuEvents(kvm_ioctls::Error),
|
VcpuGetVcpuEvents(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu events.
|
/// Failed to set KVM vcpu events.
|
||||||
VcpuSetVcpuEvents(kvm_ioctls::Error),
|
VcpuSetVcpuEvents(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu FPU.
|
/// Failed to get KVM vcpu FPU.
|
||||||
VcpuGetFpu(kvm_ioctls::Error),
|
VcpuGetFpu(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu FPU.
|
/// Failed to set KVM vcpu FPU.
|
||||||
VcpuSetFpu(kvm_ioctls::Error),
|
VcpuSetFpu(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu XSAVE.
|
/// Failed to get KVM vcpu XSAVE.
|
||||||
VcpuGetXsave(kvm_ioctls::Error),
|
VcpuGetXsave(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu XSAVE.
|
/// Failed to set KVM vcpu XSAVE.
|
||||||
VcpuSetXsave(kvm_ioctls::Error),
|
VcpuSetXsave(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to get KVM vcpu XCRS.
|
/// Failed to get KVM vcpu XCRS.
|
||||||
VcpuGetXcrs(kvm_ioctls::Error),
|
VcpuGetXcrs(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to set KVM vcpu XCRS.
|
/// Failed to set KVM vcpu XCRS.
|
||||||
VcpuSetXcrs(kvm_ioctls::Error),
|
VcpuSetXcrs(anyhow::Error),
|
||||||
|
|
||||||
/// Error resuming vCPU on shutdown
|
/// Error resuming vCPU on shutdown
|
||||||
ResumeOnShutdown(MigratableError),
|
ResumeOnShutdown(MigratableError),
|
||||||
@ -232,7 +230,7 @@ struct InterruptSourceOverride {
|
|||||||
|
|
||||||
/// A wrapper around creating and using a kvm-based VCPU.
|
/// A wrapper around creating and using a kvm-based VCPU.
|
||||||
pub struct Vcpu {
|
pub struct Vcpu {
|
||||||
fd: VcpuFd,
|
fd: Arc<dyn hypervisor::Vcpu>,
|
||||||
id: u8,
|
id: u8,
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
io_bus: Arc<devices::Bus>,
|
io_bus: Arc<devices::Bus>,
|
||||||
@ -245,24 +243,6 @@ pub struct Vcpu {
|
|||||||
mpidr: u64,
|
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 {
|
impl Vcpu {
|
||||||
/// Constructs a new VCPU for `vm`.
|
/// Constructs a new VCPU for `vm`.
|
||||||
///
|
///
|
||||||
@ -272,13 +252,13 @@ impl Vcpu {
|
|||||||
/// * `vm` - The virtual machine this vcpu will get attached to.
|
/// * `vm` - The virtual machine this vcpu will get attached to.
|
||||||
pub fn new(
|
pub fn new(
|
||||||
id: u8,
|
id: u8,
|
||||||
fd: &Arc<VmFd>,
|
fd: &Arc<dyn hypervisor::Vm>,
|
||||||
#[cfg(target_arch = "x86_64")] io_bus: Arc<devices::Bus>,
|
#[cfg(target_arch = "x86_64")] io_bus: Arc<devices::Bus>,
|
||||||
mmio_bus: Arc<devices::Bus>,
|
mmio_bus: Arc<devices::Bus>,
|
||||||
interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>,
|
interrupt_controller: Option<Arc<Mutex<dyn InterruptController>>>,
|
||||||
creation_ts: std::time::Instant,
|
creation_ts: std::time::Instant,
|
||||||
) -> Result<Arc<Mutex<Self>>> {
|
) -> Result<Arc<Mutex<Self>>> {
|
||||||
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.
|
// Initially the cpuid per vCPU is the one supported by this VM.
|
||||||
Ok(Arc::new(Mutex::new(Vcpu {
|
Ok(Arc::new(Mutex::new(Vcpu {
|
||||||
fd: kvm_vcpu,
|
fd: kvm_vcpu,
|
||||||
@ -303,7 +283,7 @@ impl Vcpu {
|
|||||||
/// * `cpuid` - (x86_64) CpuId, wrapper over the `kvm_cpuid2` structure.
|
/// * `cpuid` - (x86_64) CpuId, wrapper over the `kvm_cpuid2` structure.
|
||||||
pub fn configure(
|
pub fn configure(
|
||||||
&mut self,
|
&mut self,
|
||||||
#[cfg(target_arch = "aarch64")] vm_fd: &VmFd,
|
#[cfg(target_arch = "aarch64")] vm_fd: &Arc<dyn hypervisor::Vm>,
|
||||||
kernel_entry_point: Option<EntryPoint>,
|
kernel_entry_point: Option<EntryPoint>,
|
||||||
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
vm_memory: &GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
#[cfg(target_arch = "x86_64")] cpuid: CpuId,
|
#[cfg(target_arch = "x86_64")] cpuid: CpuId,
|
||||||
@ -413,75 +393,6 @@ impl Vcpu {
|
|||||||
ts.as_micros()
|
ts.as_micros()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
fn kvm_state(&self) -> Result<VcpuKvmState> {
|
|
||||||
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<VcpuKvmState> {
|
|
||||||
unimplemented!();
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(target_arch = "aarch64")]
|
|
||||||
fn set_kvm_state(&mut self, _state: &VcpuKvmState) -> Result<()> {
|
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const VCPU_SNAPSHOT_ID: &str = "vcpu";
|
const VCPU_SNAPSHOT_ID: &str = "vcpu";
|
||||||
@ -492,7 +403,7 @@ impl Snapshottable for Vcpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn snapshot(&self) -> std::result::Result<Snapshot, MigratableError> {
|
fn snapshot(&self) -> std::result::Result<Snapshot, MigratableError> {
|
||||||
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))
|
MigratableError::Snapshot(anyhow!("Could not get vCPU KVM state {:?}", e))
|
||||||
})?)
|
})?)
|
||||||
.map_err(|e| MigratableError::Snapshot(e.into()))?;
|
.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))
|
MigratableError::Restore(anyhow!("Could not set the vCPU KVM state {:?}", e))
|
||||||
})?;
|
})?;
|
||||||
|
|
||||||
@ -547,7 +458,7 @@ pub struct CpuManager {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
cpuid: CpuId,
|
cpuid: CpuId,
|
||||||
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
||||||
fd: Arc<VmFd>,
|
fd: Arc<dyn hypervisor::Vm>,
|
||||||
vcpus_kill_signalled: Arc<AtomicBool>,
|
vcpus_kill_signalled: Arc<AtomicBool>,
|
||||||
vcpus_pause_signalled: Arc<AtomicBool>,
|
vcpus_pause_signalled: Arc<AtomicBool>,
|
||||||
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
#[cfg_attr(target_arch = "aarch64", allow(dead_code))]
|
||||||
@ -677,16 +588,16 @@ impl CpuManager {
|
|||||||
config: &CpusConfig,
|
config: &CpusConfig,
|
||||||
device_manager: &Arc<Mutex<DeviceManager>>,
|
device_manager: &Arc<Mutex<DeviceManager>>,
|
||||||
guest_memory: GuestMemoryAtomic<GuestMemoryMmap>,
|
guest_memory: GuestMemoryAtomic<GuestMemoryMmap>,
|
||||||
#[cfg_attr(target_arch = "aarch64", allow(unused_variables))] kvm: &Kvm,
|
fd: Arc<dyn hypervisor::Vm>,
|
||||||
fd: Arc<VmFd>,
|
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
) -> Result<Arc<Mutex<CpuManager>>> {
|
) -> Result<Arc<Mutex<CpuManager>>> {
|
||||||
let mut vcpu_states = Vec::with_capacity(usize::from(config.max_vcpus));
|
let mut vcpu_states = Vec::with_capacity(usize::from(config.max_vcpus));
|
||||||
vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default);
|
vcpu_states.resize_with(usize::from(config.max_vcpus), VcpuState::default);
|
||||||
|
|
||||||
let device_manager = device_manager.lock().unwrap();
|
let device_manager = device_manager.lock().unwrap();
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[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 {
|
let cpu_manager = Arc::new(Mutex::new(CpuManager {
|
||||||
config: config.clone(),
|
config: config.clone(),
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
@ -725,7 +636,10 @@ impl CpuManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
fn patch_cpuid(kvm: &Kvm, topology: &Option<CpuTopology>) -> Result<CpuId> {
|
fn patch_cpuid(
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
|
topology: &Option<CpuTopology>,
|
||||||
|
) -> Result<CpuId> {
|
||||||
let mut cpuid_patches = Vec::new();
|
let mut cpuid_patches = Vec::new();
|
||||||
|
|
||||||
// Patch tsc deadline timer bit
|
// Patch tsc deadline timer bit
|
||||||
@ -751,9 +665,9 @@ impl CpuManager {
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Supported CPUID
|
// Supported CPUID
|
||||||
let mut cpuid = kvm
|
let mut cpuid = hypervisor
|
||||||
.get_supported_cpuid(kvm_bindings::KVM_MAX_CPUID_ENTRIES)
|
.get_cpuid()
|
||||||
.map_err(Error::PatchCpuId)?;
|
.map_err(|e| Error::PatchCpuId(e.into()))?;
|
||||||
|
|
||||||
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
|
CpuidPatch::patch_cpuid(&mut cpuid, cpuid_patches);
|
||||||
|
|
||||||
@ -804,7 +718,7 @@ impl CpuManager {
|
|||||||
.unwrap()
|
.unwrap()
|
||||||
.fd
|
.fd
|
||||||
.set_cpuid2(&cpuid)
|
.set_cpuid2(&cpuid)
|
||||||
.map_err(Error::SetSupportedCpusFailed)?;
|
.map_err(|e| Error::SetSupportedCpusFailed(e.into()))?;
|
||||||
}
|
}
|
||||||
vcpu.lock()
|
vcpu.lock()
|
||||||
.unwrap()
|
.unwrap()
|
||||||
|
@ -40,7 +40,10 @@ use devices::{
|
|||||||
interrupt_controller, interrupt_controller::InterruptController, legacy::Serial, BusDevice,
|
interrupt_controller, interrupt_controller::InterruptController, legacy::Serial, BusDevice,
|
||||||
HotPlugNotificationFlags,
|
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::TIOCGWINSZ;
|
||||||
use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE};
|
use libc::{MAP_NORESERVE, MAP_PRIVATE, MAP_SHARED, O_TMPFILE, PROT_READ, PROT_WRITE};
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
@ -186,10 +189,10 @@ pub enum DeviceManagerError {
|
|||||||
FreePciBars(pci::PciDeviceError),
|
FreePciBars(pci::PciDeviceError),
|
||||||
|
|
||||||
/// Cannot register ioevent.
|
/// Cannot register ioevent.
|
||||||
RegisterIoevent(kvm_ioctls::Error),
|
RegisterIoevent(anyhow::Error),
|
||||||
|
|
||||||
/// Cannot unregister ioevent.
|
/// Cannot unregister ioevent.
|
||||||
UnRegisterIoevent(kvm_ioctls::Error),
|
UnRegisterIoevent(anyhow::Error),
|
||||||
|
|
||||||
/// Cannot create virtio device
|
/// Cannot create virtio device
|
||||||
VirtioDevice(vmm_sys_util::errno::Error),
|
VirtioDevice(vmm_sys_util::errno::Error),
|
||||||
@ -229,7 +232,7 @@ pub enum DeviceManagerError {
|
|||||||
VfioMapRegion(pci::VfioPciError),
|
VfioMapRegion(pci::VfioPciError),
|
||||||
|
|
||||||
/// Failed to create the KVM device.
|
/// Failed to create the KVM device.
|
||||||
CreateKvmDevice(kvm_ioctls::Error),
|
CreateKvmDevice(anyhow::Error),
|
||||||
|
|
||||||
/// Failed to memory map.
|
/// Failed to memory map.
|
||||||
Mmap(io::Error),
|
Mmap(io::Error),
|
||||||
@ -430,7 +433,7 @@ struct AddressManager {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
io_bus: Arc<devices::Bus>,
|
io_bus: Arc<devices::Bus>,
|
||||||
mmio_bus: Arc<devices::Bus>,
|
mmio_bus: Arc<devices::Bus>,
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
device_tree: Arc<Mutex<DeviceTree>>,
|
device_tree: Arc<Mutex<DeviceTree>>,
|
||||||
}
|
}
|
||||||
@ -561,15 +564,16 @@ impl DeviceRelocation for AddressManager {
|
|||||||
if bar_addr == new_base {
|
if bar_addr == new_base {
|
||||||
for (event, addr) in virtio_pci_dev.ioeventfds(old_base) {
|
for (event, addr) in virtio_pci_dev.ioeventfds(old_base) {
|
||||||
let io_addr = IoEventAddress::Mmio(addr);
|
let io_addr = IoEventAddress::Mmio(addr);
|
||||||
self.vm_fd
|
self.vm_fd.unregister_ioevent(event, &io_addr).unwrap();
|
||||||
.unregister_ioevent(event, &io_addr)
|
/*
|
||||||
.map_err(|e| io::Error::from_raw_os_error(e.errno()))?;
|
map_err(io::Error::from_raw_os_error(
|
||||||
|
hypervisor::HypervisorVmError::UnregisterIoEvent,
|
||||||
|
))?; */
|
||||||
}
|
}
|
||||||
for (event, addr) in virtio_pci_dev.ioeventfds(new_base) {
|
for (event, addr) in virtio_pci_dev.ioeventfds(new_base) {
|
||||||
let io_addr = IoEventAddress::Mmio(addr);
|
let io_addr = IoEventAddress::Mmio(addr);
|
||||||
self.vm_fd
|
self.vm_fd.register_ioevent(event, &io_addr, None).unwrap();
|
||||||
.register_ioevent(event, &io_addr, NoDatamatch)
|
//.map_err(|e| io::Error::from_raw_os_error(e.errno()))?;
|
||||||
.map_err(|e| io::Error::from_raw_os_error(e.errno()))?;
|
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
let virtio_dev = virtio_pci_dev.virtio_device();
|
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 let Some(mut shm_regions) = virtio_dev.get_shm_regions() {
|
||||||
if shm_regions.addr.raw_value() == old_base {
|
if shm_regions.addr.raw_value() == old_base {
|
||||||
// Remove old region from KVM by passing a size of 0.
|
// 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,
|
slot: shm_regions.mem_slot,
|
||||||
guest_phys_addr: old_base,
|
guest_phys_addr: old_base,
|
||||||
memory_size: 0,
|
memory_size: 0,
|
||||||
@ -585,23 +589,19 @@ impl DeviceRelocation for AddressManager {
|
|||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Safe because removing an existing guest region.
|
self.vm_fd.set_user_memory_region(mem_region).unwrap();
|
||||||
unsafe {
|
//.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::from_raw_os_error(e.errno()))?;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Create new mapping by inserting new region to KVM.
|
// Create new mapping by inserting new region to KVM.
|
||||||
mem_region.guest_phys_addr = new_base;
|
mem_region.guest_phys_addr = new_base;
|
||||||
mem_region.memory_size = shm_regions.len;
|
mem_region.memory_size = shm_regions.len;
|
||||||
|
|
||||||
// Safe because the guest regions are guaranteed not to overlap.
|
self.vm_fd.set_user_memory_region(mem_region).map_err(|e| {
|
||||||
unsafe {
|
io::Error::new(
|
||||||
self.vm_fd
|
io::ErrorKind::Other,
|
||||||
.set_user_memory_region(mem_region)
|
format!("failed to set user memory regions: {:?}", e),
|
||||||
.map_err(|e| io::Error::from_raw_os_error(e.errno()))?;
|
)
|
||||||
}
|
})?;
|
||||||
|
|
||||||
// Update shared memory regions to reflect the new mapping.
|
// Update shared memory regions to reflect the new mapping.
|
||||||
shm_regions.addr = GuestAddress(new_base);
|
shm_regions.addr = GuestAddress(new_base);
|
||||||
@ -753,7 +753,7 @@ pub struct DeviceManager {
|
|||||||
|
|
||||||
impl DeviceManager {
|
impl DeviceManager {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
config: Arc<Mutex<VmConfig>>,
|
config: Arc<Mutex<VmConfig>>,
|
||||||
memory_manager: Arc<Mutex<MemoryManager>>,
|
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||||
_exit_evt: &EventFd,
|
_exit_evt: &EventFd,
|
||||||
@ -2291,15 +2291,15 @@ impl DeviceManager {
|
|||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(feature = "pci_support")]
|
#[cfg(feature = "pci_support")]
|
||||||
fn create_kvm_device(vm: &Arc<VmFd>) -> DeviceManagerResult<DeviceFd> {
|
fn create_kvm_device(vm: &Arc<dyn hypervisor::Vm>) -> DeviceManagerResult<DeviceFd> {
|
||||||
let mut vfio_dev = kvm_bindings::kvm_create_device {
|
let mut vfio_dev = hypervisor::kvm::kvm_create_device {
|
||||||
type_: kvm_bindings::kvm_device_type_KVM_DEV_TYPE_VFIO,
|
type_: hypervisor::kvm::kvm_device_type_KVM_DEV_TYPE_VFIO,
|
||||||
fd: 0,
|
fd: 0,
|
||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
vm.create_device(&mut vfio_dev)
|
vm.create_device(&mut vfio_dev)
|
||||||
.map_err(DeviceManagerError::CreateKvmDevice)
|
.map_err(|e| DeviceManagerError::CreateKvmDevice(e.into()))
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(not(feature = "pci_support"))]
|
#[cfg(not(feature = "pci_support"))]
|
||||||
@ -2582,8 +2582,8 @@ impl DeviceManager {
|
|||||||
let io_addr = IoEventAddress::Mmio(addr);
|
let io_addr = IoEventAddress::Mmio(addr);
|
||||||
self.address_manager
|
self.address_manager
|
||||||
.vm_fd
|
.vm_fd
|
||||||
.register_ioevent(event, &io_addr, NoDatamatch)
|
.register_ioevent(event, &io_addr, None)
|
||||||
.map_err(DeviceManagerError::RegisterIoevent)?;
|
.map_err(|e| DeviceManagerError::RegisterIoevent(e.into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let virtio_pci_device = Arc::new(Mutex::new(virtio_pci_device));
|
let virtio_pci_device = Arc::new(Mutex::new(virtio_pci_device));
|
||||||
@ -2739,8 +2739,8 @@ impl DeviceManager {
|
|||||||
let io_addr = IoEventAddress::Mmio(*addr);
|
let io_addr = IoEventAddress::Mmio(*addr);
|
||||||
self.address_manager
|
self.address_manager
|
||||||
.vm_fd
|
.vm_fd
|
||||||
.register_ioevent(event, &io_addr, i as u32)
|
.register_ioevent(event, &io_addr, Some(DataMatch::DataMatch32(i as u32)))
|
||||||
.map_err(DeviceManagerError::RegisterIoevent)?;
|
.map_err(|e| DeviceManagerError::RegisterIoevent(e.into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
let interrupt_group = interrupt_manager
|
let interrupt_group = interrupt_manager
|
||||||
@ -2979,7 +2979,7 @@ impl DeviceManager {
|
|||||||
self.address_manager
|
self.address_manager
|
||||||
.vm_fd
|
.vm_fd
|
||||||
.unregister_ioevent(event, &io_addr)
|
.unregister_ioevent(event, &io_addr)
|
||||||
.map_err(DeviceManagerError::UnRegisterIoevent)?;
|
.map_err(|e| DeviceManagerError::UnRegisterIoevent(e.into()))?;
|
||||||
}
|
}
|
||||||
|
|
||||||
(
|
(
|
||||||
|
@ -4,8 +4,8 @@
|
|||||||
//
|
//
|
||||||
|
|
||||||
use devices::interrupt_controller::InterruptController;
|
use devices::interrupt_controller::InterruptController;
|
||||||
use kvm_bindings::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI};
|
use hypervisor::kvm::{kvm_irq_routing, kvm_irq_routing_entry, KVM_IRQ_ROUTING_MSI};
|
||||||
use kvm_ioctls::VmFd;
|
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::mem::size_of;
|
use std::mem::size_of;
|
||||||
@ -70,7 +70,7 @@ impl InterruptRoute {
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn enable(&self, vm: &Arc<VmFd>) -> Result<()> {
|
pub fn enable(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
|
||||||
if !self.registered.load(Ordering::SeqCst) {
|
if !self.registered.load(Ordering::SeqCst) {
|
||||||
vm.register_irqfd(&self.irq_fd, self.gsi).map_err(|e| {
|
vm.register_irqfd(&self.irq_fd, self.gsi).map_err(|e| {
|
||||||
io::Error::new(
|
io::Error::new(
|
||||||
@ -86,7 +86,7 @@ impl InterruptRoute {
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn disable(&self, vm: &Arc<VmFd>) -> Result<()> {
|
pub fn disable(&self, vm: &Arc<dyn hypervisor::Vm>) -> Result<()> {
|
||||||
if self.registered.load(Ordering::SeqCst) {
|
if self.registered.load(Ordering::SeqCst) {
|
||||||
vm.unregister_irqfd(&self.irq_fd, self.gsi).map_err(|e| {
|
vm.unregister_irqfd(&self.irq_fd, self.gsi).map_err(|e| {
|
||||||
io::Error::new(
|
io::Error::new(
|
||||||
@ -109,14 +109,14 @@ pub struct KvmRoutingEntry {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub struct MsiInterruptGroup {
|
pub struct MsiInterruptGroup {
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
||||||
irq_routes: HashMap<InterruptIndex, InterruptRoute>,
|
irq_routes: HashMap<InterruptIndex, InterruptRoute>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl MsiInterruptGroup {
|
impl MsiInterruptGroup {
|
||||||
fn new(
|
fn new(
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
||||||
irq_routes: HashMap<InterruptIndex, InterruptRoute>,
|
irq_routes: HashMap<InterruptIndex, InterruptRoute>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
@ -316,7 +316,7 @@ pub struct KvmLegacyUserspaceInterruptManager {
|
|||||||
|
|
||||||
pub struct KvmMsiInterruptManager {
|
pub struct KvmMsiInterruptManager {
|
||||||
allocator: Arc<Mutex<SystemAllocator>>,
|
allocator: Arc<Mutex<SystemAllocator>>,
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -329,7 +329,7 @@ impl KvmLegacyUserspaceInterruptManager {
|
|||||||
impl KvmMsiInterruptManager {
|
impl KvmMsiInterruptManager {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
allocator: Arc<Mutex<SystemAllocator>>,
|
allocator: Arc<Mutex<SystemAllocator>>,
|
||||||
vm_fd: Arc<VmFd>,
|
vm_fd: Arc<dyn hypervisor::Vm>,
|
||||||
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
gsi_msi_routes: Arc<Mutex<HashMap<u32, KvmRoutingEntry>>>,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
KvmMsiInterruptManager {
|
KvmMsiInterruptManager {
|
||||||
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
extern crate anyhow;
|
extern crate anyhow;
|
||||||
extern crate arc_swap;
|
extern crate arc_swap;
|
||||||
|
extern crate hypervisor;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
extern crate lazy_static;
|
extern crate lazy_static;
|
||||||
#[macro_use]
|
#[macro_use]
|
||||||
@ -213,6 +214,7 @@ pub fn start_vmm_thread(
|
|||||||
api_sender: Sender<ApiRequest>,
|
api_sender: Sender<ApiRequest>,
|
||||||
api_receiver: Receiver<ApiRequest>,
|
api_receiver: Receiver<ApiRequest>,
|
||||||
seccomp_level: &SeccompLevel,
|
seccomp_level: &SeccompLevel,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
) -> Result<thread::JoinHandle<Result<()>>> {
|
) -> Result<thread::JoinHandle<Result<()>>> {
|
||||||
let http_api_event = api_event.try_clone().map_err(Error::EventFdClone)?;
|
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.
|
// Apply seccomp filter for VMM thread.
|
||||||
SeccompFilter::apply(vmm_seccomp_filter).map_err(Error::ApplySeccompFilter)?;
|
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))
|
vmm.control_loop(Arc::new(api_receiver))
|
||||||
})
|
})
|
||||||
@ -253,10 +255,16 @@ pub struct Vmm {
|
|||||||
vm: Option<Vm>,
|
vm: Option<Vm>,
|
||||||
vm_config: Option<Arc<Mutex<VmConfig>>>,
|
vm_config: Option<Arc<Mutex<VmConfig>>>,
|
||||||
vmm_path: PathBuf,
|
vmm_path: PathBuf,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Vmm {
|
impl Vmm {
|
||||||
fn new(vmm_version: String, api_evt: EventFd, vmm_path: PathBuf) -> Result<Self> {
|
fn new(
|
||||||
|
vmm_version: String,
|
||||||
|
api_evt: EventFd,
|
||||||
|
vmm_path: PathBuf,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
|
) -> Result<Self> {
|
||||||
let mut epoll = EpollContext::new().map_err(Error::Epoll)?;
|
let mut epoll = EpollContext::new().map_err(Error::Epoll)?;
|
||||||
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
let exit_evt = EventFd::new(EFD_NONBLOCK).map_err(Error::EventFdCreate)?;
|
||||||
let reset_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: None,
|
||||||
vm_config: None,
|
vm_config: None,
|
||||||
vmm_path,
|
vmm_path,
|
||||||
|
hypervisor,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -301,6 +310,7 @@ impl Vmm {
|
|||||||
exit_evt,
|
exit_evt,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
self.vmm_path.clone(),
|
self.vmm_path.clone(),
|
||||||
|
self.hypervisor.clone(),
|
||||||
)?;
|
)?;
|
||||||
self.vm = Some(vm);
|
self.vm = Some(vm);
|
||||||
}
|
}
|
||||||
@ -370,6 +380,7 @@ impl Vmm {
|
|||||||
self.vmm_path.clone(),
|
self.vmm_path.clone(),
|
||||||
source_url,
|
source_url,
|
||||||
restore_cfg.prefault,
|
restore_cfg.prefault,
|
||||||
|
self.hypervisor.clone(),
|
||||||
)?;
|
)?;
|
||||||
self.vm = Some(vm);
|
self.vm = Some(vm);
|
||||||
|
|
||||||
@ -413,7 +424,13 @@ impl Vmm {
|
|||||||
if self.reset_evt.read().is_ok() {
|
if self.reset_evt.read().is_ok() {
|
||||||
warn!("Spurious second reset event received. Ignoring.");
|
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.
|
// Then we start the new VM.
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
//
|
//
|
||||||
// SPDX-License-Identifier: Apache-2.0
|
// SPDX-License-Identifier: Apache-2.0
|
||||||
//
|
//
|
||||||
|
extern crate hypervisor;
|
||||||
use crate::config::{HotplugMethod, MemoryConfig};
|
use crate::config::{HotplugMethod, MemoryConfig};
|
||||||
use crate::MEMORY_MANAGER_SNAPSHOT_ID;
|
use crate::MEMORY_MANAGER_SNAPSHOT_ID;
|
||||||
#[cfg(feature = "acpi")]
|
#[cfg(feature = "acpi")]
|
||||||
@ -12,8 +12,9 @@ use arch::{get_host_cpu_phys_bits, layout, RegionType};
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use devices::ioapic;
|
use devices::ioapic;
|
||||||
use devices::BusDevice;
|
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::convert::TryInto;
|
||||||
use std::ffi;
|
use std::ffi;
|
||||||
use std::fs::{File, OpenOptions};
|
use std::fs::{File, OpenOptions};
|
||||||
@ -56,7 +57,7 @@ pub struct MemoryManager {
|
|||||||
next_kvm_memory_slot: u32,
|
next_kvm_memory_slot: u32,
|
||||||
start_of_device_area: GuestAddress,
|
start_of_device_area: GuestAddress,
|
||||||
end_of_device_area: GuestAddress,
|
end_of_device_area: GuestAddress,
|
||||||
pub fd: Arc<VmFd>,
|
pub fd: Arc<dyn hypervisor::Vm>,
|
||||||
hotplug_slots: Vec<HotPlugState>,
|
hotplug_slots: Vec<HotPlugState>,
|
||||||
selected_slot: usize,
|
selected_slot: usize,
|
||||||
backing_file: Option<PathBuf>,
|
backing_file: Option<PathBuf>,
|
||||||
@ -103,7 +104,7 @@ pub enum Error {
|
|||||||
InvalidSize,
|
InvalidSize,
|
||||||
|
|
||||||
/// Failed to set the user memory region.
|
/// Failed to set the user memory region.
|
||||||
SetUserMemoryRegion(kvm_ioctls::Error),
|
SetUserMemoryRegion(hypervisor::HypervisorVmError),
|
||||||
|
|
||||||
/// Failed to EventFd.
|
/// Failed to EventFd.
|
||||||
EventFdFail(io::Error),
|
EventFdFail(io::Error),
|
||||||
@ -214,7 +215,7 @@ impl BusDevice for MemoryManager {
|
|||||||
|
|
||||||
impl MemoryManager {
|
impl MemoryManager {
|
||||||
pub fn new(
|
pub fn new(
|
||||||
fd: Arc<VmFd>,
|
fd: Arc<dyn hypervisor::Vm>,
|
||||||
config: &MemoryConfig,
|
config: &MemoryConfig,
|
||||||
ext_regions: Option<Vec<MemoryRegion>>,
|
ext_regions: Option<Vec<MemoryRegion>>,
|
||||||
prefault: bool,
|
prefault: bool,
|
||||||
@ -381,7 +382,7 @@ impl MemoryManager {
|
|||||||
|
|
||||||
pub fn new_from_snapshot(
|
pub fn new_from_snapshot(
|
||||||
snapshot: &Snapshot,
|
snapshot: &Snapshot,
|
||||||
fd: Arc<VmFd>,
|
fd: Arc<dyn hypervisor::Vm>,
|
||||||
config: &MemoryConfig,
|
config: &MemoryConfig,
|
||||||
source_url: &str,
|
source_url: &str,
|
||||||
prefault: bool,
|
prefault: bool,
|
||||||
@ -685,8 +686,8 @@ impl MemoryManager {
|
|||||||
flags: if readonly { KVM_MEM_READONLY } else { 0 },
|
flags: if readonly { KVM_MEM_READONLY } else { 0 },
|
||||||
};
|
};
|
||||||
|
|
||||||
// Safe because the guest regions are guaranteed not to overlap.
|
self.fd
|
||||||
unsafe { self.fd.set_user_memory_region(mem_region) }
|
.set_user_memory_region(mem_region)
|
||||||
.map_err(Error::SetUserMemoryRegion)?;
|
.map_err(Error::SetUserMemoryRegion)?;
|
||||||
|
|
||||||
// Mark the pages as mergeable if explicitly asked for.
|
// Mark the pages as mergeable if explicitly asked for.
|
||||||
@ -738,8 +739,8 @@ impl MemoryManager {
|
|||||||
flags: 0,
|
flags: 0,
|
||||||
};
|
};
|
||||||
|
|
||||||
// Safe to remove because we know the region exist.
|
self.fd
|
||||||
unsafe { self.fd.set_user_memory_region(mem_region) }
|
.set_user_memory_region(mem_region)
|
||||||
.map_err(Error::SetUserMemoryRegion)?;
|
.map_err(Error::SetUserMemoryRegion)?;
|
||||||
|
|
||||||
// Mark the pages as unmergeable if there were previously marked as
|
// Mark the pages as unmergeable if there were previously marked as
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
extern crate arch;
|
extern crate arch;
|
||||||
extern crate devices;
|
extern crate devices;
|
||||||
extern crate epoll;
|
extern crate epoll;
|
||||||
extern crate kvm_ioctls;
|
extern crate hypervisor;
|
||||||
extern crate libc;
|
extern crate libc;
|
||||||
extern crate linux_loader;
|
extern crate linux_loader;
|
||||||
extern crate net_util;
|
extern crate net_util;
|
||||||
@ -38,17 +38,13 @@ use crate::{
|
|||||||
use anyhow::anyhow;
|
use anyhow::anyhow;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use arch::BootProtocol;
|
use arch::BootProtocol;
|
||||||
use arch::{check_required_kvm_extensions, EntryPoint};
|
use arch::EntryPoint;
|
||||||
#[cfg(target_arch = "x86_64")]
|
|
||||||
use devices::ioapic;
|
|
||||||
use devices::HotPlugNotificationFlags;
|
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;
|
use linux_loader::cmdline::Cmdline;
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use linux_loader::loader::elf::Error::InvalidElfMagicNumber;
|
use linux_loader::loader::elf::Error::InvalidElfMagicNumber;
|
||||||
use linux_loader::loader::KernelLoader;
|
use linux_loader::loader::KernelLoader;
|
||||||
|
|
||||||
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
|
use signal_hook::{iterator::Signals, SIGINT, SIGTERM, SIGWINCH};
|
||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
use std::convert::TryInto;
|
use std::convert::TryInto;
|
||||||
@ -82,12 +78,6 @@ pub enum Error {
|
|||||||
/// Cannot open the VM file descriptor.
|
/// Cannot open the VM file descriptor.
|
||||||
VmFd(io::Error),
|
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
|
/// Cannot open the kernel image
|
||||||
KernelFile(io::Error),
|
KernelFile(io::Error),
|
||||||
|
|
||||||
@ -144,9 +134,6 @@ pub enum Error {
|
|||||||
/// Failed to join on vCPU threads
|
/// Failed to join on vCPU threads
|
||||||
ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
ThreadCleanup(std::boxed::Box<dyn std::any::Any + std::marker::Send>),
|
||||||
|
|
||||||
/// Failed to create a new KVM instance
|
|
||||||
KvmNew(kvm_ioctls::Error),
|
|
||||||
|
|
||||||
/// VM is not created
|
/// VM is not created
|
||||||
VmNotCreated,
|
VmNotCreated,
|
||||||
|
|
||||||
@ -272,57 +259,14 @@ pub struct Vm {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Vm {
|
impl Vm {
|
||||||
fn kvm_new() -> Result<(Kvm, Arc<VmFd>)> {
|
|
||||||
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(
|
fn new_from_memory_manager(
|
||||||
config: Arc<Mutex<VmConfig>>,
|
config: Arc<Mutex<VmConfig>>,
|
||||||
memory_manager: Arc<Mutex<MemoryManager>>,
|
memory_manager: Arc<Mutex<MemoryManager>>,
|
||||||
fd: Arc<VmFd>,
|
fd: Arc<dyn hypervisor::Vm>,
|
||||||
kvm: Kvm,
|
|
||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
vmm_path: PathBuf,
|
vmm_path: PathBuf,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
config
|
config
|
||||||
.lock()
|
.lock()
|
||||||
@ -344,9 +288,9 @@ impl Vm {
|
|||||||
&config.lock().unwrap().cpus.clone(),
|
&config.lock().unwrap().cpus.clone(),
|
||||||
&device_manager,
|
&device_manager,
|
||||||
memory_manager.lock().unwrap().guest_memory(),
|
memory_manager.lock().unwrap().guest_memory(),
|
||||||
&kvm,
|
|
||||||
fd,
|
fd,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
|
hypervisor,
|
||||||
)
|
)
|
||||||
.map_err(Error::CpuManager)?;
|
.map_err(Error::CpuManager)?;
|
||||||
|
|
||||||
@ -382,8 +326,13 @@ impl Vm {
|
|||||||
exit_evt: EventFd,
|
exit_evt: EventFd,
|
||||||
reset_evt: EventFd,
|
reset_evt: EventFd,
|
||||||
vmm_path: PathBuf,
|
vmm_path: PathBuf,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
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(
|
let memory_manager = MemoryManager::new(
|
||||||
fd.clone(),
|
fd.clone(),
|
||||||
&config.lock().unwrap().memory.clone(),
|
&config.lock().unwrap().memory.clone(),
|
||||||
@ -396,10 +345,10 @@ impl Vm {
|
|||||||
config,
|
config,
|
||||||
memory_manager,
|
memory_manager,
|
||||||
fd,
|
fd,
|
||||||
kvm,
|
|
||||||
exit_evt,
|
exit_evt,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
vmm_path,
|
vmm_path,
|
||||||
|
hypervisor,
|
||||||
)?;
|
)?;
|
||||||
|
|
||||||
// The device manager must create the devices from here as it is part
|
// The device manager must create the devices from here as it is part
|
||||||
@ -420,8 +369,13 @@ impl Vm {
|
|||||||
vmm_path: PathBuf,
|
vmm_path: PathBuf,
|
||||||
source_url: &str,
|
source_url: &str,
|
||||||
prefault: bool,
|
prefault: bool,
|
||||||
|
hypervisor: Arc<dyn hypervisor::Hypervisor>,
|
||||||
) -> Result<Self> {
|
) -> Result<Self> {
|
||||||
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 config = vm_config_from_snapshot(snapshot).map_err(Error::Restore)?;
|
||||||
|
|
||||||
let memory_manager = if let Some(memory_manager_snapshot) =
|
let memory_manager = if let Some(memory_manager_snapshot) =
|
||||||
@ -445,10 +399,10 @@ impl Vm {
|
|||||||
config,
|
config,
|
||||||
memory_manager,
|
memory_manager,
|
||||||
fd,
|
fd,
|
||||||
kvm,
|
|
||||||
exit_evt,
|
exit_evt,
|
||||||
reset_evt,
|
reset_evt,
|
||||||
vmm_path,
|
vmm_path,
|
||||||
|
hypervisor,
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1432,9 +1386,8 @@ mod tests {
|
|||||||
#[cfg(target_arch = "x86_64")]
|
#[cfg(target_arch = "x86_64")]
|
||||||
#[test]
|
#[test]
|
||||||
pub fn test_vm() {
|
pub fn test_vm() {
|
||||||
use kvm_bindings::kvm_userspace_memory_region;
|
use hypervisor::VcpuExit;
|
||||||
use vm_memory::{GuestMemory, GuestMemoryRegion};
|
use vm_memory::{GuestMemory, GuestMemoryRegion};
|
||||||
|
|
||||||
// This example based on https://lwn.net/Articles/658511/
|
// This example based on https://lwn.net/Articles/658511/
|
||||||
let code = [
|
let code = [
|
||||||
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
|
0xba, 0xf8, 0x03, /* mov $0x3f8, %dx */
|
||||||
@ -1450,11 +1403,12 @@ pub fn test_vm() {
|
|||||||
let load_addr = GuestAddress(0x1000);
|
let load_addr = GuestAddress(0x1000);
|
||||||
let mem = GuestMemoryMmap::from_ranges(&[(load_addr, mem_size)]).unwrap();
|
let mem = GuestMemoryMmap::from_ranges(&[(load_addr, mem_size)]).unwrap();
|
||||||
|
|
||||||
let kvm = Kvm::new().expect("new KVM instance creation failed");
|
let kvm = hypervisor::kvm::KvmHyperVisor::new().unwrap();
|
||||||
let vm_fd = kvm.create_vm().expect("new VM fd creation failed");
|
let hv: Arc<dyn hypervisor::Hypervisor> = Arc::new(kvm);
|
||||||
|
let vm_fd = hv.create_vm().expect("new VM fd creation failed");
|
||||||
|
|
||||||
mem.with_regions(|index, region| {
|
mem.with_regions(|index, region| {
|
||||||
let mem_region = kvm_userspace_memory_region {
|
let mem_region = hypervisor::kvm_userspace_memory_region {
|
||||||
slot: index as u32,
|
slot: index as u32,
|
||||||
guest_phys_addr: region.start_addr().raw_value(),
|
guest_phys_addr: region.start_addr().raw_value(),
|
||||||
memory_size: region.len() as u64,
|
memory_size: region.len() as u64,
|
||||||
@ -1463,7 +1417,7 @@ pub fn test_vm() {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// Safe because the guest regions are guaranteed not to overlap.
|
// 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");
|
.expect("Cannot configure guest memory");
|
||||||
mem.write_slice(&code, load_addr)
|
mem.write_slice(&code, load_addr)
|
||||||
|
Loading…
x
Reference in New Issue
Block a user