Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 18 additions & 12 deletions alioth/src/arch/x86_64/msr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,28 @@

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! {
pub struct Efer(u32) {
#[derive(Default)]
pub struct Efer(u64) {
/// SYSCALL enable
SCE = 1 << 0;
/// IA-32e mode enable
Expand Down
9 changes: 5 additions & 4 deletions alioth/src/arch/x86_64/reg.rs
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,8 @@ bitflags! {
}

bitflags! {
pub struct Cr0(u32) {
#[derive(Default)]
pub struct Cr0(u64) {
/// CarryProtected Mode Enable
PE = 1 << 0;
/// CarryMonitor co-processor
Expand All @@ -85,6 +86,7 @@ bitflags! {
}

bitflags! {
#[derive(Default)]
pub struct Cr3(u64) {
/// CarryPage-level write-through
PWT = 1 << 3;
Expand All @@ -94,7 +96,8 @@ bitflags! {
}

bitflags! {
pub struct Cr4(u32) {
#[derive(Default)]
pub struct Cr4(u64) {
/// CarryVirtual 8086 Mode Extensions
VME = 1 << 0;
/// CarryProtected-mode Virtual Interrupts
Expand Down Expand Up @@ -195,8 +198,6 @@ pub enum SReg {
Cr3,
Cr4,
Cr8,
Efer,
ApicBase,
}

#[derive(Debug, Copy, Clone, PartialEq, Eq)]
Expand Down
5 changes: 3 additions & 2 deletions alioth/src/board/board_x86_64/board_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{
Expand Down Expand Up @@ -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(())
}
Expand All @@ -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(())
}

Expand Down
4 changes: 3 additions & 1 deletion alioth/src/hv/hv.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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")]
Expand Down Expand Up @@ -207,7 +209,7 @@ pub trait Vcpu {
fn set_cpuids(&mut self, cpuids: HashMap<CpuidIn, CpuidResult>) -> 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>;

Expand Down
4 changes: 3 additions & 1 deletion alioth/src/hv/kvm/vcpu/vcpu.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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)
}

Expand Down
35 changes: 22 additions & 13 deletions alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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::{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;
use crate::hv::kvm::vm::KvmVm;
Expand All @@ -47,13 +48,11 @@ 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,
}
};
}
Expand Down Expand Up @@ -99,13 +98,21 @@ 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,
}
};
}

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);
}
};
}
Expand Down Expand Up @@ -243,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(())
}
Expand Down Expand Up @@ -281,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(())
}
Expand Down Expand Up @@ -329,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)?;
Expand Down
11 changes: 5 additions & 6 deletions alioth/src/hv/kvm/vcpu/vcpu_x86_64/vcpu_x86_64_test.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -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 = [
(
Expand Down Expand Up @@ -280,10 +278,9 @@ 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::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),
Expand All @@ -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),
Expand Down
5 changes: 3 additions & 2 deletions alioth/src/loader/firmware/firmware_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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;
Expand Down Expand Up @@ -98,13 +99,13 @@ pub fn load<P: AsRef<Path>>(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),
(SReg::Cr8, 0),
(SReg::Efer, 0),
],
msrs: vec![(Msr::EFER, 0)],
seg_regs: vec![
(SegReg::Cs, boot_cs),
(SegReg::Ds, boot_ds),
Expand Down
12 changes: 7 additions & 5 deletions alioth/src/loader/linux/linux_x86_64.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -251,11 +251,9 @@ pub fn load<P: AsRef<Path>>(
(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::Cr0, (Cr0::NE | Cr0::PE | Cr0::PG).bits()),
(SReg::Cr3, pml4_start),
(SReg::Cr4, Cr4::PAE.bits() as u64),
(SReg::ApicBase, apic_base.0),
(SReg::Cr4, Cr4::PAE.bits()),
],
seg_regs: vec![
(SegReg::Cs, boot_cs),
Expand All @@ -268,6 +266,10 @@ pub fn load<P: AsRef<Path>>(
(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,
})
}
4 changes: 4 additions & 0 deletions alioth/src/loader/loader.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
Expand Down Expand Up @@ -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<Range<u64>>,
}

Expand Down
10 changes: 3 additions & 7 deletions alioth/src/loader/xen/xen.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -317,12 +317,7 @@ pub fn load<P: AsRef<Path>>(
(Reg::Rflags, Rflags::RESERVED_1.bits() as u64),
(Reg::Rip, entry_point),
],
sregs: vec![
(SReg::Cr0, Cr0::PE.bits() as u64),
(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),
Expand All @@ -334,6 +329,7 @@ pub fn load<P: AsRef<Path>>(
(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,
})
}
Loading
Loading