cloud-hypervisor: Add the architecture crates

Both crates are based on Firecracker commit 9cdb5b2.
They are ported to the new memory model and tests have been fixed
accordingly.

Signed-off-by: Samuel Ortiz <sameo@linux.intel.com>
This commit is contained in:
Samuel Ortiz 2019-02-25 22:53:01 +01:00
parent a0da3deb5e
commit b56b4ca834
17 changed files with 6830 additions and 0 deletions

20
arch/Cargo.toml Normal file
View File

@ -0,0 +1,20 @@
[package]
name = "arch"
version = "0.1.0"
authors = ["The Chromium OS Authors"]
[dependencies]
byteorder = "=1.2.1"
kvm-bindings = "0.1"
libc = ">=0.2.39"
kvm-ioctls = { git = "https://github.com/rust-vmm/kvm-ioctls" }
arch_gen = { path = "../arch_gen" }
[dependencies.vm-memory]
git = "https://github.com/rust-vmm/vm-memory"
features = ["backend-mmap"]
[dev-dependencies]
rand = ">=0.5.5"

View File

@ -0,0 +1,7 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
/// Kernel command line start address.
pub const CMDLINE_START: usize = 0x0;
/// Kernel command line start address maximum size.
pub const CMDLINE_MAX_SIZE: usize = 0x0;

26
arch/src/aarch64/mod.rs Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2019 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
pub mod layout;
use memory_model::{GuestAddress, GuestMemory};
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn arch_memory_regions(size: usize) -> Vec<(GuestAddress, usize)> {
vec![(GuestAddress(0), size)]
}
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn configure_system(
_guest_mem: &GuestMemory,
_cmdline_addr: GuestAddress,
_cmdline_size: usize,
_num_cpus: u8,
) -> super::Result<()> {
Ok(())
}
/// Stub function that needs to be implemented when aarch64 functionality is added.
pub fn get_reserved_mem_addr() -> usize {
0
}

54
arch/src/lib.rs Normal file
View File

@ -0,0 +1,54 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#![allow(
clippy::unreadable_literal,
clippy::const_static_lifetime,
clippy::cast_lossless,
clippy::transmute_ptr_to_ptr,
clippy::cast_ptr_alignment
)]
extern crate byteorder;
extern crate kvm_bindings;
extern crate libc;
extern crate arch_gen;
extern crate kvm_ioctls;
extern crate vm_memory;
use std::result;
use vm_memory::GuestAddress;
#[derive(Debug, PartialEq)]
pub enum Error {
#[cfg(target_arch = "x86_64")]
/// X86_64 specific error triggered during system configuration.
X86_64Setup(x86_64::Error),
/// The zero page extends past the end of guest_mem.
ZeroPagePastRamEnd,
/// Error writing the zero page of guest memory.
ZeroPageSetup,
}
pub type Result<T> = result::Result<T, Error>;
// 1MB. We don't put anything above here except the kernel itself.
pub const HIMEM_START: GuestAddress = GuestAddress(0x100000);
#[cfg(target_arch = "aarch64")]
pub mod aarch64;
#[cfg(target_arch = "aarch64")]
pub use aarch64::{
arch_memory_regions, configure_system, get_reserved_mem_addr, layout::CMDLINE_MAX_SIZE,
layout::CMDLINE_START,
};
#[cfg(target_arch = "x86_64")]
pub mod x86_64;
#[cfg(target_arch = "x86_64")]
pub use x86_64::{
arch_memory_regions, configure_system, get_32bit_gap_start as get_reserved_mem_addr,
layout::CMDLINE_MAX_SIZE, layout::CMDLINE_START,
};

115
arch/src/x86_64/gdt.rs Normal file
View File

@ -0,0 +1,115 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
// For GDT details see arch/x86/include/asm/segment.h
use kvm_bindings::kvm_segment;
/// 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 {
((((base as u64) & 0xff000000u64) << (56 - 24))
| (((flags as u64) & 0x0000f0ffu64) << 40)
| (((limit as u64) & 0x000f0000u64) << (48 - 16))
| (((base as u64) & 0x00ffffffu64) << 16)
| ((limit as u64) & 0x0000ffffu64))
}
fn get_base(entry: u64) -> u64 {
((((entry) & 0xFF00000000000000) >> 32)
| (((entry) & 0x000000FF00000000) >> 16)
| (((entry) & 0x00000000FFFF0000) >> 16))
}
fn get_limit(entry: u64) -> u32 {
((((entry) & 0x000F000000000000) >> 32) | ((entry) & 0x000000000000FFFF)) as u32
}
fn get_g(entry: u64) -> u8 {
((entry & 0x0080000000000000) >> 55) as u8
}
fn get_db(entry: u64) -> u8 {
((entry & 0x0040000000000000) >> 54) as u8
}
fn get_l(entry: u64) -> u8 {
((entry & 0x0020000000000000) >> 53) as u8
}
fn get_avl(entry: u64) -> u8 {
((entry & 0x0010000000000000) >> 52) as u8
}
fn get_p(entry: u64) -> u8 {
((entry & 0x0000800000000000) >> 47) as u8
}
fn get_dpl(entry: u64) -> u8 {
((entry & 0x0000600000000000) >> 45) as u8
}
fn get_s(entry: u64) -> u8 {
((entry & 0x0000100000000000) >> 44) as u8
}
fn get_type(entry: u64) -> u8 {
((entry & 0x00000F0000000000) >> 40) as u8
}
/// Automatically build the kvm struct for SET_SREGS from the kernel bit fields.
///
/// # Arguments
///
/// * `entry` - The gdt entry.
/// * `table_index` - Index of the entry in the gdt table.
pub fn kvm_segment_from_gdt(entry: u64, table_index: u8) -> kvm_segment {
kvm_segment {
base: get_base(entry),
limit: get_limit(entry),
selector: (table_index * 8) as u16,
type_: get_type(entry),
present: get_p(entry),
dpl: get_dpl(entry),
db: get_db(entry),
s: get_s(entry),
l: get_l(entry),
g: get_g(entry),
avl: get_avl(entry),
padding: 0,
unusable: match get_p(entry) {
0 => 1,
_ => 0,
},
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn field_parse() {
let gdt = gdt_entry(0xA09B, 0x100000, 0xfffff);
let seg = kvm_segment_from_gdt(gdt, 0);
// 0xA09B
// 'A'
assert_eq!(0x1, seg.g);
assert_eq!(0x0, seg.db);
assert_eq!(0x1, seg.l);
assert_eq!(0x0, seg.avl);
// '9'
assert_eq!(0x1, seg.present);
assert_eq!(0x0, seg.dpl);
assert_eq!(0x1, seg.s);
// 'B'
assert_eq!(0xB, seg.type_);
// base and limit
assert_eq!(0x100000, seg.base);
assert_eq!(0xfffff, seg.limit);
assert_eq!(0x0, seg.unusable);
}
}

View File

@ -0,0 +1,158 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use std::io::{self, Cursor};
use std::mem;
use std::result;
use byteorder::{LittleEndian, ReadBytesExt, WriteBytesExt};
use kvm_bindings::kvm_lapic_state;
use kvm_ioctls;
#[derive(Debug)]
pub enum Error {
GetLapic(io::Error),
SetLapic(io::Error),
}
pub type Result<T> = result::Result<T, Error>;
// Defines poached from apicdef.h kernel header.
const APIC_LVT0: usize = 0x350;
const APIC_LVT1: usize = 0x360;
const APIC_MODE_NMI: u32 = 0x4;
const APIC_MODE_EXTINT: u32 = 0x7;
fn get_klapic_reg(klapic: &kvm_lapic_state, reg_offset: usize) -> u32 {
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&[i8], &[u8]>(&klapic.regs[reg_offset..])
};
let mut reader = Cursor::new(sliceu8);
// Following call can't fail if the offsets defined above are correct.
reader
.read_u32::<LittleEndian>()
.expect("Failed to read klapic register")
}
fn set_klapic_reg(klapic: &mut kvm_lapic_state, reg_offset: usize, value: u32) {
let sliceu8 = unsafe {
// This array is only accessed as parts of a u32 word, so interpret it as a u8 array.
// Cursors are only readable on arrays of u8, not i8(c_char).
mem::transmute::<&mut [i8], &mut [u8]>(&mut klapic.regs[reg_offset..])
};
let mut writer = Cursor::new(sliceu8);
// Following call can't fail if the offsets defined above are correct.
writer
.write_u32::<LittleEndian>(value)
.expect("Failed to write klapic register")
}
fn set_apic_delivery_mode(reg: u32, mode: u32) -> u32 {
(((reg) & !0x700) | ((mode) << 8))
}
/// Configures LAPICs. LAPIC0 is set for external interrupts, LAPIC1 is set for NMI.
///
/// # Arguments
/// * `vcpu` - The VCPU object to configure.
pub fn set_lint(vcpu: &kvm_ioctls::VcpuFd) -> Result<()> {
let mut klapic = vcpu.get_lapic().map_err(Error::GetLapic)?;
let lvt_lint0 = get_klapic_reg(&klapic, APIC_LVT0);
set_klapic_reg(
&mut klapic,
APIC_LVT0,
set_apic_delivery_mode(lvt_lint0, APIC_MODE_EXTINT),
);
let lvt_lint1 = get_klapic_reg(&klapic, APIC_LVT1);
set_klapic_reg(
&mut klapic,
APIC_LVT1,
set_apic_delivery_mode(lvt_lint1, APIC_MODE_NMI),
);
vcpu.set_lapic(&klapic).map_err(Error::SetLapic)
}
#[cfg(test)]
mod tests {
extern crate kvm_ioctls;
extern crate rand;
use self::rand::Rng;
use super::*;
use kvm_ioctls::Kvm;
const KVM_APIC_REG_SIZE: usize = 0x400;
#[test]
fn test_set_and_get_klapic_reg() {
let reg_offset = 0x340;
let mut klapic = kvm_lapic_state::default();
set_klapic_reg(&mut klapic, reg_offset, 3);
let value = get_klapic_reg(&klapic, reg_offset);
assert_eq!(value, 3);
}
#[test]
#[should_panic]
fn test_set_and_get_klapic_out_of_bounds() {
let reg_offset = KVM_APIC_REG_SIZE + 10;
let mut klapic = kvm_lapic_state::default();
set_klapic_reg(&mut klapic, reg_offset, 3);
}
#[test]
fn test_apic_delivery_mode() {
let mut rng = rand::thread_rng();
let mut v: Vec<u32> = (0..20).map(|_| rng.gen::<u32>()).collect();
v.iter_mut()
.for_each(|x| *x = set_apic_delivery_mode(*x, 2));
let after: Vec<u32> = v.iter().map(|x| ((*x & !0x700) | ((2) << 8))).collect();
assert_eq!(v, after);
}
#[test]
fn test_setlint() {
let kvm = kvm_ioctls::Kvm::new().unwrap();
assert!(kvm.check_extension(kvm_ioctls::Cap::Irqchip));
let vm = kvm.create_vm().unwrap();
//the get_lapic ioctl will fail if there is no irqchip created beforehand.
assert!(vm.create_irq_chip().is_ok());
let vcpu = vm.create_vcpu(0).unwrap();
let klapic_before: kvm_lapic_state = vcpu.get_lapic().unwrap();
// Compute the value that is expected to represent LVT0 and LVT1.
let lint0 = get_klapic_reg(&klapic_before, APIC_LVT0);
let lint1 = get_klapic_reg(&klapic_before, APIC_LVT1);
let lint0_mode_expected = set_apic_delivery_mode(lint0, APIC_MODE_EXTINT);
let lint1_mode_expected = set_apic_delivery_mode(lint1, APIC_MODE_NMI);
set_lint(&vcpu).unwrap();
// Compute the value that represents LVT0 and LVT1 after set_lint.
let klapic_actual: kvm_lapic_state = vcpu.get_lapic().unwrap();
let lint0_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT0);
let lint1_mode_actual = get_klapic_reg(&klapic_actual, APIC_LVT1);
assert_eq!(lint0_mode_expected, lint0_mode_actual);
assert_eq!(lint1_mode_expected, lint1_mode_actual);
}
#[test]
fn test_setlint_fails() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
// 'get_lapic' ioctl triggered by the 'set_lint' function will fail if there is no
// irqchip created beforehand.
assert!(set_lint(&vcpu).is_err());
}
}

