thermosphere: resend debug event if not handled

This commit is contained in:
TuxSH 2020-01-28 00:38:53 +00:00
parent 984f6776c6
commit ff1aac0ab5
3 changed files with 21 additions and 6 deletions

View file

@ -69,7 +69,7 @@ void debugManagerPauseSgiHandler(void)
barrierWait(&g_debugManager.pauseBarrier);
}
void debugManagerHandlePause(void)
bool debugManagerHandlePause(void)
{
u32 coreId = currentCoreCtx->coreId;
__builtin_prefetch(&g_debugManager.pausedCoreList, 0, 3);
@ -80,6 +80,13 @@ void debugManagerHandlePause(void)
__wfe();
} while (atomic_load(&g_debugManager.pausedCoreList) & BIT(coreId));
maskIrq();
if (!g_debugManager.debugEventInfos[coreId].handled) {
// Do we still have an unhandled debug event?
// TODO build
//GDB_TrySignalDebugEvent(&g_gdbContext, &g_debugManager.debugEventInfos[coreId]);
return false;
}
}
currentCoreCtx->wasPaused = false;
@ -92,6 +99,8 @@ void debugManagerHandlePause(void)
} else if (!ssReqd && singleStepState != SingleStepState_Inactive) {
singleStepSetNextState(currentCoreCtx->guestFrame, SingleStepState_Inactive);
}
return true;
}
void debugManagerPauseCores(u32 coreList)
@ -105,7 +114,12 @@ void debugManagerUnpauseCores(u32 coreList, u32 singleStepList)
{
singleStepList &= coreList;
__builtin_prefetch(&g_debugManager.pausedCoreList, 1, 0);
FOREACH_BIT (tmp, coreId, coreList) {
if (&g_debugManager.debugEventInfos[coreId].handled) {
// Discard already handled debug events
g_debugManager.debugEventInfos[coreId].type = DBGEVENT_NONE;
}
}
// Since we're using a debugger lock, a simple stlr should be fine...
atomic_store(&g_debugManager.singleStepCoreList, singleStepList);
@ -156,7 +170,7 @@ void debugManagerReportEvent(DebugEventType type, ...)
exceptionEnterInterruptibleHypervisorCode();
unmaskIrq();
GDB_TrySignalDebugEvent(&g_gdbContext, info);
// TODO GDB_TrySignalDebugEvent(&g_gdbContext, info);
restoreInterruptFlags(flags);
}

View file

@ -22,7 +22,8 @@
extern GDBContext g_gdbContext;
typedef enum DebugEventType {
DBGEVENT_DEBUGGER_BREAK = 0,
DBGEVENT_NONE = 0,
DBGEVENT_DEBUGGER_BREAK,
DBGEVENT_EXCEPTION,
DBGEVENT_CORE_ON,
DBGEVENT_CORE_OFF,
@ -48,7 +49,7 @@ typedef struct DebugEventInfo {
void debugManagerPauseSgiHandler(void);
// Hypervisor interrupts will be serviced during the pause-wait
void debugManagerHandlePause(void);
bool debugManagerHandlePause(void);
// Note: these functions are not reentrant EXCEPT debugPauseCores(1 << currentCoreId)
// "Pause" makes sure all cores reaches the pause function before proceeding.

View file

@ -122,7 +122,7 @@ void exceptionReturnPreprocess(ExceptionStackFrame *frame)
if (currentCoreCtx->wasPaused && frame == currentCoreCtx->guestFrame) {
// Were we paused & are we about to return to the guest?
exceptionEnterInterruptibleHypervisorCode();
debugManagerHandlePause();
while (!debugManagerHandlePause());
fpuCleanInvalidateRegisterCache();
}