From 2f698eb69b2a133ee1097f1e0352e494dea5a823 Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Sat, 4 Apr 2026 17:24:02 -0700 Subject: [PATCH 1/3] fix(x86): define CR0, CR4, and EFER bitflags as u64 Signed-off-by: Changyuan Lyu --- alioth/src/arch/x86_64/msr.rs | 2 +- alioth/src/arch/x86_64/reg.rs | 4 ++-- alioth/src/loader/firmware/firmware_x86_64.rs | 2 +- alioth/src/loader/linux/linux_x86_64.rs | 6 +++--- alioth/src/loader/xen/xen.rs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/alioth/src/arch/x86_64/msr.rs b/alioth/src/arch/x86_64/msr.rs index 61e37a7b..935a92e7 100644 --- a/alioth/src/arch/x86_64/msr.rs +++ b/alioth/src/arch/x86_64/msr.rs @@ -29,7 +29,7 @@ pub const IA32_TSC_AUX: u32 = 0xc000_0103; pub const IA32_MISC_ENABLE: u32 = 0x0000_01a0; bitflags! { - pub struct Efer(u32) { + pub struct Efer(u64) { /// SYSCALL enable SCE = 1 << 0; /// IA-32e mode enable diff --git a/alioth/src/arch/x86_64/reg.rs b/alioth/src/arch/x86_64/reg.rs index e167bfe2..3cdf9930 100644 --- a/alioth/src/arch/x86_64/reg.rs +++ b/alioth/src/arch/x86_64/reg.rs @@ -58,7 +58,7 @@ bitflags! { } bitflags! { - pub struct Cr0(u32) { + pub struct Cr0(u64) { /// CarryProtected Mode Enable PE = 1 << 0; /// CarryMonitor co-processor @@ -94,7 +94,7 @@ bitflags! { } bitflags! { - pub struct Cr4(u32) { + pub struct Cr4(u64) { /// CarryVirtual 8086 Mode Extensions VME = 1 << 0; /// CarryProtected-mode Virtual Interrupts diff --git a/alioth/src/loader/firmware/firmware_x86_64.rs b/alioth/src/loader/firmware/firmware_x86_64.rs index e4523b14..a537f7a1 100644 --- a/alioth/src/loader/firmware/firmware_x86_64.rs +++ b/alioth/src/loader/firmware/firmware_x86_64.rs @@ -98,7 +98,7 @@ pub fn load>(memory: &Memory, path: P) -> Result<(InitState, ArcM (Reg::Rflags, Rflags::RESERVED_1.bits() as u64), ], sregs: vec![ - (SReg::Cr0, (Cr0::ET | Cr0::NW | Cr0::CD).bits() as u64), + (SReg::Cr0, (Cr0::ET | Cr0::NW | Cr0::CD).bits()), (SReg::Cr2, 0), (SReg::Cr3, 0), (SReg::Cr4, 0), diff --git a/alioth/src/loader/linux/linux_x86_64.rs b/alioth/src/loader/linux/linux_x86_64.rs index ae028713..973a6b6c 100644 --- a/alioth/src/loader/linux/linux_x86_64.rs +++ b/alioth/src/loader/linux/linux_x86_64.rs @@ -251,10 +251,10 @@ pub fn load>( (Reg::Rflags, Rflags::RESERVED_1.bits() as u64), ], sregs: vec![ - (SReg::Efer, (Efer::LMA | Efer::LME).bits() as u64), - (SReg::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits() as u64), + (SReg::Efer, (Efer::LMA | Efer::LME).bits()), + (SReg::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits()), (SReg::Cr3, pml4_start), - (SReg::Cr4, Cr4::PAE.bits() as u64), + (SReg::Cr4, Cr4::PAE.bits()), (SReg::ApicBase, apic_base.0), ], seg_regs: vec![ diff --git a/alioth/src/loader/xen/xen.rs b/alioth/src/loader/xen/xen.rs index e0ff14f5..ac9f3566 100644 --- a/alioth/src/loader/xen/xen.rs +++ b/alioth/src/loader/xen/xen.rs @@ -318,7 +318,7 @@ pub fn load>( (Reg::Rip, entry_point), ], sregs: vec![ - (SReg::Cr0, Cr0::PE.bits() as u64), + (SReg::Cr0, Cr0::PE.bits()), (SReg::Cr4, 0), (SReg::Efer, 0), (SReg::ApicBase, apic_base.0), From aececcce6d45a85e555363a560d3c4d470509160 Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Sat, 4 Apr 2026 17:19:44 -0700 Subject: [PATCH 2/3] refactor(kvm): use strongly-typed registers in KVM bindings Signed-off-by: Changyuan Lyu --- alioth/src/arch/x86_64/msr.rs | 1 + alioth/src/arch/x86_64/reg.rs | 3 +++ .../hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs | 23 ++++++++++--------- .../kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs | 6 ++--- alioth/src/sys/linux/kvm.rs | 22 ++++++++++-------- 5 files changed, 31 insertions(+), 24 deletions(-) diff --git a/alioth/src/arch/x86_64/msr.rs b/alioth/src/arch/x86_64/msr.rs index 935a92e7..f3d3a4b3 100644 --- a/alioth/src/arch/x86_64/msr.rs +++ b/alioth/src/arch/x86_64/msr.rs @@ -29,6 +29,7 @@ pub const IA32_TSC_AUX: u32 = 0xc000_0103; pub const IA32_MISC_ENABLE: u32 = 0x0000_01a0; bitflags! { + #[derive(Default)] pub struct Efer(u64) { /// SYSCALL enable SCE = 1 << 0; diff --git a/alioth/src/arch/x86_64/reg.rs b/alioth/src/arch/x86_64/reg.rs index 3cdf9930..bfd91200 100644 --- a/alioth/src/arch/x86_64/reg.rs +++ b/alioth/src/arch/x86_64/reg.rs @@ -58,6 +58,7 @@ bitflags! { } bitflags! { + #[derive(Default)] pub struct Cr0(u64) { /// CarryProtected Mode Enable PE = 1 << 0; @@ -85,6 +86,7 @@ bitflags! { } bitflags! { + #[derive(Default)] pub struct Cr3(u64) { /// CarryPage-level write-through PWT = 1 << 3; @@ -94,6 +96,7 @@ bitflags! { } bitflags! { + #[derive(Default)] pub struct Cr4(u64) { /// CarryVirtual 8086 Mode Extensions VME = 1 << 0; diff --git a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs index 9f34c927..76d0f48e 100644 --- a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs +++ b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs @@ -22,7 +22,8 @@ use std::os::fd::{FromRawFd, OwnedFd}; use snafu::ResultExt; use crate::arch::cpuid::CpuidIn; -use crate::arch::reg::{DtReg, DtRegVal, Reg, SReg, SegAccess, SegReg, SegRegVal}; +use crate::arch::msr::{ApicBase, Efer}; +use crate::arch::reg::{Cr0, Cr3, Cr4, DtReg, DtRegVal, Reg, SReg, SegAccess, SegReg, SegRegVal}; use crate::hv::kvm::kvm_error; use crate::hv::kvm::vcpu::KvmVcpu; use crate::hv::kvm::vm::KvmVm; @@ -47,13 +48,13 @@ impl VcpuArch { macro_rules! set_kvm_sreg { ($kvm_sregs:ident, $sreg:ident, $val:expr) => { match $sreg { - SReg::Cr0 => $kvm_sregs.cr0 = $val, + SReg::Cr0 => $kvm_sregs.cr0 = Cr0::from_bits_retain($val), SReg::Cr2 => $kvm_sregs.cr2 = $val, - SReg::Cr3 => $kvm_sregs.cr3 = $val, - SReg::Cr4 => $kvm_sregs.cr4 = $val, + SReg::Cr3 => $kvm_sregs.cr3 = Cr3::from_bits_retain($val), + SReg::Cr4 => $kvm_sregs.cr4 = Cr4::from_bits_retain($val), SReg::Cr8 => $kvm_sregs.cr8 = $val, - SReg::Efer => $kvm_sregs.efer = $val, - SReg::ApicBase => $kvm_sregs.apic_base = $val, + SReg::Efer => $kvm_sregs.efer = Efer::from_bits_retain($val), + SReg::ApicBase => $kvm_sregs.apic_base = ApicBase($val), } }; } @@ -99,13 +100,13 @@ macro_rules! set_kvm_seg_reg { macro_rules! get_kvm_sreg { ($kvm_sregs:ident, $sreg:ident) => { match $sreg { - SReg::Cr0 => $kvm_sregs.cr0, + SReg::Cr0 => $kvm_sregs.cr0.bits(), SReg::Cr2 => $kvm_sregs.cr2, - SReg::Cr3 => $kvm_sregs.cr3, - SReg::Cr4 => $kvm_sregs.cr4, + SReg::Cr3 => $kvm_sregs.cr3.bits(), + SReg::Cr4 => $kvm_sregs.cr4.bits(), SReg::Cr8 => $kvm_sregs.cr8, - SReg::Efer => $kvm_sregs.efer, - SReg::ApicBase => $kvm_sregs.apic_base, + SReg::Efer => $kvm_sregs.efer.bits(), + SReg::ApicBase => $kvm_sregs.apic_base.0, } }; } diff --git a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs index 8407debf..7266ce8b 100644 --- a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs +++ b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs @@ -280,10 +280,10 @@ fn test_kvm_run() { let idtr = DtRegVal { base: 0, limit: 0 }; vcpu.set_sregs( &[ - (SReg::Efer, (Efer::LMA | Efer::LME).bits() as u64), - (SReg::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits() as u64), + (SReg::Efer, (Efer::LMA | Efer::LME).bits()), + (SReg::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits()), (SReg::Cr3, 0x2000), - (SReg::Cr4, Cr4::PAE.bits() as u64), + (SReg::Cr4, Cr4::PAE.bits()), ], &[ (SegReg::Cs, cs), diff --git a/alioth/src/sys/linux/kvm.rs b/alioth/src/sys/linux/kvm.rs index 74debad0..680efb1e 100644 --- a/alioth/src/sys/linux/kvm.rs +++ b/alioth/src/sys/linux/kvm.rs @@ -16,6 +16,8 @@ use std::fmt::{Debug, Formatter, Result}; use bitfield::bitfield; +use crate::arch::x86_64::msr::{ApicBase, Efer}; +use crate::arch::x86_64::reg::{Cr0, Cr3, Cr4}; use crate::sys::ioctl::{ioctl_ior, ioctl_iowr}; use crate::{ bitflags, consts, ioctl_none, ioctl_read, ioctl_write_buf, ioctl_write_ptr, ioctl_write_val, @@ -231,13 +233,13 @@ pub struct KvmSregs { pub ldt: KvmSegment, pub gdt: KvmDtable, pub idt: KvmDtable, - pub cr0: u64, + pub cr0: Cr0, pub cr2: u64, - pub cr3: u64, - pub cr4: u64, + pub cr3: Cr3, + pub cr4: Cr4, pub cr8: u64, - pub efer: u64, - pub apic_base: u64, + pub efer: Efer, + pub apic_base: ApicBase, pub interrupt_bitmap: [u64; 4], } @@ -254,13 +256,13 @@ pub struct KvmSregs2 { pub ldt: KvmSegment, pub gdt: KvmDtable, pub idt: KvmDtable, - pub cr0: u64, + pub cr0: Cr0, pub cr2: u64, - pub cr3: u64, - pub cr4: u64, + pub cr3: Cr3, + pub cr4: Cr4, pub cr8: u64, - pub efer: u64, - pub apic_base: u64, + pub efer: Efer, + pub apic_base: ApicBase, pub flags: u64, pub pdptrs: [u64; 4], } From 7a7f8a8b32bd181582e694e4c40d573e02d7d280 Mon Sep 17 00:00:00 2001 From: Changyuan Lyu Date: Sat, 4 Apr 2026 17:38:57 -0700 Subject: [PATCH 3/3] refactor(x86): treat EFER and APIC_BASE as MSRs instead of SRegs Signed-off-by: Changyuan Lyu --- alioth/src/arch/x86_64/msr.rs | 27 +++++++++++-------- alioth/src/arch/x86_64/reg.rs | 2 -- alioth/src/board/board_x86_64/board_x86_64.rs | 5 ++-- alioth/src/hv/hv.rs | 4 ++- alioth/src/hv/kvm/vcpu/vcpu.rs | 4 ++- .../hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs | 22 ++++++++++----- .../kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs | 7 +++-- alioth/src/loader/firmware/firmware_x86_64.rs | 3 ++- alioth/src/loader/linux/linux_x86_64.rs | 8 +++--- alioth/src/loader/loader.rs | 4 +++ alioth/src/loader/xen/xen.rs | 10 +++---- 11 files changed, 57 insertions(+), 39 deletions(-) diff --git a/alioth/src/arch/x86_64/msr.rs b/alioth/src/arch/x86_64/msr.rs index f3d3a4b3..c21a6e38 100644 --- a/alioth/src/arch/x86_64/msr.rs +++ b/alioth/src/arch/x86_64/msr.rs @@ -14,19 +14,24 @@ use bitfield::bitfield; -use crate::bitflags; +use crate::{bitflags, consts}; // Intel Vol.4, Table 2-2. -pub const IA32_EFER: u32 = 0xc000_0080; -pub const IA32_STAR: u32 = 0xc000_0081; -pub const IA32_LSTAR: u32 = 0xc000_0082; -pub const IA32_CSTAR: u32 = 0xc000_0083; -pub const IA32_FMASK: u32 = 0xc000_0084; -pub const IA32_FS_BASE: u32 = 0xc000_0100; -pub const IA32_GS_BASE: u32 = 0xc000_0101; -pub const IA32_KERNEL_GS_BASE: u32 = 0xc000_0102; -pub const IA32_TSC_AUX: u32 = 0xc000_0103; -pub const IA32_MISC_ENABLE: u32 = 0x0000_01a0; +consts! { + pub struct Msr(u32) { + EFER = 0xc000_0080; + STAR = 0xc000_0081; + LSTAR = 0xc000_0082; + CSTAR = 0xc000_0083; + FMASK = 0xc000_0084; + FS_BASE = 0xc000_0100; + GS_BASE = 0xc000_0101; + KERNEL_GS_BASE = 0xc000_0102; + TSC_AUX = 0xc000_0103; + MISC_ENABLE = 0x0000_01a0; + APIC_BASE = 0x0000_001b; + } +} bitflags! { #[derive(Default)] diff --git a/alioth/src/arch/x86_64/reg.rs b/alioth/src/arch/x86_64/reg.rs index bfd91200..b72b1ff3 100644 --- a/alioth/src/arch/x86_64/reg.rs +++ b/alioth/src/arch/x86_64/reg.rs @@ -198,8 +198,6 @@ pub enum SReg { Cr3, Cr4, Cr8, - Efer, - ApicBase, } #[derive(Debug, Copy, Clone, PartialEq, Eq)] diff --git a/alioth/src/board/board_x86_64/board_x86_64.rs b/alioth/src/board/board_x86_64/board_x86_64.rs index 521e4396..385f525e 100644 --- a/alioth/src/board/board_x86_64/board_x86_64.rs +++ b/alioth/src/board/board_x86_64/board_x86_64.rs @@ -31,7 +31,7 @@ use crate::arch::layout::{ BIOS_DATA_END, EBDA_END, EBDA_START, IOAPIC_START, MEM_64_START, PORT_ACPI_RESET, PORT_ACPI_SLEEP_CONTROL, PORT_ACPI_TIMER, RAM_32_SIZE, }; -use crate::arch::msr::{IA32_MISC_ENABLE, MiscEnable}; +use crate::arch::msr::{MiscEnable, Msr}; use crate::board::{Board, BoardConfig, CpuTopology, PCIE_MMIO_64_SIZE, Result, VcpuGuard, error}; use crate::device::ioapic::IoApic; use crate::firmware::acpi::bindings::{ @@ -241,6 +241,7 @@ where return Ok(()); } vcpu.set_sregs(&init_state.sregs, &init_state.seg_regs, &init_state.dt_regs)?; + vcpu.set_msrs(&init_state.msrs)?; vcpu.set_regs(&init_state.regs)?; Ok(()) } @@ -257,7 +258,7 @@ where } } vcpu.set_cpuids(cpuids)?; - vcpu.set_msrs(&[(IA32_MISC_ENABLE, MiscEnable::FAST_STRINGS.bits())])?; + vcpu.set_msrs(&[(Msr::MISC_ENABLE, MiscEnable::FAST_STRINGS.bits())])?; Ok(()) } diff --git a/alioth/src/hv/hv.rs b/alioth/src/hv/hv.rs index 0958e51f..741f1658 100644 --- a/alioth/src/hv/hv.rs +++ b/alioth/src/hv/hv.rs @@ -35,6 +35,8 @@ use snafu::{AsErrorSource, Snafu}; #[cfg(target_arch = "x86_64")] use crate::arch::cpuid::CpuidIn; #[cfg(target_arch = "x86_64")] +use crate::arch::msr::Msr; +#[cfg(target_arch = "x86_64")] use crate::arch::reg::{DtReg, DtRegVal, SegReg, SegRegVal}; use crate::arch::reg::{Reg, SReg}; #[cfg(target_arch = "x86_64")] @@ -207,7 +209,7 @@ pub trait Vcpu { fn set_cpuids(&mut self, cpuids: HashMap) -> Result<(), Error>; #[cfg(target_arch = "x86_64")] - fn set_msrs(&mut self, msrs: &[(u32, u64)]) -> Result<()>; + fn set_msrs(&mut self, msrs: &[(Msr, u64)]) -> Result<()>; fn dump(&self) -> Result<(), Error>; diff --git a/alioth/src/hv/kvm/vcpu/vcpu.rs b/alioth/src/hv/kvm/vcpu/vcpu.rs index 07de7090..4c80509e 100644 --- a/alioth/src/hv/kvm/vcpu/vcpu.rs +++ b/alioth/src/hv/kvm/vcpu/vcpu.rs @@ -37,6 +37,8 @@ use snafu::ResultExt; #[cfg(target_arch = "x86_64")] use crate::arch::cpuid::CpuidIn; #[cfg(target_arch = "x86_64")] +use crate::arch::msr::Msr; +#[cfg(target_arch = "x86_64")] use crate::arch::reg::{DtReg, DtRegVal, SegReg, SegRegVal}; use crate::arch::reg::{Reg, SReg}; use crate::ffi; @@ -227,7 +229,7 @@ impl Vcpu for KvmVcpu { } #[cfg(target_arch = "x86_64")] - fn set_msrs(&mut self, msrs: &[(u32, u64)]) -> Result<()> { + fn set_msrs(&mut self, msrs: &[(Msr, u64)]) -> Result<()> { self.kvm_set_msrs(msrs) } diff --git a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs index 76d0f48e..12100062 100644 --- a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs +++ b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs @@ -22,7 +22,7 @@ use std::os::fd::{FromRawFd, OwnedFd}; use snafu::ResultExt; use crate::arch::cpuid::CpuidIn; -use crate::arch::msr::{ApicBase, Efer}; +use crate::arch::msr::{Efer, Msr}; use crate::arch::reg::{Cr0, Cr3, Cr4, DtReg, DtRegVal, Reg, SReg, SegAccess, SegReg, SegRegVal}; use crate::hv::kvm::kvm_error; use crate::hv::kvm::vcpu::KvmVcpu; @@ -53,8 +53,6 @@ macro_rules! set_kvm_sreg { SReg::Cr3 => $kvm_sregs.cr3 = Cr3::from_bits_retain($val), SReg::Cr4 => $kvm_sregs.cr4 = Cr4::from_bits_retain($val), SReg::Cr8 => $kvm_sregs.cr8 = $val, - SReg::Efer => $kvm_sregs.efer = Efer::from_bits_retain($val), - SReg::ApicBase => $kvm_sregs.apic_base = ApicBase($val), } }; } @@ -105,8 +103,16 @@ macro_rules! get_kvm_sreg { SReg::Cr3 => $kvm_sregs.cr3.bits(), SReg::Cr4 => $kvm_sregs.cr4.bits(), SReg::Cr8 => $kvm_sregs.cr8, - SReg::Efer => $kvm_sregs.efer.bits(), - SReg::ApicBase => $kvm_sregs.apic_base.0, + } + }; +} + +macro_rules! fix_kvm_efer { + ($kvm_sregs:ident) => { + if $kvm_sregs.cr0.contains(Cr0::PG) && $kvm_sregs.cr4.contains(Cr4::PAE) { + $kvm_sregs.efer |= Efer::LME | Efer::LMA; + } else { + $kvm_sregs.efer &= !(Efer::LME | Efer::LMA); } }; } @@ -244,6 +250,7 @@ impl KvmVcpu { for (reg, val) in seg_regs { set_kvm_seg_reg!(kvm_sregs2, reg, val); } + fix_kvm_efer!(kvm_sregs2); unsafe { kvm_set_sregs2(&self.fd, &kvm_sregs2) }.context(error::VcpuReg)?; Ok(()) } @@ -282,6 +289,7 @@ impl KvmVcpu { for (reg, val) in seg_regs { set_kvm_seg_reg!(kvm_sregs, reg, val); } + fix_kvm_efer!(kvm_sregs); unsafe { kvm_set_sregs(&self.fd, &kvm_sregs) }.context(error::VcpuReg)?; Ok(()) } @@ -330,14 +338,14 @@ impl KvmVcpu { Ok(()) } - pub fn kvm_set_msrs(&mut self, msrs: &[(u32, u64)]) -> Result<()> { + pub fn kvm_set_msrs(&mut self, msrs: &[(Msr, u64)]) -> Result<()> { let mut kvm_msrs = KvmMsrs { nmsrs: msrs.len() as u32, _pad: 0, entries: [KvmMsrEntry::default(); MAX_IO_MSRS], }; for (i, (index, data)) in msrs.iter().enumerate() { - kvm_msrs.entries[i].index = *index; + kvm_msrs.entries[i].index = index.raw(); kvm_msrs.entries[i].data = *data; } unsafe { kvm_set_msrs(&self.fd, &kvm_msrs) }.context(error::GuestMsr)?; diff --git a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs index 7266ce8b..ec773c70 100644 --- a/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs +++ b/alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs @@ -18,7 +18,7 @@ use std::ptr::null_mut; use assert_matches::assert_matches; use libc::{MAP_ANONYMOUS, MAP_FAILED, MAP_SHARED, PROT_EXEC, PROT_READ, PROT_WRITE, mmap}; -use crate::arch::msr::Efer; +use crate::arch::msr::{Efer, Msr}; use crate::arch::paging::Entry; use crate::arch::reg::{Cr0, Cr4, Reg, SegAccess}; use crate::ffi; @@ -68,8 +68,6 @@ fn test_vcpu_regs() { (SReg::Cr3, 0x1362d001), (SReg::Cr4, 1 << 5), (SReg::Cr8, 0x0), - (SReg::Efer, (1 << 8) | (1 << 10)), - (SReg::ApicBase, 0xfee00900), ]; let seg_regs = [ ( @@ -280,7 +278,6 @@ fn test_kvm_run() { let idtr = DtRegVal { base: 0, limit: 0 }; vcpu.set_sregs( &[ - (SReg::Efer, (Efer::LMA | Efer::LME).bits()), (SReg::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits()), (SReg::Cr3, 0x2000), (SReg::Cr4, Cr4::PAE.bits()), @@ -298,6 +295,8 @@ fn test_kvm_run() { &[(DtReg::Gdtr, gdtr), (DtReg::Idtr, idtr)], ) .unwrap(); + vcpu.set_msrs(&[(Msr::EFER, (Efer::LMA | Efer::LME).bits())]) + .unwrap(); vcpu.set_regs(&[ (Reg::Rip, 0x1000), (Reg::Rax, 0x2), diff --git a/alioth/src/loader/firmware/firmware_x86_64.rs b/alioth/src/loader/firmware/firmware_x86_64.rs index a537f7a1..2f34eeaf 100644 --- a/alioth/src/loader/firmware/firmware_x86_64.rs +++ b/alioth/src/loader/firmware/firmware_x86_64.rs @@ -20,6 +20,7 @@ use std::sync::Arc; use snafu::ResultExt; use crate::arch::layout::MEM_64_START; +use crate::arch::msr::Msr; use crate::arch::reg::{Cr0, DtReg, DtRegVal, Reg, Rflags, SReg, SegAccess, SegReg, SegRegVal}; use crate::loader::{InitState, Result, error}; use crate::mem::mapped::ArcMemPages; @@ -103,8 +104,8 @@ pub fn load>(memory: &Memory, path: P) -> Result<(InitState, ArcM (SReg::Cr3, 0), (SReg::Cr4, 0), (SReg::Cr8, 0), - (SReg::Efer, 0), ], + msrs: vec![(Msr::EFER, 0)], seg_regs: vec![ (SegReg::Cs, boot_cs), (SegReg::Ds, boot_ds), diff --git a/alioth/src/loader/linux/linux_x86_64.rs b/alioth/src/loader/linux/linux_x86_64.rs index 973a6b6c..982ef7df 100644 --- a/alioth/src/loader/linux/linux_x86_64.rs +++ b/alioth/src/loader/linux/linux_x86_64.rs @@ -25,7 +25,7 @@ use crate::arch::layout::{ APIC_START, BOOT_GDT_START, BOOT_PAGING_START, EBDA_START, KERNEL_CMDLINE_LIMIT, KERNEL_CMDLINE_START, KERNEL_IMAGE_START, LINUX_BOOT_PARAMS_START, }; -use crate::arch::msr::{ApicBase, Efer}; +use crate::arch::msr::{ApicBase, Efer, Msr}; use crate::arch::paging::Entry; use crate::arch::reg::{ Cr0, Cr4, DtReg, DtRegVal, Reg, Rflags, SReg, SegAccess, SegReg, SegRegVal, @@ -251,11 +251,9 @@ pub fn load>( (Reg::Rflags, Rflags::RESERVED_1.bits() as u64), ], sregs: vec![ - (SReg::Efer, (Efer::LMA | Efer::LME).bits()), (SReg::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits()), (SReg::Cr3, pml4_start), (SReg::Cr4, Cr4::PAE.bits()), - (SReg::ApicBase, apic_base.0), ], seg_regs: vec![ (SegReg::Cs, boot_cs), @@ -268,6 +266,10 @@ pub fn load>( (SegReg::Ldtr, boot_ldtr), ], dt_regs: vec![(DtReg::Gdtr, gdtr), (DtReg::Idtr, idtr)], + msrs: vec![ + (Msr::EFER, (Efer::LMA | Efer::LME).bits()), + (Msr::APIC_BASE, apic_base.0), + ], initramfs: initramfs_range, }) } diff --git a/alioth/src/loader/loader.rs b/alioth/src/loader/loader.rs index 3d87c3bc..bfdb753e 100644 --- a/alioth/src/loader/loader.rs +++ b/alioth/src/loader/loader.rs @@ -28,6 +28,8 @@ use std::path::Path; use serde::Deserialize; use snafu::Snafu; +#[cfg(target_arch = "x86_64")] +use crate::arch::msr::Msr; #[cfg(target_arch = "x86_64")] use crate::arch::reg::{DtReg, DtRegVal, SegReg, SegRegVal}; use crate::arch::reg::{Reg, SReg}; @@ -57,6 +59,8 @@ pub struct InitState { pub dt_regs: Vec<(DtReg, DtRegVal)>, #[cfg(target_arch = "x86_64")] pub seg_regs: Vec<(SegReg, SegRegVal)>, + #[cfg(target_arch = "x86_64")] + pub msrs: Vec<(Msr, u64)>, pub initramfs: Option>, } diff --git a/alioth/src/loader/xen/xen.rs b/alioth/src/loader/xen/xen.rs index ac9f3566..00802b05 100644 --- a/alioth/src/loader/xen/xen.rs +++ b/alioth/src/loader/xen/xen.rs @@ -28,7 +28,7 @@ use crate::arch::layout::{ APIC_START, BOOT_GDT_START, EBDA_START, HVM_START_INFO_START, KERNEL_CMDLINE_LIMIT, KERNEL_CMDLINE_START, }; -use crate::arch::msr::ApicBase; +use crate::arch::msr::{ApicBase, Msr}; use crate::arch::reg::{Cr0, DtReg, DtRegVal, Reg, Rflags, SReg, SegAccess, SegReg, SegRegVal}; use crate::loader::elf::{ ELF_HEADER_MAGIC, ELF_IDENT_CLASS_64, ELF_IDENT_LITTLE_ENDIAN, Elf64Header, Elf64Note, @@ -317,12 +317,7 @@ pub fn load>( (Reg::Rflags, Rflags::RESERVED_1.bits() as u64), (Reg::Rip, entry_point), ], - sregs: vec![ - (SReg::Cr0, Cr0::PE.bits()), - (SReg::Cr4, 0), - (SReg::Efer, 0), - (SReg::ApicBase, apic_base.0), - ], + sregs: vec![(SReg::Cr0, Cr0::PE.bits()), (SReg::Cr4, 0)], seg_regs: vec![ (SegReg::Cs, boot_cs), (SegReg::Ds, boot_ds), @@ -334,6 +329,7 @@ pub fn load>( (SegReg::Ldtr, boot_ldtr), ], dt_regs: vec![(DtReg::Gdtr, gdtr), (DtReg::Idtr, idtr)], + msrs: vec![(Msr::APIC_BASE, apic_base.0), (Msr::EFER, 0)], initramfs: initramfs_range, }) }