]> xenbits.xensource.com Git - ovmf.git/commitdiff
UefiCpuPkg: Update code to support enable ProcTrace only on BSP
authorDun Tan <dun.tan@intel.com>
Tue, 25 Apr 2023 04:47:05 +0000 (12:47 +0800)
committermergify[bot] <37929162+mergify[bot]@users.noreply.github.com>
Wed, 26 Apr 2023 09:19:51 +0000 (09:19 +0000)
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@intel.com>
Cc: Eric Dong <eric.dong@intel.com>
Reviewed-by: Ray Ni <ray.ni@intel.com>
Cc: Rahul Kumar <rahul1.kumar@intel.com>
Cc: Gerd Hoffmann <kraxel@redhat.com>
Cc: Xiao X Chen <xiao.x.chen@intel.com>
UefiCpuPkg/Library/CpuCommonFeaturesLib/CpuCommonFeaturesLib.inf
UefiCpuPkg/Library/CpuCommonFeaturesLib/ProcTrace.c
UefiCpuPkg/UefiCpuPkg.dec

index 7fbcd8da0e5721ae49049711751ff41cce374f3c..d803012ce28fb40e7bc5db9f75caa1af9208b71e 100644 (file)
@@ -4,7 +4,7 @@
 #  This library registers CPU features defined in Intel(R) 64 and IA-32\r
 #  Architectures Software Developer's Manual.\r
 #\r
-# Copyright (c) 2017 - 2019, Intel Corporation. All rights reserved.<BR>\r
+# Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>\r
 #\r
 #  SPDX-License-Identifier: BSD-2-Clause-Patent\r
 #\r
@@ -62,3 +62,4 @@
   gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset                ## SOMETIMES_CONSUMES\r
   gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceOutputScheme      ## SOMETIMES_CONSUMES\r
   gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceMemSize           ## SOMETIMES_CONSUMES\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly           ## SOMETIMES_CONSUMES\r
index 04e6a607280b28e0ccd7f2e0b6f7f1fe5d101bd1..92d6f54b42e4b48bef2ee92fac3a4b850d027e22 100644 (file)
@@ -1,7 +1,7 @@
 /** @file\r
   Intel Processor Trace feature.\r
 \r
-  Copyright (c) 2017 - 2018, Intel Corporation. All rights reserved.<BR>\r
+  Copyright (c) 2017 - 2023, Intel Corporation. All rights reserved.<BR>\r
   SPDX-License-Identifier: BSD-2-Clause-Patent\r
 \r
 **/\r
@@ -46,6 +46,8 @@ typedef struct  {
 \r
   UINTN                        *TopaMemArray;\r
 \r
+  BOOLEAN                      EnableOnBspOnly;\r
+\r
   PROC_TRACE_PROCESSOR_DATA    *ProcessorData;\r
 } PROC_TRACE_DATA;\r
 \r
@@ -77,6 +79,7 @@ ProcTraceGetConfigData (
   ConfigData->NumberOfProcessors    = (UINT32)NumberOfProcessors;\r
   ConfigData->ProcTraceMemSize      = PcdGet32 (PcdCpuProcTraceMemSize);\r
   ConfigData->ProcTraceOutputScheme = PcdGet8 (PcdCpuProcTraceOutputScheme);\r
+  ConfigData->EnableOnBspOnly       = PcdGetBool (PcdCpuProcTraceBspOnly);\r
 \r
   return ConfigData;\r
 }\r
@@ -188,6 +191,7 @@ ProcTraceInitialize (
   MSR_IA32_RTIT_OUTPUT_BASE_REGISTER       OutputBaseReg;\r
   MSR_IA32_RTIT_OUTPUT_MASK_PTRS_REGISTER  OutputMaskPtrsReg;\r
   RTIT_TOPA_TABLE_ENTRY                    *TopaEntryPtr;\r
+  BOOLEAN                                  IsBsp;\r
 \r
   //\r
   // The scope of the MSR_IA32_RTIT_* is core for below processor type, only program\r
@@ -236,6 +240,12 @@ ProcTraceInitialize (
     return RETURN_SUCCESS;\r
   }\r
 \r
+  IsBsp = (CpuInfo->ProcessorInfo.StatusFlag & PROCESSOR_AS_BSP_BIT) ? TRUE : FALSE;\r
+\r
+  if (ProcTraceData->EnableOnBspOnly && !IsBsp) {\r
+    return RETURN_SUCCESS;\r
+  }\r
+\r
   MemRegionBaseAddr = 0;\r
   FirstIn           = FALSE;\r
 \r
@@ -260,43 +270,62 @@ ProcTraceInitialize (
     //   address base in MSR, IA32_RTIT_OUTPUT_BASE (560h) bits 47:12. Note that all regions must be\r
     //   aligned based on their size, not just 4K. Thus a 2M region must have bits 20:12 cleared.\r
     //\r
-    ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));\r
-    if (ThreadMemRegionTable == NULL) {\r
-      DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));\r
-      return RETURN_OUT_OF_RESOURCES;\r
-    }\r
 \r
