diff options
Diffstat (limited to 'Kernel/Arch')
-rw-r--r-- | Kernel/Arch/x86/Processor.h | 2 | ||||
-rw-r--r-- | Kernel/Arch/x86/common/Processor.cpp | 18 |
2 files changed, 20 insertions, 0 deletions
diff --git a/Kernel/Arch/x86/Processor.h b/Kernel/Arch/x86/Processor.h index 857d3e8462..2717cb1c46 100644 --- a/Kernel/Arch/x86/Processor.h +++ b/Kernel/Arch/x86/Processor.h @@ -173,6 +173,8 @@ public: void early_initialize(u32 cpu); void initialize(u32 cpu); + void detect_hypervisor(); + void idle_begin() { s_idle_cpu_mask.fetch_or(1u << m_cpu, AK::MemoryOrder::memory_order_relaxed); diff --git a/Kernel/Arch/x86/common/Processor.cpp b/Kernel/Arch/x86/common/Processor.cpp index eb0419b524..290c84bc13 100644 --- a/Kernel/Arch/x86/common/Processor.cpp +++ b/Kernel/Arch/x86/common/Processor.cpp @@ -349,6 +349,9 @@ UNMAP_AFTER_INIT void Processor::initialize(u32 cpu) else asm volatile("fnsave %0" : "=m"(s_clean_fpu_state)); + + if (has_feature(CPUFeature::HYPERVISOR)) + detect_hypervisor(); } m_info = new ProcessorInfo(*this); @@ -360,6 +363,21 @@ UNMAP_AFTER_INIT void Processor::initialize(u32 cpu) } } +UNMAP_AFTER_INIT void Processor::detect_hypervisor() +{ + CPUID hypervisor_leaf_range(0x40000000); + + // Get signature of hypervisor. + alignas(sizeof(u32)) char hypervisor_signature_buffer[13]; + *reinterpret_cast<u32*>(hypervisor_signature_buffer) = hypervisor_leaf_range.ebx(); + *reinterpret_cast<u32*>(hypervisor_signature_buffer + 4) = hypervisor_leaf_range.ecx(); + *reinterpret_cast<u32*>(hypervisor_signature_buffer + 8) = hypervisor_leaf_range.edx(); + hypervisor_signature_buffer[12] = '\0'; + StringView hypervisor_signature(hypervisor_signature_buffer); + + dmesgln("CPU[{}]: CPUID hypervisor signature '{}' ({:#x} {:#x} {:#x}), max leaf {:#x}", id(), hypervisor_signature, hypervisor_leaf_range.ebx(), hypervisor_leaf_range.ecx(), hypervisor_leaf_range.edx(), hypervisor_leaf_range.eax()); +} + void Processor::write_raw_gdt_entry(u16 selector, u32 low, u32 high) { u16 i = (selector & 0xfffc) >> 3; |