diff --git a/thermosphere/src/debug_pause.c b/thermosphere/src/debug_pause.c index 549eab353..683917992 100644 --- a/thermosphere/src/debug_pause.c +++ b/thermosphere/src/debug_pause.c @@ -26,9 +26,14 @@ static Barrier g_debugPauseBarrier; static atomic_uint g_debugPausePausedCoreList; static atomic_uint g_debugPauseSingleStepCoreList; -void debugPauseSgiHandler(void) +static inline void debugSetThisCorePaused(void) { currentCoreCtx->wasPaused = true; +} + +void debugPauseSgiHandler(void) +{ + debugSetThisCorePaused(); barrierWait(&g_debugPauseBarrier); } @@ -76,7 +81,7 @@ void debugPauseCores(u32 coreList) } if (remainingList & BIT(currentCoreCtx->coreId)) { - currentCoreCtx->wasPaused = true; + debugSetThisCorePaused(); } unmaskIrq(); diff --git a/thermosphere/src/exception_vectors.s b/thermosphere/src/exception_vectors.s index b9eb2e39d..e13abba44 100644 --- a/thermosphere/src/exception_vectors.s +++ b/thermosphere/src/exception_vectors.s @@ -176,8 +176,9 @@ _saveMostRegisters: mrs x21, sp_el0 mrs x22, elr_el2 mrs x23, spsr_el2 - mov x24, x28 // far_el2 - mov x25, x29 // cntpct_el0 + mrs x24, esr_el2 + mov x25, x28 // far_el2 + mov x26, x29 // cntpct_el0 // See SAVE_MOST_REGISTERS macro ldp x28, x29, [sp, #-0x20] @@ -187,7 +188,7 @@ _saveMostRegisters: stp x19, x20, [sp, #0xF0] stp x21, x22, [sp, #0x100] stp x23, x24, [sp, #0x110] - stp x25, xzr, [sp, #0x120] + stp x25, x26, [sp, #0x120] ret @@ -310,7 +311,6 @@ UNKNOWN_EXCEPTION _serrorSpx EXCEPTION_HANDLER_START _synchA64, EXCEPTION_TYPE_GUEST mov x0, sp - mrs x1, esr_el2 bl handleLowerElSyncException EXCEPTION_HANDLER_END _synchA64, EXCEPTION_TYPE_GUEST @@ -328,7 +328,6 @@ UNKNOWN_EXCEPTION _serrorA64 EXCEPTION_HANDLER_START _synchA32, EXCEPTION_TYPE_GUEST mov x0, sp - mrs x1, esr_el2 bl handleLowerElSyncException EXCEPTION_HANDLER_END _synchA32, EXCEPTION_TYPE_GUEST diff --git a/thermosphere/src/exceptions.c b/thermosphere/src/exceptions.c index 69eab1632..75c04de62 100644 --- a/thermosphere/src/exceptions.c +++ b/thermosphere/src/exceptions.c @@ -69,8 +69,10 @@ void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl) } DEBUG("sp_el1\t\t%016llx\n", frame->sp_el1); DEBUG("cntpct_el0\t%016llx\n", frame->cntpct_el0); - DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0); - DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0); + if (frame == currentCoreCtx->guestFrame) { + DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0); + DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0); + } #else (void)frame; (void)sameEl; @@ -132,8 +134,9 @@ void exceptionReturnPreprocess(ExceptionStackFrame *frame) } } -void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr) +void handleLowerElSyncException(ExceptionStackFrame *frame) { + ExceptionSyndromeRegister esr = frame->esr_el2; switch (esr.ec) { case Exception_CP15RTTrap: handleMcrMrcCP15Trap(frame, esr); @@ -171,8 +174,9 @@ void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeReg } } -void handleSameElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr) +void handleSameElSyncException(ExceptionStackFrame *frame) { + ExceptionSyndromeRegister esr = frame->esr_el2; DEBUG("Same EL sync exception on core %x, EC = 0x%02llx IL=%llu ISS=0x%06llx\n", currentCoreCtx->coreId, (u64)esr.ec, esr.il, esr.iss); dumpStackFrame(frame, true); } diff --git a/thermosphere/src/exceptions.h b/thermosphere/src/exceptions.h index ef47c2bc1..9cd398845 100644 --- a/thermosphere/src/exceptions.h +++ b/thermosphere/src/exceptions.h @@ -19,24 +19,6 @@ #include "utils.h" #include "core_ctx.h" -typedef struct ExceptionStackFrame { - u64 x[31]; // x0 .. x30 - u64 sp_el1; - union { - u64 sp_el2; - u64 sp_el0; - }; - u64 elr_el2; - u64 spsr_el2; - u64 far_el2; - u64 cntpct_el0; - u64 cntp_ctl_el0; - u64 cntv_ctl_el0; - u64 reserved; -} ExceptionStackFrame; - -static_assert(sizeof(ExceptionStackFrame) == 0x140, "Wrong size for ExceptionStackFrame"); - // Adapted from https://developer.arm.com/docs/ddi0596/a/a64-shared-pseudocode-functions/shared-exceptions-pseudocode typedef enum ExceptionClass { Exception_Uncategorized = 0x0, @@ -88,6 +70,25 @@ typedef struct ExceptionSyndromeRegister { u32 res0 : 32; } ExceptionSyndromeRegister; +typedef struct ExceptionStackFrame { + u64 x[31]; // x0 .. x30 + u64 sp_el1; + union { + u64 sp_el2; + u64 sp_el0; + }; + u64 elr_el2; + u64 spsr_el2; + ExceptionSyndromeRegister esr_el2; + u64 far_el2; + u64 cntpct_el0; + u64 cntp_ctl_el0; + u64 cntv_ctl_el0; +} ExceptionStackFrame; + +static_assert(offsetof(ExceptionStackFrame, far_el2) == 0x120, "Wrong definition for ExceptionStackFrame"); +static_assert(sizeof(ExceptionStackFrame) == 0x140, "Wrong size for ExceptionStackFrame"); + static inline bool spsrIsA32(u64 spsr) { return (spsr & 0x10) != 0; @@ -139,7 +140,3 @@ void skipFaultingInstruction(ExceptionStackFrame *frame, u32 size); void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl); void exceptionEnterInterruptibleHypervisorCode(void); - -void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr); -void handleSameElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr); -void handleUnknownException(u32 offset); diff --git a/thermosphere/src/irq.c b/thermosphere/src/irq.c index 62787c205..521e225c0 100644 --- a/thermosphere/src/irq.c +++ b/thermosphere/src/irq.c @@ -206,6 +206,7 @@ void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32) u32 irqId = iar & 0x3FF; u32 srcCore = (iar >> 10) & 7; + frame->esr_el2.ec = Exception_Uncategorized; DEBUG("EL2 [core %d]: Received irq %x\n", (int)currentCoreCtx->coreId, irqId); if (irqId == GIC_IRQID_SPURIOUS) { diff --git a/thermosphere/src/irq.h b/thermosphere/src/irq.h index e14a00b16..63cfa1c6e 100644 --- a/thermosphere/src/irq.h +++ b/thermosphere/src/irq.h @@ -55,7 +55,6 @@ void initIrq(void); void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive); bool irqIsGuest(u16 id); void irqSetAffinity(u16 id, u8 affinityMask); -void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32); static inline void generateSgiForAllOthers(ThermosphereSgi id) {