thermosphere: add esr_el2 to exception frame

This commit is contained in:
TuxSH 2020-01-22 21:08:52 +00:00
parent 744491ca33
commit 418cabbd53
6 changed files with 39 additions and 34 deletions

View file

@ -26,9 +26,14 @@ static Barrier g_debugPauseBarrier;
static atomic_uint g_debugPausePausedCoreList; static atomic_uint g_debugPausePausedCoreList;
static atomic_uint g_debugPauseSingleStepCoreList; static atomic_uint g_debugPauseSingleStepCoreList;
void debugPauseSgiHandler(void) static inline void debugSetThisCorePaused(void)
{ {
currentCoreCtx->wasPaused = true; currentCoreCtx->wasPaused = true;
}
void debugPauseSgiHandler(void)
{
debugSetThisCorePaused();
barrierWait(&g_debugPauseBarrier); barrierWait(&g_debugPauseBarrier);
} }
@ -76,7 +81,7 @@ void debugPauseCores(u32 coreList)
} }
if (remainingList & BIT(currentCoreCtx->coreId)) { if (remainingList & BIT(currentCoreCtx->coreId)) {
currentCoreCtx->wasPaused = true; debugSetThisCorePaused();
} }
unmaskIrq(); unmaskIrq();

View file

@ -176,8 +176,9 @@ _saveMostRegisters:
mrs x21, sp_el0 mrs x21, sp_el0
mrs x22, elr_el2 mrs x22, elr_el2
mrs x23, spsr_el2 mrs x23, spsr_el2
mov x24, x28 // far_el2 mrs x24, esr_el2
mov x25, x29 // cntpct_el0 mov x25, x28 // far_el2
mov x26, x29 // cntpct_el0
// See SAVE_MOST_REGISTERS macro // See SAVE_MOST_REGISTERS macro
ldp x28, x29, [sp, #-0x20] ldp x28, x29, [sp, #-0x20]
@ -187,7 +188,7 @@ _saveMostRegisters:
stp x19, x20, [sp, #0xF0] stp x19, x20, [sp, #0xF0]
stp x21, x22, [sp, #0x100] stp x21, x22, [sp, #0x100]
stp x23, x24, [sp, #0x110] stp x23, x24, [sp, #0x110]
stp x25, xzr, [sp, #0x120] stp x25, x26, [sp, #0x120]
ret ret
@ -310,7 +311,6 @@ UNKNOWN_EXCEPTION _serrorSpx
EXCEPTION_HANDLER_START _synchA64, EXCEPTION_TYPE_GUEST EXCEPTION_HANDLER_START _synchA64, EXCEPTION_TYPE_GUEST
mov x0, sp mov x0, sp
mrs x1, esr_el2
bl handleLowerElSyncException bl handleLowerElSyncException
EXCEPTION_HANDLER_END _synchA64, EXCEPTION_TYPE_GUEST EXCEPTION_HANDLER_END _synchA64, EXCEPTION_TYPE_GUEST
@ -328,7 +328,6 @@ UNKNOWN_EXCEPTION _serrorA64
EXCEPTION_HANDLER_START _synchA32, EXCEPTION_TYPE_GUEST EXCEPTION_HANDLER_START _synchA32, EXCEPTION_TYPE_GUEST
mov x0, sp mov x0, sp
mrs x1, esr_el2
bl handleLowerElSyncException bl handleLowerElSyncException
EXCEPTION_HANDLER_END _synchA32, EXCEPTION_TYPE_GUEST EXCEPTION_HANDLER_END _synchA32, EXCEPTION_TYPE_GUEST

View file

@ -69,8 +69,10 @@ void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl)
} }
DEBUG("sp_el1\t\t%016llx\n", frame->sp_el1); DEBUG("sp_el1\t\t%016llx\n", frame->sp_el1);
DEBUG("cntpct_el0\t%016llx\n", frame->cntpct_el0); DEBUG("cntpct_el0\t%016llx\n", frame->cntpct_el0);
DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0); if (frame == currentCoreCtx->guestFrame) {
DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0); DEBUG("cntp_ctl_el0\t%016llx\n", frame->cntp_ctl_el0);
DEBUG("cntv_ctl_el0\t%016llx\n", frame->cntv_ctl_el0);
}
#else #else
(void)frame; (void)frame;
(void)sameEl; (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) { switch (esr.ec) {
case Exception_CP15RTTrap: case Exception_CP15RTTrap:
handleMcrMrcCP15Trap(frame, esr); 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); 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); dumpStackFrame(frame, true);
} }

View file

@ -19,24 +19,6 @@
#include "utils.h" #include "utils.h"
#include "core_ctx.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 // Adapted from https://developer.arm.com/docs/ddi0596/a/a64-shared-pseudocode-functions/shared-exceptions-pseudocode
typedef enum ExceptionClass { typedef enum ExceptionClass {
Exception_Uncategorized = 0x0, Exception_Uncategorized = 0x0,
@ -88,6 +70,25 @@ typedef struct ExceptionSyndromeRegister {
u32 res0 : 32; u32 res0 : 32;
} ExceptionSyndromeRegister; } 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) static inline bool spsrIsA32(u64 spsr)
{ {
return (spsr & 0x10) != 0; return (spsr & 0x10) != 0;
@ -139,7 +140,3 @@ void skipFaultingInstruction(ExceptionStackFrame *frame, u32 size);
void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl); void dumpStackFrame(const ExceptionStackFrame *frame, bool sameEl);
void exceptionEnterInterruptibleHypervisorCode(void); void exceptionEnterInterruptibleHypervisorCode(void);
void handleLowerElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr);
void handleSameElSyncException(ExceptionStackFrame *frame, ExceptionSyndromeRegister esr);
void handleUnknownException(u32 offset);

View file

@ -206,6 +206,7 @@ void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32)
u32 irqId = iar & 0x3FF; u32 irqId = iar & 0x3FF;
u32 srcCore = (iar >> 10) & 7; u32 srcCore = (iar >> 10) & 7;
frame->esr_el2.ec = Exception_Uncategorized;
DEBUG("EL2 [core %d]: Received irq %x\n", (int)currentCoreCtx->coreId, irqId); DEBUG("EL2 [core %d]: Received irq %x\n", (int)currentCoreCtx->coreId, irqId);
if (irqId == GIC_IRQID_SPURIOUS) { if (irqId == GIC_IRQID_SPURIOUS) {

View file

@ -55,7 +55,6 @@ void initIrq(void);
void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive); void configureInterrupt(u16 id, u8 prio, bool isLevelSensitive);
bool irqIsGuest(u16 id); bool irqIsGuest(u16 id);
void irqSetAffinity(u16 id, u8 affinityMask); void irqSetAffinity(u16 id, u8 affinityMask);
void handleIrqException(ExceptionStackFrame *frame, bool isLowerEl, bool isA32);
static inline void generateSgiForAllOthers(ThermosphereSgi id) static inline void generateSgiForAllOthers(ThermosphereSgi id)
{ {