Skip to content

Commit 47eb27b

Browse files
committed
Fix initialization of CR4_SMEP on x86_64
It used to be that secondary APs could not be initialized properly if they support `CR4_SMEP`. That is now fixed
1 parent 6078b0f commit 47eb27b

File tree

3 files changed

+44
-13
lines changed

3 files changed

+44
-13
lines changed

kos/misc/magicemulator/qemu.dee

Lines changed: 13 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -185,9 +185,19 @@ did_update_x86_64_kernel:
185185
qemuExe = fs.joinpath(qemuExe, f"qemu-system-{TARGET_ARCH}");
186186
break;
187187
case "accel":
188-
/* "-accel hax" breaks qemu's builtin GDB stub. :(
189-
* -> For now, ignore accel options if GDB is on. */
190-
if (gdbMode != "emulator") {
188+
/* "-accel *" breaks qemu's builtin GDB stub. :(
189+
*
190+
* -> For now, ignore accel options if GDB is on.
191+
*
192+
* On x86_64:
193+
* GDB keeps truncating registers to 32-bits, which makes debugging pretty much impossible
194+
* On i386:
195+
* Breakpoints don't seem to work. Though you can manually pause execution, at which point
196+
* everything else seems to be working.
197+
*/
198+
if (gdbMode == "emulator") {
199+
/* ... */
200+
} else {
191201
qemuArgs.extend({ "-accel", arg });
192202
}
193203
break;

kos/src/kernel/core/arch/i386/boot/_start64.S

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -700,6 +700,8 @@ INTERN_FUNCTION(_start)
700700
movl $(pagedir_kernel_phys), %eax
701701
movl %eax, %cr3
702702

703+
704+
703705
/* Configure the %CR4 register. */
704706
movl %cr4, %eax
705707
/* Enable PageSizeExtension (required for 2Mib pages & long-mode),
@@ -712,19 +714,24 @@ INTERN_FUNCTION(_start)
712714
jz 1f
713715
orl $(CR4_PGE), %eax
714716
1:
715-
/* Enable SMAP if supported by the host (optional feature) */
717+
718+
/* Enable SMEP if supported by the host (optional feature) */
716719
ttest mask=CPUID_7B_SMEP, loc=(V2P(bootcpu_x86_cpuid) + OFFSET_CPUID_7B)
717720
jz 1f
718721
orl $(CR4_SMEP), %eax
719722
1:
723+
720724
/* Enable FSGSBASE if supported by the host (emulated if unsupported) */
721725
ttest mask=CPUID_7B_FSGSBASE, loc=(V2P(bootcpu_x86_cpuid) + OFFSET_CPUID_7B)
722726
jz 1f
723727
orl $(CR4_FSGSBASE), %eax
724728
1:
729+
725730
/* Save the fully configured CR4 register. */
726731
movl %eax, %cr4
727732

733+
734+
728735
/* Set the LME bit in the EFER MSR register. */
729736
movl $(IA32_EFER), %ecx
730737
rdmsr
@@ -739,6 +746,7 @@ INTERN_FUNCTION(_start)
739746
orl $(IA32_EFER_SCE), %eax
740747
1: wrmsr /* Save the new configuration. */
741748

749+
742750
/* Now to actually enable paging! */
743751
movl %cr0, %eax
744752
orl $(CR0_PG | CR0_WP), %eax

kos/src/kernel/core/arch/i386/sched/smp.S

Lines changed: 22 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -615,6 +615,21 @@ PRIVATE_FUNCTION(x86_smp_init_cpuid)
615615
.Lsmp_ini_crN_donefpu:
616616
#endif /* CONFIG_HAVE_FPU */
617617

618+
/* If supported, enable SMEP now that we're in 64-bit, high-memory mode
619+
* This can only be done **after** we jumped to high memory, since the
620+
* we were previously running off of this mapping:
621+
* >> 00000000009E8000-00000000009E8FFF: 00000000009E8000+4KiB [xwu-adp][0]
622+
* Since this mapping is in what is normally user-space, it has the "u"
623+
* flag. And since SMEP causes the kernel to fault when trying to execute
624+
* user-space code, we had to wait until we got here:
625+
* >> FFFFFFFF809E8000-FFFFFFFF809EBFFF: 00000000009E8000+16KiB [xw-gadp][0]
626+
*/
627+
ttest mask=CPUID_7B_SMEP, loc=(thiscpu_x86_cpuid + OFFSET_CPUID_7B)(R_CPU)
628+
jz 1f
629+
orP $(CR4_SMEP), %Pcx
630+
1:
631+
632+
618633
/* Store results */
619634
EXTERN(thiscpu_x86_saved_cr0)
620635
movP %Pax, thiscpu_x86_saved_cr0(R_CPU)
@@ -700,7 +715,7 @@ INTERN_FUNCTION(x86_smp_entry32)
700715
ttest mask=CPUID_1D_MSR, loc=%edx
701716
jz x86_smp_boot_failure_no_msr
702717

703-
/* Configure the %CR4 register. */
718+
/* Configure the %CR4 register (except for `CR4_SMEP') */
704719
movl %cr4, %esp
705720
/* Enable PageSizeExtension (required for 2Mib pages & long-mode),
706721
* as well as PhysicalAddressExtension (required for the 48-bit
@@ -717,13 +732,17 @@ INTERN_FUNCTION(x86_smp_entry32)
717732
xorl %eax, %eax
718733
cpuid
719734
cmpl $(7), %eax
720-
jnae 2f
735+
jnae 2f /* if (!(%eax >= 7)) goto 2f */
721736
movl $(7), %eax
737+
movl $(0), %ecx /* Sub-leaf:0 */
722738
cpuid
739+
#if 0 /* This can only be enabled once we're in 64-bit mode! */
723740
ttest mask=CPUID_7B_SMEP, loc=%ebx /* Enable SMAP if supported by the host (optional feature) */
724741
jz 1f
725742
orl $(CR4_SMEP), %esp
726-
1: ttest mask=CPUID_7B_FSGSBASE, loc=%ebx /* Enable FSGSBASE if supported by the host (emulated if unsupported) */
743+
1:
744+
#endif
745+
ttest mask=CPUID_7B_FSGSBASE, loc=%ebx /* Enable FSGSBASE if supported by the host (emulated if unsupported) */
727746
jz 1f
728747
orl $(CR4_FSGSBASE), %esp
729748
1:
@@ -778,12 +797,6 @@ INTERN_FUNCTION(x86_smp_entry32)
778797
rdmsr
779798
orl $(IA32_EFER_NXE), %eax
780799
wrmsr
781-
/* With PAE + NX, try to enable its effects while
782-
* in kernel-space (if supported by the CPU) */
783-
ttest mask=CPUID_7B_SMEP, loc=(bootcpu_x86_cpuid + OFFSET_CPUID_7B)
784-
jz 1f
785-
orl $(CR4_SMEP), %esp
786-
1:
787800
#endif /* !CONFIG_NO_KERNEL_X86_PAGING_PAE */
788801
/* Enable PGE support (if necessary for setting the page directory) */
789802
ttest mask=CPUID_1D_PGE, loc=((bootcpu_x86_cpuid - KERNEL_CORE_BASE) + OFFSET_CPUID_1D)

0 commit comments

Comments
 (0)