limine: Make WP flag enabled as per spec
This commit is contained in:
parent
6caaada636
commit
15f111f5c3
|
@ -137,10 +137,9 @@ 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`),
|
||||||
LME is enabled (`EFER`).
|
WP is enabled (`cr0`), LME is enabled (`EFER`), NX is enabled (`EFER`).
|
||||||
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`).
|
||||||
The NX bit will be enabled (NX bit in `EFER`).
|
|
||||||
|
|
||||||
The A20 gate is opened.
|
The A20 gate is opened.
|
||||||
|
|
||||||
|
|
|
@ -699,7 +699,7 @@ FEAT_START
|
||||||
&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, true,
|
||||||
direct_map_offset);
|
direct_map_offset, true);
|
||||||
|
|
||||||
if (smp_info == NULL) {
|
if (smp_info == NULL) {
|
||||||
break;
|
break;
|
||||||
|
@ -800,7 +800,7 @@ FEAT_END
|
||||||
term_runtime = true;
|
term_runtime = true;
|
||||||
|
|
||||||
stivale_spinup(64, want_5lv, &pagemap, entry_point, 0,
|
stivale_spinup(64, want_5lv, &pagemap, entry_point, 0,
|
||||||
reported_addr(stack), true, (uintptr_t)local_gdt);
|
reported_addr(stack), true, true, (uintptr_t)local_gdt);
|
||||||
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,7 +5,7 @@
|
||||||
#include <mm/vmm.h>
|
#include <mm/vmm.h>
|
||||||
|
|
||||||
noreturn void stivale_spinup_32(
|
noreturn void stivale_spinup_32(
|
||||||
int bits, bool level5pg, bool enable_nx, uint32_t pagemap_top_lv,
|
int bits, bool level5pg, bool enable_nx, bool wp, uint32_t pagemap_top_lv,
|
||||||
uint32_t entry_point_lo, uint32_t entry_point_hi,
|
uint32_t entry_point_lo, uint32_t entry_point_hi,
|
||||||
uint32_t stivale_struct_lo, uint32_t stivale_struct_hi,
|
uint32_t stivale_struct_lo, uint32_t stivale_struct_hi,
|
||||||
uint32_t stack_lo, uint32_t stack_hi,
|
uint32_t stack_lo, uint32_t stack_hi,
|
||||||
|
@ -38,6 +38,15 @@ noreturn void stivale_spinup_32(
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (wp) {
|
||||||
|
asm volatile (
|
||||||
|
"movl %%cr0, %%eax\n\t"
|
||||||
|
"btsl $16, %%eax\n\t"
|
||||||
|
"movl %%eax, %%cr0\n\t"
|
||||||
|
::: "eax", "memory"
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
asm volatile (
|
asm volatile (
|
||||||
"cld\n\t"
|
"cld\n\t"
|
||||||
"movl %%eax, %%cr3\n\t"
|
"movl %%eax, %%cr3\n\t"
|
||||||
|
|
|
@ -368,7 +368,7 @@ bool stivale_load(char *config, char *cmdline) {
|
||||||
|
|
||||||
stivale_spinup(bits, want_5lv, &pagemap,
|
stivale_spinup(bits, want_5lv, &pagemap,
|
||||||
entry_point, REPORTED_ADDR((uint64_t)(uintptr_t)stivale_struct),
|
entry_point, REPORTED_ADDR((uint64_t)(uintptr_t)stivale_struct),
|
||||||
stivale_hdr.stack, false, (uintptr_t)local_gdt);
|
stivale_hdr.stack, false, false, (uintptr_t)local_gdt);
|
||||||
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
|
|
||||||
|
@ -487,7 +487,7 @@ noreturn void stivale_spinup_32(
|
||||||
noreturn void stivale_spinup(
|
noreturn void stivale_spinup(
|
||||||
int bits, bool level5pg, pagemap_t *pagemap,
|
int bits, bool level5pg, pagemap_t *pagemap,
|
||||||
uint64_t entry_point, uint64_t _stivale_struct, uint64_t stack,
|
uint64_t entry_point, uint64_t _stivale_struct, uint64_t stack,
|
||||||
bool enable_nx, uint32_t local_gdt) {
|
bool enable_nx, bool wp, uint32_t local_gdt) {
|
||||||
#if bios == 1
|
#if bios == 1
|
||||||
if (bits == 64) {
|
if (bits == 64) {
|
||||||
// If we're going 64, we might as well call this BIOS interrupt
|
// If we're going 64, we might as well call this BIOS interrupt
|
||||||
|
@ -509,8 +509,8 @@ noreturn void stivale_spinup(
|
||||||
|
|
||||||
irq_flush_type = IRQ_PIC_APIC_FLUSH;
|
irq_flush_type = IRQ_PIC_APIC_FLUSH;
|
||||||
|
|
||||||
common_spinup(stivale_spinup_32, 11,
|
common_spinup(stivale_spinup_32, 12,
|
||||||
bits, level5pg, enable_nx, (uint32_t)(uintptr_t)pagemap->top_level,
|
bits, level5pg, enable_nx, wp, (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)_stivale_struct, (uint32_t)(_stivale_struct >> 32),
|
(uint32_t)_stivale_struct, (uint32_t)(_stivale_struct >> 32),
|
||||||
(uint32_t)stack, (uint32_t)(stack >> 32), local_gdt);
|
(uint32_t)stack, (uint32_t)(stack >> 32), local_gdt);
|
||||||
|
|
|
@ -17,6 +17,6 @@ pagemap_t stivale_build_pagemap(bool level5pg, bool unmap_null, struct elf_range
|
||||||
noreturn void stivale_spinup(
|
noreturn void stivale_spinup(
|
||||||
int bits, bool level5pg, pagemap_t *pagemap,
|
int bits, bool level5pg, pagemap_t *pagemap,
|
||||||
uint64_t entry_point, uint64_t stivale_struct, uint64_t stack,
|
uint64_t entry_point, uint64_t stivale_struct, uint64_t stack,
|
||||||
bool enable_nx, uint32_t local_gdt);
|
bool enable_nx, bool wp, uint32_t local_gdt);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -765,7 +765,8 @@ have_tm_tag:;
|
||||||
&cpu_count, &bsp_lapic_id,
|
&cpu_count, &bsp_lapic_id,
|
||||||
bits == 64, want_5lv,
|
bits == 64, want_5lv,
|
||||||
pagemap, smp_hdr_tag->flags & 1, want_pmrs,
|
pagemap, smp_hdr_tag->flags & 1, want_pmrs,
|
||||||
stivale2_hdr.flags & (1 << 1) ? direct_map_offset : 0);
|
stivale2_hdr.flags & (1 << 1) ? direct_map_offset : 0,
|
||||||
|
want_pmrs);
|
||||||
|
|
||||||
if (smp_info != NULL) {
|
if (smp_info != NULL) {
|
||||||
tag->tag.identifier = STIVALE2_STRUCT_TAG_SMP_ID;
|
tag->tag.identifier = STIVALE2_STRUCT_TAG_SMP_ID;
|
||||||
|
@ -833,7 +834,7 @@ have_tm_tag:;
|
||||||
|
|
||||||
stivale_spinup(bits, want_5lv, &pagemap, entry_point,
|
stivale_spinup(bits, want_5lv, &pagemap, entry_point,
|
||||||
REPORTED_ADDR((uint64_t)(uintptr_t)stivale2_struct),
|
REPORTED_ADDR((uint64_t)(uintptr_t)stivale2_struct),
|
||||||
stivale2_hdr.stack, want_pmrs, (uintptr_t)local_gdt);
|
stivale2_hdr.stack, want_pmrs, want_pmrs, (uintptr_t)local_gdt);
|
||||||
|
|
||||||
__builtin_unreachable();
|
__builtin_unreachable();
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,7 @@ struct trampoline_passed_info {
|
||||||
static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
|
static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
|
||||||
struct smp_information *info_struct,
|
struct smp_information *info_struct,
|
||||||
bool longmode, bool lv5, uint32_t pagemap,
|
bool longmode, bool lv5, uint32_t pagemap,
|
||||||
bool x2apic, bool nx, uint64_t hhdm) {
|
bool x2apic, bool nx, uint64_t hhdm, bool wp) {
|
||||||
size_t trampoline_size = (size_t)_binary_smp_trampoline_bin_end
|
size_t trampoline_size = (size_t)_binary_smp_trampoline_bin_end
|
||||||
- (size_t)_binary_smp_trampoline_bin_start;
|
- (size_t)_binary_smp_trampoline_bin_start;
|
||||||
|
|
||||||
|
@ -78,6 +78,7 @@ static bool smp_start_ap(uint32_t lapic_id, struct gdtr *gdtr,
|
||||||
passed_info->smp_tpl_target_mode = ((uint32_t)x2apic << 2)
|
passed_info->smp_tpl_target_mode = ((uint32_t)x2apic << 2)
|
||||||
| ((uint32_t)lv5 << 1)
|
| ((uint32_t)lv5 << 1)
|
||||||
| ((uint32_t)nx << 3)
|
| ((uint32_t)nx << 3)
|
||||||
|
| ((uint32_t)wp << 4)
|
||||||
| (uint32_t)longmode;
|
| (uint32_t)longmode;
|
||||||
passed_info->smp_tpl_gdt = *gdtr;
|
passed_info->smp_tpl_gdt = *gdtr;
|
||||||
passed_info->smp_tpl_booted_flag = 0;
|
passed_info->smp_tpl_booted_flag = 0;
|
||||||
|
@ -122,7 +123,8 @@ struct smp_information *init_smp(size_t header_hack_size,
|
||||||
pagemap_t pagemap,
|
pagemap_t pagemap,
|
||||||
bool x2apic,
|
bool x2apic,
|
||||||
bool nx,
|
bool nx,
|
||||||
uint64_t hhdm) {
|
uint64_t hhdm,
|
||||||
|
bool wp) {
|
||||||
if (!lapic_check())
|
if (!lapic_check())
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
@ -227,7 +229,7 @@ struct smp_information *init_smp(size_t header_hack_size,
|
||||||
// Try to start the AP
|
// Try to start the AP
|
||||||
if (!smp_start_ap(lapic->lapic_id, &gdtr, info_struct,
|
if (!smp_start_ap(lapic->lapic_id, &gdtr, info_struct,
|
||||||
longmode, lv5, (uintptr_t)pagemap.top_level,
|
longmode, lv5, (uintptr_t)pagemap.top_level,
|
||||||
x2apic, nx, hhdm)) {
|
x2apic, nx, hhdm, wp)) {
|
||||||
print("smp: FAILED to bring-up AP\n");
|
print("smp: FAILED to bring-up AP\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
@ -264,7 +266,7 @@ struct smp_information *init_smp(size_t header_hack_size,
|
||||||
// Try to start the AP
|
// Try to start the AP
|
||||||
if (!smp_start_ap(x2lapic->x2apic_id, &gdtr, info_struct,
|
if (!smp_start_ap(x2lapic->x2apic_id, &gdtr, info_struct,
|
||||||
longmode, lv5, (uintptr_t)pagemap.top_level,
|
longmode, lv5, (uintptr_t)pagemap.top_level,
|
||||||
true, nx, hhdm)) {
|
true, nx, hhdm, wp)) {
|
||||||
print("smp: FAILED to bring-up AP\n");
|
print("smp: FAILED to bring-up AP\n");
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
|
@ -23,6 +23,7 @@ struct smp_information *init_smp(size_t header_hack_size,
|
||||||
pagemap_t pagemap,
|
pagemap_t pagemap,
|
||||||
bool x2apic,
|
bool x2apic,
|
||||||
bool nx,
|
bool nx,
|
||||||
uint64_t hhdm);
|
uint64_t hhdm,
|
||||||
|
bool wp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -101,6 +101,14 @@ smp_trampoline:
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
.nonx:
|
.nonx:
|
||||||
|
test dword [rbx + passed_info.target_mode], (1 << 4)
|
||||||
|
jz .nowp
|
||||||
|
|
||||||
|
mov rax, cr0
|
||||||
|
bts rax, 16
|
||||||
|
mov cr0, rax
|
||||||
|
|
||||||
|
.nowp:
|
||||||
mov rax, qword [rbx + passed_info.hhdm]
|
mov rax, qword [rbx + passed_info.hhdm]
|
||||||
add qword [rbx + passed_info.gdtr + 2], rax
|
add qword [rbx + passed_info.gdtr + 2], rax
|
||||||
lgdt [rbx + passed_info.gdtr]
|
lgdt [rbx + passed_info.gdtr]
|
||||||
|
|
Loading…
Reference in New Issue