1 year ago

#377185

test-img

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

Accepted video resources