Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Deferred signals investigation #1666

Open
Sonicadvance1 opened this issue Apr 29, 2022 · 5 comments
Open

Deferred signals investigation #1666

Sonicadvance1 opened this issue Apr 29, 2022 · 5 comments
Assignees
Milestone

Comments

@Sonicadvance1
Copy link
Member

Sonicadvance1 commented Apr 29, 2022

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"

  • Introduce the concept of "exit points" in the JIT, places where we can handle state
  • Sprinkle "exit points" around in blocks in such a way that there is a bounded time between them
  • Modify signal setters to block all signals on signals entry
  • Modify signal handlers to resume JIT execution up to the next "exit point", and then handle the signal
  • Edge cases: signals on syscalls, signals in non-jit code
  • Add a signal torture test or two to our tests

Other related ideas

  • Add signal safe mode for all locks

Curent low level ideas for first implementation

  • use ldb/stb [ctx-1], #0 + a guard page before the context for low cost handling of "should we exit from exit point" checks

(Description updated by @skmp)

@skmp
Copy link
Contributor

skmp commented May 4, 2022

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
Copy link
Contributor

skmp commented May 5, 2022

Investigating further while waiting for the SMC reviews,

  • Implemented the usermode queuing (can only queue one signal per thread right now) using the str [ctx-1], 0 trick + mprotect to trigger a second fault, later on, that is used to dispatch the pending signal.
  • Modified signal dispatch logic to always build guest ucontext, and to not store host context
  • Modified signal returns to discard host context and redispatch the guest ucontext
  • Still returns using ud2, though implementing rt_sigreturn will be trivial at this point
  • Several incompatibilities with the kernel though
  • Added special support for syscalls that self-restart to not defer the signals.
  • Added basic exception support for LoadMemTSO/StoreMemTSO (via a special op, MemCheck)
  • Works for x86-64 host / guest pair

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
Copy link
Contributor

skmp commented May 16, 2022

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
Copy link
Contributor

skmp commented May 16, 2022

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.

@skmp skmp changed the title Deferred signals Deferred signals investigation May 16, 2022
@skmp skmp modified the milestones: 2210, 2209 Aug 10, 2022
@skmp skmp moved this to 🆕 New in Next Project Milestone Aug 18, 2022
@skmp skmp moved this from 🆕 New to 📋 RelN in Next Project Milestone Aug 18, 2022
@skmp skmp moved this from 📋 Current Milestone to 🆕 Unplanned in Next Project Milestone Aug 18, 2022
@neobrain
Copy link
Member

neobrain commented Sep 26, 2023

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

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

@neobrain neobrain reopened this Sep 26, 2023
@github-project-automation github-project-automation bot moved this from 🆕 Unschedulled to 📋 Milestone in Next Project Milestone Sep 26, 2023
@Sonicadvance1 Sonicadvance1 reopened this Nov 9, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
Status: 📋 Milestone
Development

No branches or pull requests

3 participants