limine: Make NX feature not mandatory
This commit is contained in:
parent
c44f514738
commit
d3385da3e3
|
@ -139,7 +139,7 @@ IF flag, VM flag, and direction flag are cleared on entry. Other flags
|
||||||
undefined.
|
undefined.
|
||||||
|
|
||||||
PG is enabled (`cr0`), PE is enabled (`cr0`), PAE is enabled (`cr4`),
|
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
|
If 5-level paging is requested and available, then 5-level paging is enabled
|
||||||
(LA57 bit in `cr4`).
|
(LA57 bit in `cr4`).
|
||||||
|
|
||||||
|
|
|
@ -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_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))
|
#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 new_pagemap(int lv) {
|
||||||
pagemap_t pagemap;
|
pagemap_t pagemap;
|
||||||
pagemap.levels = lv;
|
pagemap.levels = lv;
|
||||||
|
|
|
@ -21,7 +21,6 @@ enum page_size {
|
||||||
Size1GiB
|
Size1GiB
|
||||||
};
|
};
|
||||||
|
|
||||||
void vmm_assert_nx(void);
|
|
||||||
pagemap_t new_pagemap(int lv);
|
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);
|
void map_page(pagemap_t pagemap, uint64_t virt_addr, uint64_t phys_addr, uint64_t flags, enum page_size page_size);
|
||||||
|
|
||||||
|
|
|
@ -862,6 +862,14 @@ FEAT_END
|
||||||
efi_exit_boot_services();
|
efi_exit_boot_services();
|
||||||
#endif
|
#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
|
// SMP
|
||||||
FEAT_START
|
FEAT_START
|
||||||
struct limine_smp_request *smp_request = get_request(LIMINE_SMP_REQUEST);
|
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,
|
smp_info = init_smp(0, (void **)&smp_array,
|
||||||
&cpu_count, &bsp_lapic_id,
|
&cpu_count, &bsp_lapic_id,
|
||||||
true, want_5lv,
|
true, want_5lv,
|
||||||
pagemap, smp_request->flags & LIMINE_SMP_X2APIC, true,
|
pagemap, smp_request->flags & LIMINE_SMP_X2APIC, nx_available,
|
||||||
direct_map_offset, true);
|
direct_map_offset, true);
|
||||||
#elif defined (__aarch64__)
|
#elif defined (__aarch64__)
|
||||||
uint64_t bsp_mpidr;
|
uint64_t bsp_mpidr;
|
||||||
|
@ -1004,8 +1012,6 @@ FEAT_END
|
||||||
rm_int(0x15, &r, &r);
|
rm_int(0x15, &r, &r);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
vmm_assert_nx();
|
|
||||||
|
|
||||||
pic_mask_all();
|
pic_mask_all();
|
||||||
io_apic_mask_all();
|
io_apic_mask_all();
|
||||||
|
|
||||||
|
@ -1013,11 +1019,11 @@ FEAT_END
|
||||||
|
|
||||||
uint64_t reported_stack = reported_addr(stack);
|
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,
|
want_5lv, (uint32_t)(uintptr_t)pagemap.top_level,
|
||||||
(uint32_t)entry_point, (uint32_t)(entry_point >> 32),
|
(uint32_t)entry_point, (uint32_t)(entry_point >> 32),
|
||||||
(uint32_t)reported_stack, (uint32_t)(reported_stack >> 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__)
|
#elif defined (__aarch64__)
|
||||||
vmm_assert_4k_pages();
|
vmm_assert_4k_pages();
|
||||||
|
|
||||||
|
|
|
@ -5,10 +5,13 @@ section .text
|
||||||
global limine_spinup_32
|
global limine_spinup_32
|
||||||
limine_spinup_32:
|
limine_spinup_32:
|
||||||
; Enable EFER.NXE
|
; Enable EFER.NXE
|
||||||
|
cmp dword [esp+32], 0 ; nx_available
|
||||||
|
je .no_nx
|
||||||
mov ecx, 0xc0000080
|
mov ecx, 0xc0000080
|
||||||
rdmsr
|
rdmsr
|
||||||
bts eax, 11
|
bts eax, 11
|
||||||
wrmsr
|
wrmsr
|
||||||
|
.no_nx:
|
||||||
|
|
||||||
; Enable CR4.LA57
|
; Enable CR4.LA57
|
||||||
cmp dword [esp+4], 0 ; level5pg
|
cmp dword [esp+4], 0 ; level5pg
|
||||||
|
|
Loading…
Reference in New Issue