X-Git-Url: https://git.proxmox.com/?p=mirror_edk2.git;a=blobdiff_plain;f=UefiCpuPkg%2FPiSmmCpuDxeSmm%2FSmmProfile.c;h=b4fe0bc23b6cb6f9d0b0a53050d5255700366456;hp=8ddde9acb55c331fca5cc66e9fea0d935e2eee79;hb=f33d5d68abc02727dc828c1079e72ab65e1d63af;hpb=529a5a860996b5e83941bab50a7b8604139264a1 diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c index 8ddde9acb5..b4fe0bc23b 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmProfile.c @@ -1,7 +1,9 @@ /** @file Enable SMM profile. -Copyright (c) 2012 - 2015, Intel Corporation. All rights reserved.
+Copyright (c) 2012 - 2017, Intel Corporation. All rights reserved.
+Copyright (c) 2017, AMD Incorporated. All rights reserved.
+ This program and the accompanying materials are licensed and made available under the terms and conditions of the BSD License which accompanies this distribution. The full text of the license may be found at @@ -32,7 +34,7 @@ UINTN mMsrDsAreaSize = SMM_PROFILE_DTS_SIZE; // // The flag indicates if execute-disable is supported by processor. // -BOOLEAN mXdSupported = FALSE; +BOOLEAN mXdSupported = TRUE; // // The flag indicates if execute-disable is enabled on processor. @@ -42,7 +44,7 @@ BOOLEAN mXdEnabled = FALSE; // // The flag indicates if BTS is supported by processor. // -BOOLEAN mBtsSupported = FALSE; +BOOLEAN mBtsSupported = TRUE; // // The flag indicates if SMM profile starts to record data. @@ -85,6 +87,12 @@ MEMORY_PROTECTION_RANGE mProtectionMemRangeTemplate[] = { // {{0x00000000, 0x00000000},TRUE,TRUE}, + // + // SMRAM ranges not covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz (to be fixed in runtime). + // It is always present and instruction fetches are allowed. + // {{0x00000000, 0x00000000},TRUE,FALSE}, + // + // // Future extended range could be added here. // @@ -144,7 +152,7 @@ GetCpuIndex ( ApicId = GetApicId (); - for (Index = 0; Index < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); Index++) { + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { if (gSmmCpuPrivate->ProcessorInfo[Index].ProcessorId == ApicId) { return Index; } @@ -249,6 +257,33 @@ DebugExceptionHandler ( ClearTrapFlag (SystemContext); } +/** + Check if the input address is in SMM ranges. + + @param[in] Address The input address. + + @retval TRUE The input address is in SMM. + @retval FALSE The input address is not in SMM. +**/ +BOOLEAN +IsInSmmRanges ( + IN EFI_PHYSICAL_ADDRESS Address + ) +{ + UINTN Index; + + if ((Address >= mCpuHotPlugData.SmrrBase) && (Address < mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) { + return TRUE; + } + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + if (Address >= mSmmCpuSmramRanges[Index].CpuStart && + Address < mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize) { + return TRUE; + } + } + return FALSE; +} + /** Check if the memory address will be mapped by 4KB-page. @@ -264,7 +299,6 @@ IsAddressValid ( { UINTN Index; - *Nx = FALSE; if (FeaturePcdGet (PcdCpuSmmProfileEnable)) { // // Check configuration @@ -279,9 +313,9 @@ IsAddressValid ( return FALSE; } else { - if ((Address < mCpuHotPlugData.SmrrBase) || - (Address >= mCpuHotPlugData.SmrrBase + mCpuHotPlugData.SmrrSize)) { - *Nx = TRUE; + *Nx = TRUE; + if (IsInSmmRanges (Address)) { + *Nx = FALSE; } return TRUE; } @@ -337,12 +371,11 @@ InitProtectedMemRange ( { UINTN Index; UINTN NumberOfDescriptors; - UINTN NumberOfMmioDescriptors; + UINTN NumberOfAddedDescriptors; UINTN NumberOfProtectRange; UINTN NumberOfSpliteRange; EFI_GCD_MEMORY_SPACE_DESCRIPTOR *MemorySpaceMap; UINTN TotalSize; - EFI_STATUS Status; EFI_PHYSICAL_ADDRESS ProtectBaseAddress; EFI_PHYSICAL_ADDRESS ProtectEndAddress; EFI_PHYSICAL_ADDRESS Top2MBAlignedAddress; @@ -351,25 +384,25 @@ InitProtectedMemRange ( UINT64 Low4KBPageSize; NumberOfDescriptors = 0; - NumberOfMmioDescriptors = 0; + NumberOfAddedDescriptors = mSmmCpuSmramRangeCount; NumberOfSpliteRange = 0; MemorySpaceMap = NULL; // // Get MMIO ranges from GCD and add them into protected memory ranges. // - Status = gDS->GetMemorySpaceMap ( - &NumberOfDescriptors, - &MemorySpaceMap - ); + gDS->GetMemorySpaceMap ( + &NumberOfDescriptors, + &MemorySpaceMap + ); for (Index = 0; Index < NumberOfDescriptors; Index++) { if (MemorySpaceMap[Index].GcdMemoryType == EfiGcdMemoryTypeMemoryMappedIo) { - NumberOfMmioDescriptors++; + NumberOfAddedDescriptors++; } } - if (NumberOfMmioDescriptors != 0) { - TotalSize = NumberOfMmioDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate); + if (NumberOfAddedDescriptors != 0) { + TotalSize = NumberOfAddedDescriptors * sizeof (MEMORY_PROTECTION_RANGE) + sizeof (mProtectionMemRangeTemplate); mProtectionMemRange = (MEMORY_PROTECTION_RANGE *) AllocateZeroPool (TotalSize); ASSERT (mProtectionMemRange != NULL); mProtectionMemRangeCount = TotalSize / sizeof (MEMORY_PROTECTION_RANGE); @@ -386,10 +419,28 @@ InitProtectedMemRange ( mSplitMemRange = (MEMORY_RANGE *) AllocateZeroPool (TotalSize); ASSERT (mSplitMemRange != NULL); + // + // Create SMM ranges which are set to present and execution-enable. + // + NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE); + for (Index = 0; Index < mSmmCpuSmramRangeCount; Index++) { + if (mSmmCpuSmramRanges[Index].CpuStart >= mProtectionMemRange[0].Range.Base && + mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize < mProtectionMemRange[0].Range.Top) { + // + // If the address have been already covered by mCpuHotPlugData.SmrrBase/mCpuHotPlugData.SmrrSiz + // + break; + } + mProtectionMemRange[NumberOfProtectRange].Range.Base = mSmmCpuSmramRanges[Index].CpuStart; + mProtectionMemRange[NumberOfProtectRange].Range.Top = mSmmCpuSmramRanges[Index].CpuStart + mSmmCpuSmramRanges[Index].PhysicalSize; + mProtectionMemRange[NumberOfProtectRange].Present = TRUE; + mProtectionMemRange[NumberOfProtectRange].Nx = FALSE; + NumberOfProtectRange++; + } + // // Create MMIO ranges which are set to present and execution-disable. // - NumberOfProtectRange = sizeof (mProtectionMemRangeTemplate) / sizeof (MEMORY_PROTECTION_RANGE); for (Index = 0; Index < NumberOfDescriptors; Index++) { if (MemorySpaceMap[Index].GcdMemoryType != EfiGcdMemoryTypeMemoryMappedIo) { continue; @@ -400,6 +451,12 @@ InitProtectedMemRange ( mProtectionMemRange[NumberOfProtectRange].Nx = TRUE; NumberOfProtectRange++; } + + // + // Check and updated actual protected memory ranges count + // + ASSERT (NumberOfProtectRange <= mProtectionMemRangeCount); + mProtectionMemRangeCount = NumberOfProtectRange; } // @@ -519,7 +576,7 @@ InitPaging ( // continue; } - Pde = (UINT64 *)(UINTN)(Pml4[Level1] & PHYSICAL_ADDRESS_MASK); + Pde = (UINT64 *)(UINTN)(Pml4[Level1] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); } else { Pde = (UINT64*)(UINTN)mSmmProfileCr3; } @@ -530,7 +587,13 @@ InitPaging ( // continue; } - Pte = (UINT64 *)(UINTN)(*Pde & PHYSICAL_ADDRESS_MASK); + if ((*Pde & IA32_PG_PS) != 0) { + // + // This is 1G entry, skip it + // + continue; + } + Pte = (UINT64 *)(UINTN)(*Pde & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); if (Pte == 0) { continue; } @@ -552,14 +615,14 @@ InitPaging ( // ASSERT (Address == (*Pte & PHYSICAL_ADDRESS_MASK)); - Pt = AllocatePages (1); + Pt = AllocatePageTableMemory (1); ASSERT (Pt != NULL); // Split it for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++) { - Pt[Level4] = Address + ((Level4 << 12) | IA32_PG_RW | IA32_PG_P); + Pt[Level4] = Address + ((Level4 << 12) | mAddressEncMask | PAGE_ATTRIBUTE_BITS); } // end for PT - *Pte = (UINTN)Pt | IA32_PG_RW | IA32_PG_P; + *Pte = (UINT64)(UINTN)Pt | mAddressEncMask | PAGE_ATTRIBUTE_BITS; } // end if IsAddressSplit } // end for PTE } // end for PDE @@ -577,7 +640,7 @@ InitPaging ( // continue; } - Pde = (UINT64 *)(UINTN)(Pml4[Level1] & PHYSICAL_ADDRESS_MASK); + Pde = (UINT64 *)(UINTN)(Pml4[Level1] & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); } else { Pde = (UINT64*)(UINTN)mSmmProfileCr3; } @@ -588,7 +651,16 @@ InitPaging ( // continue; } - Pte = (UINT64 *)(UINTN)(*Pde & PHYSICAL_ADDRESS_MASK); + if ((*Pde & IA32_PG_PS) != 0) { + // + // This is 1G entry, set NX bit and skip it + // + if (mXdSupported) { + *Pde = *Pde | IA32_PG_NX; + } + continue; + } + Pte = (UINT64 *)(UINTN)(*Pde & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); if (Pte == 0) { continue; } @@ -608,20 +680,20 @@ InitPaging ( // // Patch to remove Present flag and RW flag // - *Pte = *Pte & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P)); + *Pte = *Pte & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } if (Nx && mXdSupported) { *Pte = *Pte | IA32_PG_NX; } } else { // 4KB page - Pt = (UINT64 *)(UINTN)(*Pte & PHYSICAL_ADDRESS_MASK); + Pt = (UINT64 *)(UINTN)(*Pte & ~mAddressEncMask & PHYSICAL_ADDRESS_MASK); if (Pt == 0) { continue; } for (Level4 = 0; Level4 < SIZE_4KB / sizeof(*Pt); Level4++, Pt++) { if (!IsAddressValid (Address, &Nx)) { - *Pt = *Pt & (INTN)(INT32)(~(IA32_PG_RW | IA32_PG_P)); + *Pt = *Pt & (INTN)(INT32)(~PAGE_ATTRIBUTE_BITS); } if (Nx && mXdSupported) { *Pt = *Pt | IA32_PG_NX; @@ -776,18 +848,16 @@ InitSmmProfileCallBack ( IN EFI_HANDLE Handle ) { - EFI_STATUS Status; - // // Save to variable so that SMM profile data can be found. // - Status = gRT->SetVariable ( - SMM_PROFILE_NAME, - &gEfiCallerIdGuid, - EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, - sizeof(mSmmProfileBase), - &mSmmProfileBase - ); + gRT->SetVariable ( + SMM_PROFILE_NAME, + &gEfiCallerIdGuid, + EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS, + sizeof(mSmmProfileBase), + &mSmmProfileBase + ); // // Get Software SMI from FADT @@ -818,13 +888,13 @@ InitSmmProfileInternal ( UINTN MsrDsAreaSizePerCpu; UINTN TotalSize; - mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + mPFEntryCount = (UINTN *)AllocateZeroPool (sizeof (UINTN) * mMaxNumberOfCpus); ASSERT (mPFEntryCount != NULL); mLastPFEntryValue = (UINT64 (*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool ( - sizeof (mLastPFEntryValue[0]) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + sizeof (mLastPFEntryValue[0]) * mMaxNumberOfCpus); ASSERT (mLastPFEntryValue != NULL); mLastPFEntryPointer = (UINT64 *(*)[MAX_PF_ENTRY_COUNT])AllocateZeroPool ( - sizeof (mLastPFEntryPointer[0]) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + sizeof (mLastPFEntryPointer[0]) * mMaxNumberOfCpus); ASSERT (mLastPFEntryPointer != NULL); // @@ -865,17 +935,17 @@ InitSmmProfileInternal ( mSmmProfileBase->NumCpus = gSmmCpuPrivate->SmmCoreEntryContext.NumberOfCpus; if (mBtsSupported) { - mMsrDsArea = (MSR_DS_AREA_STRUCT **)AllocateZeroPool (sizeof (MSR_DS_AREA_STRUCT *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + mMsrDsArea = (MSR_DS_AREA_STRUCT **)AllocateZeroPool (sizeof (MSR_DS_AREA_STRUCT *) * mMaxNumberOfCpus); ASSERT (mMsrDsArea != NULL); - mMsrBTSRecord = (BRANCH_TRACE_RECORD **)AllocateZeroPool (sizeof (BRANCH_TRACE_RECORD *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + mMsrBTSRecord = (BRANCH_TRACE_RECORD **)AllocateZeroPool (sizeof (BRANCH_TRACE_RECORD *) * mMaxNumberOfCpus); ASSERT (mMsrBTSRecord != NULL); - mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * PcdGet32 (PcdCpuMaxLogicalProcessorNumber)); + mMsrPEBSRecord = (PEBS_RECORD **)AllocateZeroPool (sizeof (PEBS_RECORD *) * mMaxNumberOfCpus); ASSERT (mMsrPEBSRecord != NULL); mMsrDsAreaBase = (MSR_DS_AREA_STRUCT *)((UINTN)Base + mSmmProfileSize); - MsrDsAreaSizePerCpu = mMsrDsAreaSize / PcdGet32 (PcdCpuMaxLogicalProcessorNumber); + MsrDsAreaSizePerCpu = mMsrDsAreaSize / mMaxNumberOfCpus; mBTSRecordNumber = (MsrDsAreaSizePerCpu - sizeof(PEBS_RECORD) * PEBS_RECORD_NUMBER - sizeof(MSR_DS_AREA_STRUCT)) / sizeof(BRANCH_TRACE_RECORD); - for (Index = 0; Index < PcdGet32 (PcdCpuMaxLogicalProcessorNumber); Index++) { + for (Index = 0; Index < mMaxNumberOfCpus; Index++) { mMsrDsArea[Index] = (MSR_DS_AREA_STRUCT *)((UINTN)mMsrDsAreaBase + MsrDsAreaSizePerCpu * Index); mMsrBTSRecord[Index] = (BRANCH_TRACE_RECORD *)((UINTN)mMsrDsArea[Index] + sizeof(MSR_DS_AREA_STRUCT)); mMsrPEBSRecord[Index] = (PEBS_RECORD *)((UINTN)mMsrDsArea[Index] + MsrDsAreaSizePerCpu - sizeof(PEBS_RECORD) * PEBS_RECORD_NUMBER); @@ -934,8 +1004,9 @@ CheckFeatureSupported ( VOID ) { - UINT32 RegEax; - UINT32 RegEdx; + UINT32 RegEax; + UINT32 RegEdx; + MSR_IA32_MISC_ENABLE_REGISTER MiscEnableMsr; if (mXdSupported) { AsmCpuid (CPUID_EXTENDED_FUNCTION, &RegEax, NULL, NULL, NULL); @@ -944,6 +1015,7 @@ CheckFeatureSupported ( // Extended CPUID functions are not supported on this processor. // mXdSupported = FALSE; + PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1); } AsmCpuid (CPUID_EXTENDED_CPU_SIG, NULL, NULL, NULL, &RegEdx); @@ -952,6 +1024,7 @@ CheckFeatureSupported ( // Execute Disable Bit feature is not supported on this processor. // mXdSupported = FALSE; + PatchInstructionX86 (gPatchXdSupported, mXdSupported, 1); } } @@ -966,10 +1039,10 @@ CheckFeatureSupported ( // BTINT bits in the MSR_DEBUGCTLA MSR. // 2. The IA32_DS_AREA MSR can be programmed to point to the DS save area. // - if ((AsmMsrBitFieldRead64 (MSR_IA32_MISC_ENABLE, 11, 11) == 0) && - (AsmMsrBitFieldRead64 (MSR_IA32_MISC_ENABLE, 12, 12) == 0)) { + MiscEnableMsr.Uint64 = AsmReadMsr64 (MSR_IA32_MISC_ENABLE); + if (MiscEnableMsr.Bits.BTS == 1) { // - // BTS facilities is supported. + // BTS facilities is not supported if MSR_IA32_MISC_ENABLE.BTS bit is set. // mBtsSupported = FALSE; } @@ -977,67 +1050,6 @@ CheckFeatureSupported ( } } -/** - Check if XD and BTS features are supported by all processors. - -**/ -VOID -CheckProcessorFeature ( - VOID - ) -{ - EFI_STATUS Status; - EFI_MP_SERVICES_PROTOCOL *MpServices; - - Status = gBS->LocateProtocol (&gEfiMpServiceProtocolGuid, NULL, (VOID **)&MpServices); - ASSERT_EFI_ERROR (Status); - - // - // First detect if XD and BTS are supported - // - mXdSupported = TRUE; - mBtsSupported = TRUE; - - // - // Check if XD and BTS are supported on all processors. - // - CheckFeatureSupported (); - - // - //Check on other processors if BSP supports this - // - if (mXdSupported || mBtsSupported) { - MpServices->StartupAllAPs ( - MpServices, - (EFI_AP_PROCEDURE) CheckFeatureSupported, - TRUE, - NULL, - 0, - NULL, - NULL - ); - } -} - -/** - Enable XD feature. - -**/ -VOID -ActivateXd ( - VOID - ) -{ - UINT64 MsrRegisters; - - MsrRegisters = AsmReadMsr64 (MSR_EFER); - if ((MsrRegisters & MSR_EFER_XD) != 0) { - return ; - } - MsrRegisters |= MSR_EFER_XD; - AsmWriteMsr64 (MSR_EFER, MsrRegisters); -} - /** Enable single step. @@ -1072,8 +1084,6 @@ ActivateLBR ( if ((DebugCtl & MSR_DEBUG_CTL_LBR) != 0) { return ; } - AsmWriteMsr64 (MSR_LER_FROM_LIP, 0); - AsmWriteMsr64 (MSR_LER_TO_LIP, 0); DebugCtl |= MSR_DEBUG_CTL_LBR; AsmWriteMsr64 (MSR_DEBUG_CTL, DebugCtl); } @@ -1244,7 +1254,7 @@ RestorePageTableBelow4G ( // PageTable[PTIndex] = (PFAddress & ~((1ull << 21) - 1)); PageTable[PTIndex] |= (UINT64)IA32_PG_PS; - PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P); + PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS; if ((ErrorCode & IA32_PF_EC_ID) != 0) { PageTable[PTIndex] &= ~IA32_PG_NX; } @@ -1277,7 +1287,7 @@ RestorePageTableBelow4G ( // Set new entry // PageTable[PTIndex] = (PFAddress & ~((1ull << 12) - 1)); - PageTable[PTIndex] |= (UINT64)(IA32_PG_RW | IA32_PG_P); + PageTable[PTIndex] |= (UINT64)PAGE_ATTRIBUTE_BITS; if ((ErrorCode & IA32_PF_EC_ID) != 0) { PageTable[PTIndex] &= ~IA32_PG_NX; } @@ -1299,6 +1309,8 @@ SmmProfilePFHandler ( { UINT64 *PageTable; UINT64 PFAddress; + UINT64 RestoreAddress; + UINTN RestorePageNumber; UINTN CpuIndex; UINTN Index; UINT64 InstructionAddress; @@ -1308,7 +1320,6 @@ SmmProfilePFHandler ( SMM_PROFILE_ENTRY *SmmProfileEntry; UINT64 SmiCommand; EFI_STATUS Status; - UINTN SwSmiCpuIndex; UINT8 SoftSmiValue; EFI_SMM_SAVE_STATE_IO_INFO IoInfo; @@ -1329,10 +1340,21 @@ SmmProfilePFHandler ( PFAddress = AsmReadCr2 (); CpuIndex = GetCpuIndex (); - if (PFAddress <= 0xFFFFFFFF) { - RestorePageTableBelow4G (PageTable, PFAddress, CpuIndex, ErrorCode); - } else { - RestorePageTableAbove4G (PageTable, PFAddress, CpuIndex, ErrorCode, &IsValidPFAddress); + // + // Memory operation cross pages, like "rep mov" instruction, will cause + // infinite loop between this and Debug Trap handler. We have to make sure + // that current page and the page followed are both in PRESENT state. + // + RestorePageNumber = 2; + RestoreAddress = PFAddress; + while (RestorePageNumber > 0) { + if (RestoreAddress <= 0xFFFFFFFF) { + RestorePageTableBelow4G (PageTable, RestoreAddress, CpuIndex, ErrorCode); + } else { + RestorePageTableAbove4G (PageTable, RestoreAddress, CpuIndex, ErrorCode, &IsValidPFAddress); + } + RestoreAddress += EFI_PAGE_SIZE; + RestorePageNumber--; } if (!IsValidPFAddress) { @@ -1351,10 +1373,6 @@ SmmProfilePFHandler ( } } - // - // Try to find which CPU trigger SWSMI - // - SwSmiCpuIndex = 0; // // Indicate it is not software SMI // @@ -1365,10 +1383,6 @@ SmmProfilePFHandler ( continue; } if (IoInfo.IoPort == mSmiCommandPort) { - // - // Great! Find it. - // - SwSmiCpuIndex = Index; // // A software SMI triggered by SMI command port has been found, get SmiCommand from SMI command port. // @@ -1439,5 +1453,8 @@ InitIdtr ( VOID ) { - SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_DEBUG, DebugExceptionHandler); + EFI_STATUS Status; + + Status = SmmRegisterExceptionHandler (&mSmmCpuService, EXCEPT_IA32_DEBUG, DebugExceptionHandler); + ASSERT_EFI_ERROR (Status); }