1
Fork 0
mirror of https://github.com/RGBCube/serenity synced 2025-07-08 17:27:35 +00:00

Kernel: Move CPU feature detection to Arch/x86/CPU.{cpp.h}

We now refuse to boot on machines that don't support PAE since all
of our paging code depends on it.

Also let's only enable SSE and PGE support if the CPU advertises it.
This commit is contained in:
Andreas Kling 2020-01-01 12:56:21 +01:00
parent 3d59db4be4
commit 5aeaab601e
6 changed files with 70 additions and 44 deletions

View file

@ -21,19 +21,8 @@ MemoryManager& MM
return *s_the;
}
void MemoryManager::detect_cpu_features()
{
CPUID extended_processor_info(0x80000001);
m_has_nx_support = (extended_processor_info.edx() & (1 << 20)) != 0;
CPUID extended_features(0x7);
m_has_smep_support = (extended_features.ebx() & (1 << 7)) != 0;
}
MemoryManager::MemoryManager(u32 physical_address_for_kernel_page_tables)
{
detect_cpu_features();
m_kernel_page_directory = PageDirectory::create_at_fixed_address(PhysicalAddress(physical_address_for_kernel_page_tables));
for (size_t i = 0; i < 4; ++i) {
m_low_page_tables[i] = (PageTableEntry*)(physical_address_for_kernel_page_tables + PAGE_SIZE * (5 + i));
@ -51,6 +40,11 @@ MemoryManager::~MemoryManager()
void MemoryManager::initialize_paging()
{
if (!g_cpu_supports_pae) {
kprintf("x86: Cannot boot on machines without PAE support.\n");
hang();
}
#ifdef MM_DEBUG
dbgprintf("MM: Kernel page directory @ %p\n", kernel_page_directory().cr3());
#endif
@ -71,14 +65,14 @@ void MemoryManager::initialize_paging()
// Disable execution from 0MB through 1MB (BIOS data, legacy things, ...)
for (size_t i = 0; i < (1 * MB); ++i) {
auto& pte = ensure_pte(kernel_page_directory(), VirtualAddress(i));
if (m_has_nx_support)
if (g_cpu_supports_nx)
pte.set_execute_disabled(true);
}
// Disable execution from 2MB through 8MB (kmalloc, kmalloc_eternal, slabs, page tables, ...)
for (size_t i = 1; i < 4; ++i) {
auto& pte = kernel_page_directory().table().directory(0)[i];
if (m_has_nx_support)
if (g_cpu_supports_nx)
pte.set_execute_disabled(true);
}
@ -181,40 +175,44 @@ void MemoryManager::initialize_paging()
dbgprintf("MM: Installing page directory\n");
#endif
// Turn on CR4.PGE so the CPU will respect the G bit in page tables.
asm volatile(
"mov %cr4, %eax\n"
"orl $0x80, %eax\n"
"mov %eax, %cr4\n");
// Turn on CR4.PAE
asm volatile(
"mov %cr4, %eax\n"
"orl $0x20, %eax\n"
"mov %eax, %cr4\n");
if (m_has_smep_support) {
kprintf("MM: SMEP support detected; enabling\n");
// Turn on CR4.SMEP
asm volatile(
"mov %cr4, %eax\n"
"orl $0x100000, %eax\n"
"mov %eax, %cr4\n");
if (g_cpu_supports_pge) {
// Turn on CR4.PGE so the CPU will respect the G bit in page tables.
asm volatile(
"mov %cr4, %eax\n"
"orl $0x80, %eax\n"
"mov %eax, %cr4\n");
kprintf("x86: PGE support enabled\n");
} else {
kprintf("MM: SMEP support not detected\n");
kprintf("x86: PGE support not detected\n");
}
if (m_has_nx_support) {
kprintf("MM: NX support detected; enabling NXE flag\n");
if (g_cpu_supports_smep) {
// Turn on CR4.SMEP
asm volatile(
"mov %cr4, %eax\n"
"orl $0x100000, %eax\n"
"mov %eax, %cr4\n");
kprintf("x86: SMEP support enabled\n");
} else {
kprintf("x86: SMEP support not detected\n");
}
if (g_cpu_supports_nx) {
// Turn on IA32_EFER.NXE
asm volatile(
"movl $0xc0000080, %ecx\n"
"rdmsr\n"
"orl $0x800, %eax\n"
"wrmsr\n");
kprintf("x86: NX support enabled\n");
} else {
kprintf("MM: NX support not detected\n");
kprintf("x86: NX support not detected\n");
}
asm volatile("movl %%eax, %%cr3" ::"a"(kernel_page_directory().cr3()));