diff options
| author | lizzie <lizzie@eden-emu.dev> | 2026-05-15 22:01:42 +0200 |
|---|---|---|
| committer | crueter <crueter@eden-emu.dev> | 2026-05-15 22:01:42 +0200 |
| commit | bc9b9480fbbde8ee6ad2fc118e9f0afc96dd65ec (patch) | |
| tree | 0eacd6123e7cb1f3a13ca657113b82de8ce27a2a | |
| parent | d1ceeeca229383ed44b74d4d9d248c50359d5b58 (diff) | |
[dynarmic] fix 12th-gen Intel CPUs crashing due to UMONITOR (#3954)
see https://github.com/herumi/xbyak/issues/255
> Proof: https://godbolt.org/z/9vseq4Ynj
> Xbyak currently implements it as:
> ```c++
> void umonitor(const Reg& r) {
> int idx = r.getIdx();
> if (idx > 7) XBYAK_THROW(ERR_BAD_PARAMETER) //umonitor DOES accept r8,r9,r10,etc this is NOT correct
> int bit = r.getBit();
> if (BIT != bit) {
> if ((BIT == 32 && bit == 16) || (BIT == 64 && bit == 32)) {
> db(0x67);
> } else {
> XBYAK_THROW(ERR_BAD_SIZE_OF_REGISTER)
> }
> }
> db(0xF3); db(0x0F); db(0xAE); setModRM(3, 6, idx);
> }
> ```
> My program was throwing Xbyak::Exception and I tracked it down to this particular umonitor
Signed-off-by: lizzie <lizzie@eden-emu.dev>
Reviewed-on: https://git.eden-emu.dev/eden-emu/eden/pulls/3954
Reviewed-by: crueter <crueter@eden-emu.dev>
Reviewed-by: MaranBr <maranbr@eden-emu.dev>
| -rw-r--r-- | src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp index e3f1721132..1a80ae638a 100644 --- a/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp +++ b/src/dynarmic/src/dynarmic/common/spin_lock_x64.cpp @@ -26,6 +26,7 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 Xbyak::Label start, loop; code.jmp(start, code.T_NEAR); code.L(loop); + if (waitpkg) { // TODO: this is because we lack regalloc - so better to be safe :( code.push(Xbyak::util::rax); @@ -33,7 +34,14 @@ void EmitSpinLockLock(Xbyak::CodeGenerator& code, Xbyak::Reg64 ptr, Xbyak::Reg32 code.push(Xbyak::util::rdx); // TODO: This clobbers EAX and EDX did we tell the regalloc? // ARM ptr for address-monitoring - code.umonitor(ptr); + + // XBYAK BUG: code.umonitor(ptr); see issue #255 + // replace once xbyak has been fixed + code.db(0xF3); + if (ptr.getIdx() >= 8) code.db(0x41); + code.db(0x0F); code.db(0xAE); + code.db(uint8_t((3 << 6) | ((6 & 7) << 3) | (ptr.getIdx() & 7))); + // tmp.bit[0] = 0: C0.1 | Slow Wakup | Better Savings // tmp.bit[0] = 1: C0.2 | Fast Wakup | Lesser Savings // edx:eax is implicitly used as a 64-bit deadline timestamp |
