diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c index f4db6c8b60..3c68c97024 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/Ia32/SmmFuncsArch.c @@ -126,6 +126,61 @@ InitGdt ( return GdtTssTables; } +/** + This function sets GDT/IDT buffer to be RO and XP. +**/ +VOID +PatchGdtIdtMap ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS BaseAddress; + UINTN Size; + + // + // GDT + // + DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - GDT:\n")); + + BaseAddress = mGdtBuffer; + Size = ALIGN_VALUE(mGdtBufferSize, SIZE_4KB); + if (!FeaturePcdGet (PcdCpuSmmStackGuard)) { + // + // Do not set RO for IA32 when stack guard feature is enabled. + // Stack Guard need use task switch to switch stack. + // It need write GDT and TSS. + // + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_RO + ); + } + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_XP + ); + + // + // IDT + // + DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - IDT:\n")); + + BaseAddress = gcSmiIdtr.Base; + Size = ALIGN_VALUE(gcSmiIdtr.Limit + 1, SIZE_4KB); + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_RO + ); + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_XP + ); +} + /** Transfer AP to safe hlt-loop after it finished restore CPU features on S3 patch. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h index 611cbc190a..9160fa8b8a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/PiSmmCpuDxeSmm.h @@ -497,6 +497,14 @@ InitGdt ( OUT UINTN *GdtStepSize ); +/** + This function sets GDT/IDT buffer to be RO and XP. +**/ +VOID +PatchGdtIdtMap ( + VOID + ); + /** Register the SMM Foundation entry point. @@ -569,6 +577,66 @@ SmmBlockingStartupThisAp ( IN OUT VOID *ProcArguments OPTIONAL ); +/** + This function sets the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to set for the memory region. + + @retval EFI_SUCCESS The attributes were set for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmSetMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + +/** + This function clears the attributes for the memory region specified by BaseAddress and + Length from their current attributes to the attributes specified by Attributes. + + @param[in] BaseAddress The physical address that is the start address of a memory region. + @param[in] Length The size in bytes of the memory region. + @param[in] Attributes The bit mask of attributes to clear for the memory region. + + @retval EFI_SUCCESS The attributes were cleared for the memory region. + @retval EFI_ACCESS_DENIED The attributes for the memory resource range specified by + BaseAddress and Length cannot be modified. + @retval EFI_INVALID_PARAMETER Length is zero. + Attributes specified an illegal combination of attributes that + cannot be set together. + @retval EFI_OUT_OF_RESOURCES There are not enough system resources to modify the attributes of + the memory resource range. + @retval EFI_UNSUPPORTED The processor does not support one or more bytes of the memory + resource range specified by BaseAddress and Length. + The bit mask of attributes is not support for the memory resource + range specified by BaseAddress and Length. + +**/ +EFI_STATUS +EFIAPI +SmmClearMemoryAttributes ( + IN EFI_PHYSICAL_ADDRESS BaseAddress, + IN UINT64 Length, + IN UINT64 Attributes + ); + /** Initialize MP synchronization data. diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c index 6becc1b445..588aa270d8 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/SmmCpuMemoryManagement.c @@ -749,54 +749,6 @@ PatchSmmSaveStateMap ( ); } -/** - This function sets GDT/IDT buffer to be RO and XP. -**/ -VOID -PatchGdtIdtMap ( - VOID - ) -{ - EFI_PHYSICAL_ADDRESS BaseAddress; - UINTN Size; - - // - // GDT - // - DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - GDT:\n")); - - BaseAddress = mGdtBuffer; - Size = ALIGN_VALUE(mGdtBufferSize, SIZE_4KB); - SmmSetMemoryAttributes ( - BaseAddress, - Size, - EFI_MEMORY_RO - ); - SmmSetMemoryAttributes ( - BaseAddress, - Size, - EFI_MEMORY_XP - ); - - // - // IDT - // - DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - IDT:\n")); - - BaseAddress = gcSmiIdtr.Base; - Size = ALIGN_VALUE(gcSmiIdtr.Limit + 1, SIZE_4KB); - SmmSetMemoryAttributes ( - BaseAddress, - Size, - EFI_MEMORY_RO - ); - SmmSetMemoryAttributes ( - BaseAddress, - Size, - EFI_MEMORY_XP - ); -} - /** This function sets memory attribute according to MemoryAttributesTable. **/ diff --git a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c index 9fc00c1578..9d26e44a9a 100644 --- a/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c +++ b/UefiCpuPkg/PiSmmCpuDxeSmm/X64/SmmFuncsArch.c @@ -95,6 +95,54 @@ InitGdt ( return GdtTssTables; } +/** + This function sets GDT/IDT buffer to be RO and XP. +**/ +VOID +PatchGdtIdtMap ( + VOID + ) +{ + EFI_PHYSICAL_ADDRESS BaseAddress; + UINTN Size; + + // + // GDT + // + DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - GDT:\n")); + + BaseAddress = mGdtBuffer; + Size = ALIGN_VALUE(mGdtBufferSize, SIZE_4KB); + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_RO + ); + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_XP + ); + + // + // IDT + // + DEBUG ((DEBUG_INFO, "PatchGdtIdtMap - IDT:\n")); + + BaseAddress = gcSmiIdtr.Base; + Size = ALIGN_VALUE(gcSmiIdtr.Limit + 1, SIZE_4KB); + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_RO + ); + SmmSetMemoryAttributes ( + BaseAddress, + Size, + EFI_MEMORY_XP + ); +} + /** Get Protected mode code segment from current GDT table. @@ -154,4 +202,3 @@ TransferApToSafeState ( ASSERT (FALSE); } -