fix XCR0 emulation
All checks were successful
Check / Build ISO (nightly-2025-04-27) (push) Successful in 46s
Release ISO / release (push) Successful in 57s

This commit is contained in:
Masato Imai
2025-08-23 07:15:22 +00:00
parent 2d0db85574
commit 5df8c77ea7
4 changed files with 18 additions and 66 deletions

View File

@@ -1,56 +0,0 @@
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00000000
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=00000000 EFL=00000000 [-------] CPL=0 II=0 A20=0 SMM=0 HLT=0
ES =0000 00000000 00000000 00000000
CS =0000 00000000 00000000 00000000
SS =0000 00000000 00000000 00000000
DS =0000 00000000 00000000 00000000
FS =0000 00000000 00000000 00000000
GS =0000 00000000 00000000 00000000
LDT=0000 00000000 00000000 00000000
TR =0000 00000000 00000000 00000000
GDT= 00000000 00000000
IDT= 00000000 00000000
CR0=00000000 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=0000000000000000 DR7=0000000000000000
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=0000 FSW=0000 [ST=0] FTW=ff MXCSR=00000000
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000
CPU Reset (CPU 0)
EAX=00000000 EBX=00000000 ECX=00000000 EDX=00060fb1
ESI=00000000 EDI=00000000 EBP=00000000 ESP=00000000
EIP=0000fff0 EFL=00000002 [-------] CPL=0 II=0 A20=1 SMM=0 HLT=0
ES =0000 00000000 0000ffff 00009300
CS =f000 ffff0000 0000ffff 00009b00
SS =0000 00000000 0000ffff 00009300
DS =0000 00000000 0000ffff 00009300
FS =0000 00000000 0000ffff 00009300
GS =0000 00000000 0000ffff 00009300
LDT=0000 00000000 0000ffff 00008200
TR =0000 00000000 0000ffff 00008b00
GDT= 00000000 0000ffff
IDT= 00000000 0000ffff
CR0=60000010 CR2=00000000 CR3=00000000 CR4=00000000
DR0=0000000000000000 DR1=0000000000000000 DR2=0000000000000000 DR3=0000000000000000
DR6=00000000ffff0ff0 DR7=0000000000000400
CCS=00000000 CCD=00000000 CCO=DYNAMIC
EFER=0000000000000000
FCW=037f FSW=0000 [ST=0] FTW=00 MXCSR=00001f80
FPR0=0000000000000000 0000 FPR1=0000000000000000 0000
FPR2=0000000000000000 0000 FPR3=0000000000000000 0000
FPR4=0000000000000000 0000 FPR5=0000000000000000 0000
FPR6=0000000000000000 0000 FPR7=0000000000000000 0000
XMM00=0000000000000000 0000000000000000 XMM01=0000000000000000 0000000000000000
XMM02=0000000000000000 0000000000000000 XMM03=0000000000000000 0000000000000000
XMM04=0000000000000000 0000000000000000 XMM05=0000000000000000 0000000000000000
XMM06=0000000000000000 0000000000000000 XMM07=0000000000000000 0000000000000000

View File

@@ -6,10 +6,9 @@ EFI_BINARY="$1"
./create-iso.sh "$EFI_BINARY" ./create-iso.sh "$EFI_BINARY"
qemu-system-x86_64 -enable-kvm \ qemu-system-x86_64 -enable-kvm \
-m 2G \ -m 512M \
-serial mon:stdio \ -serial mon:stdio \
-nographic \ -nographic \
-no-reboot \
-drive if=pflash,format=raw,readonly=on,file=OVMF_CODE.fd \ -drive if=pflash,format=raw,readonly=on,file=OVMF_CODE.fd \
-drive if=pflash,format=raw,readonly=on,file=OVMF_VARS.fd \ -drive if=pflash,format=raw,readonly=on,file=OVMF_VARS.fd \
-cdrom nel_os.iso \ -cdrom nel_os.iso \

View File

@@ -1,3 +1,5 @@
#![allow(non_snake_case)]
use modular_bitfield::{bitfield, prelude::B44}; use modular_bitfield::{bitfield, prelude::B44};
use crate::vmm::x86_64::intel::vcpu::IntelVCpu; use crate::vmm::x86_64::intel::vcpu::IntelVCpu;
@@ -26,7 +28,6 @@ pub struct XCR0 {
pub xtilecfg: bool, pub xtilecfg: bool,
pub xtiledata: bool, pub xtiledata: bool,
pub apx: bool, pub apx: bool,
#[skip]
_reserved: B44, _reserved: B44,
} }

