1 year ago
#377185

Petr Skocik
Returning from a signal handler without going the kernel + userspace interrupts
This is a followup on my older question: Returning from a signal handler via setcontext
I tried to write the assembly for doing the context switch from a signal handler back to the interrupted context without the kernel assist (the sigreturn system call) for a signal handler where blocked signals don't need to be changed (SA_NODEFER
).
It seems doable (mostly just reloading registers) up to a final point: setting %rsp
and %rip
back.
From what I understand, if there was no red zone, I could do something like:
//use %rax to old %rsp, and %rcx as a scratch register
mov RSP_OFFSET(%rdi), %rax
// push old rip, rax, rcx, rdi using the scratch %rcx register
mov RIP_OFFSET(%rdi), %rcx
mov %rcx, -8(%rax)
mov RAX_OFFSET(%rdi), %rcx
mov %rcx, -16(%rax)
mov RCX_OFFSET(%rdi), %rcx
mov %rcx, -24(%rax)
mov RDI_OFFSET(%rdi), %rcx
mov %rcx, -32(%rax)
//make rax point to old_rsp - 32
lea -32(%rax), %rax
mov %rax, %rsp //restore rsp to that
//restore the pushed registers through actual popping
pop %rdi
pop %rcx
pop %rax
//pop and set %rip
ret
but with the redzone it seems impossible as there's (?) no way to atomically (with respect to signals) and without register use pop off a large amount from the stack and jump to an address stored deep in the popped off portion (or somewhere completely different as is the case with alternate signal stacks). I looked at hardware task switching but that is unsupported in 64-bit protected mode.
How will this work with the upcoming user-level interrupts? Will those handlers be able to somehow return without going through the kernel?
linux
assembly
signals
x86-64
interrupt
0 Answers
Your Answer