From da100f12a6a204091371c804922471935b736b63 Mon Sep 17 00:00:00 2001 From: Andreas Kling Date: Fri, 19 Feb 2021 15:19:10 +0100 Subject: [PATCH] Kernel: Add helpers for manipulating x86 control registers Use read_cr{0,2,3,4} and write_cr{0,3,4} helpers instead of inline asm. --- Kernel/Arch/i386/CPU.cpp | 91 ++++++++++++++-------------------------- Kernel/Arch/i386/CPU.h | 6 ++- 2 files changed, 37 insertions(+), 60 deletions(-) diff --git a/Kernel/Arch/i386/CPU.cpp b/Kernel/Arch/i386/CPU.cpp index 0011f8c1e1..a5467e911d 100644 --- a/Kernel/Arch/i386/CPU.cpp +++ b/Kernel/Arch/i386/CPU.cpp @@ -149,18 +149,7 @@ static void dump(const RegisterState& regs) dbgln(" ds={:04x} es={:04x} fs={:04x} gs={:04x}", (u16)regs.ds, (u16)regs.es, (u16)regs.fs, (u16)regs.gs); dbgln(" eax={:08x} ebx={:08x} ecx={:08x} edx={:08x}", regs.eax, regs.ebx, regs.ecx, regs.edx); dbgln(" ebp={:08x} esp={:08x} esi={:08x} edi={:08x}", regs.ebp, regs.esp, regs.esi, regs.edi); - - u32 cr0; - asm("movl %%cr0, %%eax" - : "=a"(cr0)); - u32 cr2; - asm("movl %%cr2, %%eax" - : "=a"(cr2)); - u32 cr3 = read_cr3(); - u32 cr4; - asm("movl %%cr4, %%eax" - : "=a"(cr4)); - dbgln(" cr0={:08x} cr2={:08x} cr3={:08x} cr4={:08x}", cr0, cr2, cr3, cr4); + dbgln(" cr0={:08x} cr2={:08x} cr3={:08x} cr4={:08x}", read_cr0(), read_cr2(), read_cr3(), read_cr4()); } void handle_crash(RegisterState& regs, const char* description, int signal, bool out_of_memory) @@ -364,20 +353,11 @@ void breakpoint_handler(TrapFrame* trap) current_thread->send_urgent_signal_to_self(SIGTRAP); } -#define EH(i, msg) \ - static void _exception##i() \ - { \ - dbgln("{}", msg); \ - u32 cr0, cr2, cr3, cr4; \ - asm("movl %%cr0, %%eax" \ - : "=a"(cr0)); \ - asm("movl %%cr2, %%eax" \ - : "=a"(cr2)); \ - asm("movl %%cr3, %%eax" \ - : "=a"(cr3)); \ - asm("movl %%cr4, %%eax" \ - : "=a"(cr4)); \ - PANIC("cr0={:08x} cr2={:08x} cr3={:08x} cr4={:08x}", cr0, cr2, cr3, cr4); \ +#define EH(i, msg) \ + static void _exception##i() \ + { \ + dbgln("{}", msg); \ + PANIC("cr0={:08x} cr2={:08x} cr3={:08x} cr4={:08x}", read_cr0(), read_cr2(), read_cr3(), read_cr4()); \ } EH(2, "Unknown error") @@ -733,16 +713,20 @@ void exit_trap(TrapFrame* trap) return Processor::current().exit_trap(*trap); } +void write_cr0(u32 value) +{ + asm volatile("movl %%eax, %%cr0" ::"a"(value)); +} + +void write_cr4(u32 value) +{ + asm volatile("movl %%eax, %%cr4" ::"a"(value)); +} + static void sse_init() { - asm volatile( - "mov %cr0, %eax\n" - "andl $0xfffffffb, %eax\n" - "orl $0x2, %eax\n" - "mov %eax, %cr0\n" - "mov %cr4, %eax\n" - "orl $0x600, %eax\n" - "mov %eax, %cr4\n"); + write_cr0((read_cr0() & 0xfffffffbu) | 0x2); + write_cr4(read_cr4() | 0x600); } u32 read_cr0() @@ -753,6 +737,14 @@ u32 read_cr0() return cr0; } +u32 read_cr2() +{ + u32 cr2; + asm("movl %%cr2, %%eax" + : "=a"(cr2)); + return cr2; +} + u32 read_cr3() { u32 cr3; @@ -911,18 +903,11 @@ void Processor::cpu_setup() if (has_feature(CPUFeature::SSE)) sse_init(); - asm volatile( - "movl %%cr0, %%eax\n" - "orl $0x00010000, %%eax\n" - "movl %%eax, %%cr0\n" :: - : "%eax", "memory"); + write_cr0(read_cr0() | 0x00010000); if (has_feature(CPUFeature::PGE)) { // Turn on CR4.PGE so the CPU will respect the G bit in page tables. - asm volatile( - "mov %cr4, %eax\n" - "orl $0x80, %eax\n" - "mov %eax, %cr4\n"); + write_cr4(read_cr4() | 0x80); } if (has_feature(CPUFeature::NX)) { @@ -936,32 +921,20 @@ void Processor::cpu_setup() if (has_feature(CPUFeature::SMEP)) { // Turn on CR4.SMEP - asm volatile( - "mov %cr4, %eax\n" - "orl $0x100000, %eax\n" - "mov %eax, %cr4\n"); + write_cr4(read_cr4() | 0x100000); } if (has_feature(CPUFeature::SMAP)) { // Turn on CR4.SMAP - asm volatile( - "mov %cr4, %eax\n" - "orl $0x200000, %eax\n" - "mov %eax, %cr4\n"); + write_cr4(read_cr4() | 0x200000); } if (has_feature(CPUFeature::UMIP)) { - asm volatile( - "mov %cr4, %eax\n" - "orl $0x800, %eax\n" - "mov %eax, %cr4\n"); + write_cr4(read_cr4() | 0x800); } if (has_feature(CPUFeature::TSC)) { - asm volatile( - "mov %cr4, %eax\n" - "orl $0x4, %eax\n" - "mov %eax, %cr4\n"); + write_cr4(read_cr4() | 0x4); } } diff --git a/Kernel/Arch/i386/CPU.h b/Kernel/Arch/i386/CPU.h index cd8e4d9dba..3bfcf68f35 100644 --- a/Kernel/Arch/i386/CPU.h +++ b/Kernel/Arch/i386/CPU.h @@ -526,10 +526,14 @@ inline FlatPtr offset_in_page(const void* address) } u32 read_cr0(); +u32 read_cr2(); u32 read_cr3(); -void write_cr3(u32); u32 read_cr4(); +void write_cr0(u32); +void write_cr3(u32); +void write_cr4(u32); + u32 read_dr6(); static inline bool is_kernel_mode()