25
arch/src/x86_64/layout.rs Normal file
View File

@ -0,0 +1,25 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use vm_memory::GuestAddress;
/// Magic addresses externally used to lay out x86_64 VMs.
/// Initial stack for the boot CPU.
pub const BOOT_STACK_START: GuestAddress = GuestAddress(0x8000);
pub const BOOT_STACK_POINTER: GuestAddress = GuestAddress(0x8ff0);
/// Kernel command line start address.
pub const CMDLINE_START: GuestAddress = GuestAddress(0x20000);
/// Kernel command line start address maximum size.
pub const CMDLINE_MAX_SIZE: usize = 0x10000;
/// Address for the TSS setup.
pub const KVM_TSS_ADDRESS: GuestAddress = GuestAddress(0xfffbd000);
/// The 'zero page', a.k.a linux kernel bootparams.
pub const ZERO_PAGE_START: GuestAddress = GuestAddress(0x7000);

280
arch/src/x86_64/mod.rs Normal file
View File

@ -0,0 +1,280 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
mod gdt;
pub mod interrupts;
pub mod layout;
mod mptable;
pub mod regs;
use std::mem;
use arch_gen::x86::bootparam::{boot_params, E820_RAM};
use vm_memory::{
Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap, GuestUsize,
};
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `DataInit`) where:
// * the type that is implementing the trait is foreign or
// * all of the parameters being passed to the trait (if there are any) are also foreign
// is prohibited.
#[derive(Copy, Clone, Default)]
struct BootParamsWrapper(boot_params);
// It is safe to initialize BootParamsWrap which is a wrapper over `boot_params` (a series of ints).
unsafe impl ByteValued for BootParamsWrapper {}
#[derive(Debug, PartialEq)]
pub enum Error {
/// Invalid e820 setup params.
E820Configuration,
/// Error writing MP table to memory.
MpTableSetup(mptable::Error),
}
impl From<Error> for super::Error {
fn from(e: Error) -> super::Error {
super::Error::X86_64Setup(e)
}
}
// Where BIOS/VGA magic would live on a real PC.
const EBDA_START: GuestAddress = GuestAddress(0x9fc00);
const FIRST_ADDR_PAST_32BITS: GuestAddress = GuestAddress(1 << 32);
const MEM_32BIT_GAP_SIZE: GuestUsize = (768 << 20);
/// Returns a Vec of the valid memory addresses.
/// These should be used to configure the GuestMemory structure for the platform.
/// For x86_64 all addresses are valid from the start of the kernel except a
/// carve out at the end of 32bit address space.
pub fn arch_memory_regions(size: GuestUsize) -> Vec<(GuestAddress, usize)> {
let memory_gap_start = FIRST_ADDR_PAST_32BITS
.checked_sub(MEM_32BIT_GAP_SIZE as u64)
.expect("32-bit hole is too large");
let requested_memory_size = GuestAddress(size as u64);
let mut regions = Vec::new();
// case1: guest memory fits before the gap
if size as u64 <= memory_gap_start.raw_value() {
regions.push((GuestAddress(0), size as usize));
// case2: guest memory extends beyond the gap
} else {
// push memory before the gap
regions.push((GuestAddress(0), memory_gap_start.raw_value() as usize));
regions.push((
FIRST_ADDR_PAST_32BITS,
requested_memory_size.unchecked_offset_from(memory_gap_start) as usize,
));
}
regions
}
/// X86 specific memory hole/memory mapped devices/reserved area.
pub fn get_32bit_gap_start() -> GuestAddress {
FIRST_ADDR_PAST_32BITS
.checked_sub(MEM_32BIT_GAP_SIZE)
.expect("32-bit hole is too large")
}
/// Configures the system and should be called once per vm before starting vcpu threads.
///
/// # Arguments
///
/// * `guest_mem` - The memory to be used by the guest.
/// * `cmdline_addr` - Address in `guest_mem` where the kernel command line was loaded.
/// * `cmdline_size` - Size of the kernel command line in bytes including the null terminator.
/// * `num_cpus` - Number of virtual CPUs the guest will have.
pub fn configure_system(
guest_mem: &GuestMemoryMmap,
cmdline_addr: GuestAddress,
cmdline_size: usize,
num_cpus: u8,
) -> super::Result<()> {
const KERNEL_BOOT_FLAG_MAGIC: u16 = 0xaa55;
const KERNEL_HDR_MAGIC: u32 = 0x53726448;
const KERNEL_LOADER_OTHER: u8 = 0xff;
const KERNEL_MIN_ALIGNMENT_BYTES: u32 = 0x1000000; // Must be non-zero.
let first_addr_past_32bits = FIRST_ADDR_PAST_32BITS;
let end_32bit_gap_start = get_32bit_gap_start();
let himem_start = super::HIMEM_START;
// Note that this puts the mptable at the last 1k of Linux's 640k base RAM
mptable::setup_mptable(guest_mem, num_cpus).map_err(Error::MpTableSetup)?;
let mut params: BootParamsWrapper = BootParamsWrapper(boot_params::default());
params.0.hdr.type_of_loader = KERNEL_LOADER_OTHER;
params.0.hdr.boot_flag = KERNEL_BOOT_FLAG_MAGIC;
params.0.hdr.header = KERNEL_HDR_MAGIC;
params.0.hdr.cmd_line_ptr = cmdline_addr.raw_value() as u32;
params.0.hdr.cmdline_size = cmdline_size as u32;
params.0.hdr.kernel_alignment = KERNEL_MIN_ALIGNMENT_BYTES;
add_e820_entry(&mut params.0, 0, EBDA_START.raw_value(), E820_RAM)?;
let mem_end = guest_mem.end_addr();
if mem_end < end_32bit_gap_start {
add_e820_entry(
&mut params.0,
himem_start.raw_value(),
mem_end.unchecked_offset_from(himem_start),
E820_RAM,
)?;
} else {
add_e820_entry(
&mut params.0,
himem_start.raw_value(),
end_32bit_gap_start.unchecked_offset_from(himem_start),
E820_RAM,
)?;
if mem_end > first_addr_past_32bits {
add_e820_entry(
&mut params.0,
first_addr_past_32bits.raw_value(),
mem_end.unchecked_offset_from(first_addr_past_32bits),
E820_RAM,
)?;
}
}
let zero_page_addr = layout::ZERO_PAGE_START;
guest_mem
.checked_offset(zero_page_addr, mem::size_of::<boot_params>())
.ok_or(super::Error::ZeroPagePastRamEnd)?;
guest_mem
.write_obj(params, zero_page_addr)
.map_err(|_| super::Error::ZeroPageSetup)?;
Ok(())
}
/// Add an e820 region to the e820 map.
/// Returns Ok(()) if successful, or an error if there is no space left in the map.
fn add_e820_entry(
params: &mut boot_params,
addr: u64,
size: u64,
mem_type: u32,
) -> Result<(), Error> {
if params.e820_entries >= params.e820_map.len() as u8 {
return Err(Error::E820Configuration);
}
params.e820_map[params.e820_entries as usize].addr = addr;
params.e820_map[params.e820_entries as usize].size = size;
params.e820_map[params.e820_entries as usize].type_ = mem_type;
params.e820_entries += 1;
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use arch_gen::x86::bootparam::e820entry;
#[test]
fn regions_lt_4gb() {
let regions = arch_memory_regions(1 << 29 as GuestUsize);
assert_eq!(1, regions.len());
assert_eq!(GuestAddress(0), regions[0].0);
assert_eq!(1usize << 29, regions[0].1);
}
#[test]
fn regions_gt_4gb() {
let regions = arch_memory_regions((1 << 32 as GuestUsize) + 0x8000);
assert_eq!(2, regions.len());
assert_eq!(GuestAddress(0), regions[0].0);
assert_eq!(GuestAddress(1 << 32), regions[1].0);
}
#[test]
fn test_32bit_gap() {
assert_eq!(
get_32bit_gap_start(),
FIRST_ADDR_PAST_32BITS
.checked_sub(MEM_32BIT_GAP_SIZE as u64)
.expect("32-bit hole is too large")
);
}
#[test]
fn test_system_configuration() {
let no_vcpus = 4;
let gm = GuestMemoryMmap::new(&vec![(GuestAddress(0), 0x10000)]).unwrap();
let config_err = configure_system(&gm, GuestAddress(0), 0, 1);
assert!(config_err.is_err());
assert_eq!(
config_err.unwrap_err(),
super::super::Error::X86_64Setup(super::Error::MpTableSetup(
mptable::Error::NotEnoughMemory
))
);
// Now assigning some memory that falls before the 32bit memory hole.
let mem_size = 128 << 20;
let arch_mem_regions = arch_memory_regions(mem_size);
let gm = GuestMemoryMmap::new(&arch_mem_regions).unwrap();
configure_system(&gm, GuestAddress(0), 0, no_vcpus).unwrap();
// Now assigning some memory that is equal to the start of the 32bit memory hole.
let mem_size = 3328 << 20;
let arch_mem_regions = arch_memory_regions(mem_size);
let gm = GuestMemoryMmap::new(&arch_mem_regions).unwrap();
configure_system(&gm, GuestAddress(0), 0, no_vcpus).unwrap();
// Now assigning some memory that falls after the 32bit memory hole.
let mem_size = 3330 << 20;
let arch_mem_regions = arch_memory_regions(mem_size);
let gm = GuestMemoryMmap::new(&arch_mem_regions).unwrap();
configure_system(&gm, GuestAddress(0), 0, no_vcpus).unwrap();
}
#[test]
fn test_add_e820_entry() {
let e820_map = [(e820entry {
addr: 0x1,
size: 4,
type_: 1,
}); 128];
let expected_params = boot_params {
e820_map,
e820_entries: 1,
..Default::default()
};
let mut params: boot_params = Default::default();
add_e820_entry(
&mut params,
e820_map[0].addr,
e820_map[0].size,
e820_map[0].type_,
)
.unwrap();
assert_eq!(
format!("{:?}", params.e820_map[0]),
format!("{:?}", expected_params.e820_map[0])
);
assert_eq!(params.e820_entries, expected_params.e820_entries);
// Exercise the scenario where the field storing the length of the e820 entry table is
// is bigger than the allocated memory.
params.e820_entries = params.e820_map.len() as u8 + 1;
assert!(add_e820_entry(
&mut params,
e820_map[0].addr,
e820_map[0].size,
e820_map[0].type_
)
.is_err());
}
}

