mirror of https://review.coreboot.org/STM.git
First cut at stack trace
This commit is contained in:
parent
69eb78f6c8
commit
2cdfe88c33
BIN
Stm/StmPe.suo
BIN
Stm/StmPe.suo
Binary file not shown.
|
@ -19,6 +19,13 @@ typedef struct {
|
|||
CHAR8 *Str;
|
||||
} DATA_STR;
|
||||
|
||||
extern UINTN
|
||||
TranslateEPTGuestToHost (
|
||||
IN UINT64 EptPointer,
|
||||
IN UINTN Addr,
|
||||
OUT EPT_ENTRY **EntryPtr OPTIONAL
|
||||
);
|
||||
|
||||
GLOBAL_REMOVE_IF_UNREFERENCED
|
||||
DATA_STR mVmxCapabilityMsrStr[] = {
|
||||
{IA32_VMX_BASIC_MSR_INDEX, "VMX_BASIC_MSR "},
|
||||
|
@ -503,4 +510,59 @@ DumpRegContext (
|
|||
for (Index = 0; Index < sizeof(mX86RegisterStr)/sizeof(mX86RegisterStr[0]) / (sizeof(UINT64)/sizeof(UINTN)); Index++) {
|
||||
DumpRegFiled (Reg, &mX86RegisterStr[Index]);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
This function dumps the guest stack.
|
||||
|
||||
@param Index - CPU Index
|
||||
|
||||
Assumes 1-1 mapping in the guest page tables between the
|
||||
guest virtual address and the guest physical address
|
||||
|
||||
**/
|
||||
|
||||
VOID DumpGuestStack(IN UINT32 Index)
|
||||
{
|
||||
|
||||
UINT32 VmType = mHostContextCommon.HostContextPerCpu[Index].GuestVmType;
|
||||
UINT32 i;
|
||||
UINT64 Location;
|
||||
UINT64 RelLoc;
|
||||
UINTN StackTop = (UINTN)VmReadN (VMCS_N_GUEST_RSP_INDEX);
|
||||
UINTN StackLen;
|
||||
UINT64 Stack[20]; // will limit output to at most the first 20 stack elements (64bit)
|
||||
|
||||
StackTop = TranslateEPTGuestToHost(mGuestContextCommonSmm[VmType].EptPointer.Uint64, StackTop, 0L);
|
||||
|
||||
// make sure that stack exists within the EPT tables
|
||||
// otherwise print an error message
|
||||
|
||||
if(StackTop == 0)
|
||||
{
|
||||
DEBUG ((EFI_D_ERROR, "%ld DumpGuestStack - Stack registers have bad addresses\n", Index));
|
||||
return;
|
||||
}
|
||||
|
||||
StackLen = (((UINT64)StackTop + 0x1000) & (~0xFFF)) - (UINT64)StackTop;
|
||||
|
||||
if(StackLen > 160)
|
||||
StackLen = 160; // max stackdump of 20 64-bit words
|
||||
|
||||
CopyMem (Stack, (VOID *)(UINTN)StackTop, StackLen);
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld Stacktrace\n", Index));
|
||||
|
||||
|
||||
Location = (UINT64)StackTop;
|
||||
RelLoc = 0;
|
||||
|
||||
for(i = 0; RelLoc < StackLen; i++)
|
||||
{
|
||||
|
||||
DEBUG ((EFI_D_INFO, "%ld: %016lx %016lx\n", Index, Location, Stack[i] ));
|
||||
RelLoc =+ 8;
|
||||
}
|
||||
DEBUG((EFI_D_ERROR, "%ld End Stacktrace\n", Index));
|
||||
}
|
|
@ -41,18 +41,17 @@ InitPeGuestVmcs (
|
|||
VM_EXEC_2ND_PROCESSOR_BASES_VMEXIT_CONTROLS ProcessorBasedCtrls2nd;
|
||||
GUEST_INTERRUPTIBILITY_STATE GuestInterruptibilityState;
|
||||
VM_EXIT_MSR_ENTRY *VmExitMsrEntry;
|
||||
//UINT32 VmType;
|
||||
|
||||
//VmType = mHostContextCommon.HostContextPerCpu[CpuIndex].GuestVmType;
|
||||
|
||||
DEBUG((EFI_D_ERROR, "%ld InitPeGuestVmcs Starting - VmType: %d\n", CpuIndex, VmType));
|
||||
|
||||
// setup pin based controls
|
||||
UINT32 ExceptionBitmap;
|
||||
UINT32 PageFaultErrorCodeMask;
|
||||
UINT32 PageFaultErrorCodeMatch;
|
||||
|
||||
Data64 = AsmReadMsr64 (IA32_VMX_PINBASED_CTLS_MSR_INDEX);
|
||||
PinBasedCtls.Uint32 = (UINT32)(Data64 & 0xFFFFFFFF);
|
||||
PinBasedCtls.Bits.ExternalInterrupt = 0; // external interrupt
|
||||
PinBasedCtls.Bits.Nmi = 1; // NMI is used for the SMI case
|
||||
PinBasedCtls.Bits.Nmi = 1; // NMI is used to allow for when an SMI occurs when one of the processors
|
||||
// is running a VM/PE to allow the other processors to interrupt the VM/PE
|
||||
// so that he SMI handler can process the SMI
|
||||
PinBasedCtls.Bits.VmxPreemptionTimer = 1; // Timer (was zero)
|
||||
|
||||
// Processor based controls
|
||||
|
@ -93,6 +92,10 @@ InitPeGuestVmcs (
|
|||
GuestInterruptibilityState.Uint32 = 0;
|
||||
GuestInterruptibilityState.Bits.BlockingBySmi = 1;
|
||||
|
||||
#define VMCS_32_CONTROL_EXCEPTION_BITMAP_INDEX 0x4004
|
||||
#define VMCS_32_CONTROL_PAGE_FAULT_ERROR_CODE_MASK_INDEX 0x4006
|
||||
#define VMCS_32_CONTROL_PAGE_FAULT_ERROR_CODE_MATCH_INDEX 0x4008
|
||||
|
||||
//
|
||||
// Control field
|
||||
//
|
||||
|
|
|
@ -151,6 +151,7 @@ ResumeToBiosExceptionHandler (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (Reg);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
CpuDeadLoop ();
|
||||
return ;
|
||||
|
@ -227,6 +228,7 @@ ReturnFromBiosExceptionHandler (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (Reg);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
CpuDeadLoop ();
|
||||
return ;
|
||||
|
|
|
@ -254,7 +254,7 @@ void LaunchPeVm(UINT32 PeType, UINT32 CpuIndex)
|
|||
DEBUG ((EFI_D_ERROR, "%ld LaunchPeVm - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
|
||||
DumpGuestStack(CpuIndex);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
}
|
||||
|
||||
|
@ -365,6 +365,7 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
DumpVmcsAllField(); // temp debug
|
||||
DumpVmxCapabillityMsr();
|
||||
DumpRegContext(&mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Register);
|
||||
DumpGuestStack(CpuIndex);
|
||||
print_region_list(PeType, CpuIndex);
|
||||
|
||||
if((PERM_VM_CRASH_BREAKDOWN & PeVmData[PeType].UserModule.VmConfig) == PERM_VM_CRASH_BREAKDOWN)
|
||||
|
@ -463,7 +464,6 @@ UINT32 PostPeVmProc(UINT32 rc, UINT32 CpuIndex, UINT32 mode)
|
|||
VmWriteN (VMCS_N_GUEST_RSP_INDEX, (UINTN)mHostContextCommon.HostContextPerCpu[CpuIndex].TxtProcessorSmmDescriptor->SmmSmiHandlerRsp);
|
||||
VmWriteN (VMCS_N_GUEST_CR3_INDEX, mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Cr3);
|
||||
|
||||
|
||||
STM_PERF_START (CpuIndex, 0, "BiosSmmHandler", "SmiEventHandler");
|
||||
|
||||
if (mGuestContextCommonSmm[PeType].GuestContextPerCpu[0].Launched) {
|
||||
|
|
|
@ -173,7 +173,7 @@ VOID
|
|||
DEBUG ((EFI_D_ERROR, "%ld PeStmHandlerSmm - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", Index, (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmm[VmType].GuestContextPerCpu[pIndex].Register);
|
||||
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
DEBUG((EFI_D_ERROR, "%ld PeStmHandlerSmm - CpuDeadLoop\n", Index));
|
||||
CpuDeadLoop ();
|
||||
|
|
|
@ -39,6 +39,8 @@ UINTN
|
|||
|
||||
extern VMCSFIELDOFFSET VmcsFieldOffsetTable[];
|
||||
extern void MapVmcs ();
|
||||
extern PE_VM_DATA PeVmData[4];
|
||||
|
||||
/**
|
||||
|
||||
This function is the STM_API_MAP_ADDRESS_RANGEVMCALL handler for SMM VM/PE.
|
||||
|
@ -60,6 +62,20 @@ STM_STATUS
|
|||
UINT32 VmType = mHostContextCommon.HostContextPerCpu[Index].GuestVmType;
|
||||
UINTN PhysAddressParameter;
|
||||
UINTN PhysAddressParameterEnd;
|
||||
UINT64 GuestSmmEnd = PeVmData[VmType].UserModule.AddressSpaceStart + PeVmData[VmType].UserModule.AddressSpaceSize - 1;
|
||||
|
||||
// Make sure the parameter address is with the part of the guest that is within SMRAM
|
||||
|
||||
if((AddressParameter < PeVmData[VmType].UserModule.AddressSpaceStart)||
|
||||
(AddressParameter > GuestSmmEnd) ||
|
||||
((AddressParameter + sizeof(STM_MAP_ADDRESS_RANGE_DESCRIPTOR)) > GuestSmmEnd))
|
||||
{
|
||||
DEBUG ((EFI_D_ERROR, "%ld PeSmmVmcallMapAddressRangeHandler - Security Violation! - parameter block not in guest physical within SMRAM\n", Index));
|
||||
DEBUG ((EFI_D_ERROR, "%ld PeSmmVmcallMapAddressRangeHandler - AddressParameter = 0x%016llx",
|
||||
Index,
|
||||
AddressParameter));
|
||||
return ERROR_STM_SECURITY_VIOLATION;
|
||||
}
|
||||
|
||||
PhysAddressParameter = TranslateEPTGuestToHost(mGuestContextCommonSmm[VmType].EptPointer.Uint64, (UINTN)AddressParameter, 0L);
|
||||
PhysAddressParameterEnd = TranslateEPTGuestToHost(mGuestContextCommonSmm[VmType].EptPointer.Uint64, (UINTN)AddressParameter + sizeof(STM_MAP_ADDRESS_RANGE_DESCRIPTOR), 0L);
|
||||
|
@ -69,7 +85,9 @@ STM_STATUS
|
|||
if(((PhysAddressParameter == 0)||(PhysAddressParameterEnd == 0))||
|
||||
((PhysAddressParameter & ~0xFFF) != (PhysAddressParameterEnd & ~0XFFF)))
|
||||
{
|
||||
// TODO - need to address the potential of having a parameter block split across tow oages
|
||||
// TODO - need to address the potential of having a parameter block split across two pages
|
||||
// currently the VM/PE is created as a single block...
|
||||
|
||||
DEBUG ((EFI_D_ERROR, "%ld PeSmmVmcallMapAddressRangeHandler - Security Violation! - parameter block not in guest physical address space or split across two pages\n", Index));
|
||||
DEBUG ((EFI_D_ERROR, "%ld PeSmmVmcallMapAddressRangeHandler - PhysAddressParameter = 0x%016llx, PhysAddressParameterEnd = 0x%016llx\n",
|
||||
Index,
|
||||
|
|
|
@ -107,6 +107,7 @@ SmiEventHandler (
|
|||
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmm[SMI_HANDLER].GuestContextPerCpu[Index].Register);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
|
||||
CpuDeadLoop ();
|
||||
|
|
|
@ -164,7 +164,7 @@ VOID
|
|||
DEBUG ((EFI_D_ERROR, "%ld StmHandlerSmi - VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", Index, (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmi.GuestContextPerCpu[Index].Register);
|
||||
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
|
||||
CpuDeadLoop ();
|
||||
|
|
|
@ -67,6 +67,7 @@ UnknownHandlerSmm (
|
|||
DEBUG ((EFI_D_ERROR, "!!!UnknownHandlerSmm - %d\n", (UINTN)Index));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext(&mGuestContextCommonSmm[SMI_HANDLER].GuestContextPerCpu[Index].Register);
|
||||
DumpGuestStack(Index);
|
||||
|
||||
{
|
||||
UINT8 *Buffer;
|
||||
|
@ -158,7 +159,7 @@ StmHandlerSmm (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmm[VmType].GuestContextPerCpu[pIndex].Register);
|
||||
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
|
||||
CpuDeadLoop ();
|
||||
|
|
|
@ -138,6 +138,7 @@ VOID
|
|||
DEBUG ((EFI_D_ERROR, "%ld RsmHandler VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)Index, (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmi.GuestContextPerCpu[Index].Register);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
|
||||
CpuDeadLoop ();
|
||||
|
|
|
@ -72,6 +72,7 @@ SmmTeardown (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (&mGuestContextCommonSmm[VmType].GuestContextPerCpu[Index].Register);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
CpuDeadLoop ();
|
||||
}
|
||||
|
|
|
@ -123,6 +123,7 @@ StmTeardown (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (Reg);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
#endif
|
||||
|
||||
|
|
|
@ -166,6 +166,7 @@ ResumeToBiosExceptionHandler (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (Reg);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
CpuDeadLoop ();
|
||||
return ;
|
||||
|
@ -257,6 +258,7 @@ ReturnFromBiosExceptionHandler (
|
|||
DEBUG ((EFI_D_ERROR, "VMCS_32_RO_VM_INSTRUCTION_ERROR: %08x\n", (UINTN)VmRead32 (VMCS_32_RO_VM_INSTRUCTION_ERROR_INDEX)));
|
||||
DumpVmcsAllField ();
|
||||
DumpRegContext (Reg);
|
||||
DumpGuestStack(Index);
|
||||
ReleaseSpinLock (&mHostContextCommon.DebugLock);
|
||||
CpuDeadLoop ();
|
||||
return ;
|
||||
|
|
|
@ -651,6 +651,18 @@ DumpRegContext (
|
|||
IN X86_REGISTER *Reg
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
This function dumps the guest stack.
|
||||
|
||||
@param Index - CPU Index
|
||||
|
||||
**/
|
||||
VOID
|
||||
DumpGuestStack(
|
||||
IN UINT32 Index
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
Initialize external vector table pointer.
|
||||
|
|
Loading…
Reference in New Issue