-    ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;\r
-\r
-    for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {\r
-      Pages          = EFI_SIZE_TO_PAGES (MemRegionSize);\r
-      Alignment      = MemRegionSize;\r
-      AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
-      if (AlignedAddress == 0) {\r
-        DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));\r
-        if (Index == 0) {\r
-          //\r
-          // Could not allocate for BSP even\r
-          //\r
-          FreePool ((VOID *)ThreadMemRegionTable);\r
-          ThreadMemRegionTable = NULL;\r
-          return RETURN_OUT_OF_RESOURCES;\r
+    Pages     = EFI_SIZE_TO_PAGES (MemRegionSize);\r
+    Alignment = MemRegionSize;\r
+    if (ProcTraceData->EnableOnBspOnly) {\r
+      //\r
+      // When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.\r
+      //\r
+      MemRegionBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+      if (MemRegionBaseAddr == 0) {\r
+        //\r
+        // Could not allocate for BSP even\r
+        //\r
+        DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate buffer for BSP\n"));\r
+        return RETURN_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT MemRegionBaseAddr(aligned) for BSP only: 0x%llX.\n", (UINT64)MemRegionBaseAddr));\r
+    } else {\r
+      ThreadMemRegionTable = (UINTN *)AllocatePool (ProcTraceData->NumberOfProcessors * sizeof (UINTN *));\r
+      if (ThreadMemRegionTable == NULL) {\r
+        DEBUG ((DEBUG_ERROR, "Allocate ProcTrace ThreadMemRegionTable Failed\n"));\r
+        return RETURN_OUT_OF_RESOURCES;\r
+      }\r
+\r
+      ProcTraceData->ThreadMemRegionTable = ThreadMemRegionTable;\r
+\r
+      for (Index = 0; Index < ProcTraceData->NumberOfProcessors; Index++, ProcTraceData->AllocatedThreads++) {\r
+        AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+        if (AlignedAddress == 0) {\r
+          DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, allocated only for %d threads\n", ProcTraceData->AllocatedThreads));\r
+          if (Index == 0) {\r
+            //\r
+            // Could not allocate for BSP even\r
+            //\r
+            FreePool ((VOID *)ThreadMemRegionTable);\r
+            ThreadMemRegionTable = NULL;\r
+            return RETURN_OUT_OF_RESOURCES;\r
+          }\r
+\r
+          break;\r
         }\r
 \r
-        break;\r
+        ThreadMemRegionTable[Index] = AlignedAddress;\r
+        DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));\r
       }\r
 \r
-      ThreadMemRegionTable[Index] = AlignedAddress;\r
-      DEBUG ((DEBUG_INFO, "ProcTrace: PT MemRegionBaseAddr(aligned) for thread %d: 0x%llX \n", Index, (UINT64)ThreadMemRegionTable[Index]));\r
+      DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
     }\r
-\r
-    DEBUG ((DEBUG_INFO, "ProcTrace: Allocated PT mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
   }\r
 \r
-  if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
-    MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];\r
-  } else {\r
-    return RETURN_SUCCESS;\r
+  if (!ProcTraceData->EnableOnBspOnly) {\r
+    if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
+      MemRegionBaseAddr = ProcTraceData->ThreadMemRegionTable[ProcessorNumber];\r
+    } else {\r
+      return RETURN_SUCCESS;\r
+    }\r
   }\r
 \r
   ///\r
@@ -367,50 +396,67 @@ ProcTraceInitialize (
     //\r
     if (FirstIn) {\r
       DEBUG ((DEBUG_INFO, "ProcTrace: Enabling ToPA scheme \n"));\r
-      //\r
-      // Let BSP allocate ToPA table mem for all threads\r
-      //\r
-      TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));\r
-      if (TopaMemArray == NULL) {\r
-        DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));\r
-        return RETURN_OUT_OF_RESOURCES;\r
-      }\r
 \r
-      ProcTraceData->TopaMemArray = TopaMemArray;\r
+      Pages     = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));\r
+      Alignment = 0x1000;\r
 \r