403
arch/src/x86_64/mptable.rs Normal file
View File

@ -0,0 +1,403 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use std::io;
use std::mem;
use std::result;
use std::slice;
use libc::c_char;
use arch_gen::x86::mpspec;
use vm_memory::{Address, ByteValued, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
// This is a workaround to the Rust enforcement specifying that any implementation of a foreign
// trait (in this case `ByteValued`) where:
// * the type that is implementing the trait is foreign or
// * all of the parameters being passed to the trait (if there are any) are also foreign
// is prohibited.
#[derive(Copy, Clone, Default)]
struct MpcBusWrapper(mpspec::mpc_bus);
#[derive(Copy, Clone, Default)]
struct MpcCpuWrapper(mpspec::mpc_cpu);
#[derive(Copy, Clone, Default)]
struct MpcIntsrcWrapper(mpspec::mpc_intsrc);
#[derive(Copy, Clone, Default)]
struct MpcIoapicWrapper(mpspec::mpc_ioapic);
#[derive(Copy, Clone, Default)]
struct MpcTableWrapper(mpspec::mpc_table);
#[derive(Copy, Clone, Default)]
struct MpcLintsrcWrapper(mpspec::mpc_lintsrc);
#[derive(Copy, Clone, Default)]
struct MpfIntelWrapper(mpspec::mpf_intel);
// These `mpspec` wrapper types are only data, reading them from data is a safe initialization.
unsafe impl ByteValued for MpcBusWrapper {}
unsafe impl ByteValued for MpcCpuWrapper {}
unsafe impl ByteValued for MpcIntsrcWrapper {}
unsafe impl ByteValued for MpcIoapicWrapper {}
unsafe impl ByteValued for MpcTableWrapper {}
unsafe impl ByteValued for MpcLintsrcWrapper {}
unsafe impl ByteValued for MpfIntelWrapper {}
// MPTABLE, describing VCPUS.
const MPTABLE_START: GuestAddress = GuestAddress(0x9fc00);
#[derive(Debug, PartialEq)]
pub enum Error {
/// There was too little guest memory to store the entire MP table.
NotEnoughMemory,
/// The MP table has too little address space to be stored.
AddressOverflow,
/// Failure while zeroing out the memory for the MP table.
Clear,
/// Number of CPUs exceeds the maximum supported CPUs
TooManyCpus,
/// Failure to write the MP floating pointer.
WriteMpfIntel,
/// Failure to write MP CPU entry.
WriteMpcCpu,
/// Failure to write MP ioapic entry.
WriteMpcIoapic,
/// Failure to write MP bus entry.
WriteMpcBus,
/// Failure to write MP interrupt source entry.
WriteMpcIntsrc,
/// Failure to write MP local interrupt source entry.
WriteMpcLintsrc,
/// Failure to write MP table header.
WriteMpcTable,
}
pub type Result<T> = result::Result<T, Error>;
// With APIC/xAPIC, there are only 255 APIC IDs available. And IOAPIC occupies
// one APIC ID, so only 254 CPUs at maximum may be supported. Actually it's
// a large number for FC usecases.
pub const MAX_SUPPORTED_CPUS: u32 = 254;
// Convenience macro for making arrays of diverse character types.
macro_rules! char_array {
($t:ty; $( $c:expr ),*) => ( [ $( $c as $t ),* ] )
}
// Most of these variables are sourced from the Intel MP Spec 1.4.
const SMP_MAGIC_IDENT: [c_char; 4] = char_array!(c_char; '_', 'M', 'P', '_');
const MPC_SIGNATURE: [c_char; 4] = char_array!(c_char; 'P', 'C', 'M', 'P');
const MPC_SPEC: i8 = 4;
const MPC_OEM: [c_char; 8] = char_array!(c_char; 'F', 'C', ' ', ' ', ' ', ' ', ' ', ' ');
const MPC_PRODUCT_ID: [c_char; 12] = ['0' as c_char; 12];
const BUS_TYPE_ISA: [u8; 6] = char_array!(u8; 'I', 'S', 'A', ' ', ' ', ' ');
const IO_APIC_DEFAULT_PHYS_BASE: u32 = 0xfec00000; // source: linux/arch/x86/include/asm/apicdef.h
const APIC_DEFAULT_PHYS_BASE: u32 = 0xfee00000; // source: linux/arch/x86/include/asm/apicdef.h
const APIC_VERSION: u8 = 0x14;
const CPU_STEPPING: u32 = 0x600;
const CPU_FEATURE_APIC: u32 = 0x200;
const CPU_FEATURE_FPU: u32 = 0x001;
fn compute_checksum<T: Copy>(v: &T) -> u8 {
// Safe because we are only reading the bytes within the size of the `T` reference `v`.
let v_slice = unsafe { slice::from_raw_parts(v as *const T as *const u8, mem::size_of::<T>()) };
let mut checksum: u8 = 0;
for i in v_slice.iter() {
checksum = checksum.wrapping_add(*i);
}
checksum
}
fn mpf_intel_compute_checksum(v: &mpspec::mpf_intel) -> u8 {
let checksum = compute_checksum(v).wrapping_sub(v.checksum);
(!checksum).wrapping_add(1)
}
fn compute_mp_size(num_cpus: u8) -> usize {
mem::size_of::<MpfIntelWrapper>()
+ mem::size_of::<MpcTableWrapper>()
+ mem::size_of::<MpcCpuWrapper>() * (num_cpus as usize)
+ mem::size_of::<MpcIoapicWrapper>()
+ mem::size_of::<MpcBusWrapper>()
+ mem::size_of::<MpcIntsrcWrapper>() * 16
+ mem::size_of::<MpcLintsrcWrapper>() * 2
}
/// Performs setup of the MP table for the given `num_cpus`.
pub fn setup_mptable(mem: &GuestMemoryMmap, num_cpus: u8) -> Result<()> {
if num_cpus as u32 > MAX_SUPPORTED_CPUS {
return Err(Error::TooManyCpus);
}
// Used to keep track of the next base pointer into the MP table.
let mut base_mp = MPTABLE_START;
let mp_size = compute_mp_size(num_cpus);
let mut checksum: u8 = 0;
let ioapicid: u8 = num_cpus + 1;
// The checked_add here ensures the all of the following base_mp.unchecked_add's will be without
// overflow.
if let Some(end_mp) = base_mp.checked_add((mp_size - 1) as u64) {
if !mem.address_in_range(end_mp) {
return Err(Error::NotEnoughMemory);
}
} else {
return Err(Error::AddressOverflow);
}
mem.read_exact_from(base_mp, &mut io::repeat(0), mp_size)
.map_err(|_| Error::Clear)?;
{
let mut mpf_intel = MpfIntelWrapper(mpspec::mpf_intel::default());
let size = mem::size_of::<MpfIntelWrapper>() as u64;
mpf_intel.0.signature = SMP_MAGIC_IDENT;
mpf_intel.0.length = 1;
mpf_intel.0.specification = 4;
mpf_intel.0.physptr = (base_mp.raw_value() + size) as u32;
mpf_intel.0.checksum = mpf_intel_compute_checksum(&mpf_intel.0);
mem.write_obj(mpf_intel, base_mp)
.map_err(|_| Error::WriteMpfIntel)?;
base_mp = base_mp.unchecked_add(size);
}
// We set the location of the mpc_table here but we can't fill it out until we have the length
// of the entire table later.
let table_base = base_mp;
base_mp = base_mp.unchecked_add(mem::size_of::<MpcTableWrapper>() as u64);
{
let size = mem::size_of::<MpcCpuWrapper>();
for cpu_id in 0..num_cpus {
let mut mpc_cpu = MpcCpuWrapper(mpspec::mpc_cpu::default());
mpc_cpu.0.type_ = mpspec::MP_PROCESSOR as u8;
mpc_cpu.0.apicid = cpu_id;
mpc_cpu.0.apicver = APIC_VERSION;
mpc_cpu.0.cpuflag = mpspec::CPU_ENABLED as u8
| if cpu_id == 0 {
mpspec::CPU_BOOTPROCESSOR as u8
} else {
0
};
mpc_cpu.0.cpufeature = CPU_STEPPING;
mpc_cpu.0.featureflag = CPU_FEATURE_APIC | CPU_FEATURE_FPU;
mem.write_obj(mpc_cpu, base_mp)
.map_err(|_| Error::WriteMpcCpu)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_cpu.0));
}
}
{
let size = mem::size_of::<MpcBusWrapper>();
let mut mpc_bus = MpcBusWrapper(mpspec::mpc_bus::default());
mpc_bus.0.type_ = mpspec::MP_BUS as u8;
mpc_bus.0.busid = 0;
mpc_bus.0.bustype = BUS_TYPE_ISA;
mem.write_obj(mpc_bus, base_mp)
.map_err(|_| Error::WriteMpcBus)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_bus.0));
}
{
let size = mem::size_of::<MpcIoapicWrapper>();
let mut mpc_ioapic = MpcIoapicWrapper(mpspec::mpc_ioapic::default());
mpc_ioapic.0.type_ = mpspec::MP_IOAPIC as u8;
mpc_ioapic.0.apicid = ioapicid;
mpc_ioapic.0.apicver = APIC_VERSION;
mpc_ioapic.0.flags = mpspec::MPC_APIC_USABLE as u8;
mpc_ioapic.0.apicaddr = IO_APIC_DEFAULT_PHYS_BASE;
mem.write_obj(mpc_ioapic, base_mp)
.map_err(|_| Error::WriteMpcIoapic)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_ioapic.0));
}
// Per kvm_setup_default_irq_routing() in kernel
for i in 0..16 {
let size = mem::size_of::<MpcIntsrcWrapper>();
let mut mpc_intsrc = MpcIntsrcWrapper(mpspec::mpc_intsrc::default());
mpc_intsrc.0.type_ = mpspec::MP_INTSRC as u8;
mpc_intsrc.0.irqtype = mpspec::mp_irq_source_types_mp_INT as u8;
mpc_intsrc.0.irqflag = mpspec::MP_IRQDIR_DEFAULT as u16;
mpc_intsrc.0.srcbus = 0;
mpc_intsrc.0.srcbusirq = i;
mpc_intsrc.0.dstapic = ioapicid;
mpc_intsrc.0.dstirq = i;
mem.write_obj(mpc_intsrc, base_mp)
.map_err(|_| Error::WriteMpcIntsrc)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_intsrc.0));
}
{
let size = mem::size_of::<MpcLintsrcWrapper>();
let mut mpc_lintsrc = MpcLintsrcWrapper(mpspec::mpc_lintsrc::default());
mpc_lintsrc.0.type_ = mpspec::MP_LINTSRC as u8;
mpc_lintsrc.0.irqtype = mpspec::mp_irq_source_types_mp_ExtINT as u8;
mpc_lintsrc.0.irqflag = mpspec::MP_IRQDIR_DEFAULT as u16;
mpc_lintsrc.0.srcbusid = 0;
mpc_lintsrc.0.srcbusirq = 0;
mpc_lintsrc.0.destapic = 0;
mpc_lintsrc.0.destapiclint = 0;
mem.write_obj(mpc_lintsrc, base_mp)
.map_err(|_| Error::WriteMpcLintsrc)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_lintsrc.0));
}
{
let size = mem::size_of::<MpcLintsrcWrapper>();
let mut mpc_lintsrc = MpcLintsrcWrapper(mpspec::mpc_lintsrc::default());
mpc_lintsrc.0.type_ = mpspec::MP_LINTSRC as u8;
mpc_lintsrc.0.irqtype = mpspec::mp_irq_source_types_mp_NMI as u8;
mpc_lintsrc.0.irqflag = mpspec::MP_IRQDIR_DEFAULT as u16;
mpc_lintsrc.0.srcbusid = 0;
mpc_lintsrc.0.srcbusirq = 0;
mpc_lintsrc.0.destapic = 0xFF; /* to all local APICs */
mpc_lintsrc.0.destapiclint = 1;
mem.write_obj(mpc_lintsrc, base_mp)
.map_err(|_| Error::WriteMpcLintsrc)?;
base_mp = base_mp.unchecked_add(size as u64);
checksum = checksum.wrapping_add(compute_checksum(&mpc_lintsrc.0));
}
// At this point we know the size of the mp_table.
let table_end = base_mp;
{
let mut mpc_table = MpcTableWrapper(mpspec::mpc_table::default());
mpc_table.0.signature = MPC_SIGNATURE;
mpc_table.0.length = table_end.unchecked_offset_from(table_base) as u16;
mpc_table.0.spec = MPC_SPEC;
mpc_table.0.oem = MPC_OEM;
mpc_table.0.productid = MPC_PRODUCT_ID;
mpc_table.0.lapic = APIC_DEFAULT_PHYS_BASE;
checksum = checksum.wrapping_add(compute_checksum(&mpc_table.0));
mpc_table.0.checksum = (!checksum).wrapping_add(1) as i8;
mem.write_obj(mpc_table, table_base)
.map_err(|_| Error::WriteMpcTable)?;
}
Ok(())
}
#[cfg(test)]
mod tests {
use super::*;
use vm_memory::GuestUsize;
fn table_entry_size(type_: u8) -> usize {
match type_ as u32 {
mpspec::MP_PROCESSOR => mem::size_of::<MpcCpuWrapper>(),
mpspec::MP_BUS => mem::size_of::<MpcBusWrapper>(),
mpspec::MP_IOAPIC => mem::size_of::<MpcIoapicWrapper>(),
mpspec::MP_INTSRC => mem::size_of::<MpcIntsrcWrapper>(),
mpspec::MP_LINTSRC => mem::size_of::<MpcLintsrcWrapper>(),
_ => panic!("unrecognized mpc table entry type: {}", type_),
}
}
#[test]
fn bounds_check() {
let num_cpus = 4;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
}
#[test]
fn bounds_check_fails() {
let num_cpus = 4;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus) - 1)]).unwrap();
assert!(setup_mptable(&mem, num_cpus).is_err());
}
#[test]
fn mpf_intel_checksum() {
let num_cpus = 1;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
assert_eq!(
mpf_intel_compute_checksum(&mpf_intel.0),
mpf_intel.0.checksum
);
}
#[test]
fn mpc_table_checksum() {
let num_cpus = 4;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(num_cpus))]).unwrap();
setup_mptable(&mem, num_cpus).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap();
struct Sum(u8);
impl io::Write for Sum {
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
for v in buf.iter() {
self.0 = self.0.wrapping_add(*v);
}
Ok(buf.len())
}
fn flush(&mut self) -> io::Result<()> {
Ok(())
}
}
let mut sum = Sum(0);
mem.write_to(mpc_offset, &mut sum, mpc_table.0.length as usize)
.unwrap();
assert_eq!(sum.0, 0);
}
#[test]
fn cpu_entry_count() {
let mem =
GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(MAX_SUPPORTED_CPUS as u8))])
.unwrap();
for i in 0..MAX_SUPPORTED_CPUS as u8 {
setup_mptable(&mem, i).unwrap();
let mpf_intel: MpfIntelWrapper = mem.read_obj(MPTABLE_START).unwrap();
let mpc_offset = GuestAddress(mpf_intel.0.physptr as GuestUsize);
let mpc_table: MpcTableWrapper = mem.read_obj(mpc_offset).unwrap();
let mpc_end = mpc_offset
.checked_add(mpc_table.0.length as GuestUsize)
.unwrap();
let mut entry_offset = mpc_offset
.checked_add(mem::size_of::<MpcTableWrapper>() as GuestUsize)
.unwrap();
let mut cpu_count = 0;
while entry_offset < mpc_end {
let entry_type: u8 = mem.read_obj(entry_offset).unwrap();
entry_offset = entry_offset
.checked_add(table_entry_size(entry_type) as GuestUsize)
.unwrap();
assert!(entry_offset <= mpc_end);
if entry_type as u32 == mpspec::MP_PROCESSOR {
cpu_count += 1;
}
}
assert_eq!(cpu_count, i);
}
}
#[test]
fn cpu_entry_count_max() {
let cpus = MAX_SUPPORTED_CPUS + 1;
let mem = GuestMemoryMmap::new(&[(MPTABLE_START, compute_mp_size(cpus as u8))]).unwrap();
let result = setup_mptable(&mem, cpus as u8).unwrap_err();
assert_eq!(result, Error::TooManyCpus);
}
}

