mirror of
https://github.com/mii443/nel_os.git
synced 2025-08-22 16:15:38 +00:00
switch
This commit is contained in:
@ -6,7 +6,12 @@ use super::{vcpu::VCpu, vmcs::VmxLeaf};
|
|||||||
pub fn handle_cpuid_exit(vcpu: &mut VCpu) {
|
pub fn handle_cpuid_exit(vcpu: &mut VCpu) {
|
||||||
let regs = &mut vcpu.guest_registers;
|
let regs = &mut vcpu.guest_registers;
|
||||||
|
|
||||||
let vendor: &[u8; 12] = b"AuthenticAMD";
|
let vendor: &[u8; 12] = if vcpu.emulate_amd {
|
||||||
|
b"AuthenticAMD"
|
||||||
|
} else {
|
||||||
|
b"miHypervisor"
|
||||||
|
};
|
||||||
|
|
||||||
let brand_string: &[u8; 48] = b"mii Hypervisor CPU on Intel VT-x \0";
|
let brand_string: &[u8; 48] = b"mii Hypervisor CPU on Intel VT-x \0";
|
||||||
|
|
||||||
let vendor = unsafe { core::mem::transmute::<&[u8; 12], &[u32; 3]>(vendor) };
|
let vendor = unsafe { core::mem::transmute::<&[u8; 12], &[u32; 3]>(vendor) };
|
||||||
|
@ -16,6 +16,20 @@ const OPCODE_SYSCALL: u8 = 0x05;
|
|||||||
|
|
||||||
const RFLAGS_AC_BIT: u64 = 1 << 18;
|
const RFLAGS_AC_BIT: u64 = 1 << 18;
|
||||||
|
|
||||||
|
pub struct OpcodeEmulator {
|
||||||
|
pub original_opcode: Option<[u8; 16]>,
|
||||||
|
pub replaced_address: Option<u64>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl OpcodeEmulator {
|
||||||
|
pub fn new() -> Self {
|
||||||
|
OpcodeEmulator {
|
||||||
|
original_opcode: None,
|
||||||
|
replaced_address: None,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pub fn emulate_opcode(vcpu: &mut VCpu, instruction_bytes: [u8; 16], valid_bytes: u64) -> bool {
|
pub fn emulate_opcode(vcpu: &mut VCpu, instruction_bytes: [u8; 16], valid_bytes: u64) -> bool {
|
||||||
if instruction_bytes[0] != OPCODE_TWO_BYTE_ESCAPE || valid_bytes < 2 {
|
if instruction_bytes[0] != OPCODE_TWO_BYTE_ESCAPE || valid_bytes < 2 {
|
||||||
return false;
|
return false;
|
||||||
@ -36,6 +50,10 @@ pub fn emulate_opcode(vcpu: &mut VCpu, instruction_bytes: [u8; 16], valid_bytes:
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn emulate_syscall(vcpu: &mut VCpu) -> bool {
|
fn emulate_syscall(vcpu: &mut VCpu) -> bool {
|
||||||
|
if !vcpu.emulate_amd {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
let current_rip = unsafe { vmread(vmcs::guest::RIP).unwrap() };
|
let current_rip = unsafe { vmread(vmcs::guest::RIP).unwrap() };
|
||||||
let return_address = current_rip + 2;
|
let return_address = current_rip + 2;
|
||||||
|
|
||||||
|
@ -27,7 +27,7 @@ use crate::{
|
|||||||
subscribe_with_context,
|
subscribe_with_context,
|
||||||
vmm::{
|
vmm::{
|
||||||
cpuid, cr,
|
cpuid, cr,
|
||||||
emulation::opcode::emulate_opcode,
|
emulation::opcode::{emulate_opcode, OpcodeEmulator},
|
||||||
fpu,
|
fpu,
|
||||||
io::{self, InitPhase, Serial, PIC},
|
io::{self, InitPhase, Serial, PIC},
|
||||||
msr,
|
msr,
|
||||||
@ -51,6 +51,7 @@ use super::{
|
|||||||
};
|
};
|
||||||
|
|
||||||
const SIZE_2MIB: u64 = 2 * 1024 * 1024;
|
const SIZE_2MIB: u64 = 2 * 1024 * 1024;
|
||||||
|
const GUEST_MEMORY_SIZE: u64 = 2 * 1024 * 1024 * 1024;
|
||||||
|
|
||||||
static EPT_FRAME_ALLOCATOR: AtomicPtr<BootInfoFrameAllocator> =
|
static EPT_FRAME_ALLOCATOR: AtomicPtr<BootInfoFrameAllocator> =
|
||||||
AtomicPtr::new(core::ptr::null_mut());
|
AtomicPtr::new(core::ptr::null_mut());
|
||||||
@ -74,6 +75,8 @@ pub struct VCpu {
|
|||||||
pub io_bitmap_b: x86_64::structures::paging::PhysFrame,
|
pub io_bitmap_b: x86_64::structures::paging::PhysFrame,
|
||||||
pub pic: PIC,
|
pub pic: PIC,
|
||||||
pub pending_irq: u16,
|
pub pending_irq: u16,
|
||||||
|
pub opcode_emulator: OpcodeEmulator,
|
||||||
|
pub emulate_amd: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
const TEMP_STACK_SIZE: usize = 4096;
|
const TEMP_STACK_SIZE: usize = 4096;
|
||||||
@ -187,6 +190,8 @@ impl VCpu {
|
|||||||
io_bitmap_b,
|
io_bitmap_b,
|
||||||
pic: PIC::new(),
|
pic: PIC::new(),
|
||||||
pending_irq: 0,
|
pending_irq: 0,
|
||||||
|
opcode_emulator: OpcodeEmulator::new(),
|
||||||
|
emulate_amd: false,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -308,19 +313,17 @@ impl VCpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub fn setup_guest_memory(&mut self, frame_allocator: &mut BootInfoFrameAllocator) -> u64 {
|
pub fn setup_guest_memory(&mut self, frame_allocator: &mut BootInfoFrameAllocator) -> u64 {
|
||||||
let guest_memory_size = 2 * 1024 * 1024 * 1024;
|
|
||||||
|
|
||||||
info!(
|
info!(
|
||||||
"Setting up guest memory with on-demand allocation (reported size: {}MB)",
|
"Setting up guest memory with on-demand allocation (reported size: {}MB)",
|
||||||
guest_memory_size / (1024 * 1024)
|
GUEST_MEMORY_SIZE / (1024 * 1024)
|
||||||
);
|
);
|
||||||
|
|
||||||
self.load_kernel(linux::BZIMAGE, guest_memory_size);
|
self.load_kernel(linux::BZIMAGE, GUEST_MEMORY_SIZE);
|
||||||
|
|
||||||
let eptp = EPTP::new(&self.ept.root_table);
|
let eptp = EPTP::new(&self.ept.root_table);
|
||||||
unsafe { vmwrite(vmcs::control::EPTP_FULL, eptp.0).unwrap() };
|
unsafe { vmwrite(vmcs::control::EPTP_FULL, eptp.0).unwrap() };
|
||||||
|
|
||||||
guest_memory_size
|
GUEST_MEMORY_SIZE
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn register_msrs(&mut self, mapper: &OffsetPageTable<'static>) {
|
pub fn register_msrs(&mut self, mapper: &OffsetPageTable<'static>) {
|
||||||
@ -988,7 +991,7 @@ impl VCpu {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn handle_ept_violation(&mut self, gpa: u64) {
|
fn handle_ept_violation(&mut self, gpa: u64) {
|
||||||
if gpa >= 2 * 1024 * 1024 * 1024 {
|
if gpa >= GUEST_MEMORY_SIZE {
|
||||||
panic!(
|
panic!(
|
||||||
"EPT Violation: Guest tried to access memory beyond 2GB at {:#x}",
|
"EPT Violation: Guest tried to access memory beyond 2GB at {:#x}",
|
||||||
gpa
|
gpa
|
||||||
|
Reference in New Issue
Block a user