x86: mask simd exceptions for userspace
This commit is contained in:
parent
98fe60bc12
commit
17dc8e9a4d
2
Cargo.lock
generated
2
Cargo.lock
generated
@ -898,7 +898,9 @@ name = "kernel-arch-x86"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags 2.6.0",
|
||||
"bytemuck",
|
||||
"kernel-arch-interface",
|
||||
"static_assertions",
|
||||
"tock-registers",
|
||||
]
|
||||
|
||||
|
@ -123,7 +123,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
|
||||
Ok(Self {
|
||||
inner: UnsafeCell::new(Inner { sp }),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new()),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new(true)),
|
||||
stack_base_phys,
|
||||
stack_size: USER_TASK_PAGES * 0x1000,
|
||||
|
||||
@ -159,7 +159,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
|
||||
Ok(Self {
|
||||
inner: UnsafeCell::new(Inner { sp }),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new()),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new(false)),
|
||||
stack_base_phys,
|
||||
stack_size: KERNEL_TASK_PAGES * 0x1000,
|
||||
|
||||
|
@ -6,8 +6,10 @@ edition = "2021"
|
||||
[dependencies]
|
||||
kernel-arch-interface = { path = "../interface" }
|
||||
|
||||
bytemuck = { version = "1.16.1", features = ["derive"] }
|
||||
bitflags = "2.6.0"
|
||||
tock-registers = "0.8.1"
|
||||
static_assertions = "1.1.0"
|
||||
|
||||
[lints.rust]
|
||||
unexpected_cfgs = { level = "allow", check-cfg = ['cfg(rust_analyzer)'] }
|
||||
|
@ -217,6 +217,9 @@ fn enable_features(ecx: EcxFeatures, edx: EdxFeatures) {
|
||||
}
|
||||
}
|
||||
if edx.contains(EdxFeatures::SSE) && ecx.contains(EcxFeatures::XSAVE) {
|
||||
assert!(edx.contains(EdxFeatures::FPU));
|
||||
CR0.modify(CR0::MP::SET);
|
||||
CR4.modify(CR4::OSXMMEXCPT::SET);
|
||||
XCR0.modify(XCR0::SSE::SET);
|
||||
}
|
||||
if ecx.contains(EcxFeatures::AVX) {
|
||||
|
@ -183,6 +183,8 @@ mod cr4 {
|
||||
OSXSAVE OFFSET(18) NUMBITS(1) [],
|
||||
/// If set, PCID is enabled
|
||||
PCIDE OFFSET(17) NUMBITS(1) [],
|
||||
/// Indicates OS support for unmasked SIMD exceptions
|
||||
OSXMMEXCPT OFFSET(10) NUMBITS(1) [],
|
||||
/// Indicates OS support for FXSAVE and FXRSTOR instructions
|
||||
OSFXSR OFFSET(9) NUMBITS(1) [],
|
||||
/// Performance-Monitoring Counter enable
|
||||
@ -424,21 +426,89 @@ pub use msr::ia32_sfmask::MSR_IA32_SFMASK;
|
||||
pub use msr::ia32_star::MSR_IA32_STAR;
|
||||
pub use xcr0::XCR0;
|
||||
|
||||
use bytemuck::{Pod, Zeroable};
|
||||
use static_assertions::const_assert_eq;
|
||||
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C, align(16))]
|
||||
struct FpuContextInner {
|
||||
fcw: u16,
|
||||
fsw: u16,
|
||||
ftw: u8,
|
||||
_0: u8,
|
||||
fop: u16,
|
||||
fip: u32,
|
||||
fcs: u16,
|
||||
_1: u16,
|
||||
|
||||
fdp: u32,
|
||||
fds: u16,
|
||||
_2: u16,
|
||||
mxcsr: u32,
|
||||
mxcsr_mask: u32,
|
||||
|
||||
mm: [u128; 8],
|
||||
xmm: [u128; 8],
|
||||
_3: [u128; 14],
|
||||
}
|
||||
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
#[derive(Clone, Copy, Pod, Zeroable)]
|
||||
#[repr(C, align(16))]
|
||||
struct FpuContextInner {
|
||||
fcw: u16,
|
||||
fsw: u16,
|
||||
ftw: u8,
|
||||
_0: u8,
|
||||
fop: u16,
|
||||
fip: u64,
|
||||
|
||||
fdp: u64,
|
||||
mxcsr: u32,
|
||||
mxcsr_mask: u32,
|
||||
|
||||
mm: [u128; 8],
|
||||
xmm: [u128; 16],
|
||||
_1: [u128; 6],
|
||||
}
|
||||
|
||||
const_assert_eq!(size_of::<FpuContextInner>(), 512);
|
||||
|
||||
#[repr(C, align(16))]
|
||||
pub struct FpuContext {
|
||||
inner: [u8; 512],
|
||||
inner: FpuContextInner,
|
||||
}
|
||||
|
||||
impl FpuContext {
|
||||
pub const fn new() -> Self {
|
||||
Self { inner: [0; 512] }
|
||||
pub fn new(mask_exceptions: bool) -> Self {
|
||||
const ALL_EXCEPTIONS_MASK: u32 = (1 << 12) | (1 << 11) | (1 << 10) | (1 << 9) | (1 << 8);
|
||||
let mut inner = FpuContextInner::zeroed();
|
||||
if mask_exceptions {
|
||||
inner.mxcsr |= ALL_EXCEPTIONS_MASK;
|
||||
}
|
||||
Self { inner }
|
||||
}
|
||||
|
||||
pub fn store(this: *mut Self) {
|
||||
unsafe { core::arch::asm!("fxsave ({})", in(reg) this, options(att_syntax)) }
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
unsafe {
|
||||
core::arch::x86::_fxsave(this as _)
|
||||
}
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
unsafe {
|
||||
core::arch::x86_64::_fxsave64(this as _)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn restore(this: *const Self) {
|
||||
unsafe { core::arch::asm!("fxrstor ({})", in(reg) this, options(att_syntax)) }
|
||||
#[cfg(any(target_arch = "x86", rust_analyzer))]
|
||||
unsafe {
|
||||
core::arch::x86::_fxrstor(this as _)
|
||||
}
|
||||
#[cfg(any(target_arch = "x86_64", rust_analyzer))]
|
||||
unsafe {
|
||||
core::arch::x86_64::_fxrstor64(this as _)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -388,7 +388,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
|
||||
Ok(Self {
|
||||
inner: UnsafeCell::new(Inner { sp, tss_rsp0: rsp0 }),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new()),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new(true)),
|
||||
stack_base_phys,
|
||||
stack_size: USER_TASK_PAGES * 0x1000,
|
||||
_alloc: PhantomData,
|
||||
@ -434,7 +434,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
|
||||
Ok(Self {
|
||||
inner: UnsafeCell::new(Inner { sp, tss_rsp0: 0 }),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new()),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new(false)),
|
||||
stack_base_phys,
|
||||
stack_size: KERNEL_TASK_PAGES * 0x1000,
|
||||
|
||||
@ -473,7 +473,7 @@ impl<K: KernelTableManager, PA: PhysicalMemoryAllocator<Address = PhysicalAddres
|
||||
|
||||
Ok(Self {
|
||||
inner: UnsafeCell::new(Inner { sp, tss_rsp0: rsp0 }),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new()),
|
||||
fpu_context: UnsafeCell::new(FpuContext::new(true)),
|
||||
stack_base_phys,
|
||||
stack_size: USER_TASK_PAGES * 0x1000,
|
||||
|
||||
|
4
kernel/modules/test_mod/Cargo.lock
generated
4
kernel/modules/test_mod/Cargo.lock
generated
@ -1,6 +1,6 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
version = 4
|
||||
|
||||
[[package]]
|
||||
name = "aarch64-cpu"
|
||||
@ -284,7 +284,9 @@ name = "kernel-arch-x86"
|
||||
version = "0.1.0"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
"bytemuck",
|
||||
"kernel-arch-interface",
|
||||
"static_assertions",
|
||||
"tock-registers",
|
||||
]
|
||||
|
||||
|
@ -156,6 +156,10 @@ fn user_exception_inner(kind: ExceptionKind, frame: &mut ExceptionFrame) {
|
||||
ExceptionKind::Breakpoint => {
|
||||
todo!()
|
||||
}
|
||||
ExceptionKind::SimdFpuException => {
|
||||
thread.raise_signal(Signal::MemoryAccessViolation);
|
||||
true
|
||||
}
|
||||
_ => todo!("No handler for exception: {:?}", kind),
|
||||
};
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user