452
arch/src/x86_64/regs.rs Normal file
View File

@ -0,0 +1,452 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
use std::{io, mem, result};
use super::gdt::{gdt_entry, kvm_segment_from_gdt};
use arch_gen::x86::msr_index;
use kvm_bindings::{kvm_fpu, kvm_msr_entry, kvm_msrs, kvm_regs, kvm_sregs};
use kvm_ioctls::VcpuFd;
use vm_memory::{Address, Bytes, GuestAddress, GuestMemory, GuestMemoryMmap};
// Initial pagetables.
const PML4_START: GuestAddress = GuestAddress(0x9000);
const PDPTE_START: GuestAddress = GuestAddress(0xa000);
const PDE_START: GuestAddress = GuestAddress(0xb000);
#[derive(Debug)]
pub enum Error {
/// Failed to get SREGs for this CPU.
GetStatusRegisters(io::Error),
/// Failed to set base registers for this CPU.
SetBaseRegisters(io::Error),
/// Failed to configure the FPU.
SetFPURegisters(io::Error),
/// Setting up MSRs failed.
SetModelSpecificRegisters(io::Error),
/// Failed to set SREGs for this CPU.
SetStatusRegisters(io::Error),
/// Writing the GDT to RAM failed.
WriteGDT,
/// Writing the IDT to RAM failed.
WriteIDT,
/// Writing PDPTE to RAM failed.
WritePDPTEAddress,
/// Writing PDE to RAM failed.
WritePDEAddress,
/// Writing PML4 to RAM failed.
WritePML4Address,
}
pub type Result<T> = result::Result<T, Error>;
/// Configure Floating-Point Unit (FPU) registers for a given CPU.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_fpu(vcpu: &VcpuFd) -> Result<()> {
let fpu: kvm_fpu = kvm_fpu {
fcw: 0x37f,
mxcsr: 0x1f80,
..Default::default()
};
vcpu.set_fpu(&fpu).map_err(Error::SetFPURegisters)
}
/// Configure Model Specific Registers (MSRs) for a given CPU.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_msrs(vcpu: &VcpuFd) -> Result<()> {
let entry_vec = create_msr_entries();
let vec_size_bytes =
mem::size_of::<kvm_msrs>() + (entry_vec.len() * mem::size_of::<kvm_msr_entry>());
let vec: Vec<u8> = Vec::with_capacity(vec_size_bytes);
let msrs: &mut kvm_msrs = unsafe {
// Converting the vector's memory to a struct is unsafe. Carefully using the read-only
// vector to size and set the members ensures no out-of-bounds errors below.
&mut *(vec.as_ptr() as *mut kvm_msrs)
};
unsafe {
// Mapping the unsized array to a slice is unsafe because the length isn't known.
// Providing the length used to create the struct guarantees the entire slice is valid.
let entries: &mut [kvm_msr_entry] = msrs.entries.as_mut_slice(entry_vec.len());
entries.copy_from_slice(&entry_vec);
}
msrs.nmsrs = entry_vec.len() as u32;
vcpu.set_msrs(msrs)
.map_err(Error::SetModelSpecificRegisters)
}
/// Configure base registers for a given CPU.
///
/// # Arguments
///
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
/// * `boot_ip` - Starting instruction pointer.
/// * `boot_sp` - Starting stack pointer.
/// * `boot_si` - Must point to zero page address per Linux ABI.
pub fn setup_regs(vcpu: &VcpuFd, boot_ip: u64, boot_sp: u64, boot_si: u64) -> Result<()> {
let regs: kvm_regs = kvm_regs {
rflags: 0x0000000000000002u64,
rip: boot_ip,
rsp: boot_sp,
rbp: boot_sp,
rsi: boot_si,
..Default::default()
};
vcpu.set_regs(&regs).map_err(Error::SetBaseRegisters)
}
/// Configures the segment registers and system page tables for a given CPU.
///
/// # Arguments
///
/// * `mem` - The memory that will be passed to the guest.
/// * `vcpu` - Structure for the VCPU that holds the VCPU's fd.
pub fn setup_sregs(mem: &GuestMemoryMmap, vcpu: &VcpuFd) -> Result<()> {
let mut sregs: kvm_sregs = vcpu.get_sregs().map_err(Error::GetStatusRegisters)?;
configure_segments_and_sregs(mem, &mut sregs)?;
setup_page_tables(mem, &mut sregs)?; // TODO(dgreid) - Can this be done once per system instead?
vcpu.set_sregs(&sregs).map_err(Error::SetStatusRegisters)
}
const BOOT_GDT_OFFSET: GuestAddress = GuestAddress(0x500);
const BOOT_IDT_OFFSET: GuestAddress = GuestAddress(0x520);
const BOOT_GDT_MAX: usize = 4;
const EFER_LMA: u64 = 0x400;
const EFER_LME: u64 = 0x100;
const X86_CR0_PE: u64 = 0x1;
const X86_CR0_PG: u64 = 0x80000000;
const X86_CR4_PAE: u64 = 0x20;
fn write_gdt_table(table: &[u64], guest_mem: &GuestMemoryMmap) -> Result<()> {
let boot_gdt_addr = BOOT_GDT_OFFSET;
for (index, entry) in table.iter().enumerate() {
let addr = guest_mem
.checked_offset(boot_gdt_addr, index * mem::size_of::<u64>())
.ok_or(Error::WriteGDT)?;
guest_mem
.write_obj(*entry, addr)
.map_err(|_| Error::WriteGDT)?;
}
Ok(())
}
fn write_idt_value(val: u64, guest_mem: &GuestMemoryMmap) -> Result<()> {
let boot_idt_addr = BOOT_IDT_OFFSET;
guest_mem
.write_obj(val, boot_idt_addr)
.map_err(|_| Error::WriteIDT)
}
fn configure_segments_and_sregs(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> {
let gdt_table: [u64; BOOT_GDT_MAX as usize] = [
gdt_entry(0, 0, 0), // NULL
gdt_entry(0xa09b, 0, 0xfffff), // CODE
gdt_entry(0xc093, 0, 0xfffff), // DATA
gdt_entry(0x808b, 0, 0xfffff), // TSS
];
let code_seg = kvm_segment_from_gdt(gdt_table[1], 1);
let data_seg = kvm_segment_from_gdt(gdt_table[2], 2);
let tss_seg = kvm_segment_from_gdt(gdt_table[3], 3);
// Write segments
write_gdt_table(&gdt_table[..], mem)?;
sregs.gdt.base = BOOT_GDT_OFFSET.raw_value();
sregs.gdt.limit = mem::size_of_val(&gdt_table) as u16 - 1;
write_idt_value(0, mem)?;
sregs.idt.base = BOOT_IDT_OFFSET.raw_value();
sregs.idt.limit = mem::size_of::<u64>() as u16 - 1;
sregs.cs = code_seg;
sregs.ds = data_seg;
sregs.es = data_seg;
sregs.fs = data_seg;
sregs.gs = data_seg;
sregs.ss = data_seg;
sregs.tr = tss_seg;
/* 64-bit protected mode */
sregs.cr0 |= X86_CR0_PE;
sregs.efer |= EFER_LME | EFER_LMA;
Ok(())
}
fn setup_page_tables(mem: &GuestMemoryMmap, sregs: &mut kvm_sregs) -> Result<()> {
// Puts PML4 right after zero page but aligned to 4k.
// Entry covering VA [0..512GB)
mem.write_obj(PDPTE_START.raw_value() | 0x03, PML4_START)
.map_err(|_| Error::WritePML4Address)?;
// Entry covering VA [0..1GB)
mem.write_obj(PDE_START.raw_value() | 0x03, PDPTE_START)
.map_err(|_| Error::WritePDPTEAddress)?;
// 512 2MB entries together covering VA [0..1GB). Note we are assuming
// CPU supports 2MB pages (/proc/cpuinfo has 'pse'). All modern CPUs do.
for i in 0..512 {
mem.write_obj((i << 21) + 0x83u64, PDE_START.unchecked_add(i * 8))
.map_err(|_| Error::WritePDEAddress)?;
}
sregs.cr3 = PML4_START.raw_value();
sregs.cr4 |= X86_CR4_PAE;
sregs.cr0 |= X86_CR0_PG;
Ok(())
}
fn create_msr_entries() -> Vec<kvm_msr_entry> {
let mut entries = Vec::<kvm_msr_entry>::new();
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_SYSENTER_CS,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_SYSENTER_ESP,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_SYSENTER_EIP,
data: 0x0,
..Default::default()
});
// x86_64 specific msrs, we only run on x86_64 not x86.
entries.push(kvm_msr_entry {
index: msr_index::MSR_STAR,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_CSTAR,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_KERNEL_GS_BASE,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_SYSCALL_MASK,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_LSTAR,
data: 0x0,
..Default::default()
});
// end of x86_64 specific code
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_TSC,
data: 0x0,
..Default::default()
});
entries.push(kvm_msr_entry {
index: msr_index::MSR_IA32_MISC_ENABLE,
data: msr_index::MSR_IA32_MISC_ENABLE_FAST_STRING as u64,
..Default::default()
});
entries
}
#[cfg(test)]
mod tests {
extern crate kvm_ioctls;
extern crate vm_memory;
use super::*;
use kvm_ioctls::Kvm;
use vm_memory::{GuestAddress, GuestMemoryMmap};
fn create_guest_mem() -> GuestMemoryMmap {
GuestMemoryMmap::new(&vec![(GuestAddress(0), 0x10000)]).unwrap()
}
fn read_u64(gm: &GuestMemoryMmap, offset: GuestAddress) -> u64 {
gm.read_obj(offset).unwrap()
}
#[test]
fn segments_and_sregs() {
let mut sregs: kvm_sregs = Default::default();
let gm = create_guest_mem();
configure_segments_and_sregs(&gm, &mut sregs).unwrap();
assert_eq!(0x0, read_u64(&gm, BOOT_GDT_OFFSET));
assert_eq!(
0xaf9b000000ffff,
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(8))
);
assert_eq!(
0xcf93000000ffff,
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(16))
);
assert_eq!(
0x8f8b000000ffff,
read_u64(&gm, BOOT_GDT_OFFSET.unchecked_add(24))
);
assert_eq!(0x0, read_u64(&gm, BOOT_IDT_OFFSET));
assert_eq!(0, sregs.cs.base);
assert_eq!(0xfffff, sregs.ds.limit);
assert_eq!(0x10, sregs.es.selector);
assert_eq!(1, sregs.fs.present);
assert_eq!(1, sregs.gs.g);
assert_eq!(0, sregs.ss.avl);
assert_eq!(0, sregs.tr.base);
assert_eq!(0xfffff, sregs.tr.limit);
assert_eq!(0, sregs.tr.avl);
assert_eq!(X86_CR0_PE, sregs.cr0);
assert_eq!(EFER_LME | EFER_LMA, sregs.efer);
}
#[test]
fn page_tables() {
let mut sregs: kvm_sregs = Default::default();
let gm = create_guest_mem();
setup_page_tables(&gm, &mut sregs).unwrap();
assert_eq!(0xa003, read_u64(&gm, PML4_START));
assert_eq!(0xb003, read_u64(&gm, PDPTE_START));
for i in 0..512 {
assert_eq!(
(i << 21) + 0x83u64,
read_u64(&gm, PDE_START.unchecked_add(i * 8))
);
}
assert_eq!(PML4_START.raw_value(), sregs.cr3);
assert_eq!(X86_CR4_PAE, sregs.cr4);
assert_eq!(X86_CR0_PG, sregs.cr0);
}
#[test]
fn test_setup_fpu() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
setup_fpu(&vcpu).unwrap();
let expected_fpu: kvm_fpu = kvm_fpu {
fcw: 0x37f,
mxcsr: 0x1f80,
..Default::default()
};
let actual_fpu: kvm_fpu = vcpu.get_fpu().unwrap();
// TODO: auto-generate kvm related structures with PartialEq on.
assert_eq!(expected_fpu.fcw, actual_fpu.fcw);
// Setting the mxcsr register from kvm_fpu inside setup_fpu does not influence anything.
// See 'kvm_arch_vcpu_ioctl_set_fpu' from arch/x86/kvm/x86.c.
// The mxcsr will stay 0 and the assert below fails. Decide whether or not we should
// remove it at all.
// assert!(expected_fpu.mxcsr == actual_fpu.mxcsr);
}
#[test]
fn test_setup_msrs() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
setup_msrs(&vcpu).unwrap();
// This test will check against the last MSR entry configured (the tenth one).
// See create_msr_entries for details.
let test_kvm_msrs_entry = [kvm_msr_entry {
index: msr_index::MSR_IA32_MISC_ENABLE,
..Default::default()
}];
let vec_size_bytes = mem::size_of::<kvm_msrs>() + mem::size_of::<kvm_msr_entry>();
let vec: Vec<u8> = Vec::with_capacity(vec_size_bytes);
let mut msrs: &mut kvm_msrs = unsafe {
// Converting the vector's memory to a struct is unsafe. Carefully using the read-only
// vector to size and set the members ensures no out-of-bounds errors below.
&mut *(vec.as_ptr() as *mut kvm_msrs)
};
unsafe {
let entries: &mut [kvm_msr_entry] = msrs.entries.as_mut_slice(1);
entries.copy_from_slice(&test_kvm_msrs_entry);
}
msrs.nmsrs = 1;
// get_msrs returns the number of msrs that it succeed in reading. We only want to read 1
// in this test case scenario.
let read_msrs = vcpu.get_msrs(&mut msrs).unwrap();
assert_eq!(read_msrs, 1);
// Official entries that were setup when we did setup_msrs. We need to assert that the
// tenth one (i.e the one with index msr_index::MSR_IA32_MISC_ENABLE has the data we
// expect.
let entry_vec = create_msr_entries();
unsafe {
assert_eq!(entry_vec[9], msrs.entries.as_slice(1)[0]);
}
}
#[test]
fn test_setup_regs() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let expected_regs: kvm_regs = kvm_regs {
rflags: 0x0000000000000002u64,
rip: 1,
rsp: 2,
rbp: 2,
rsi: 3,
..Default::default()
};
setup_regs(
&vcpu,
expected_regs.rip,
expected_regs.rsp,
expected_regs.rsi,
)
.unwrap();
let actual_regs: kvm_regs = vcpu.get_regs().unwrap();
assert_eq!(actual_regs, expected_regs);
}
#[test]
fn test_setup_sregs() {
let kvm = Kvm::new().unwrap();
let vm = kvm.create_vm().unwrap();
let vcpu = vm.create_vcpu(0).unwrap();
let mut expected_sregs: kvm_sregs = vcpu.get_sregs().unwrap();
let gm = create_guest_mem();
configure_segments_and_sregs(&gm, &mut expected_sregs).unwrap();
setup_page_tables(&gm, &mut expected_sregs).unwrap();
setup_sregs(&gm, &vcpu).unwrap();
let actual_sregs: kvm_sregs = vcpu.get_sregs().unwrap();
assert_eq!(expected_sregs, actual_sregs);
}
}

