[edk2-devel] [Patch V3 1/2] UefiCpuPkg: Update code to support enable ProcTrace only on BSP

duntan dun.tan at intel.com
Wed Apr 26 01:54:28 UTC 2023


Update code to support enable ProcTrace only on BSP. Add a new
dynamic PCD to indicate if enable ProcTrace only on BSP. In
ProcTrace.c code, if this new PCD is true, only allocate buffer
and set CtrlReg.Bits.TraceEn to 1 for BSP.

Bugzila: https://bugzilla.tianocore.org/show_bug.cgi?id=4423
Signed-off-by: Dun Tan <dun.tan at intel.com>
Cc: Eric Dong <eric.dong at intel.com>
Cc: Ray Ni <ray.ni at intel.com>
Cc: Rahul Kumar <rahul1.kumar at intel.com>
Cc: Gerd Hoffmann <kraxel at redhat.com>
Cc: Xiao X Chen <xiao.x.chen at intel.com>
---
 UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf |   3 ++-
 UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c              | 174 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++----------------------------------------------------------------
 UefiCpuPkg/UefiCpuPkg.dec                                        |   7 +++++++
 3 files changed, 119 insertions(+), 65 deletions(-)

diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf
index 7fbcd8da0e..d803012ce2 100644
--- a/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf
+++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf
@@ -4,7 +4,7 @@
 #  This library registers CPU features defined in Intel(R) 64 and IA-32
 #  Architectures Software Developer's Manual.
 #
-# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>
+# Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>
 #
 #  SPDX-License-Identifier: BSD-2-Clause-Patent
 #
@@ -62,3 +62,4 @@
   gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset                ## SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme      ## SOMETIMES_CONSUMES
   gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize           ## SOMETIMES_CONSUMES
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly           ## SOMETIMES_CONSUMES
diff --git a/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c
index 04e6a60728..92d6f54b42 100644
--- a/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c
+++ b/UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c
@@ -1,7 +1,7 @@
 /** @file
   Intel Processor Trace feature.
 
-  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>
+  Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>
   SPDX-License-Identifier: BSD-2-Clause-Patent
 
 **/
@@ -46,6 +46,8 @@ typedef struct  {
 
   UINTN                        *TopaMemArray;
 
+  BOOLEAN                      EnableOnBspOnly;
+
   PROC_TRACE_PROCESSOR_DATA    *ProcessorData;
 } PROC_TRACE_DATA;
 
@@ -77,6 +79,7 @@ ProcTraceGetConfigData (
   ConfigData->NumberOfProcessors    = (UINT32)NumberOfProcessors;
   ConfigData->ProcTraceMemSize      = PcdGet32 (PcdCpuProcTraceMemSize);
   ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme);
+  ConfigData->EnableOnBspOnly       = PcdGetBool (PcdCpuProcTraceBspOnly);
 
   return ConfigData;
 }
@@ -188,6 +191,7 @@ ProcTraceInitialize (
   MSR_IA32_RTIT_OUTPUT_BASE_REGISTER       OutputBaseReg;
   MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER  OutputMaskPtrsReg;
   RTIT_TOPA_TABLE_ENTRY                    *TopaEntryPtr;
+  BOOLEAN                                  IsBsp;
 
   //
   // The scope of the MSR_IA32_RTIT_* is core for below processor type, only program
@@ -236,6 +240,12 @@ ProcTraceInitialize (
     return RETURN_SUCCESS;
   }
 
+  IsBsp = (CpuInfo->ProcessorInfo.StatusFlag & PROCESSOR_AS_BSP_BIT) ? TRUE : FALSE;
+
+  if (ProcTraceData->EnableOnBspOnly && !IsBsp) {
+    return RETURN_SUCCESS;
+  }
+
   MemRegionBaseAddr = 0;
   FirstIn           = FALSE;
 
@@ -260,43 +270,62 @@ ProcTraceInitialize (
     //   address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be
     //   aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared.
     //
-    ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));
-    if (ThreadMemRegionTable == NULL) {
-      DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));
-      return RETURN_OUT_OF_RESOURCES;
-    }
 
-    ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;
-
-    for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {
-      Pages          = EFI_SIZE_TO_PAGES (MemRegionSize);
-      Alignment      = MemRegionSize;
-      AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
-      if (AlignedAddress == 0) {
-        DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));
-        if (Index == 0) {
-          //
-          // Could not allocate for BSP even
-          //
-          FreePool ((VOID *)ThreadMemRegionTable);
-          ThreadMemRegionTable = NULL;
-          return RETURN_OUT_OF_RESOURCES;
+    Pages     = EFI_SIZE_TO_PAGES (MemRegionSize);
+    Alignment = MemRegionSize;
+    if (ProcTraceData->EnableOnBspOnly) {
+      //
+      // When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.
+      //
+      MemRegionBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
+      if (MemRegionBaseAddr == 0) {
+        //
+        // Could not allocate for BSP even
+        //
+        DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate buffer for BSP\n"));
+        return RETURN_OUT_OF_RESOURCES;
+      }
+
+      DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT MemRegionBaseAddr(aligned) for BSP only: 0x%llX.\n", (UINT64)MemRegionBaseAddr));
+    } else {
+      ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));
+      if (ThreadMemRegionTable == NULL) {
+        DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));
+        return RETURN_OUT_OF_RESOURCES;
+      }
+
+      ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;
+
+      for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {
+        AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
+        if (AlignedAddress == 0) {
+          DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));
+          if (Index == 0) {
+            //
+            // Could not allocate for BSP even
+            //
+            FreePool ((VOID *)ThreadMemRegionTable);
+            ThreadMemRegionTable = NULL;
+            return RETURN_OUT_OF_RESOURCES;
+          }
+
+          break;
         }
 
