From d3385da3e339b8796e8ba558cdadee877fe18123 Mon Sep 17 00:00:00 2001 From: mintsuki Date: Fri, 2 Sep 2022 03:31:22 +0200 Subject: [PATCH] limine: Make NX feature not mandatory --- PROTOCOL.md | 2 +- common/mm/vmm.c | 7 ------- common/mm/vmm.h | 1 - common/protos/limine.c | 16 +++++++++++----- common/protos/limine_32.asm_x86 | 3 +++ 5 files changed, 15 insertions(+), 14 deletions(-) diff --git a/PROTOCOL.md b/PROTOCOL.md index 5ace4d65..616789c0 100644 --- a/PROTOCOL.md +++ b/PROTOCOL.md @@ -139,7 +139,7 @@ IF flag, VM flag, and direction flag are cleared on entry. Other flags undefined. PG is enabled (`cr0`), PE is enabled (`cr0`), PAE is enabled (`cr4`), -WP is enabled (`cr0`), LME is enabled (`EFER`), NX is enabled (`EFER`). +WP is enabled (`cr0`), LME is enabled (`EFER`), NX is enabled (`EFER`) if available. If 5-level paging is requested and available, then 5-level paging is enabled (LA57 bit in `cr4`). diff --git a/common/mm/vmm.c b/common/mm/vmm.c index a1103572..e2bdd7da 100644 --- a/common/mm/vmm.c +++ b/common/mm/vmm.c @@ -28,13 +28,6 @@ static pt_entry_t *get_next_level(pagemap_t pagemap, pt_entry_t *current_level, #define PT_IS_LARGE(x) (((x) & (PT_FLAG_VALID | PT_FLAG_LARGE)) == (PT_FLAG_VALID | PT_FLAG_LARGE)) #define PT_TO_VMM_FLAGS(x) ((x) & (PT_FLAG_WRITE | PT_FLAG_NX)) -void vmm_assert_nx(void) { - uint32_t a, b, c, d; - if (!cpuid(0x80000001, 0, &a, &b, &c, &d) || !(d & (1 << 20))) { - panic(false, "vmm: NX functionality not available on this CPU."); - } -} - pagemap_t new_pagemap(int lv) { pagemap_t pagemap; pagemap.levels = lv; diff --git a/common/mm/vmm.h b/common/mm/vmm.h index 3031da3b..3927c9bc 100644 --- a/common/mm/vmm.h +++ b/common/mm/vmm.h @@ -21,7 +21,6 @@ enum page_size { Size1GiB }; -void vmm_assert_nx(void); pagemap_t new_pagemap(int lv); void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size); diff --git a/common/protos/limine.c b/common/protos/limine.c index f565743a..4b2735da 100644 --- a/common/protos/limine.c +++ b/common/protos/limine.c @@ -862,6 +862,14 @@ FEAT_END efi_exit_boot_services(); #endif +#if defined (__x86_64__) || defined (__i386__) + // Check if we have NX + bool nx_available = false; + if (cpuid(0x80000001, 0, &eax, &ebx, &ecx, &edx) && (edx & (1 << 20))) { + nx_available = true; + } +#endif + // SMP FEAT_START struct limine_smp_request *smp_request = get_request(LIMINE_SMP_REQUEST); @@ -877,7 +885,7 @@ FEAT_START smp_info = init_smp(0, (void **)&smp_array, &cpu_count, &bsp_lapic_id, true, want_5lv, - pagemap, smp_request->flags & LIMINE_SMP_X2APIC, true, + pagemap, smp_request->flags & LIMINE_SMP_X2APIC, nx_available, direct_map_offset, true); #elif defined (__aarch64__) uint64_t bsp_mpidr; @@ -1004,8 +1012,6 @@ FEAT_END rm_int(0x15, &r, &r); #endif - vmm_assert_nx(); - pic_mask_all(); io_apic_mask_all(); @@ -1013,11 +1019,11 @@ FEAT_END uint64_t reported_stack = reported_addr(stack); - common_spinup(limine_spinup_32, 7, + common_spinup(limine_spinup_32, 8, want_5lv, (uint32_t)(uintptr_t)pagemap.top_level, (uint32_t)entry_point, (uint32_t)(entry_point >> 32), (uint32_t)reported_stack, (uint32_t)(reported_stack >> 32), - (uint32_t)(uintptr_t)local_gdt); + (uint32_t)(uintptr_t)local_gdt, nx_available); #elif defined (__aarch64__) vmm_assert_4k_pages(); diff --git a/common/protos/limine_32.asm_x86 b/common/protos/limine_32.asm_x86 index 94ac426f..60a7e0a1 100644 --- a/common/protos/limine_32.asm_x86 +++ b/common/protos/limine_32.asm_x86 @@ -5,10 +5,13 @@ section .text global limine_spinup_32 limine_spinup_32: ; Enable EFER.NXE + cmp dword [esp+32], 0 ; nx_available + je .no_nx mov ecx, 0xc0000080 rdmsr bts eax, 11 wrmsr + .no_nx: ; Enable CR4.LA57 cmp dword [esp+4], 0 ; level5pg