ARM64EC: Fix inline SMC handling for writes in the same page as the current block

Consider a page with two blocks in it, A and B. Block A performs SMC on B then A.
With the previous logic, the SMC write of B would unprotect the page and then
the inline SMC touching A would not be detected and a single-step would not be forced.
This commit is contained in:
Billy Laws committed 2025-07-23 18:46:28 +01:00
1 parent c3c2789cdf
commit 573d0858ac
1 file changed
+2 -2
+2 -2
View File
@@ -709,8 +709,8 @@ bool ResetToConsistentStateImpl(EXCEPTION_RECORD* Exception, CONTEXT* GuestConte
if (InvalidationTracker && InvalidationTracker->HandleRWXAccessViolation(FaultAddress)) {
FEXCORE_PROFILE_INSTANT_INCREMENT(Thread, AccumulatedSMCCount, 1);
if (CTX->IsAddressInCodeBuffer(Thread, NativeContext->Pc) && !CTX->IsCurrentBlockSingleInst(CPUArea.ThreadState()) &&
CTX->IsAddressInCurrentBlock(Thread, FaultAddress, 8)) {
// If we are not patching ourself (single inst block case) and patching the current block, this is inline SMC. Reconstruct the current context (before the SMC write) then single step the write to reduce it to regular SMC.
CTX->IsAddressInCurrentBlock(Thread, FaultAddress & FEXCore::Utils::FEX_PAGE_MASK, FEXCore::Utils::FEX_PAGE_SIZE)) {
// If we are not patching ourself (single inst block case) and potentially patching the current block, this is inline SMC. Reconstruct the current context (before the SMC write) then single step the write to reduce it to regular SMC.
Exception::ReconstructThreadState(Thread, *NativeContext);
LogMan::Msg::DFmt("Handled inline self-modifying code: pc: {:X} rip: {:X} fault: {:X}", NativeContext->Pc,
Thread->CurrentFrame->State.rip, FaultAddress);