-        break;
+        ThreadMemRegionTable[Index] = AlignedAddress;
+        DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));
       }
 
-      ThreadMemRegionTable[Index] = AlignedAddress;
-      DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));
+      DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));
     }
-
-    DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));
   }
 
-  if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
-    MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];
-  } else {
-    return RETURN_SUCCESS;
+  if (!ProcTraceData->EnableOnBspOnly) {
+    if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
+      MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];
+    } else {
+      return RETURN_SUCCESS;
+    }
   }
 
   ///
@@ -367,50 +396,67 @@ ProcTraceInitialize (
     //
     if (FirstIn) {
       DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n"));
-      //
-      // Let BSP allocate ToPA table mem for all threads
-      //
-      TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));
-      if (TopaMemArray == NULL) {
-        DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));
-        return RETURN_OUT_OF_RESOURCES;
-      }
 
-      ProcTraceData->TopaMemArray = TopaMemArray;
+      Pages     = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));
+      Alignment = 0x1000;
 
-      for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {
-        Pages          = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));
-        Alignment      = 0x1000;
-        AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
-        if (AlignedAddress == 0) {
-          if (Index < ProcTraceData->AllocatedThreads) {
-            ProcTraceData->AllocatedThreads = Index;
-          }
+      if (ProcTraceData->EnableOnBspOnly) {
+        //
+        // When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.
+        //
+        TopaTableBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
+        if (TopaTableBaseAddr == 0) {
+          DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate ToPA mem for BSP"));
+          return RETURN_OUT_OF_RESOURCES;
+        }
 
-          DEBUG ((DEBUG_ERROR, "ProcTrace:  Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));
-          if (Index == 0) {
-            //
-            // Could not allocate for BSP even
-            //
-            FreePool ((VOID *)TopaMemArray);
-            TopaMemArray = NULL;
-            return RETURN_OUT_OF_RESOURCES;
+        DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for BSP only: 0x%llX \n", (UINT64)TopaTableBaseAddr));
+      } else {
+        //
+        // Let BSP allocate ToPA table mem for all threads
+        //
+        TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));
+        if (TopaMemArray == NULL) {
+          DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));
+          return RETURN_OUT_OF_RESOURCES;
+        }
+
+        ProcTraceData->TopaMemArray = TopaMemArray;
+
+        for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {
+          AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);
+          if (AlignedAddress == 0) {
+            if (Index < ProcTraceData->AllocatedThreads) {
+              ProcTraceData->AllocatedThreads = Index;
+            }
+
+            DEBUG ((DEBUG_ERROR, "ProcTrace:  Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));
+            if (Index == 0) {
+              //
+              // Could not allocate for BSP even
+              //
+              FreePool ((VOID *)TopaMemArray);
+              TopaMemArray = NULL;
+              return RETURN_OUT_OF_RESOURCES;
+            }
+
+            break;
           }
 
-          break;
+          TopaMemArray[Index] = AlignedAddress;
+          DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));
         }
 
-        TopaMemArray[Index] = AlignedAddress;
-        DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));
+        DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));
       }
-
-      DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));
     }
 
-    if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
-      TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];
-    } else {
-      return RETURN_SUCCESS;
+    if (!ProcTraceData->EnableOnBspOnly) {
+      if (ProcessorNumber < ProcTraceData->AllocatedThreads) {
+        TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];
+      } else {
+        return RETURN_SUCCESS;
+      }
     }
 
     TopaTable                 = (PROC_TRACE_TOPA_TABLE *)TopaTableBaseAddr;
diff --git a/UefiCpuPkg/UefiCpuPkg.dec b/UefiCpuPkg/UefiCpuPkg.dec
index a5528277ff..14dadfbf53 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -422,5 +422,12 @@
   # @Prompt GHCB Hypervisor Features
   gUefiCpuPkgTokenSpaceGuid.PcdGhcbHypervisorFeatures|0x0|UINT64|0x60000018
 
+  ## This PCD indicates whether CPU processor trace is enabled on BSP only when CPU processor trace is enabled.<BR><BR>
+  #  This PCD is ignored if CPU processor trace is disabled.<BR><BR>
+  #  TRUE  - CPU processor trace is enabled on BSP only.<BR>
+  #  FASLE - CPU processor trace is enabled on all CPU.<BR>
+  # @Prompt Enable CPU processor trace only on BSP.
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly|FALSE|BOOLEAN|0x60000019
+
 [UserExtensions.TianoCore."ExtraFiles"]
   UefiCpuPkgExtra.uni
-- 
2.39.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103606): https://edk2.groups.io/g/devel/message/103606
Mute This Topic: https://groups.io/mt/98506881/1813853
Group Owner: devel+owner at edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [edk2-devel-archive at redhat.com]
-=-=-=-=-=-=-=-=-=-=-=-




More information about the edk2-devel-archive mailing list