diff --git a/src/vmm/cpuid.rs b/src/vmm/cpuid.rs index 9226abd..abc5445 100644 --- a/src/vmm/cpuid.rs +++ b/src/vmm/cpuid.rs @@ -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) }; diff --git a/src/vmm/emulation/opcode.rs b/src/vmm/emulation/opcode.rs index 2ebe5d5..6c4c6be 100644 --- a/src/vmm/emulation/opcode.rs +++ b/src/vmm/emulation/opcode.rs @@ -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, +} + +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; diff --git a/src/vmm/vcpu.rs b/src/vmm/vcpu.rs index 4f6f036..4ab523b 100644 --- a/src/vmm/vcpu.rs +++ b/src/vmm/vcpu.rs @@ -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 = 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