FEX-Emu / FEX

A fast usermode x86 and x86-64 emulator for Arm64 Linux
https://fex-emu.com
MIT License
2.1k stars 117 forks source link

Deferred signals investigation #1666

Open Sonicadvance1 opened 2 years ago

Sonicadvance1 commented 2 years ago

Overview

This has interesting complications and can resolve unity problems.

Current high level idea

Add a new config option or two that enables "deferred/safe signal handling"

Other related ideas

Curent low level ideas for first implementation

(Description updated by @skmp)

skmp commented 2 years ago

Spent some time today on this as a break from the SMC work, and an inconvenience is that fully restoring a context seems quite hard on aarch64, and possibly will require some sort of SMC magic (limited branch range) or a dedicated scratch register (returns to JIT only) or slightly abusing rt_sigreturn (see https://github.com/deroko/switch/blob/master/switch.md for some juicy fun).

Another approach is to resume from the signal and implement our own signal queues in user mode, or to modify the restored signal state. I think i'll explore this route first.

skmp commented 2 years ago

Investigating further while waiting for the SMC reviews,

Also hastily merged in the SMC work as unity depends on that too. Will rebase cleanly.

This gets Unity 2020.1 /much/ further, with Mango getting ingame. Screenshot from 2022-05-05 16-04-20

Interestingly, unity (mono) needs full ucontext to recover from SIGSEGVs around null pointer accesses. Looks like mono generates NullReferenceExceptions and gracefully recovers there.

The code is very hasty at places. POC branch >> https://github.com/FEX-Emu/FEX/compare/skmp/deferred-signals-poc?expand=1

skmp commented 2 years ago

Spent some time on this over the weekend, I think we should split to two parts.

Deferring guest signals for (a) signal safety and for (b) state reconstruction / recovery.

(a) Is easy to do by adding a "is signal pending" check before returns to the JIT (syscalls, compile code, thunks). This can be easily done either in the dispatcher/jit side, or the C++ side. The only complication is automatically restarted system calls. It has near zero overhead, and doesn't suffer from execution 'overshot', just delayed signal delivery. This will largely resolve signal safety issues.

(b) Is more tricky and will come with a perf cost.

skmp commented 2 years ago

For thunks, we may want to allow them to be interrupted, as that would be closer to what the guest application can observe when running natively. Recovering the context is not a worry in that case.

neobrain commented 11 months ago

This is implemented in the latest version, isn't it?

(EDIT: Yikes, didn't mean to insta-close, hit the wrong button)