Only set process regs for faults from ring 3.
This fixes a deadlock that might occur if a page fault is triggered while a lock to the current context is held.
This commit is contained in:
4
Cargo.lock
generated
4
Cargo.lock
generated
@@ -1,5 +1,7 @@
|
||||
# This file is automatically @generated by Cargo.
|
||||
# It is not intended for manual editing.
|
||||
version = 3
|
||||
|
||||
[[package]]
|
||||
name = "autocfg"
|
||||
version = "1.0.1"
|
||||
@@ -165,7 +167,7 @@ dependencies = [
|
||||
|
||||
[[package]]
|
||||
name = "redox_syscall"
|
||||
version = "0.2.9"
|
||||
version = "0.2.10"
|
||||
dependencies = [
|
||||
"bitflags",
|
||||
]
|
||||
|
||||
@@ -331,6 +331,9 @@ macro_rules! interrupt_stack {
|
||||
paste::item! {
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn [<__interrupt_ $name>]($stack: &mut $crate::arch::x86_64::interrupt::InterruptStack) {
|
||||
// Deadlock safety: interrupts are not normally enabled in the kernel, except in
|
||||
// kmain. However, no locks for context list nor even individual context locks, are
|
||||
// ever meant to be acquired there.
|
||||
let _guard = $crate::ptrace::set_process_regs($stack);
|
||||
|
||||
// TODO: Force the declarations to specify unsafe?
|
||||
@@ -410,7 +413,18 @@ macro_rules! interrupt_error {
|
||||
paste::item! {
|
||||
#[no_mangle]
|
||||
unsafe extern "C" fn [<__interrupt_ $name>]($stack: &mut $crate::arch::x86_64::interrupt::handler::InterruptErrorStack) {
|
||||
let _guard = $crate::ptrace::set_process_regs(&mut $stack.inner);
|
||||
let _guard;
|
||||
|
||||
// Only set_ptrace_process_regs if this error occured from userspace. If this fault
|
||||
// originated from kernel mode, we have no idea what it might have locked (and
|
||||
// kernel mode faults are never meant to occur unless something is wrong, and will
|
||||
// not context switch anyway, rendering that statement useless in such a case
|
||||
// anyway).
|
||||
//
|
||||
// Check the privilege level of CS against ring 3.
|
||||
if $stack.inner.iret.cs & 0b11 == 0b11 {
|
||||
_guard = $crate::ptrace::set_process_regs(&mut $stack.inner);
|
||||
}
|
||||
|
||||
#[allow(unused_unsafe)]
|
||||
unsafe {
|
||||
|
||||
Reference in New Issue
Block a user