Merge branch 'catch-kernel-signal' into 'master'

Catch kernel signal

See merge request redox-os/kernel!135
This commit is contained in:
Jeremy Soller
2020-07-14 12:53:46 +00:00
4 changed files with 33 additions and 27 deletions

View File

@@ -18,8 +18,6 @@ interrupt_stack!(divide_by_zero, stack, {
interrupt_stack!(debug, stack, {
let mut handled = false;
let guard = ptrace::set_process_regs(stack);
// Disable singlestep before there is a breakpoint, since the breakpoint
// handler might end up setting it again but unless it does we want the
// default to be false.
@@ -33,8 +31,6 @@ interrupt_stack!(debug, stack, {
stack.set_singlestep(had_singlestep);
}
drop(guard);
if !handled {
println!("Debug trap");
stack.dump();
@@ -61,11 +57,7 @@ interrupt_stack!(breakpoint, stack, {
// int3 instruction. After all, it's the sanest thing to do.
stack.iret.rip -= 1;
let guard = ptrace::set_process_regs(stack);
if ptrace::breakpoint_callback(PTRACE_STOP_BREAKPOINT, None).is_none() {
drop(guard);
println!("Breakpoint trap");
stack.dump();
ksignal(SIGTRAP);

View File

@@ -189,7 +189,6 @@ interrupt_stack!(pit, stack, {
timeout::trigger();
if PIT_TICKS.fetch_add(1, Ordering::SeqCst) >= 10 {
let _guard = ptrace::set_process_regs(stack);
let _ = context::switch();
}
});

View File

@@ -48,9 +48,8 @@ impl ScratchRegisters {
}
macro_rules! scratch_push {
() => (asm!(
"push rax
push rcx
(without rax) => (asm!(
"push rcx
push rdx
push rdi
push rsi
@@ -60,6 +59,10 @@ macro_rules! scratch_push {
push r11"
: : : : "intel", "volatile"
));
() => ({
asm!("push rax" : : : : "intel", "volatile");
scratch_push!(without rax);
});
}
macro_rules! scratch_pop {
@@ -332,6 +335,7 @@ macro_rules! interrupt_stack {
pub unsafe extern fn $name () {
#[inline(never)]
unsafe fn inner($stack: &mut $crate::arch::x86_64::macros::InterruptStack) {
let _guard = ptrace::set_process_regs($stack);
$func
}
@@ -362,20 +366,14 @@ macro_rules! interrupt_stack {
#[derive(Default)]
#[repr(packed)]
pub struct InterruptErrorStack {
pub fs: usize,
pub preserved: PreservedRegisters,
pub scratch: ScratchRegisters,
pub code: usize,
pub iret: IretRegisters,
pub inner: InterruptStack,
}
impl InterruptErrorStack {
pub fn dump(&self) {
self.iret.dump();
self.inner.dump();
println!("CODE: {:>016X}", { self.code });
self.scratch.dump();
self.preserved.dump();
println!("FS: {:>016X}", { self.fs });
}
}
@@ -385,12 +383,23 @@ macro_rules! interrupt_error {
#[naked]
pub unsafe extern fn $name () {
#[inline(never)]
unsafe fn inner($stack: &$crate::arch::x86_64::macros::InterruptErrorStack) {
unsafe fn inner($stack: &mut $crate::arch::x86_64::macros::InterruptErrorStack) {
let _guard = ptrace::set_process_regs(&mut $stack.inner);
$func
}
// Push scratch registers
interrupt_push!();
// Swap RAX and error code, in order to push the code later and be
// compatible with InterruptStack.
asm!("xchg [rsp], rax" : : : : "intel", "volatile");
// Push all the registers (except for rax which is already pushed,
// in place of the error code)
scratch_push!(without rax);
preserved_push!();
fs_push!();
// Finally, push rax (now containing error code)
asm!("push rax" : : : : "intel", "volatile");
// Get reference to stack variables
let rsp: usize;
@@ -400,14 +409,14 @@ macro_rules! interrupt_error {
$crate::arch::x86_64::pti::map();
// Call inner rust function
inner(&*(rsp as *const $crate::arch::x86_64::macros::InterruptErrorStack));
inner(&mut *(rsp as *mut $crate::arch::x86_64::macros::InterruptErrorStack));
// Unmap kernel
$crate::arch::x86_64::pti::unmap();
// Pop scratch registers, error code, and return
interrupt_pop!();
// Pop error code, registers, and return
asm!("add rsp, 8" : : : : "intel", "volatile"); // pop error code
interrupt_pop!();
iret!();
}
};

View File

@@ -274,5 +274,11 @@ pub extern fn ksignal(signal: usize) {
println!("NAME {}", unsafe { ::core::str::from_utf8_unchecked(&context.name.lock()) });
}
}
syscall::exit(signal & 0x7F);
// Try running kill(getpid(), signal), but fallback to exiting
syscall::getpid()
.and_then(|pid| syscall::kill(pid, signal).map(|_| ()))
.unwrap_or_else(|_| {
syscall::exit(signal & 0x7F);
});
}