Skip to content

Commit c054ee8

Browse files
committed
[x86][mmu] only write to CR4 if necessary
In legacy builds it's possible to boot on a cpu that doesn't appear to have CR4 implemented (Am586 to be precise), but there's no features needed to set, so it seems that this was architecturally okay.
1 parent f52ef45 commit c054ee8

File tree

2 files changed

+25
-19
lines changed

2 files changed

+25
-19
lines changed

arch/x86/32/mmu.c

Lines changed: 13 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -422,15 +422,18 @@ void x86_mmu_early_init_percpu(void) {
422422
x86_set_cr0(cr0);
423423

424424
/* Set some mmu control bits in CR4 */
425-
uint32_t cr4 = x86_get_cr4();
426-
if (x86_feature_test(X86_FEATURE_PGE))
427-
cr4 |= X86_CR4_PGE;
428-
if (x86_feature_test(X86_FEATURE_SMEP))
429-
cr4 |= X86_CR4_SMEP;
430-
/* TODO: enable SMAP when the rest of the system is ready for it */
431-
//if (x86_feature_test(X86_FEATURE_SMAP))
432-
// cr4 |= X86_CR4_SMAP;
433-
x86_set_cr4(cr4);
425+
uint32_t bits = 0;
426+
bits |= x86_feature_test(X86_FEATURE_PGE) ? X86_CR4_PGE : 0;
427+
bits |= x86_feature_test(X86_FEATURE_PSE) ? X86_CR4_PSE : 0;
428+
bits |= x86_feature_test(X86_FEATURE_SMEP) ? X86_CR4_SMEP : 0;
429+
/* for now, we dont support SMAP due to some tests that assume they can access user space */
430+
// bits |= x86_feature_test(X86_FEATURE_SMAP) ? X86_CR4_SMAP : 0;
431+
if (bits) {
432+
/* don't touch cr4 unless we need to, early cpus will fault if its not implemented */
433+
uint32_t cr4 = x86_get_cr4();
434+
cr4 |= bits;
435+
x86_set_cr4(cr4);
436+
}
434437
}
435438

436439
void x86_mmu_early_init(void) {
@@ -453,7 +456,7 @@ void x86_mmu_init(void) {
453456
status_t arch_mmu_init_aspace(arch_aspace_t * const aspace, const vaddr_t base, const size_t size, const uint flags) {
454457
DEBUG_ASSERT(aspace);
455458

456-
TRACEF("aspace %p, base %#lx, size %#zx, flags %#x\n", aspace, base, size, flags);
459+
LTRACEF("aspace %p, base %#lx, size %#zx, flags %#x\n", aspace, base, size, flags);
457460

458461
/* validate that the base + size is sane and doesn't wrap */
459462
DEBUG_ASSERT(size > PAGE_SIZE);

arch/x86/64/mmu.c

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -633,15 +633,18 @@ void x86_mmu_early_init_percpu(void) {
633633
x86_set_cr0(cr0);
634634

635635
/* Set some mmu control bits in CR4 */
636-
uint32_t cr4 = x86_get_cr4();
637-
if (x86_feature_test(X86_FEATURE_PGE))
638-
cr4 |= X86_CR4_PGE;
639-
if (x86_feature_test(X86_FEATURE_SMEP))
640-
cr4 |= X86_CR4_SMEP;
641-
/* TODO: enable SMAP when the rest of the system is ready for it */
642-
//if (x86_feature_test(X86_FEATURE_SMAP))
643-
// cr4 |= X86_CR4_SMAP;
644-
x86_set_cr4(cr4);
636+
uint32_t bits = 0;
637+
bits |= x86_feature_test(X86_FEATURE_PGE) ? X86_CR4_PGE : 0;
638+
bits |= x86_feature_test(X86_FEATURE_PSE) ? X86_CR4_PSE : 0;
639+
bits |= x86_feature_test(X86_FEATURE_SMEP) ? X86_CR4_SMEP : 0;
640+
/* for now, we dont support SMAP due to some tests that assume they can access user space */
641+
// bits |= x86_feature_test(X86_FEATURE_SMAP) ? X86_CR4_SMAP : 0;
642+
if (bits) {
643+
/* don't touch cr4 unless we need to, early cpus will fault if its not implemented */
644+
uint32_t cr4 = x86_get_cr4();
645+
cr4 |= bits;
646+
x86_set_cr4(cr4);
647+
}
645648

646649
/* Set NXE bit in MSR_EFER */
647650
uint64_t efer_msr = read_msr(X86_MSR_IA32_EFER);

0 commit comments

Comments
 (0)