View File

@@ -6,7 +6,7 @@ use core::arch::{
use raw_cpuid::cpuid; use raw_cpuid::cpuid;
use x86::controlregs::cr4; use x86::controlregs::cr4;
use x86_64::{ use x86_64::{
registers::control::Cr4Flags, registers::control::{Cr4, Cr4Flags},
structures::paging::{FrameAllocator, Size4KiB}, structures::paging::{FrameAllocator, Size4KiB},
VirtAddr, VirtAddr,
}; };
@@ -233,10 +233,11 @@ impl IntelVCpu {
self.pic.inject_exception(vector, error_code).unwrap(); self.pic.inject_exception(vector, error_code).unwrap();
} }
} }
} else {
self.pic.inject_exception(vector, error_code).unwrap();
} }
} }
_ => { _ => {
info!("VM exit reason: {:?}", exit_reason);
return Err("Unhandled VM exit reason"); return Err("Unhandled VM exit reason");
} }
} }
@@ -257,7 +258,9 @@ impl IntelVCpu {
let guest_cr4 = vmread(x86::vmx::vmcs::guest::CR4)?; let guest_cr4 = vmread(x86::vmx::vmcs::guest::CR4)?;
if guest_cr4 & Cr4Flags::OSXSAVE.bits() != 0 && u64::from(self.guest_xcr0) != self.host_xcr0 if guest_cr4 & Cr4Flags::OSXSAVE.bits() != 0
&& u64::from(self.guest_xcr0) != self.host_xcr0
&& u64::from(self.guest_xcr0) != 0
{ {
unsafe { unsafe {
_xsetbv(0, u64::from(self.guest_xcr0)); _xsetbv(0, u64::from(self.guest_xcr0));
@@ -351,6 +354,11 @@ impl IntelVCpu {
msr::register_msrs(self).map_err(|_| "MSR error")?; msr::register_msrs(self).map_err(|_| "MSR error")?;
let cr4 = Cr4::read() | Cr4Flags::OSFXSR;
unsafe {
Cr4::write(cr4);
}
Ok(()) Ok(())
} }
@@ -384,7 +392,7 @@ impl IntelVCpu {
vmwrite(vmcs::host::CR3, unsafe { cr3() })?; vmwrite(vmcs::host::CR3, unsafe { cr3() })?;
vmwrite( vmwrite(
vmcs::host::CR4, vmcs::host::CR4,
unsafe { cr4() }.bits() as u64, /* | Cr4Flags::OSXSAVE.bits()*/ unsafe { cr4() }.bits() as u64 | Cr4Flags::OSXSAVE.bits(),
)?; )?;
vmwrite( vmwrite(
@@ -531,8 +539,8 @@ impl IntelVCpu {
vmwrite(vmcs::guest::RIP, common::linux::LAYOUT_KERNEL_BASE)?; vmwrite(vmcs::guest::RIP, common::linux::LAYOUT_KERNEL_BASE)?;
self.guest_registers.rsi = common::linux::LAYOUT_BOOTPARAM; self.guest_registers.rsi = common::linux::LAYOUT_BOOTPARAM;
//vmwrite(vmcs::control::CR0_READ_SHADOW, vmread(vmcs::guest::CR0)?)?; vmwrite(vmcs::control::CR0_READ_SHADOW, vmread(vmcs::guest::CR0)?)?;
//vmwrite(vmcs::control::CR4_READ_SHADOW, vmread(vmcs::guest::CR4)?)?; vmwrite(vmcs::control::CR4_READ_SHADOW, vmread(vmcs::guest::CR4)?)?;
Ok(()) Ok(())
} }
@@ -542,7 +550,7 @@ impl IntelVCpu {
let pml4_base = cr3 & !0xFFF; // Clear lower 12 bits to get page table base let pml4_base = cr3 & !0xFFF; // Clear lower 12 bits to get page table base
let efer = vmread(x86::vmx::vmcs::guest::IA32_EFER_FULL).unwrap_or(0); let efer = vmread(x86::vmx::vmcs::guest::IA32_EFER_FULL).unwrap_or(0);
let is_long_mode = (efer & (1 << 8)) != 0; // LME bit let is_long_mode = (efer & (1 << 10)) != 0; // LMA bit
if !is_long_mode { if !is_long_mode {
return Ok(vaddr & 0xFFFFFFFF); return Ok(vaddr & 0xFFFFFFFF);