Compare commits
11 Commits
db650f470f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
cb006a8df8 | ||
|
|
ce079a1067 | ||
|
|
0bfb86a2b4 | ||
|
|
baeed3320f | ||
|
|
525b6cbf0d | ||
|
|
33c511dcb0 | ||
|
|
53a31749b4 | ||
|
|
a355e91c6e | ||
|
|
294e4f719d | ||
|
|
1606184551 | ||
|
|
a0188056f0 |
@@ -47,6 +47,27 @@ pub fn _print(args: ::core::fmt::Arguments) {
|
||||
});
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_byte(byte: u8) {
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
SERIAL1.lock().send(byte);
|
||||
});
|
||||
}
|
||||
|
||||
#[inline(always)]
|
||||
pub fn write_bytes(bytes: &[u8]) {
|
||||
use x86_64::instructions::interrupts;
|
||||
|
||||
interrupts::without_interrupts(|| {
|
||||
let mut serial = SERIAL1.lock();
|
||||
for &b in bytes {
|
||||
serial.send(b);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
#[macro_export]
|
||||
macro_rules! print {
|
||||
($($arg:tt)*) => {
|
||||
|
||||
@@ -1 +1,2 @@
|
||||
pub mod vcpu;
|
||||
pub mod vmcb;
|
||||
|
||||
@@ -3,18 +3,32 @@ use x86_64::structures::paging::{FrameAllocator, Size4KiB};
|
||||
|
||||
use crate::{
|
||||
error, info,
|
||||
vmm::{x86_64::common, VCpu},
|
||||
vmm::{
|
||||
x86_64::{amd::vmcb::Vmcb, common},
|
||||
VCpu,
|
||||
},
|
||||
};
|
||||
|
||||
pub struct AMDVCpu;
|
||||
pub struct AMDVCpu {
|
||||
vmcb: Vmcb,
|
||||
}
|
||||
|
||||
impl AMDVCpu {
|
||||
pub fn setup(&mut self) -> Result<(), &'static str> {
|
||||
info!("Setting up AMD VCPU");
|
||||
|
||||
let raw_vmcb = self.vmcb.get_raw_vmcb();
|
||||
raw_vmcb.set_intercept_hlt(true);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl VCpu for AMDVCpu {
|
||||
fn run(
|
||||
&mut self,
|
||||
_frame_allocator: &mut dyn FrameAllocator<Size4KiB>,
|
||||
) -> Result<(), &'static str> {
|
||||
info!("VCpu on AMD");
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
@@ -39,7 +53,7 @@ impl VCpu for AMDVCpu {
|
||||
unimplemented!("AMDVCpu::get_guest_memory_size is not implemented yet")
|
||||
}
|
||||
|
||||
fn new(_frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str>
|
||||
fn new(frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str>
|
||||
where
|
||||
Self: Sized,
|
||||
{
|
||||
@@ -47,7 +61,9 @@ impl VCpu for AMDVCpu {
|
||||
efer |= 1 << 12;
|
||||
common::write_msr(0xc000_0080, efer);
|
||||
|
||||
Ok(AMDVCpu)
|
||||
Ok(AMDVCpu {
|
||||
vmcb: Vmcb::new(frame_allocator)?,
|
||||
})
|
||||
}
|
||||
|
||||
fn is_supported() -> bool
|
||||
|
||||
241
nel_os_kernel/src/vmm/x86_64/amd/vmcb.rs
Normal file
241
nel_os_kernel/src/vmm/x86_64/amd/vmcb.rs
Normal file
@@ -0,0 +1,241 @@
|
||||
#![allow(non_snake_case)]
|
||||
|
||||
use modular_bitfield::{bitfield, prelude::*};
|
||||
use x86_64::structures::paging::{FrameAllocator, PhysFrame, Size4KiB};
|
||||
|
||||
pub struct Vmcb {
|
||||
pub frame: PhysFrame,
|
||||
}
|
||||
|
||||
impl Vmcb {
|
||||
pub fn new(frame_allocator: &mut impl FrameAllocator<Size4KiB>) -> Result<Self, &'static str> {
|
||||
let frame = frame_allocator
|
||||
.allocate_frame()
|
||||
.ok_or("Failed to allocate VMCB frame")?;
|
||||
Ok(Vmcb { frame })
|
||||
}
|
||||
|
||||
pub fn get_raw_vmcb(&self) -> &mut RawVmcb {
|
||||
let ptr = self.frame.start_address().as_u64() as *mut RawVmcb;
|
||||
unsafe { &mut *ptr }
|
||||
}
|
||||
}
|
||||
|
||||
#[bitfield]
|
||||
pub struct RawVmcb {
|
||||
// 000h
|
||||
pub intercept_cr_read: B16,
|
||||
pub intercept_cr_write: B16,
|
||||
// 004h
|
||||
pub intercept_dr_read: B16,
|
||||
pub intercept_dr_write: B16,
|
||||
// 008h
|
||||
pub intercept_exceptions: B32,
|
||||
// 00Ch
|
||||
pub intercept_intr: bool,
|
||||
pub intercept_nmi: bool,
|
||||
pub intercept_smi: bool,
|
||||
pub intercept_init: bool,
|
||||
pub intercept_vintr: bool,
|
||||
pub intercept_cr0_write_ts_or_mp: bool,
|
||||
pub intercept_read_idtr: bool,
|
||||
pub intercept_read_gdtr: bool,
|
||||
pub intercept_read_ldtr: bool,
|
||||
pub intercept_read_tr: bool,
|
||||
pub intercept_write_idtr: bool,
|
||||
pub intercept_write_gdtr: bool,
|
||||
pub intercept_write_ldtr: bool,
|
||||
pub intercept_write_tr: bool,
|
||||
pub intercept_rdtsc: bool,
|
||||
pub intercept_rdpmc: bool,
|
||||
pub intercept_pushf: bool,
|
||||
pub intercept_popf: bool,
|
||||
pub intercept_cpuid: bool,
|
||||
pub intercept_rsm: bool,
|
||||
pub intercept_iret: bool,
|
||||
pub intercept_int_n: bool,
|
||||
pub intercept_invd: bool,
|
||||
pub intercept_pause: bool,
|
||||
pub intercept_hlt: bool,
|
||||
pub intercept_invlpg: bool,
|
||||
pub intercept_invlpga: bool,
|
||||
pub intercept_ioio_prot: bool,
|
||||
pub intercept_msr_prot: bool,
|
||||
pub intercept_task_switch: bool,
|
||||
pub intercept_ferr_freeze: bool,
|
||||
pub intercept_shutdown: bool,
|
||||
// 010h
|
||||
pub intercept_vmrun: bool,
|
||||
pub intercept_vmcall: bool,
|
||||
pub intercept_vmload: bool,
|
||||
pub intercept_vmsave: bool,
|
||||
pub intercept_stgi: bool,
|
||||
pub intercept_clgi: bool,
|
||||
pub intercept_skinit: bool,
|
||||
pub intercept_rdtscp: bool,
|
||||
pub intercept_icebp: bool,
|
||||
pub intercept_wbinvd_and_wbnoinvd: bool,
|
||||
pub intercept_monitor_and_monitorx: bool,
|
||||
pub intercept_mwait_and_mwaitx_unconditionally: bool,
|
||||
pub intercept_mwait_and_mwaitx: bool,
|
||||
pub intercept_xsetbv: bool,
|
||||
pub intercept_rdpru: bool,
|
||||
pub intercept_write_efer_after_guest_inst_finish: bool,
|
||||
pub intercept_write_cr0_after_guest_inst_finish: B16,
|
||||
// 014h
|
||||
pub intercept_all_invlpgb: bool,
|
||||
pub intercept_illegally_specified_invlpgb: bool,
|
||||
pub intercept_invpcid: bool,
|
||||
pub intercept_mcommit: bool,
|
||||
pub intercept_tlbsync: bool,
|
||||
pub intercept_bus_lock: bool,
|
||||
pub intercept_idle_hlt: bool,
|
||||
#[skip]
|
||||
__: B25,
|
||||
// 018h-03Bh
|
||||
#[skip]
|
||||
__: B128,
|
||||
#[skip]
|
||||
__: B128,
|
||||
#[skip]
|
||||
__: B32,
|
||||
// 03Ch
|
||||
pub pause_filter_threshold: B16,
|
||||
// 03Eh
|
||||
pub pause_filter_count: B16,
|
||||
// 040h
|
||||
pub iopm_base_physical_address: B64,
|
||||
// 048h
|
||||
pub msrpm_base_physical_address: B64,
|
||||
// 050h
|
||||
pub tsc_offset: B64,
|
||||
// 058h
|
||||
pub guest_asid: B32,
|
||||
pub tlb_control: TlbControl,
|
||||
pub allow_larger_rap: bool,
|
||||
pub clear_rap_on_vmrun: bool,
|
||||
#[skip]
|
||||
__: B22,
|
||||
// 060h
|
||||
pub v_tpr: B8,
|
||||
pub v_irq: bool,
|
||||
pub vgif: bool,
|
||||
pub v_nmi: bool,
|
||||
pub v_nmi_mask: bool,
|
||||
#[skip]
|
||||
__: B3,
|
||||
pub v_intr_prio: B4,
|
||||
pub v_ign_tpr: bool,
|
||||
#[skip]
|
||||
__: B3,
|
||||
pub v_intr_masking: bool,
|
||||
pub amd_virtual_gif: bool,
|
||||
pub v_nmi_enable: bool,
|
||||
#[skip]
|
||||
__: B3,
|
||||
pub x2avic_enable: bool,
|
||||
pub avic_enable: bool,
|
||||
pub v_intr_vector: B8,
|
||||
#[skip]
|
||||
__: B24,
|
||||
// 068h
|
||||
pub interrupt_shadow: bool,
|
||||
pub guest_interrupt_mask: bool,
|
||||
#[skip]
|
||||
__: B62,
|
||||
// 070h
|
||||
pub exit_code: B64,
|
||||
// 078h
|
||||
pub exit_info1: B64,
|
||||
// 080h
|
||||
pub exit_info2: B64,
|
||||
// 088h
|
||||
pub exit_int_info: B64,
|
||||
// 090h
|
||||
pub np_enable: bool,
|
||||
pub enable_sev: bool,
|
||||
pub enable_encrypted_state: bool,
|
||||
pub guest_mode_execution_trap: bool,
|
||||
pub sss_check_enable: bool,
|
||||
pub virtual_transparent_encryption: bool,
|
||||
pub enable_read_only_guest_page_table: bool,
|
||||
pub enable_invlpgb_and_tlbsync: bool,
|
||||
#[skip]
|
||||
__: B56,
|
||||
// 098h
|
||||
pub avic_apic_bar: B52,
|
||||
#[skip]
|
||||
__: B12,
|
||||
// 0A0h
|
||||
pub ghcb_gpa: B64,
|
||||
// 0A8h
|
||||
pub event_injection: B64,
|
||||
// 0B0h
|
||||
pub n_cr3: B64,
|
||||
// 0D8h
|
||||
pub lbr_virtualization_enable: bool,
|
||||
pub vmload_vmsave_virtualization_enable: bool,
|
||||
pub ibs_virtualization_enable: bool,
|
||||
pub pmc_virtualization_enable: bool,
|
||||
#[skip]
|
||||
__: B60,
|
||||
// 0C0h
|
||||
pub vmcb_clean_bits: B32,
|
||||
#[skip]
|
||||
__: B32,
|
||||
// 0C8h
|
||||
pub next_rip: B64,
|
||||
// 0D0h
|
||||
pub fetched_bytes: B8,
|
||||
pub gutest_instruction_bytes: B120,
|
||||
// 0E0h
|
||||
pub avic_apic_backing_page_pointer: B52,
|
||||
#[skip]
|
||||
__: B12,
|
||||
// 0E8-0EFh Reserved
|
||||
#[skip]
|
||||
__: B64,
|
||||
#[skip]
|
||||
__: B64,
|
||||
#[skip]
|
||||
__: B64,
|
||||
#[skip]
|
||||
__: B64,
|
||||
// 0F0h
|
||||
#[skip]
|
||||
__: B12,
|
||||
pub avic_logical_table_pointer: B40,
|
||||
#[skip]
|
||||
__: B12,
|
||||
// 0F8h
|
||||
pub avic_physical_max_index: B12,
|
||||
pub avic_physical_table_pointer: B40,
|
||||
#[skip]
|
||||
__: B12,
|
||||
// 100h-107h Reserved
|
||||
#[skip]
|
||||
__: B64,
|
||||
// 108h
|
||||
#[skip]
|
||||
__: B12,
|
||||
pub vmsa_pointer: B40,
|
||||
#[skip]
|
||||
__: B12,
|
||||
// 110h
|
||||
pub vmgexit_rax: B64,
|
||||
// 118h
|
||||
pub vmgexit_cpl: B8,
|
||||
}
|
||||
|
||||
#[derive(Specifier, Debug, Clone, Copy, PartialEq, Eq)]
|
||||
#[repr(u8)]
|
||||
pub enum TlbControl {
|
||||
DoNothing = 0,
|
||||
FlushAll = 1,
|
||||
_RESERVED1 = 2,
|
||||
FlushGuest = 3,
|
||||
_RESERVED2 = 4,
|
||||
FlushHost = 5,
|
||||
_RESERVED3 = 6,
|
||||
FlushGuestNonGlobal = 7,
|
||||
}
|
||||
@@ -28,7 +28,8 @@ pub struct XCR0 {
|
||||
pub xtilecfg: bool,
|
||||
pub xtiledata: bool,
|
||||
pub apx: bool,
|
||||
_reserved: B44,
|
||||
#[skip]
|
||||
__: B44,
|
||||
}
|
||||
|
||||
pub fn set_xcr(vcpu: &mut IntelVCpu, index: u32, xcr: u64) -> Result<(), &'static str> {
|
||||
|
||||
@@ -1,10 +1,14 @@
|
||||
use x86::vmx::{self, vmcs};
|
||||
use x86::{
|
||||
io::inb,
|
||||
vmx::{self, vmcs},
|
||||
};
|
||||
use x86_64::structures::paging::{FrameAllocator, PhysFrame, Size4KiB};
|
||||
|
||||
use super::qual::QualIo;
|
||||
use crate::{
|
||||
info,
|
||||
interrupt::subscriber::InterruptContext,
|
||||
serial,
|
||||
vmm::x86_64::intel::{
|
||||
register::GuestRegisters, vmcs::controls::EntryIntrInfo, vmread, vmwrite,
|
||||
},
|
||||
@@ -19,7 +23,7 @@ pub fn vmm_interrupt_subscriber(vcpu_ptr: *mut core::ffi::c_void, context: &Inte
|
||||
|
||||
if 0x20 <= context.vector && context.vector <= 0x20 + 16 {
|
||||
let irq = context.vector - 0x20;
|
||||
vcpu.pending_irq |= 1 << irq;
|
||||
vcpu.pic.pending_irq |= 1 << irq;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -37,6 +41,12 @@ pub enum ReadSel {
|
||||
Isr,
|
||||
}
|
||||
|
||||
#[derive(Debug, Clone, Copy, Default)]
|
||||
pub struct Serial {
|
||||
pub ier: u8,
|
||||
pub mcr: u8,
|
||||
}
|
||||
|
||||
pub struct Pic {
|
||||
pub primary_mask: u8,
|
||||
pub secondary_mask: u8,
|
||||
@@ -50,6 +60,8 @@ pub struct Pic {
|
||||
pub secondary_isr: u8,
|
||||
pub primary_read_sel: ReadSel,
|
||||
pub secondary_read_sel: ReadSel,
|
||||
pub serial: Serial,
|
||||
pub pending_irq: u16,
|
||||
}
|
||||
|
||||
impl Pic {
|
||||
@@ -67,6 +79,8 @@ impl Pic {
|
||||
secondary_isr: 0,
|
||||
primary_read_sel: ReadSel::Irr,
|
||||
secondary_read_sel: ReadSel::Irr,
|
||||
serial: Serial::default(),
|
||||
pending_irq: 0,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -82,11 +96,8 @@ impl Pic {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn inject_external_interrupt(
|
||||
&mut self,
|
||||
pending_irq: &mut u16,
|
||||
) -> Result<bool, &'static str> {
|
||||
let pending = *pending_irq;
|
||||
pub fn inject_external_interrupt(&mut self) -> Result<bool, &'static str> {
|
||||
let pending = self.pending_irq;
|
||||
|
||||
if pending == 0 {
|
||||
return Ok(false);
|
||||
@@ -148,7 +159,7 @@ impl Pic {
|
||||
u32::from(interrupt_info) as u64,
|
||||
)?;
|
||||
|
||||
*pending_irq &= !irq_bit;
|
||||
self.pending_irq &= !irq_bit;
|
||||
return Ok(true);
|
||||
}
|
||||
|
||||
@@ -188,6 +199,7 @@ impl Pic {
|
||||
0x20..=0x21 => self.handle_pic_in(regs, qual),
|
||||
0xA0..=0xA1 => self.handle_pic_in(regs, qual),
|
||||
0x0070..=0x0071 => regs.rax = 0,
|
||||
0x03F8..=0x03FF => self.handle_serial_in(regs, qual),
|
||||
_ => regs.rax = 0,
|
||||
}
|
||||
}
|
||||
@@ -198,11 +210,56 @@ impl Pic {
|
||||
0xC000..=0xCFFF => {} //ignore
|
||||
0x20..=0x21 => self.handle_pic_out(regs, qual),
|
||||
0xA0..=0xA1 => self.handle_pic_out(regs, qual),
|
||||
0x03F8..=0x03FF => self.handle_serial_out(regs, qual),
|
||||
0x0070..=0x0071 => {} //ignore
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_serial_in(&self, regs: &mut GuestRegisters, qual: QualIo) {
|
||||
match qual.port() {
|
||||
0x3F8 => regs.rax = unsafe { inb(qual.port()).into() },
|
||||
0x3F9 => regs.rax = self.serial.ier as u64,
|
||||
0x3FA => {} //regs.rax = 0, // unsafe { inb(qual.port()).into() },
|
||||
0x3FB => {} //regs.rax = 0,
|
||||
0x3FC => {} //regs.rax = 0, //self.serial.mcr as u64,
|
||||
0x3FD => {
|
||||
if qual.size() == 1 {
|
||||
regs.rax = 0x60
|
||||
}
|
||||
}
|
||||
0x3FE => {
|
||||
if qual.size() == 1 {
|
||||
regs.rax = 0xb0
|
||||
}
|
||||
}
|
||||
0x3FF => {} //regs.rax = 0,
|
||||
_ => {
|
||||
panic!("Serial in: invalid port: {:#x}", qual.port());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_serial_out(&mut self, regs: &mut GuestRegisters, qual: QualIo) {
|
||||
match qual.port() {
|
||||
0x3F8 => serial::write_byte(regs.rax as u8),
|
||||
0x3F9 => {
|
||||
self.serial.ier = regs.rax as u8;
|
||||
if regs.rax & 0b10 != 0 {
|
||||
self.pending_irq |= 1 << 4;
|
||||
}
|
||||
}
|
||||
0x3FA => {}
|
||||
0x3FB => {}
|
||||
0x3FC => self.serial.mcr = regs.rax as u8,
|
||||
0x3FD => {}
|
||||
0x3FF => {}
|
||||
_ => {
|
||||
panic!("Serial out: invalid port: {:#x}", qual.port());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fn handle_pic_in(&self, regs: &mut GuestRegisters, qual: QualIo) {
|
||||
match qual.port() {
|
||||
0x20 => {
|
||||
@@ -324,8 +381,8 @@ impl IOBitmap {
|
||||
core::ptr::write_bytes(bitmap_b_addr as *mut u8, u8::MAX, 4096);
|
||||
}
|
||||
|
||||
self.set_io_ports(0x02F8..=0x03FF);
|
||||
self.set_io_ports(0x0040..=0x0047);
|
||||
//self.set_io_ports(0x02F8..=0x03EF);
|
||||
|
||||
vmwrite(vmcs::control::IO_BITMAP_A_ADDR_FULL, bitmap_a_addr as u64)?;
|
||||
vmwrite(vmcs::control::IO_BITMAP_B_ADDR_FULL, bitmap_b_addr as u64)?;
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
use core::convert::TryFrom;
|
||||
use core::fmt::Debug;
|
||||
|
||||
use modular_bitfield::prelude::{B1, B16, B32, B4, B8};
|
||||
use modular_bitfield::prelude::{B1, B16, B3, B32, B4, B9};
|
||||
use modular_bitfield::{bitfield, Specifier};
|
||||
|
||||
#[repr(u8)]
|
||||
@@ -113,12 +113,12 @@ pub struct QualCr {
|
||||
#[repr(u64)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct QualIo {
|
||||
pub size: B4,
|
||||
pub size: B3,
|
||||
pub direction: B1,
|
||||
pub string: B1,
|
||||
pub rep: B1,
|
||||
pub operand_encoding: B1,
|
||||
_reserved1: B8,
|
||||
_reserved1: B9,
|
||||
pub port: B16,
|
||||
_reserved2: B32,
|
||||
}
|
||||
|
||||
@@ -52,9 +52,8 @@ pub struct IntelVCpu {
|
||||
pub host_msr: ShadowMsr,
|
||||
pub guest_msr: ShadowMsr,
|
||||
pub ia32e_enabled: bool,
|
||||
pic: super::io::Pic,
|
||||
pub pic: super::io::Pic,
|
||||
io_bitmap: IOBitmap,
|
||||
pub pending_irq: u16,
|
||||
pub host_xcr0: u64,
|
||||
pub guest_xcr0: XCR0,
|
||||
}
|
||||
@@ -87,10 +86,7 @@ impl IntelVCpu {
|
||||
|
||||
match exit_reason {
|
||||
VmxExitReason::HLT => {
|
||||
let injected = self
|
||||
.pic
|
||||
.inject_external_interrupt(&mut self.pending_irq)
|
||||
.unwrap_or(false);
|
||||
let injected = self.pic.inject_external_interrupt().unwrap_or(false);
|
||||
|
||||
if !injected {
|
||||
unsafe {
|
||||
@@ -151,7 +147,7 @@ impl IntelVCpu {
|
||||
asm!("cli");
|
||||
}
|
||||
|
||||
self.pic.inject_external_interrupt(&mut self.pending_irq)?;
|
||||
self.pic.inject_external_interrupt()?;
|
||||
}
|
||||
VmxExitReason::EPT_VIOLATION => {
|
||||
let guest_address = vmread(vmcs::ro::GUEST_PHYSICAL_ADDR_FULL)?;
|
||||
@@ -916,7 +912,6 @@ impl VCpu for IntelVCpu {
|
||||
ia32e_enabled: false,
|
||||
pic: super::io::Pic::new(),
|
||||
io_bitmap: IOBitmap::new(frame_allocator),
|
||||
pending_irq: 0,
|
||||
host_xcr0: 0,
|
||||
guest_xcr0: XCR0::new(),
|
||||
})
|
||||
|
||||
@@ -9,14 +9,17 @@ use crate::vmm::x86_64::intel::vmcs;
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PinBasedVmExecutionControls {
|
||||
pub external_interrupt_exiting: bool,
|
||||
_reserved1: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub interrupt_window_exiting: bool,
|
||||
pub nmi_exiting: bool,
|
||||
_reserved2: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub virtual_nmi: bool,
|
||||
pub activate_vmx_preemption_timer: bool,
|
||||
pub process_posted_interrupts: bool,
|
||||
_reserved3: B24,
|
||||
#[skip]
|
||||
__: B24,
|
||||
}
|
||||
|
||||
impl PinBasedVmExecutionControls {
|
||||
@@ -36,21 +39,26 @@ impl PinBasedVmExecutionControls {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PrimaryProcessorBasedVmExecutionControls {
|
||||
_reserved1: B2,
|
||||
#[skip]
|
||||
__: B2,
|
||||
pub interrupt_window: bool,
|
||||
pub tsc_offsetting: bool,
|
||||
_reserved2: B3,
|
||||
#[skip]
|
||||
__: B3,
|
||||
pub hlt: bool,
|
||||
_reserved3: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub invlpg: bool,
|
||||
pub mwait: bool,
|
||||
pub rdpmc: bool,
|
||||
pub rdtsc: bool,
|
||||
_reserved4: B2,
|
||||
#[skip]
|
||||
__: B2,
|
||||
pub cr3load: bool,
|
||||
pub cr3store: bool,
|
||||
pub activate_teritary_controls: bool,
|
||||
_reserved5: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub cr8load: bool,
|
||||
pub cr8store: bool,
|
||||
pub use_tpr_shadow: bool,
|
||||
@@ -58,7 +66,8 @@ pub struct PrimaryProcessorBasedVmExecutionControls {
|
||||
pub mov_dr: bool,
|
||||
pub unconditional_io: bool,
|
||||
pub use_io_bitmap: bool,
|
||||
_reserved6: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub monitor_trap: bool,
|
||||
pub use_msr_bitmap: bool,
|
||||
pub monitor: bool,
|
||||
@@ -114,7 +123,8 @@ pub struct SecondaryProcessorBasedVmExecutionControls {
|
||||
pub enable_enclv: bool,
|
||||
pub vmm_buslock_detect: bool,
|
||||
pub instruction_timeout: bool,
|
||||
_reserved: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
}
|
||||
|
||||
impl SecondaryProcessorBasedVmExecutionControls {
|
||||
@@ -134,13 +144,16 @@ impl SecondaryProcessorBasedVmExecutionControls {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct EntryControls {
|
||||
_reserved1: B2,
|
||||
#[skip]
|
||||
__: B2,
|
||||
pub load_debug_controls: bool,
|
||||
_reserved2: B6,
|
||||
#[skip]
|
||||
__: B6,
|
||||
pub ia32e_mode_guest: bool,
|
||||
pub entry_smm: bool,
|
||||
pub deactivate_dualmonitor: bool,
|
||||
_reserved3: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub load_perf_global_ctrl: bool,
|
||||
pub load_ia32_pat: bool,
|
||||
pub load_ia32_efer: bool,
|
||||
@@ -151,7 +164,8 @@ pub struct EntryControls {
|
||||
pub load_cet_state: bool,
|
||||
pub load_guest_lbr_ctl: bool,
|
||||
pub load_pkrs: bool,
|
||||
_reserved4: B9,
|
||||
#[skip]
|
||||
__: B9,
|
||||
}
|
||||
|
||||
impl EntryControls {
|
||||
@@ -171,15 +185,20 @@ impl EntryControls {
|
||||
#[repr(u32)]
|
||||
#[derive(Debug, Clone, Copy)]
|
||||
pub struct PrimaryExitControls {
|
||||
_reserved1: B2,
|
||||
#[skip]
|
||||
__: B2,
|
||||
pub save_debug: bool,
|
||||
_reserved2: B6,
|
||||
#[skip]
|
||||
__: B6,
|
||||
pub host_addr_space_size: bool,
|
||||
_reserved3: B3,
|
||||
#[skip]
|
||||
__: B3,
|
||||
pub load_perf_global_ctrl: bool,
|
||||
_reserved4: B1,
|
||||
#[skip]
|
||||
__: B1,
|
||||
pub ack_interrupt_onexit: bool,
|
||||
_reserved5: B2,
|
||||
#[skip]
|
||||
__: B2,
|
||||
pub save_ia32_pat: bool,
|
||||
pub load_ia32_pat: bool,
|
||||
pub save_ia32_efer: bool,
|
||||
@@ -216,6 +235,7 @@ pub struct EntryIntrInfo {
|
||||
pub vector: B8,
|
||||
pub typ: B3,
|
||||
pub ec_available: bool,
|
||||
_reserved: B19,
|
||||
#[skip]
|
||||
__: B19,
|
||||
pub valid: bool,
|
||||
}
|
||||
|
||||
@@ -26,14 +26,16 @@ pub struct SegmentRights {
|
||||
pub desc_type: DescriptorType,
|
||||
pub dpl: B2,
|
||||
pub present: bool,
|
||||
_reserved: B4,
|
||||
#[skip]
|
||||
__: B4,
|
||||
pub avl: bool,
|
||||
pub long: bool,
|
||||
pub db: bool,
|
||||
#[bits = 1]
|
||||
pub granularity: Granularity,
|
||||
pub unusable: bool,
|
||||
_reserved2: B15,
|
||||
#[skip]
|
||||
__: B15,
|
||||
}
|
||||
|
||||
impl Default for SegmentRights {
|
||||
|
||||
Reference in New Issue
Block a user