This commit is contained in:
Masato Imai
2025-06-28 10:03:56 +00:00
parent 29d32cc361
commit df0e7943c6
3 changed files with 34 additions and 8 deletions

View File

@ -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) };

View File

@ -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;

View File

@ -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