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",
|
"kernel-common",
|
||||||
"lock_api",
|
"lock_api",
|
||||||
"log",
|
"log",
|
||||||
|
"raw-cpuid",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
|
|
@ -15,6 +15,7 @@ embedded-graphics = "0.8.1"
|
||||||
kernel-common = {path = "../lib/kernel-common"}
|
kernel-common = {path = "../lib/kernel-common"}
|
||||||
lock_api = "0.4.12"
|
lock_api = "0.4.12"
|
||||||
log = "0.4.22"
|
log = "0.4.22"
|
||||||
|
raw-cpuid = "11.2.0"
|
||||||
|
|
||||||
[lints.clippy]
|
[lints.clippy]
|
||||||
missing_safety_doc = "allow"
|
missing_safety_doc = "allow"
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
use core::arch::asm;
|
use core::arch::{asm, global_asm};
|
||||||
|
|
||||||
use kernel_common::instructions::sti;
|
use kernel_common::instructions::sti;
|
||||||
|
use raw_cpuid::CpuId;
|
||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
cpu::{gdt::setup_gdt, idt::setup_idt},
|
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]
|
#[no_mangle]
|
||||||
extern "C" fn ap_main() -> ! {
|
extern "C" fn ap_main() -> ! {
|
||||||
setup_gdt();
|
setup_gdt();
|
||||||
|
@ -25,9 +32,24 @@ extern "C" fn ap_main() -> ! {
|
||||||
panic!("Yielding to idle task failed");
|
panic!("Yielding to idle task failed");
|
||||||
}
|
}
|
||||||
pub fn set_cpu_flags() {
|
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 {
|
unsafe {
|
||||||
// SMAP and SMEP
|
// Time Stamp Disable, SMEP and SMAP
|
||||||
asm!("mov rax, cr4; bts rax, 20; bts rax, 21; mov cr4, rax", out("rax") _);
|
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() {
|
pub fn enable_user_memory_access() {
|
||||||
|
|
|
@ -58,6 +58,7 @@ pub fn setup_gdt() {
|
||||||
tss.rsp[0] = allocate_stack();
|
tss.rsp[0] = allocate_stack();
|
||||||
tss.ist[0] = allocate_stack();
|
tss.ist[0] = allocate_stack();
|
||||||
tss.ist[1] = allocate_stack();
|
tss.ist[1] = allocate_stack();
|
||||||
|
tss.ist[2] = allocate_stack();
|
||||||
let gdt = Box::leak(Box::new(GDT {
|
let gdt = Box::leak(Box::new(GDT {
|
||||||
entries: [
|
entries: [
|
||||||
GDTEntry {
|
GDTEntry {
|
||||||
|
@ -88,16 +89,16 @@ pub fn setup_gdt() {
|
||||||
limit_low: 0,
|
limit_low: 0,
|
||||||
base_low: 0,
|
base_low: 0,
|
||||||
base_middle: 0,
|
base_middle: 0,
|
||||||
access: 0xfa,
|
access: 0xf2,
|
||||||
flags: 0x20,
|
flags: 0,
|
||||||
base_high: 0,
|
base_high: 0,
|
||||||
},
|
},
|
||||||
GDTEntry {
|
GDTEntry {
|
||||||
limit_low: 0,
|
limit_low: 0,
|
||||||
base_low: 0,
|
base_low: 0,
|
||||||
base_middle: 0,
|
base_middle: 0,
|
||||||
access: 0xf2,
|
access: 0xfa,
|
||||||
flags: 0,
|
flags: 0x20,
|
||||||
base_high: 0,
|
base_high: 0,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
|
|
|
@ -325,4 +325,5 @@ pub fn setup_idt() {
|
||||||
}
|
}
|
||||||
idt.entries[2].ist = 1; // NMI
|
idt.entries[2].ist = 1; // NMI
|
||||||
idt.entries[8].ist = 2; // Double fault
|
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();
|
let lapic_id = get_current_lapic_id();
|
||||||
IN_ISR_HANDLER[lapic_id].store(true, Ordering::SeqCst);
|
IN_ISR_HANDLER[lapic_id].store(true, Ordering::SeqCst);
|
||||||
if state.isr < 32 {
|
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]);
|
warn!("Exception in usermode: {}", EXCEPTIONS[state.isr as usize]);
|
||||||
terminate_current_task();
|
terminate_current_task();
|
||||||
state.isr = ISR_SCHEDULER;
|
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
|
.global jump_usermode
|
||||||
jump_usermode:
|
jump_usermode:
|
||||||
mov $0x23, %ax
|
mov $0x1b, %ax
|
||||||
mov %ax, %ds
|
mov %ax, %ds
|
||||||
mov %ax, %es
|
mov %ax, %es
|
||||||
mov %ax, %fs
|
mov %ax, %fs
|
||||||
mov %ax, %gs
|
mov %ax, %gs
|
||||||
push $0x23
|
push $0x1b
|
||||||
push $0
|
push $0
|
||||||
pushf
|
pushf
|
||||||
push $0x1b
|
push $0x23
|
||||||
push %rdi
|
push %rdi
|
||||||
|
|
||||||
xor %rax, %rax
|
xor %rax, %rax
|
||||||
|
|
|
@ -54,6 +54,7 @@ fn main() -> Status {
|
||||||
uefi::helpers::init().unwrap();
|
uefi::helpers::init().unwrap();
|
||||||
BOOT_SERVICES_ACTIVE.store(true, Ordering::SeqCst);
|
BOOT_SERVICES_ACTIVE.store(true, Ordering::SeqCst);
|
||||||
assert!(features.has_rdrand());
|
assert!(features.has_rdrand());
|
||||||
|
assert!(features.has_tsc());
|
||||||
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
let extended_features = cpuid.get_extended_feature_info().unwrap();
|
||||||
assert!(extended_features.has_smap());
|
assert!(extended_features.has_smap());
|
||||||
assert!(extended_features.has_smep());
|
assert!(extended_features.has_smep());
|
||||||
|
|
2
qemu.sh
2
qemu.sh
|
@ -2,4 +2,4 @@
|
||||||
# shellcheck disable=SC2068
|
# shellcheck disable=SC2068
|
||||||
set -euo pipefail
|
set -euo pipefail
|
||||||
./build.sh
|
./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