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) {
|
||||
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 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;
|
||||
|
||||
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 {
|
||||
if instruction_bytes[0] != OPCODE_TWO_BYTE_ESCAPE || valid_bytes < 2 {
|
||||
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 {
|
||||
if !vcpu.emulate_amd {
|
||||
return false;
|
||||
}
|
||||
|
||||
let current_rip = unsafe { vmread(vmcs::guest::RIP).unwrap() };
|
||||
let return_address = current_rip + 2;
|
||||
|
||||
|
@ -27,7 +27,7 @@ use crate::{
|
||||
subscribe_with_context,
|
||||
vmm::{
|
||||
cpuid, cr,
|
||||
emulation::opcode::emulate_opcode,
|
||||
emulation::opcode::{emulate_opcode, OpcodeEmulator},
|
||||
fpu,
|
||||
io::{self, InitPhase, Serial, PIC},
|
||||
msr,
|
||||
@ -51,6 +51,7 @@ use super::{
|
||||
};
|
||||
|
||||
const SIZE_2MIB: u64 = 2 * 1024 * 1024;
|
||||
const GUEST_MEMORY_SIZE: u64 = 2 * 1024 * 1024 * 1024;
|
||||
|
||||
static EPT_FRAME_ALLOCATOR: AtomicPtr<BootInfoFrameAllocator> =
|
||||
AtomicPtr::new(core::ptr::null_mut());
|
||||
@ -74,6 +75,8 @@ pub struct VCpu {
|
||||
pub io_bitmap_b: x86_64::structures::paging::PhysFrame,
|
||||
pub pic: PIC,
|
||||
pub pending_irq: u16,
|
||||
pub opcode_emulator: OpcodeEmulator,
|
||||
pub emulate_amd: bool,
|
||||
}
|
||||
|
||||
const TEMP_STACK_SIZE: usize = 4096;
|
||||
@ -187,6 +190,8 @@ impl VCpu {
|
||||
io_bitmap_b,
|
||||
pic: PIC::new(),
|
||||
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 {
|
||||
let guest_memory_size = 2 * 1024 * 1024 * 1024;
|
||||
|
||||
info!(
|
||||
"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);
|
||||
unsafe { vmwrite(vmcs::control::EPTP_FULL, eptp.0).unwrap() };
|
||||
|
||||
guest_memory_size
|
||||
GUEST_MEMORY_SIZE
|
||||
}
|
||||
|
||||
pub fn register_msrs(&mut self, mapper: &OffsetPageTable<'static>) {
|
||||
@ -988,7 +991,7 @@ impl VCpu {
|
||||
}
|
||||
|
||||
fn handle_ept_violation(&mut self, gpa: u64) {
|
||||
if gpa >= 2 * 1024 * 1024 * 1024 {
|
||||
if gpa >= GUEST_MEMORY_SIZE {
|
||||
panic!(
|
||||
"EPT Violation: Guest tried to access memory beyond 2GB at {:#x}",
|
||||
gpa
|
||||
|
Reference in New Issue
Block a user