Prepare for syscalls
All checks were successful
Build / build (push) Successful in 2m48s

This commit is contained in:
Mathieu Strypsteen 2024-12-22 11:56:18 +01:00
parent 2e4460ace6
commit 25693bb57c
10 changed files with 44 additions and 12 deletions

1
Cargo.lock generated
View file

@ -221,6 +221,7 @@ dependencies = [
"kernel-common",
"lock_api",
"log",
"raw-cpuid",
]
[[package]]

View file

@ -15,6 +15,7 @@ embedded-graphics = "0.8.1"
kernel-common = {path = "../lib/kernel-common"}
lock_api = "0.4.12"
log = "0.4.22"
raw-cpuid = "11.2.0"
[lints.clippy]
missing_safety_doc = "allow"

View file

@ -1,6 +1,7 @@
use core::arch::asm;
use core::arch::{asm, global_asm};
use kernel_common::instructions::sti;
use raw_cpuid::CpuId;
use crate::{
cpu::{gdt::setup_gdt, idt::setup_idt},
@ -10,6 +11,12 @@ use crate::{
},
};
global_asm!(include_str!("syscall.s"), options(att_syntax));
extern "C" {
fn syscall();
}
#[no_mangle]
extern "C" fn ap_main() -> ! {
setup_gdt();
@ -25,9 +32,24 @@ extern "C" fn ap_main() -> ! {
panic!("Yielding to idle task failed");
}
pub fn set_cpu_flags() {
let cpuid = CpuId::new();
let features = cpuid.get_feature_info().unwrap();
let extended_features = cpuid.get_extended_feature_info().unwrap();
unsafe {
// SMAP and SMEP
asm!("mov rax, cr4; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _);
// Time Stamp Disable, SMEP and SMAP
asm!("mov rax, cr4; bts rax, 2; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _);
if features.has_mce() {
asm!("mov rax, cr4; bts rax, 6; mov cr4, rax", out("rax") _);
}
if extended_features.has_umip() {
asm!("mov rax, cr4; bts rax, 11; mov cr4, rax", out("rax") _);
}
// System Call Extensions
asm!("rdmsr; bts rax, 0; wrmsr", in("rcx") 0xc0000080_u64, out("rax") _, out("rdx") _);
asm!("wrmsr", in("rcx") 0xc0000081_u64, in("rax") 0, in("rdx") 8 | 16 << 16);
asm!("wrmsr", in("rcx") 0xc0000082_u64, in("rax") syscall, in("rdx") syscall as u64 >> 32);
// Clear IF and DF
asm!("wrmsr", in("rcx") 0xc0000084_u64, in("rax") 1 << 9 | 1 << 10, in("rdx") 0);
}
}
pub fn enable_user_memory_access() {

View file

@ -58,6 +58,7 @@ pub fn setup_gdt() {
tss.rsp[0] = allocate_stack();
tss.ist[0] = allocate_stack();
tss.ist[1] = allocate_stack();
tss.ist[2] = allocate_stack();
let gdt = Box::leak(Box::new(GDT {
entries: [
GDTEntry {
@ -88,16 +89,16 @@ pub fn setup_gdt() {
limit_low: 0,
base_low: 0,
base_middle: 0,
access: 0xfa,
flags: 0x20,
access: 0xf2,
flags: 0,
base_high: 0,
},
GDTEntry {
limit_low: 0,
base_low: 0,
base_middle: 0,
access: 0xf2,
flags: 0,
access: 0xfa,
flags: 0x20,
base_high: 0,
},
],

View file

@ -325,4 +325,5 @@ pub fn setup_idt() {
}
idt.entries[2].ist = 1; // NMI
idt.entries[8].ist = 2; // Double fault
idt.entries[18].ist = 3; // Machine Check
}

View file

@ -111,7 +111,7 @@ extern "C" fn isr_handler(state: &mut ISRState) {
let lapic_id = get_current_lapic_id();
IN_ISR_HANDLER[lapic_id].store(true, Ordering::SeqCst);
if state.isr < 32 {
if state.cs == 0x1b && state.isr != 2 && state.isr != 8 {
if state.cs == 0x23 && state.isr != 2 && state.isr != 8 && state.isr != 18 {
warn!("Exception in usermode: {}", EXCEPTIONS[state.isr as usize]);
terminate_current_task();
state.isr = ISR_SCHEDULER;

5
kernel/src/cpu/syscall.s Normal file
View file

@ -0,0 +1,5 @@
.text
.global syscall
syscall:
jmp .

View file

@ -2,15 +2,15 @@
.global jump_usermode
jump_usermode:
mov $0x23, %ax
mov $0x1b, %ax
mov %ax, %ds
mov %ax, %es
mov %ax, %fs
mov %ax, %gs
push $0x23
push $0x1b
push $0
pushf
push $0x1b
push $0x23
push %rdi
xor %rax, %rax

View file

@ -54,6 +54,7 @@ fn main() -> Status {
uefi::helpers::init().unwrap();
BOOT_SERVICES_ACTIVE.store(true, Ordering::SeqCst);
assert!(features.has_rdrand());
assert!(features.has_tsc());
let extended_features = cpuid.get_extended_feature_info().unwrap();
assert!(extended_features.has_smap());
assert!(extended_features.has_smep());

View file

@ -2,4 +2,4 @@
# shellcheck disable=SC2068
set -euo pipefail
./build.sh
qemu-system-x86_64 -M q35 -accel kvm -cpu qemu64,rdrand,smap,smep -smp 4 -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@
qemu-system-x86_64 -M q35 -accel kvm -cpu qemu64,rdrand,smap,smep,umip -smp 4 -m 256M -L /usr/share/OVMF -bios OVMF_CODE.fd -drive file=img/os.img,format=raw $@