Skip to content

Commit 83b2220

Browse files
committed
x86_64: various fixes for no-execute pages
1 parent bd74d15 commit 83b2220

File tree

4 files changed

+25
-16
lines changed

4 files changed

+25
-16
lines changed

src/platform/x86_64/apic/apic.c

+1-7
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,9 @@ int apicInit() {
3434
while(1);
3535
}
3636

37-
// check for PAE/NX
37+
// check for syscall/sysret instructions
3838
memset(&regs, 0, sizeof(CPUIDRegisters));
3939
readCPUID(0x80000001, &regs);
40-
if(!(regs.edx & (1 << 20))) {
41-
KERROR("CPU doesn't support PAE/NX\n");
42-
while(1);
43-
}
44-
45-
// and syscall/sysret instructions
4640
if(!(regs.edx & (1 << 11))) {
4741
KERROR("CPU doesn't support fast syscall/sysret\n");
4842
while(1);

src/platform/x86_64/apic/smp.c

-3
Original file line numberDiff line numberDiff line change
@@ -76,9 +76,6 @@ void smpCPUInfoSetup() {
7676
readCPUID(1, &regs);
7777
uint8_t apicID = regs.ebx >> 24;
7878

79-
// enable NX
80-
writeMSR(MSR_EFER, readMSR(MSR_EFER) | MSR_EFER_NX_ENABLE);
81-
8279
// enable fast fxsave/fxrstor if supported
8380
memset(&regs, 0, sizeof(CPUIDRegisters));
8481
readCPUID(0x80000001, &regs);

src/platform/x86_64/apic/smpstub.asm

+8
Original file line numberDiff line numberDiff line change
@@ -59,6 +59,14 @@ times 0x100 - ($-$$) nop
5959
mov fs, rax
6060
mov gs, rax
6161

62+
; enable NX - this is necessary here because the pages mapping the stack
63+
; are marked as no-execute, so we cannot wait until the C code to do this
64+
; else we get unhandled page faults :)
65+
mov ecx, 0xC0000080
66+
rdmsr
67+
or eax, 0x800
68+
wrmsr
69+
6270
mov rax, 0x1FF0 ; top of stack pointer
6371
mov rsp, [rax]
6472
mov rbp, rsp

src/platform/x86_64/cpu/paging.c

+16-6
Original file line numberDiff line numberDiff line change
@@ -20,9 +20,19 @@ static uint64_t *kernelPagingRoot; // pml4 -- PHYSICAL ADDRESS
2020
*/
2121

2222
int platformPagingSetup() {
23-
// identity map the lower memory
24-
// this is already true but we need to replace the paging structs built
25-
// by the boot loader
23+
// check for PAE/NX
24+
CPUIDRegisters regs;
25+
memset(&regs, 0, sizeof(CPUIDRegisters));
26+
readCPUID(0x80000001, &regs);
27+
if(!(regs.edx & (1 << 20))) {
28+
KERROR("CPU doesn't support PAE/NX\n");
29+
while(1);
30+
}
31+
32+
// enable no-execute pages
33+
writeMSR(MSR_EFER, readMSR(MSR_EFER) | MSR_EFER_NX_ENABLE);
34+
35+
// map physical memory into the higher half
2636
uint64_t *pml4 = (uint64_t *)pmmAllocate(); // 512 GiB per entry
2737
uint64_t *pdp = (uint64_t *)pmmAllocate(); // 1 GiB per entry
2838

@@ -58,7 +68,7 @@ int platformPagingSetup() {
5868
writeCR3((uint64_t)pml4);
5969

6070
ttyRemapFramebuffer();
61-
KDEBUG("kernel paging structures created, identity mapped %d GiB\n", KERNEL_BASE_MAPPED);
71+
KDEBUG("kernel paging structures created, mapped %d GiB at 0x%X\n", KERNEL_BASE_MAPPED, KERNEL_MMIO_BASE);
6272
kernelPagingRoot = pml4;
6373
return 0;
6474
}
@@ -137,7 +147,7 @@ uintptr_t platformGetPage(int *flags, uintptr_t addr) {
137147
if(!(ptEntry & PT_PAGE_NXE)) *flags |= PLATFORM_PAGE_EXEC;
138148
if(ptEntry & PT_PAGE_NO_CACHE) *flags |= PLATFORM_PAGE_NO_CACHE;
139149

140-
return (ptEntry & ~(PAGE_SIZE-1)) | offset;
150+
return (ptEntry & ~(PAGE_SIZE-1) & ~(PT_PAGE_NXE)) | offset;
141151
}
142152

143153
/* platformMapPage(): maps a physical address to a logical address
@@ -205,7 +215,7 @@ uintptr_t platformMapPage(uintptr_t logical, uintptr_t physical, int flags) {
205215
if(flags & PLATFORM_PAGE_PRESENT) parsedFlags |= PT_PAGE_PRESENT;
206216
if(flags & PLATFORM_PAGE_WRITE) parsedFlags |= PT_PAGE_RW;
207217
if(flags & PLATFORM_PAGE_USER) parsedFlags |= PT_PAGE_USER;
208-
if(!flags & PLATFORM_PAGE_EXEC) parsedFlags |= PT_PAGE_NXE;
218+
if(!(flags & PLATFORM_PAGE_EXEC)) parsedFlags |= PT_PAGE_NXE;
209219
if(flags & PLATFORM_PAGE_NO_CACHE) parsedFlags |= PT_PAGE_NO_CACHE | PT_PAGE_WRITE_THROUGH;
210220

211221
pt[ptIndex] = physical | parsedFlags;

0 commit comments

Comments
 (0)