4
arch_gen/Cargo.lock generated Normal file
View File

@ -0,0 +1,4 @@
[[package]]
name = "arch_gen"
version = "0.1.0"

7
arch_gen/Cargo.toml Normal file
View File

@ -0,0 +1,7 @@
[package]
name = "arch_gen"
version = "0.1.0"
authors = ["Amazon firecracker team <firecracker-devel@amazon.com>"]
[dependencies]

5
arch_gen/src/lib.rs Normal file
View File

@ -0,0 +1,5 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
#[cfg(any(target_arch = "x86", target_arch = "x86_64"))]
pub mod x86;

File diff suppressed because it is too large Load Diff

26
arch_gen/src/x86/mod.rs Normal file
View File

@ -0,0 +1,26 @@
// Copyright 2018 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0
//
// Portions Copyright 2017 The Chromium OS Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the THIRD-PARTY file.
#[allow(non_upper_case_globals)]
#[allow(non_camel_case_types)]
#[allow(non_snake_case)]
#[allow(
clippy::unreadable_literal,
clippy::const_static_lifetime,
clippy::trivially_copy_pass_by_ref,
clippy::useless_transmute,
clippy::should_implement_trait,
clippy::transmute_ptr_to_ptr
)]
pub mod bootparam;
#[allow(non_camel_case_types)]
#[allow(non_upper_case_globals)]
#[allow(clippy::unreadable_literal, clippy::const_static_lifetime)]
pub mod mpspec;
#[allow(non_upper_case_globals)]
#[allow(clippy::unreadable_literal, clippy::const_static_lifetime)]
pub mod msr_index;