-      for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {\r
-        Pages          = EFI_SIZE_TO_PAGES (sizeof (PROC_TRACE_TOPA_TABLE));\r
-        Alignment      = 0x1000;\r
-        AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
-        if (AlignedAddress == 0) {\r
-          if (Index < ProcTraceData->AllocatedThreads) {\r
-            ProcTraceData->AllocatedThreads = Index;\r
-          }\r
+      if (ProcTraceData->EnableOnBspOnly) {\r
+        //\r
+        // When only enable ProcTrace on BSP, this is the first and only time ProcTraceInitialize() runs.\r
+        //\r
+        TopaTableBaseAddr = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+        if (TopaTableBaseAddr == 0) {\r
+          DEBUG ((DEBUG_ERROR, "ProcTrace: Out of mem, failed to allocate ToPA mem for BSP"));\r
+          return RETURN_OUT_OF_RESOURCES;\r
+        }\r
 \r
-          DEBUG ((DEBUG_ERROR, "ProcTrace:  Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));\r
-          if (Index == 0) {\r
-            //\r
-            // Could not allocate for BSP even\r
-            //\r
-            FreePool ((VOID *)TopaMemArray);\r
-            TopaMemArray = NULL;\r
-            return RETURN_OUT_OF_RESOURCES;\r
+        DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for BSP only: 0x%llX \n", (UINT64)TopaTableBaseAddr));\r
+      } else {\r
+        //\r
+        // Let BSP allocate ToPA table mem for all threads\r
+        //\r
+        TopaMemArray = (UINTN *)AllocatePool (ProcTraceData->AllocatedThreads * sizeof (UINTN *));\r
+        if (TopaMemArray == NULL) {\r
+          DEBUG ((DEBUG_ERROR, "ProcTrace: Allocate mem for ToPA Failed\n"));\r
+          return RETURN_OUT_OF_RESOURCES;\r
+        }\r
+\r
+        ProcTraceData->TopaMemArray = TopaMemArray;\r
+\r
+        for (Index = 0; Index < ProcTraceData->AllocatedThreads; Index++) {\r
+          AlignedAddress = (UINTN)AllocateAlignedReservedPages (Pages, Alignment);\r
+          if (AlignedAddress == 0) {\r
+            if (Index < ProcTraceData->AllocatedThreads) {\r
+              ProcTraceData->AllocatedThreads = Index;\r
+            }\r
+\r
+            DEBUG ((DEBUG_ERROR, "ProcTrace:  Out of mem, allocated ToPA mem only for %d threads\n", ProcTraceData->AllocatedThreads));\r
+            if (Index == 0) {\r
+              //\r
+              // Could not allocate for BSP even\r
+              //\r
+              FreePool ((VOID *)TopaMemArray);\r
+              TopaMemArray = NULL;\r
+              return RETURN_OUT_OF_RESOURCES;\r
+            }\r
+\r
+            break;\r
           }\r
 \r
-          break;\r
+          TopaMemArray[Index] = AlignedAddress;\r
+          DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));\r
         }\r
 \r
-        TopaMemArray[Index] = AlignedAddress;\r
-        DEBUG ((DEBUG_INFO, "ProcTrace: Topa table address(aligned) for thread %d is 0x%llX \n", Index, (UINT64)TopaMemArray[Index]));\r
+        DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
       }\r
-\r
-      DEBUG ((DEBUG_INFO, "ProcTrace: Allocated ToPA mem for %d thread \n", ProcTraceData->AllocatedThreads));\r
     }\r
 \r
-    if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
-      TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];\r
-    } else {\r
-      return RETURN_SUCCESS;\r
+    if (!ProcTraceData->EnableOnBspOnly) {\r
+      if (ProcessorNumber < ProcTraceData->AllocatedThreads) {\r
+        TopaTableBaseAddr = ProcTraceData->TopaMemArray[ProcessorNumber];\r
+      } else {\r
+        return RETURN_SUCCESS;\r
+      }\r
     }\r
 \r
     TopaTable                 = (PROC_TRACE_TOPA_TABLE *)TopaTableBaseAddr;\r
index a5528277ffb53ba7845252c4c9357754adfbe564..6845e807060bce02b805b657c607d42e350991b3 100644 (file)
   # @Prompt Current boot is a power-on reset.\r
   gUefiCpuPkgTokenSpaceGuid.PcdIsPowerOnReset|FALSE|BOOLEAN|0x0000001B\r
 \r
+  ## This PCD indicates whether CPU processor trace is enabled on BSP only when CPU processor trace is enabled.<BR><BR>\r
+  #  This PCD is ignored if CPU processor trace is disabled.<BR><BR>\r
+  #  TRUE  - CPU processor trace is enabled on BSP only.<BR>\r
+  #  FASLE - CPU processor trace is enabled on all CPU.<BR>\r
+  # @Prompt Enable CPU processor trace only on BSP.\r
+  gUefiCpuPkgTokenSpaceGuid.PcdCpuProcTraceBspOnly|FALSE|BOOLEAN|0x60000019\r
+\r
 [PcdsFixedAtBuild.X64, PcdsPatchableInModule.X64, PcdsDynamic.X64, PcdsDynamicEx.X64]\r
   ## Indicate access to non-SMRAM memory is restricted to reserved, runtime and ACPI NVS type after SmmReadyToLock.\r
   #  MMIO access is always allowed regardless of the value of this PCD.\r