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:
4lDO2
2021-08-06 15:41:07 +02:00
parent 862265f150
commit 1047728f35
2 changed files with 18 additions and 2 deletions

4
Cargo.lock generated
View File

@@ -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",
]

View File

@@ -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 {