832
arch_gen/src/x86/mpspec.rs Normal file
View File

@ -0,0 +1,832 @@
// 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 THIRD-PARTY file.
/* automatically generated by rust-bindgen */
pub const MPC_SIGNATURE: &'static [u8; 5usize] = b"PCMP\x00";
pub const MP_PROCESSOR: ::std::os::raw::c_uint = 0;
pub const MP_BUS: ::std::os::raw::c_uint = 1;
pub const MP_IOAPIC: ::std::os::raw::c_uint = 2;
pub const MP_INTSRC: ::std::os::raw::c_uint = 3;
pub const MP_LINTSRC: ::std::os::raw::c_uint = 4;
pub const MP_TRANSLATION: ::std::os::raw::c_uint = 192;
pub const CPU_ENABLED: ::std::os::raw::c_uint = 1;
pub const CPU_BOOTPROCESSOR: ::std::os::raw::c_uint = 2;
pub const CPU_STEPPING_MASK: ::std::os::raw::c_uint = 15;
pub const CPU_MODEL_MASK: ::std::os::raw::c_uint = 240;
pub const CPU_FAMILY_MASK: ::std::os::raw::c_uint = 3840;
pub const BUSTYPE_EISA: &'static [u8; 5usize] = b"EISA\x00";
pub const BUSTYPE_ISA: &'static [u8; 4usize] = b"ISA\x00";
pub const BUSTYPE_INTERN: &'static [u8; 7usize] = b"INTERN\x00";
pub const BUSTYPE_MCA: &'static [u8; 4usize] = b"MCA\x00";
pub const BUSTYPE_VL: &'static [u8; 3usize] = b"VL\x00";
pub const BUSTYPE_PCI: &'static [u8; 4usize] = b"PCI\x00";
pub const BUSTYPE_PCMCIA: &'static [u8; 7usize] = b"PCMCIA\x00";
pub const BUSTYPE_CBUS: &'static [u8; 5usize] = b"CBUS\x00";
pub const BUSTYPE_CBUSII: &'static [u8; 7usize] = b"CBUSII\x00";
pub const BUSTYPE_FUTURE: &'static [u8; 7usize] = b"FUTURE\x00";
pub const BUSTYPE_MBI: &'static [u8; 4usize] = b"MBI\x00";
pub const BUSTYPE_MBII: &'static [u8; 5usize] = b"MBII\x00";
pub const BUSTYPE_MPI: &'static [u8; 4usize] = b"MPI\x00";
pub const BUSTYPE_MPSA: &'static [u8; 5usize] = b"MPSA\x00";
pub const BUSTYPE_NUBUS: &'static [u8; 6usize] = b"NUBUS\x00";
pub const BUSTYPE_TC: &'static [u8; 3usize] = b"TC\x00";
pub const BUSTYPE_VME: &'static [u8; 4usize] = b"VME\x00";
pub const BUSTYPE_XPRESS: &'static [u8; 7usize] = b"XPRESS\x00";
pub const MPC_APIC_USABLE: ::std::os::raw::c_uint = 1;
pub const MP_IRQDIR_DEFAULT: ::std::os::raw::c_uint = 0;
pub const MP_IRQDIR_HIGH: ::std::os::raw::c_uint = 1;
pub const MP_IRQDIR_LOW: ::std::os::raw::c_uint = 3;
pub const MP_APIC_ALL: ::std::os::raw::c_uint = 255;
pub const MPC_OEM_SIGNATURE: &'static [u8; 5usize] = b"_OEM\x00";
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpf_intel {
pub signature: [::std::os::raw::c_char; 4usize],
pub physptr: ::std::os::raw::c_uint,
pub length: ::std::os::raw::c_uchar,
pub specification: ::std::os::raw::c_uchar,
pub checksum: ::std::os::raw::c_uchar,
pub feature1: ::std::os::raw::c_uchar,
pub feature2: ::std::os::raw::c_uchar,
pub feature3: ::std::os::raw::c_uchar,
pub feature4: ::std::os::raw::c_uchar,
pub feature5: ::std::os::raw::c_uchar,
}
#[test]
fn bindgen_test_layout_mpf_intel() {
assert_eq!(
::std::mem::size_of::<mpf_intel>(),
16usize,
concat!("Size of: ", stringify!(mpf_intel))
);
assert_eq!(
::std::mem::align_of::<mpf_intel>(),
4usize,
concat!("Alignment of ", stringify!(mpf_intel))
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).signature as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(signature)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).physptr as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(physptr)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).length as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(length)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).specification as *const _ as usize },
9usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(specification)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).checksum as *const _ as usize },
10usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(checksum)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature1 as *const _ as usize },
11usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(feature1)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature2 as *const _ as usize },
12usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(feature2)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature3 as *const _ as usize },
13usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(feature3)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature4 as *const _ as usize },
14usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(feature4)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpf_intel)).feature5 as *const _ as usize },
15usize,
concat!(
"Alignment of field: ",
stringify!(mpf_intel),
"::",
stringify!(feature5)
)
);
}
impl Clone for mpf_intel {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_table {
pub signature: [::std::os::raw::c_char; 4usize],
pub length: ::std::os::raw::c_ushort,
pub spec: ::std::os::raw::c_char,
pub checksum: ::std::os::raw::c_char,
pub oem: [::std::os::raw::c_char; 8usize],
pub productid: [::std::os::raw::c_char; 12usize],
pub oemptr: ::std::os::raw::c_uint,
pub oemsize: ::std::os::raw::c_ushort,
pub oemcount: ::std::os::raw::c_ushort,
pub lapic: ::std::os::raw::c_uint,
pub reserved: ::std::os::raw::c_uint,
}
#[test]
fn bindgen_test_layout_mpc_table() {
assert_eq!(
::std::mem::size_of::<mpc_table>(),
44usize,
concat!("Size of: ", stringify!(mpc_table))
);
assert_eq!(
::std::mem::align_of::<mpc_table>(),
4usize,
concat!("Alignment of ", stringify!(mpc_table))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).signature as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(signature)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).length as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(length)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).spec as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(spec)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).checksum as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(checksum)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oem as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(oem)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).productid as *const _ as usize },
16usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(productid)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oemptr as *const _ as usize },
28usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(oemptr)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oemsize as *const _ as usize },
32usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(oemsize)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).oemcount as *const _ as usize },
34usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(oemcount)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).lapic as *const _ as usize },
36usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(lapic)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_table)).reserved as *const _ as usize },
40usize,
concat!(
"Alignment of field: ",
stringify!(mpc_table),
"::",
stringify!(reserved)
)
);
}
impl Clone for mpc_table {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_cpu {
pub type_: ::std::os::raw::c_uchar,
pub apicid: ::std::os::raw::c_uchar,
pub apicver: ::std::os::raw::c_uchar,
pub cpuflag: ::std::os::raw::c_uchar,
pub cpufeature: ::std::os::raw::c_uint,
pub featureflag: ::std::os::raw::c_uint,
pub reserved: [::std::os::raw::c_uint; 2usize],
}
#[test]
fn bindgen_test_layout_mpc_cpu() {
assert_eq!(
::std::mem::size_of::<mpc_cpu>(),
20usize,
concat!("Size of: ", stringify!(mpc_cpu))
);
assert_eq!(
::std::mem::align_of::<mpc_cpu>(),
4usize,
concat!("Alignment of ", stringify!(mpc_cpu))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(type_)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).apicid as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(apicid)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).apicver as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(apicver)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).cpuflag as *const _ as usize },
3usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(cpuflag)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).cpufeature as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(cpufeature)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).featureflag as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(featureflag)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_cpu)).reserved as *const _ as usize },
12usize,
concat!(
"Alignment of field: ",
stringify!(mpc_cpu),
"::",
stringify!(reserved)
)
);
}
impl Clone for mpc_cpu {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_bus {
pub type_: ::std::os::raw::c_uchar,
pub busid: ::std::os::raw::c_uchar,
pub bustype: [::std::os::raw::c_uchar; 6usize],
}
#[test]
fn bindgen_test_layout_mpc_bus() {
assert_eq!(
::std::mem::size_of::<mpc_bus>(),
8usize,
concat!("Size of: ", stringify!(mpc_bus))
);
assert_eq!(
::std::mem::align_of::<mpc_bus>(),
1usize,
concat!("Alignment of ", stringify!(mpc_bus))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_bus)).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_bus),
"::",
stringify!(type_)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_bus)).busid as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
stringify!(mpc_bus),
"::",
stringify!(busid)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_bus)).bustype as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(mpc_bus),
"::",
stringify!(bustype)
)
);
}
impl Clone for mpc_bus {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_ioapic {
pub type_: ::std::os::raw::c_uchar,
pub apicid: ::std::os::raw::c_uchar,
pub apicver: ::std::os::raw::c_uchar,
pub flags: ::std::os::raw::c_uchar,
pub apicaddr: ::std::os::raw::c_uint,
}
#[test]
fn bindgen_test_layout_mpc_ioapic() {
assert_eq!(
::std::mem::size_of::<mpc_ioapic>(),
8usize,
concat!("Size of: ", stringify!(mpc_ioapic))
);
assert_eq!(
::std::mem::align_of::<mpc_ioapic>(),
4usize,
concat!("Alignment of ", stringify!(mpc_ioapic))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_ioapic),
"::",
stringify!(type_)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).apicid as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
stringify!(mpc_ioapic),
"::",
stringify!(apicid)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).apicver as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(mpc_ioapic),
"::",
stringify!(apicver)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).flags as *const _ as usize },
3usize,
concat!(
"Alignment of field: ",
stringify!(mpc_ioapic),
"::",
stringify!(flags)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_ioapic)).apicaddr as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpc_ioapic),
"::",
stringify!(apicaddr)
)
);
}
impl Clone for mpc_ioapic {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_intsrc {
pub type_: ::std::os::raw::c_uchar,
pub irqtype: ::std::os::raw::c_uchar,
pub irqflag: ::std::os::raw::c_ushort,
pub srcbus: ::std::os::raw::c_uchar,
pub srcbusirq: ::std::os::raw::c_uchar,
pub dstapic: ::std::os::raw::c_uchar,
pub dstirq: ::std::os::raw::c_uchar,
}
#[test]
fn bindgen_test_layout_mpc_intsrc() {
assert_eq!(
::std::mem::size_of::<mpc_intsrc>(),
8usize,
concat!("Size of: ", stringify!(mpc_intsrc))
);
assert_eq!(
::std::mem::align_of::<mpc_intsrc>(),
2usize,
concat!("Alignment of ", stringify!(mpc_intsrc))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(type_)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).irqtype as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(irqtype)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).irqflag as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(irqflag)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).srcbus as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(srcbus)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).srcbusirq as *const _ as usize },
5usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(srcbusirq)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).dstapic as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(dstapic)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_intsrc)).dstirq as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
stringify!(mpc_intsrc),
"::",
stringify!(dstirq)
)
);
}
impl Clone for mpc_intsrc {
fn clone(&self) -> Self {
*self
}
}
pub const mp_irq_source_types_mp_INT: mp_irq_source_types = 0;
pub const mp_irq_source_types_mp_NMI: mp_irq_source_types = 1;
pub const mp_irq_source_types_mp_SMI: mp_irq_source_types = 2;
pub const mp_irq_source_types_mp_ExtINT: mp_irq_source_types = 3;
pub type mp_irq_source_types = ::std::os::raw::c_uint;
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_lintsrc {
pub type_: ::std::os::raw::c_uchar,
pub irqtype: ::std::os::raw::c_uchar,
pub irqflag: ::std::os::raw::c_ushort,
pub srcbusid: ::std::os::raw::c_uchar,
pub srcbusirq: ::std::os::raw::c_uchar,
pub destapic: ::std::os::raw::c_uchar,
pub destapiclint: ::std::os::raw::c_uchar,
}
#[test]
fn bindgen_test_layout_mpc_lintsrc() {
assert_eq!(
::std::mem::size_of::<mpc_lintsrc>(),
8usize,
concat!("Size of: ", stringify!(mpc_lintsrc))
);
assert_eq!(
::std::mem::align_of::<mpc_lintsrc>(),
2usize,
concat!("Alignment of ", stringify!(mpc_lintsrc))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).type_ as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(type_)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).irqtype as *const _ as usize },
1usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(irqtype)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).irqflag as *const _ as usize },
2usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(irqflag)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).srcbusid as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(srcbusid)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).srcbusirq as *const _ as usize },
5usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(srcbusirq)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).destapic as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(destapic)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_lintsrc)).destapiclint as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
stringify!(mpc_lintsrc),
"::",
stringify!(destapiclint)
)
);
}
impl Clone for mpc_lintsrc {
fn clone(&self) -> Self {
*self
}
}
#[repr(C)]
#[derive(Debug, Default, Copy)]
pub struct mpc_oemtable {
pub signature: [::std::os::raw::c_char; 4usize],
pub length: ::std::os::raw::c_ushort,
pub rev: ::std::os::raw::c_char,
pub checksum: ::std::os::raw::c_char,
pub mpc: [::std::os::raw::c_char; 8usize],
}
#[test]
fn bindgen_test_layout_mpc_oemtable() {
assert_eq!(
::std::mem::size_of::<mpc_oemtable>(),
16usize,
concat!("Size of: ", stringify!(mpc_oemtable))
);
assert_eq!(
::std::mem::align_of::<mpc_oemtable>(),
2usize,
concat!("Alignment of ", stringify!(mpc_oemtable))
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).signature as *const _ as usize },
0usize,
concat!(
"Alignment of field: ",
stringify!(mpc_oemtable),
"::",
stringify!(signature)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).length as *const _ as usize },
4usize,
concat!(
"Alignment of field: ",
stringify!(mpc_oemtable),
"::",
stringify!(length)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).rev as *const _ as usize },
6usize,
concat!(
"Alignment of field: ",
stringify!(mpc_oemtable),
"::",
stringify!(rev)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).checksum as *const _ as usize },
7usize,
concat!(
"Alignment of field: ",
stringify!(mpc_oemtable),
"::",
stringify!(checksum)
)
);
assert_eq!(
unsafe { &(*(0 as *const mpc_oemtable)).mpc as *const _ as usize },
8usize,
concat!(
"Alignment of field: ",
stringify!(mpc_oemtable),
"::",
stringify!(mpc)
)
);
}
impl Clone for mpc_oemtable {
fn clone(&self) -> Self {
*self
}
}
pub const mp_bustype_MP_BUS_ISA: mp_bustype = 1;
pub const mp_bustype_MP_BUS_EISA: mp_bustype = 2;
pub const mp_bustype_MP_BUS_PCI: mp_bustype = 3;
pub type mp_bustype = ::std::os::raw::c_uint;

View File

@ -0,0 +1,543 @@
// 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 THIRD-PARTY 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;