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....@intel.com>
Cc: Eric Dong <eric.d...@intel.com>
Reviewed-by: Ray Ni <ray...@intel.com>
Cc: Rahul Kumar <rahul1.ku...@intel.com>
Cc: Gerd Hoffmann <kra...@redhat.com>
Cc: Xiao X Chen <xiao.x.c...@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..6845e80706 100644
--- a/UefiCpuPkg/UefiCpuPkg.dec
+++ b/UefiCpuPkg/UefiCpuPkg.dec
@@ -338,6 +338,13 @@
   # @Prompt Current boot is a power-on reset.
   gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset|FALSE|BOOLEAN|0x0000001B
 
+  ## 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
+
 [PcdsFixedAtBuild.X64, PcdsPatchableInModule.X64, PcdsDynamic.X64, 
PcdsDynamicEx.X64]
   ## Indicate access to non-SMRAM memory is restricted to reserved, runtime 
and ACPI NVS type after SmmReadyToLock.
   #  MMIO access is always allowed regardless of the value of this PCD.
-- 
2.39.1.windows.1



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#103633): https://edk2.groups.io/g/devel/message/103633
Mute This Topic: https://groups.io/mt/98510428/21656
Group Owner: devel+ow...@edk2.groups.io
Unsubscribe: https://edk2.groups.io/g/devel/unsub [arch...@mail-archive.com]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to