2015-10-19 21:12:53 +02:00
|
|
|
/** @file
|
|
|
|
SMM profile internal header file.
|
|
|
|
|
UefiCpuPkg/PiSmmCpuDxeSmm: Check PDE entry exist or not before use
Before the commit 701b5797 & 4ceefd6d, 2MB-page will be created to
cover [0: 4G] by default if SmmProfile enabled, and it will be go
through to change 2MB-page into 4KB-page during page table update
(InitPaging). If so, there was no problem to assert PDE entry exist
in the RestorePageTableBelow4G.
But after above commits, PageTableMap API is used to create/update
the page table, 1G-page will be the default page table mode, and
only covers the limited address range. Those not covered ranges
will be marked as non-present in 1g-page level address. If so,
2M-page address might not exist, it's incorrect to assert PDE
entry exist in the RestorePageTableBelow4G.
The correct behavior should check PDE entry exist or not, if not,
PDE should be allocated and assigned to PDPTE.
Note:
RestorePageTableBelow4G () does not use 1G page size entries
for the creation of new pages, maintaining consistency with the
behavior of the original code.
The purpose of this patch is to ensure that a Page Directory Entry
(PDE) exists prior to its usage.
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-07-15 04:16:12 +02:00
|
|
|
Copyright (c) 2012 - 2024, Intel Corporation. All rights reserved.<BR>
|
2020-06-22 15:18:25 +02:00
|
|
|
Copyright (c) 2020, AMD Incorporated. All rights reserved.<BR>
|
2019-04-04 01:07:22 +02:00
|
|
|
SPDX-License-Identifier: BSD-2-Clause-Patent
|
2015-10-19 21:12:53 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
|
|
|
|
#ifndef _SMM_PROFILE_INTERNAL_H_
|
|
|
|
#define _SMM_PROFILE_INTERNAL_H_
|
|
|
|
|
|
|
|
#include <Protocol/SmmReadyToLock.h>
|
|
|
|
#include <Library/CpuLib.h>
|
|
|
|
#include <IndustryStandard/Acpi.h>
|
|
|
|
|
|
|
|
#include "SmmProfileArch.h"
|
|
|
|
|
|
|
|
//
|
|
|
|
// Configure the SMM_PROFILE DTS region size
|
|
|
|
//
|
|
|
|
#define SMM_PROFILE_DTS_SIZE (4 * 1024 * 1024) // 4M
|
|
|
|
|
|
|
|
#define MAX_PF_PAGE_COUNT 0x2
|
|
|
|
|
|
|
|
#define PEBS_RECORD_NUMBER 0x2
|
|
|
|
|
|
|
|
#define MAX_PF_ENTRY_COUNT 10
|
|
|
|
|
|
|
|
//
|
|
|
|
// This MACRO just enable unit test for the profile
|
|
|
|
// Please disable it.
|
|
|
|
//
|
|
|
|
|
|
|
|
#define IA32_PF_EC_ID (1u << 4)
|
|
|
|
|
|
|
|
#define SMM_PROFILE_NAME L"SmmProfileData"
|
|
|
|
|
|
|
|
//
|
|
|
|
// CPU generic definition
|
|
|
|
//
|
2024-10-22 23:20:41 +02:00
|
|
|
#define MSR_EFER_XD 0x800
|
2015-10-19 21:12:53 +02:00
|
|
|
|
2024-10-22 23:20:41 +02:00
|
|
|
#define CPUID1_EDX_BTS_AVAILABLE 0x200000
|
2015-10-19 21:12:53 +02:00
|
|
|
|
2024-10-22 23:20:41 +02:00
|
|
|
#define DR6_SINGLE_STEP 0x4000
|
2015-10-19 21:12:53 +02:00
|
|
|
|
2024-10-22 23:20:41 +02:00
|
|
|
#define MSR_DS_AREA 0x600
|
2015-10-19 21:12:53 +02:00
|
|
|
|
2018-08-20 05:35:58 +02:00
|
|
|
#define HEAP_GUARD_NONSTOP_MODE \
|
|
|
|
((PcdGet8 (PcdHeapGuardPropertyMask) & (BIT6|BIT3|BIT2)) > BIT6)
|
|
|
|
|
|
|
|
#define NULL_DETECTION_NONSTOP_MODE \
|
|
|
|
((PcdGet8 (PcdNullPointerDetectionPropertyMask) & (BIT6|BIT1)) > BIT6)
|
|
|
|
|
2015-10-19 21:12:53 +02:00
|
|
|
typedef struct {
|
|
|
|
EFI_PHYSICAL_ADDRESS Base;
|
|
|
|
EFI_PHYSICAL_ADDRESS Top;
|
|
|
|
} MEMORY_RANGE;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
MEMORY_RANGE Range;
|
|
|
|
BOOLEAN Present;
|
|
|
|
BOOLEAN Nx;
|
|
|
|
} MEMORY_PROTECTION_RANGE;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
UINT64 HeaderSize;
|
|
|
|
UINT64 MaxDataEntries;
|
|
|
|
UINT64 MaxDataSize;
|
|
|
|
UINT64 CurDataEntries;
|
|
|
|
UINT64 CurDataSize;
|
|
|
|
UINT64 TsegStart;
|
|
|
|
UINT64 TsegSize;
|
|
|
|
UINT64 NumSmis;
|
|
|
|
UINT64 NumCpus;
|
|
|
|
} SMM_PROFILE_HEADER;
|
|
|
|
|
|
|
|
typedef struct {
|
|
|
|
UINT64 SmiNum;
|
|
|
|
UINT64 CpuNum;
|
|
|
|
UINT64 ApicId;
|
|
|
|
UINT64 ErrorCode;
|
|
|
|
UINT64 Instruction;
|
|
|
|
UINT64 Address;
|
|
|
|
UINT64 SmiCmd;
|
|
|
|
} SMM_PROFILE_ENTRY;
|
|
|
|
|
2024-08-01 10:59:28 +02:00
|
|
|
extern UINTN gSmiExceptionHandlers[];
|
|
|
|
extern BOOLEAN mXdSupported;
|
|
|
|
X86_ASSEMBLY_PATCH_LABEL gPatchXdSupported;
|
|
|
|
X86_ASSEMBLY_PATCH_LABEL gPatchMsrIa32MiscEnableSupported;
|
|
|
|
extern UINTN *mPFEntryCount;
|
2015-10-19 21:12:53 +02:00
|
|
|
extern UINT64 (*mLastPFEntryValue)[MAX_PF_ENTRY_COUNT];
|
|
|
|
extern UINT64 *(*mLastPFEntryPointer)[MAX_PF_ENTRY_COUNT];
|
|
|
|
|
|
|
|
//
|
|
|
|
// Internal functions
|
|
|
|
//
|
|
|
|
|
|
|
|
/**
|
|
|
|
Update IDT table to replace page fault handler and INT 1 handler.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
InitIdtr (
|
|
|
|
VOID
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Check if the memory address will be mapped by 4KB-page.
|
|
|
|
|
|
|
|
@param Address The address of Memory.
|
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
|
|
|
IsAddressSplit (
|
|
|
|
IN EFI_PHYSICAL_ADDRESS Address
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
2024-08-02 05:45:49 +02:00
|
|
|
Check if the SMM profile page fault address above 4GB is in protected range or not.
|
2015-10-19 21:12:53 +02:00
|
|
|
|
2024-08-02 05:45:49 +02:00
|
|
|
@param[in] Address The address of Memory.
|
|
|
|
@param[out] Nx The flag indicates if the memory is execute-disable.
|
|
|
|
|
|
|
|
@retval TRUE The input address is in protected range.
|
|
|
|
@retval FALSE The input address is not in protected range.
|
2015-10-19 21:12:53 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
BOOLEAN
|
2024-08-02 05:45:49 +02:00
|
|
|
IsSmmProfilePFAddressAbove4GValid (
|
|
|
|
IN EFI_PHYSICAL_ADDRESS Address,
|
|
|
|
OUT BOOLEAN *Nx
|
2015-10-19 21:12:53 +02:00
|
|
|
);
|
|
|
|
|
UefiCpuPkg/PiSmmCpuDxeSmm: Check PDE entry exist or not before use
Before the commit 701b5797 & 4ceefd6d, 2MB-page will be created to
cover [0: 4G] by default if SmmProfile enabled, and it will be go
through to change 2MB-page into 4KB-page during page table update
(InitPaging). If so, there was no problem to assert PDE entry exist
in the RestorePageTableBelow4G.
But after above commits, PageTableMap API is used to create/update
the page table, 1G-page will be the default page table mode, and
only covers the limited address range. Those not covered ranges
will be marked as non-present in 1g-page level address. If so,
2M-page address might not exist, it's incorrect to assert PDE
entry exist in the RestorePageTableBelow4G.
The correct behavior should check PDE entry exist or not, if not,
PDE should be allocated and assigned to PDPTE.
Note:
RestorePageTableBelow4G () does not use 1G page size entries
for the creation of new pages, maintaining consistency with the
behavior of the original code.
The purpose of this patch is to ensure that a Page Directory Entry
(PDE) exists prior to its usage.
Signed-off-by: Jiaxin Wu <jiaxin.wu@intel.com>
2024-07-15 04:16:12 +02:00
|
|
|
/**
|
|
|
|
Allocate free Page for PageFault handler use.
|
|
|
|
|
|
|
|
@return Page address.
|
|
|
|
|
|
|
|
**/
|
|
|
|
UINT64
|
|
|
|
AllocPage (
|
|
|
|
VOID
|
|
|
|
);
|
|
|
|
|
2015-10-19 21:12:53 +02:00
|
|
|
/**
|
2024-07-31 09:20:14 +02:00
|
|
|
Create new entry in page table for page fault address in SmmProfilePFHandler.
|
2015-10-19 21:12:53 +02:00
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
2024-07-31 09:20:14 +02:00
|
|
|
SmmProfileMapPFAddress (
|
2015-10-19 21:12:53 +02:00
|
|
|
VOID
|
|
|
|
);
|
|
|
|
|
|
|
|
/**
|
|
|
|
Clear TF in FLAGS.
|
|
|
|
|
|
|
|
@param SystemContext A pointer to the processor context when
|
|
|
|
the interrupt occurred on the processor.
|
|
|
|
|
|
|
|
**/
|
|
|
|
VOID
|
|
|
|
ClearTrapFlag (
|
|
|
|
IN OUT EFI_SYSTEM_CONTEXT SystemContext
|
|
|
|
);
|
|
|
|
|
|
|
|
#endif // _SMM_PROFILE_H_
|