This commit is contained in:
parent
2e4460ace6
commit
25693bb57c
10 changed files with 44 additions and 12 deletions
1
Cargo.lock
generated
1
Cargo.lock
generated
|
@ -221,6 +221,7 @@ dependencies = [
|
|||
"kernel-common",
|
||||
"lock_api",
|
||||
"log",
|
||||
"raw-cpuid",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -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"
|
||||
|
|
|
@ -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() {
|
||||
|
|
|
@ -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,
|
||||
},
|
||||
],
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
|
@ -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
5
kernel/src/cpu/syscall.s
Normal file
|
@ -0,0 +1,5 @@
|
|||
.text
|
||||
|
||||
.global syscall
|
||||
syscall:
|
||||
jmp .
|
|
@ -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
|
||||
|
|
|
@ -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());
|
||||
|
|
2
qemu.sh
2
qemu.sh
|
@ -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 $@
|
||||
|
|
Loading…
Add table
Reference in a new issue