GicGetCpuRedistributorBase() returns 0 both when the redistributor
region cannot be mapped and when the TYPER walk finds no frame with
this CPU's affinity.  In RELEASE builds the ASSERT_EFI_ERROR() inside
that helper is compiled out, so GicV3DxeInitialize() proceeds and
issues MmioWrite32() to offset 0x0000+ from a NULL base.

Return EFI_NOT_FOUND explicitly instead of touching low memory.

Cc: Ard Biesheuvel <[email protected]>
Cc: Leif Lindholm <[email protected]>
Cc: Sami Mujawar <[email protected]>
Cc: Vishal Oliyil Kunnnil <[email protected]>
Assisted-by: claude-opus-5
Signed-off-by: Alexander Graf <[email protected]>
---
 ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c | 46 +++++++++++++++-----
 1 file changed, 34 insertions(+), 12 deletions(-)

diff --git a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c 
b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c
index 5fd28e3f57..f4b532ba5f 100644
--- a/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c
+++ b/ArmPkg/Drivers/ArmGicDxe/GicV3/ArmGicV3Dxe.c
@@ -39,14 +39,25 @@ STATIC UINTN                       mGicMaxSpiIntId;
 STATIC UINTN                       mGicMaxExtSpiIntId;

 

 /**

- * Return the base address of the GIC redistributor for the current CPU

- *

- * @retval Base address of the associated GIC Redistributor

- */

+  Return the base address of the GIC redistributor for the current CPU.

+

+  @param[in]   GicRedistributorBase  Base address of the first GIC

+                                     redistributor frame in the discovery

+                                     range.

+  @param[out]  Base                  On success, the base address of the GIC

+                                     redistributor associated with the

+                                     current CPU.

+

+  @retval EFI_SUCCESS       The redistributor of the current CPU was found.

+  @retval EFI_DEVICE_ERROR  A redistributor frame could not be mapped.

+  @retval EFI_NOT_FOUND     No redistributor frame matches the affinity of

+                            the current CPU.

+**/

 STATIC

-UINTN

+EFI_STATUS

 GicGetCpuRedistributorBase (

-  IN UINTN  GicRedistributorBase

+  IN  UINTN  GicRedistributorBase,

+  OUT UINTN  *Base

   )

 {

   UINTN       MpId;

@@ -80,14 +91,14 @@ GicGetCpuRedistributorBase (
         GicCpuRedistributorBase,

         Status

         ));

-      ASSERT_EFI_ERROR (Status);

-      return 0;

+      return EFI_DEVICE_ERROR;

     }

 

     TypeRegister = MmioRead64 (GicCpuRedistributorBase + ARM_GICR_TYPER);

     Affinity     = ARM_GICR_TYPER_GET_AFFINITY (TypeRegister);

     if (Affinity == CpuAffinity) {

-      return GicCpuRedistributorBase;

+      *Base = GicCpuRedistributorBase;

+      return EFI_SUCCESS;

     }

 

     // Move to the next GIC Redistributor frame.

@@ -102,8 +113,13 @@ GicGetCpuRedistributorBase (
   } while ((TypeRegister & ARM_GICR_TYPER_LAST) == 0);

 

   // The Redistributor has not been found for the current CPU

-  ASSERT_EFI_ERROR (EFI_NOT_FOUND);

-  return 0;

+  DEBUG ((

+    DEBUG_ERROR,

+    "%a: No GICv3 redistributor found for CPU with affinity 0x%lx\n",

+    __func__,

+    (UINT64)CpuAffinity

+    ));

+  return EFI_NOT_FOUND;

 }

 

 typedef enum {

@@ -784,7 +800,13 @@ GicV3DxeInitialize (
     return Status;

   }

 

-  mGicRedistributorBase = GicGetCpuRedistributorBase (PcdGet64 
(PcdGicRedistributorsBase));

+  Status = GicGetCpuRedistributorBase (

+             (UINTN)PcdGet64 (PcdGicRedistributorsBase),

+             &mGicRedistributorBase

+             );

+  if (EFI_ERROR (Status)) {

+    return Status;

+  }

 

   RegValue = ArmGicV3GetControlSystemRegisterEnable ();

   if ((RegValue & ICC_SRE_EL2_SRE) == 0) {

-- 
2.47.3



-=-=-=-=-=-=-=-=-=-=-=-
Groups.io Links: You receive all messages sent to this group.
View/Reply Online (#122084): https://edk2.groups.io/g/devel/message/122084
Mute This Topic: https://groups.io/mt/120797181/21656
Group Owner: [email protected]
Unsubscribe: https://edk2.groups.io/g/devel/unsub [[email protected]]
-=-=-=-=-=-=-=-=-=-=-=-


Reply via email to