mirror of
https://github.com/memtest86plus/memtest86plus.git
synced 2025-02-25 18:55:23 -06:00
WIP BROKEN NX enablement, for now only for the second page directory.
TODO: * selective NX enablement on pd0, pd1 and pd3. Unconditional NX on the whole pd3 makes memtest86+ reboot in a QEMU-emulated computer. * if supported on all x86_64 CPUs, simply enable long mode and NX simultaneously ? A real K8 dual-core processor didn't seem to hate it, at least. * startup code: NX enablement for x86, on capable computers (CPUID 0x80000001, edx bit 20). * set the appropriate flag in the headers.
This commit is contained in:
parent
a541469850
commit
61afe1143b
@ -104,6 +104,7 @@ startup:
|
|||||||
movl %esi, boot_params_addr@GOTOFF(%ebx)
|
movl %esi, boot_params_addr@GOTOFF(%ebx)
|
||||||
|
|
||||||
# ...and check if the processor supports long mode.
|
# ...and check if the processor supports long mode.
|
||||||
|
# TODO and NX
|
||||||
|
|
||||||
movl $0x80000000, %eax # check if function 0x80000001 is available
|
movl $0x80000000, %eax # check if function 0x80000001 is available
|
||||||
pushl %ebx # ebx is overwritten by cpuid
|
pushl %ebx # ebx is overwritten by cpuid
|
||||||
@ -206,7 +207,7 @@ init_idt_descr:
|
|||||||
jz 1f # bail if not supported
|
jz 1f # bail if not supported
|
||||||
|
|
||||||
movl %cr4, %eax # enable PAE
|
movl %cr4, %eax # enable PAE
|
||||||
orl $0x00000020, %eax
|
orb $0x20, %al
|
||||||
movl %eax, %cr4
|
movl %eax, %cr4
|
||||||
|
|
||||||
leal pdp@GOTOFF(%ebx), %eax # set the page directory base address
|
leal pdp@GOTOFF(%ebx), %eax # set the page directory base address
|
||||||
@ -219,7 +220,7 @@ init_idt_descr:
|
|||||||
|
|
||||||
movl $0xc0000080, %ecx # enable long mode
|
movl $0xc0000080, %ecx # enable long mode
|
||||||
rdmsr
|
rdmsr
|
||||||
orl $0x00000100, %eax
|
orb $0x01, %ah
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
leal pml4@GOTOFF(%ebx), %eax # set the page directory base address
|
leal pml4@GOTOFF(%ebx), %eax # set the page directory base address
|
||||||
@ -648,17 +649,17 @@ gdt_end:
|
|||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
.macro ptes64 start, count=64
|
.macro ptes64 start, flags, count=64
|
||||||
.quad \start + 0x0000000 + 0x83
|
.quad \start + 0x0000000 + \flags
|
||||||
.quad \start + 0x0200000 + 0x83
|
.quad \start + 0x0200000 + \flags
|
||||||
.quad \start + 0x0400000 + 0x83
|
.quad \start + 0x0400000 + \flags
|
||||||
.quad \start + 0x0600000 + 0x83
|
.quad \start + 0x0600000 + \flags
|
||||||
.quad \start + 0x0800000 + 0x83
|
.quad \start + 0x0800000 + \flags
|
||||||
.quad \start + 0x0A00000 + 0x83
|
.quad \start + 0x0A00000 + \flags
|
||||||
.quad \start + 0x0C00000 + 0x83
|
.quad \start + 0x0C00000 + \flags
|
||||||
.quad \start + 0x0E00000 + 0x83
|
.quad \start + 0x0E00000 + \flags
|
||||||
.if \count-1
|
.if \count-1
|
||||||
ptes64 "(\start+0x01000000)",\count-1
|
ptes64 "(\start+0x01000000)", \flags, \count-1
|
||||||
.endif
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -702,22 +703,22 @@ pdp:
|
|||||||
.align 4096
|
.align 4096
|
||||||
.globl pd0
|
.globl pd0
|
||||||
pd0:
|
pd0:
|
||||||
ptes64 0x0000000000000000
|
ptes64 0x0000000000000000,0x0000000000000083
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
.globl pd1
|
.globl pd1
|
||||||
pd1:
|
pd1:
|
||||||
ptes64 0x0000000040000000
|
ptes64 0x0000000040000000,0x0000000000000083
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
.globl pd2
|
.globl pd2
|
||||||
pd2:
|
pd2:
|
||||||
ptes64 0x0000000080000000
|
ptes64 0x0000000080000000,0x0000000000000083
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
.globl pd3
|
.globl pd3
|
||||||
pd3:
|
pd3:
|
||||||
ptes64 0x00000000C0000000
|
ptes64 0x00000000C0000000,0x0000000000000083
|
||||||
|
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
|
@ -71,14 +71,14 @@ startup32:
|
|||||||
# Enable PAE.
|
# Enable PAE.
|
||||||
|
|
||||||
movl %cr4, %eax
|
movl %cr4, %eax
|
||||||
orl $0x20, %eax
|
orb $0x20, %al
|
||||||
movl %eax, %cr4
|
movl %eax, %cr4
|
||||||
|
|
||||||
# Enable long mode.
|
# Enable long mode.
|
||||||
|
|
||||||
movl $0xc0000080, %ecx
|
movl $0xc0000080, %ecx
|
||||||
rdmsr
|
rdmsr
|
||||||
orl $0x00000100, %eax
|
orb $0x01, %ah
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
# Enable paging and protection.
|
# Enable paging and protection.
|
||||||
@ -162,6 +162,13 @@ startup:
|
|||||||
leaq _stacks(%rip), %rsp
|
leaq _stacks(%rip), %rsp
|
||||||
addq %rax, %rsp
|
addq %rax, %rsp
|
||||||
|
|
||||||
|
# Enable NX.
|
||||||
|
|
||||||
|
movl $0xc0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
orb $0x08, %ah
|
||||||
|
wrmsr
|
||||||
|
|
||||||
# Initialise the pml4 and pdp tables.
|
# Initialise the pml4 and pdp tables.
|
||||||
|
|
||||||
leaq pml4(%rip), %rcx
|
leaq pml4(%rip), %rcx
|
||||||
@ -255,8 +262,8 @@ flush: movw $KERNEL_DS, %ax
|
|||||||
# Enable SSE.
|
# Enable SSE.
|
||||||
|
|
||||||
movq %cr0, %rax
|
movq %cr0, %rax
|
||||||
andw $0xfffb, %ax # clear coprocessor emulation bit
|
andb $0xfb, %al # clear coprocessor emulation bit
|
||||||
orw $0x0002, %ax # set coprocessor monitoring bit
|
orb $0x02, %al # set coprocessor monitoring bit
|
||||||
mov %rax, %cr0
|
mov %rax, %cr0
|
||||||
movq %cr4, %rax
|
movq %cr4, %rax
|
||||||
orw $0x0600, %ax # set OSFXSR and OSXMMEXCPT
|
orw $0x0600, %ax # set OSFXSR and OSXMMEXCPT
|
||||||
@ -465,17 +472,17 @@ gdt_end:
|
|||||||
|
|
||||||
.data
|
.data
|
||||||
|
|
||||||
.macro ptes64 start, count=64
|
.macro ptes64 start, flags, count=64
|
||||||
.quad \start + 0x0000000 + 0x83
|
.quad \start + 0x0000000 + \flags
|
||||||
.quad \start + 0x0200000 + 0x83
|
.quad \start + 0x0200000 + \flags
|
||||||
.quad \start + 0x0400000 + 0x83
|
.quad \start + 0x0400000 + \flags
|
||||||
.quad \start + 0x0600000 + 0x83
|
.quad \start + 0x0600000 + \flags
|
||||||
.quad \start + 0x0800000 + 0x83
|
.quad \start + 0x0800000 + \flags
|
||||||
.quad \start + 0x0A00000 + 0x83
|
.quad \start + 0x0A00000 + \flags
|
||||||
.quad \start + 0x0C00000 + 0x83
|
.quad \start + 0x0C00000 + \flags
|
||||||
.quad \start + 0x0E00000 + 0x83
|
.quad \start + 0x0E00000 + \flags
|
||||||
.if \count-1
|
.if \count-1
|
||||||
ptes64 "(\start+0x01000000)",\count-1
|
ptes64 "(\start+0x01000000)", \flags, \count-1
|
||||||
.endif
|
.endif
|
||||||
.endm
|
.endm
|
||||||
|
|
||||||
@ -514,22 +521,22 @@ pdp:
|
|||||||
.align 4096
|
.align 4096
|
||||||
.globl pd0
|
.globl pd0
|
||||||
pd0:
|
pd0:
|
||||||
ptes64 0x0000000000000000
|
ptes64 0x0000000000000000,0x0000000000000083
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
.globl pd1
|
.globl pd1
|
||||||
pd1:
|
pd1:
|
||||||
ptes64 0x0000000040000000
|
ptes64 0x0000000040000000,0x0000000000000083
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
.globl pd2
|
.globl pd2
|
||||||
pd2:
|
pd2:
|
||||||
ptes64 0x0000000080000000
|
ptes64 0x0000000080000000,0x8000000000000083
|
||||||
|
|
||||||
.align 4096
|
.align 4096
|
||||||
.globl pd3
|
.globl pd3
|
||||||
pd3:
|
pd3:
|
||||||
ptes64 0x00000000C0000000
|
ptes64 0x00000000C0000000,0x0000000000000083
|
||||||
|
|
||||||
.previous
|
.previous
|
||||||
|
|
||||||
@ -567,14 +574,14 @@ data32 lgdt ap_gdt_descr - ap_trampoline
|
|||||||
# Enable PAE.
|
# Enable PAE.
|
||||||
|
|
||||||
movl %cr4, %eax
|
movl %cr4, %eax
|
||||||
orl $0x20, %eax
|
orb $0x20, %al
|
||||||
movl %eax, %cr4
|
movl %eax, %cr4
|
||||||
|
|
||||||
# Enable long mode.
|
# Enable long mode.
|
||||||
|
|
||||||
movl $0xc0000080, %ecx
|
movl $0xc0000080, %ecx
|
||||||
rdmsr
|
rdmsr
|
||||||
orl $0x00000100, %eax
|
orb $0x01, %ah
|
||||||
wrmsr
|
wrmsr
|
||||||
|
|
||||||
# Enable paging and protection.
|
# Enable paging and protection.
|
||||||
@ -583,6 +590,13 @@ data32 lgdt ap_gdt_descr - ap_trampoline
|
|||||||
orl $0x80000001, %eax
|
orl $0x80000001, %eax
|
||||||
movl %eax, %cr0
|
movl %eax, %cr0
|
||||||
|
|
||||||
|
# Enable NX.
|
||||||
|
|
||||||
|
movl $0xc0000080, %ecx
|
||||||
|
rdmsr
|
||||||
|
orb $0x08, %ah
|
||||||
|
wrmsr
|
||||||
|
|
||||||
# Jump to the 64-bit entry point.
|
# Jump to the 64-bit entry point.
|
||||||
ap_jump:
|
ap_jump:
|
||||||
data32 ljmp $KERNEL_CS, $0
|
data32 ljmp $KERNEL_CS, $0
|
||||||
|
@ -100,7 +100,9 @@ typedef union {
|
|||||||
uint32_t : 12; // ECX feature flags, bit 20
|
uint32_t : 12; // ECX feature flags, bit 20
|
||||||
uint32_t x2apic : 1;
|
uint32_t x2apic : 1;
|
||||||
uint32_t : 10; // ECX feature flags, bit 31
|
uint32_t : 10; // ECX feature flags, bit 31
|
||||||
uint32_t : 29; // EDX extended feature flags, bit 0
|
uint32_t : 19; // EDX extended feature flags, bit 0
|
||||||
|
uint32_t nx : 1;
|
||||||
|
uint32_t : 9;
|
||||||
uint32_t lm : 1;
|
uint32_t lm : 1;
|
||||||
uint32_t : 2; // EDX extended feature flags, bit 31
|
uint32_t : 2; // EDX extended feature flags, bit 31
|
||||||
};
|
};
|
||||||
|
@ -125,13 +125,14 @@ bool map_window(uintptr_t start_page)
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (cpuid_info.flags.lm == 0 && (start_page >= PAGE_C(64,GB))) {
|
if (cpuid_info.flags.lm == 0 && (start_page >= PAGE_C(64,GB))) {
|
||||||
// Fail, we want an address that is out of bounds
|
// Fail, we want an address that is out of bounds
|
||||||
// for PAE and no long mode (ie. 32 bit CPU).
|
// for PAE and no long mode (ie. 32 bit CPU).
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
// Compute the page table entries.
|
// Compute the page table entries.
|
||||||
|
uint64_t flags = cpuid_info.flags.nx ? UINT64_C(0x8000000000000083) : 0x83;
|
||||||
for (uintptr_t i = 0; i < 512; i++) {
|
for (uintptr_t i = 0; i < 512; i++) {
|
||||||
pd2[i] = ((uint64_t)window << 30) + (i << VM_PAGE_SHIFT) + 0x83;
|
pd2[i] = ((uint64_t)window << 30) + (i << VM_PAGE_SHIFT) + flags;
|
||||||
}
|
}
|
||||||
// Reload the PDBR to flush any remnants of the old mapping.
|
// Reload the PDBR to flush any remnants of the old mapping.
|
||||||
load_pdbr();
|
load_pdbr();
|
||||||
|
Loading…
Reference in New Issue
Block a user