From dc4d42302c22f012d78f6495ea23ceaa3e23842e Mon Sep 17 00:00:00 2001 From: Dandan Bi Date: Fri, 12 Mar 2021 18:05:07 +0800 Subject: [PATCH] MdePkg/Baseib: Filter/trace MSR access for IA32/X64 REF: https://bugzilla.tianocore.org/show_bug.cgi?id=3246 Cc: Michael D Kinney Cc: Liming Gao Cc: Zhiguang Liu Signed-off-by: Dandan Bi Reviewed-by: Michael D Kinney Reviewed-by: Liming Gao Acked-by: Ard Biesheuvel --- MdePkg/Library/BaseLib/BaseLib.inf | 3 ++ MdePkg/Library/BaseLib/Ia32/GccInlinePriv.c | 38 +++++++++++------- MdePkg/Library/BaseLib/Ia32/ReadMsr64.c | 38 ++++++++++++++++-- MdePkg/Library/BaseLib/Ia32/WriteMsr64.c | 22 +++++++---- MdePkg/Library/BaseLib/X64/GccInlinePriv.c | 43 ++++++++++++++------- MdePkg/Library/BaseLib/X64/ReadMsr64.c | 15 ++++++- MdePkg/Library/BaseLib/X64/WriteMsr64.c | 13 ++++++- 7 files changed, 129 insertions(+), 43 deletions(-) diff --git a/MdePkg/Library/BaseLib/BaseLib.inf b/MdePkg/Library/BaseLib/BaseLib.inf index fe8f68bbcf..b76f3af380 100644 --- a/MdePkg/Library/BaseLib/BaseLib.inf +++ b/MdePkg/Library/BaseLib/BaseLib.inf @@ -413,6 +413,9 @@ DebugLib BaseMemoryLib +[LibraryClasses.X64, LibraryClasses.IA32] + RegisterFilterLib + [Pcd] gEfiMdePkgTokenSpaceGuid.PcdMaximumLinkedListLength ## SOMETIMES_CONSUMES gEfiMdePkgTokenSpaceGuid.PcdMaximumAsciiStringLength ## SOMETIMES_CONSUMES diff --git a/MdePkg/Library/BaseLib/Ia32/GccInlinePriv.c b/MdePkg/Library/BaseLib/Ia32/GccInlinePriv.c index 30aa63243b..40e8c08beb 100644 --- a/MdePkg/Library/BaseLib/Ia32/GccInlinePriv.c +++ b/MdePkg/Library/BaseLib/Ia32/GccInlinePriv.c @@ -2,7 +2,7 @@ GCC inline implementation of BaseLib processor specific functions that use privlidged instructions. - Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,6 +10,7 @@ #include "BaseLibInternals.h" +#include /** Enables CPU interrupts. @@ -63,12 +64,17 @@ AsmReadMsr64 ( ) { UINT64 Data; - - __asm__ __volatile__ ( - "rdmsr" - : "=A" (Data) // %0 - : "c" (Index) // %1 - ); + BOOLEAN Flag; + + Flag = FilterBeforeMsrRead (Index, &Data); + if (Flag) { + __asm__ __volatile__ ( + "rdmsr" + : "=A" (Data) // %0 + : "c" (Index) // %1 + ); + } + FilterAfterMsrRead (Index, &Data); return Data; } @@ -97,12 +103,18 @@ AsmWriteMsr64 ( IN UINT64 Value ) { - __asm__ __volatile__ ( - "wrmsr" - : - : "c" (Index), - "A" (Value) - ); + BOOLEAN Flag; + + Flag = FilterBeforeMsrWrite (Index, &Value); + if (Flag) { + __asm__ __volatile__ ( + "wrmsr" + : + : "c" (Index), + "A" (Value) + ); + } + FilterAfterMsrWrite (Index, &Value); return Value; } diff --git a/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c b/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c index 6d2394b1a3..afe3aa5bdc 100644 --- a/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c +++ b/MdePkg/Library/BaseLib/Ia32/ReadMsr64.c @@ -1,13 +1,13 @@ /** @file AsmReadMsr64 function - Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ - +#include /** Returns a 64-bit Machine Specific Register(MSR). @@ -24,8 +24,7 @@ **/ UINT64 -EFIAPI -AsmReadMsr64 ( +AsmReadMsr64Internal ( IN UINT32 Index ) { @@ -35,3 +34,34 @@ AsmReadMsr64 ( } } +/** + Returns a 64-bit Machine Specific Register(MSR). + + Reads and returns the 64-bit MSR specified by Index. No parameter checking is + performed on Index, and some Index values may cause CPU exceptions. The + caller must either guarantee that Index is valid, or the caller must set up + exception handlers to catch the exceptions. This function is only available + on IA-32 and x64. + + @param Index The 32-bit MSR index to read. + + @return The value of the MSR identified by Index. + +**/ +UINT64 +EFIAPI +AsmReadMsr64 ( + IN UINT32 Index + ) +{ + UINT64 Value; + BOOLEAN Flag; + + Flag = FilterBeforeMsrRead (Index, &Value); + if (Flag) { + Value = AsmReadMsr64Internal (Index); + } + FilterAfterMsrRead (Index, &Value); + + return Value; +} diff --git a/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c b/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c index badf1d8e58..ba0cf3f74c 100644 --- a/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c +++ b/MdePkg/Library/BaseLib/Ia32/WriteMsr64.c @@ -1,13 +1,13 @@ /** @file AsmWriteMsr64 function - Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ - +#include /** Writes a 64-bit value to a Machine Specific Register(MSR), and returns the @@ -33,11 +33,19 @@ AsmWriteMsr64 ( IN UINT64 Value ) { - _asm { - mov edx, dword ptr [Value + 4] - mov eax, dword ptr [Value + 0] - mov ecx, Index - wrmsr + BOOLEAN Flag; + + Flag = FilterBeforeMsrWrite (Index, &Value); + if (Flag) { + _asm { + mov edx, dword ptr [Value + 4] + mov eax, dword ptr [Value + 0] + mov ecx, Index + wrmsr + } } + FilterAfterMsrWrite (Index, &Value); + + return Value; } diff --git a/MdePkg/Library/BaseLib/X64/GccInlinePriv.c b/MdePkg/Library/BaseLib/X64/GccInlinePriv.c index 98be19b3c7..e4920f2116 100644 --- a/MdePkg/Library/BaseLib/X64/GccInlinePriv.c +++ b/MdePkg/Library/BaseLib/X64/GccInlinePriv.c @@ -2,7 +2,7 @@ GCC inline implementation of BaseLib processor specific functions that use privlidged instructions. - Copyright (c) 2006 - 2020, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
Portions copyright (c) 2008 - 2009, Apple Inc. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent @@ -10,6 +10,7 @@ #include "BaseLibInternals.h" +#include /** Enables CPU interrupts. @@ -64,13 +65,20 @@ AsmReadMsr64 ( { UINT32 LowData; UINT32 HighData; - - __asm__ __volatile__ ( - "rdmsr" - : "=a" (LowData), // %0 - "=d" (HighData) // %1 - : "c" (Index) // %2 - ); + UINT64 Value; + BOOLEAN Flag; + + Flag = FilterBeforeMsrRead (Index, &Value); + if (Flag) { + __asm__ __volatile__ ( + "rdmsr" + : "=a" (LowData), // %0 + "=d" (HighData) // %1 + : "c" (Index) // %2 + ); + Value = (((UINT64)HighData) << 32) | LowData; + } + FilterAfterMsrRead (Index, &Value); return (((UINT64)HighData) << 32) | LowData; } @@ -101,17 +109,22 @@ AsmWriteMsr64 ( { UINT32 LowData; UINT32 HighData; + BOOLEAN Flag; LowData = (UINT32)(Value); HighData = (UINT32)(Value >> 32); - __asm__ __volatile__ ( - "wrmsr" - : - : "c" (Index), - "a" (LowData), - "d" (HighData) - ); + Flag = FilterBeforeMsrWrite (Index, &Value); + if (Flag) { + __asm__ __volatile__ ( + "wrmsr" + : + : "c" (Index), + "a" (LowData), + "d" (HighData) + ); + } + FilterAfterMsrWrite (Index, &Value); return Value; } diff --git a/MdePkg/Library/BaseLib/X64/ReadMsr64.c b/MdePkg/Library/BaseLib/X64/ReadMsr64.c index 5ee7ca53f3..36a349432c 100644 --- a/MdePkg/Library/BaseLib/X64/ReadMsr64.c +++ b/MdePkg/Library/BaseLib/X64/ReadMsr64.c @@ -1,7 +1,7 @@ /** @file CpuBreakpoint function. - Copyright (c) 2006 - 2008, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,6 +10,8 @@ Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. **/ +#include + unsigned __int64 __readmsr (int register); #pragma intrinsic(__readmsr) @@ -28,6 +30,15 @@ AsmReadMsr64 ( IN UINT32 Index ) { - return __readmsr (Index); + UINT64 Value; + BOOLEAN Flag; + + Flag = FilterBeforeMsrRead (Index, &Value); + if (Flag) { + Value = __readmsr (Index); + } + FilterAfterMsrRead (Index, &Value); + + return Value; } diff --git a/MdePkg/Library/BaseLib/X64/WriteMsr64.c b/MdePkg/Library/BaseLib/X64/WriteMsr64.c index 98c5458d8a..bb030832c4 100644 --- a/MdePkg/Library/BaseLib/X64/WriteMsr64.c +++ b/MdePkg/Library/BaseLib/X64/WriteMsr64.c @@ -1,7 +1,7 @@ /** @file CpuBreakpoint function. - Copyright (c) 2006 - 2010, Intel Corporation. All rights reserved.
+ Copyright (c) 2006 - 2021, Intel Corporation. All rights reserved.
SPDX-License-Identifier: BSD-2-Clause-Patent **/ @@ -10,6 +10,8 @@ Microsoft Visual Studio 7.1 Function Prototypes for I/O Intrinsics. **/ +#include + void __writemsr (unsigned long Register, unsigned __int64 Value); #pragma intrinsic(__writemsr) @@ -30,7 +32,14 @@ AsmWriteMsr64 ( IN UINT64 Value ) { - __writemsr (Index, Value); + BOOLEAN Flag; + + Flag = FilterBeforeMsrWrite (Index, &Value); + if (Flag) { + __writemsr (Index, Value); + } + FilterAfterMsrWrite (Index, &Value); + return Value; } -- 2.39.2