[PATCH v3 07/31] coresight: etm4x: Properly control filter in CPU idle with FEAT_TRF

Mike Leach mike.leach at linaro.org
Tue Sep 30 08:39:01 PDT 2025


On Mon, 15 Sept 2025 at 11:33, Leo Yan <leo.yan at arm.com> wrote:
>
> If a CPU supports FEAT_TRF, as described in the section K5.5 "Context
> switching", Arm ARM (ARM DDI 0487 L.a), it defines a flow to prohibit
> program-flow trace, execute a TSB CSYNC instruction for flushing,
> followed by clearing TRCPRGCTLR.EN bit.
>
> To restore the state, the reverse sequence is required.
>
> This differs from the procedure described in the section 3.4.1 "The
> procedure when powering down the PE" of ARM IHI0064H.b, which involves
> the OS Lock to prevent external debugger accesses and implicitly
> disables trace.
>
> To be compatible with different ETM versions, explicitly control trace
> unit using etm4_disable_trace_unit() and etm4_enable_trace_unit()
> during CPU idle to comply with FEAT_TRF.
>
> As a result, the save states for TRFCR_ELx and trcprgctlr are redundant,
> remove them.
>
> Fixes: f188b5e76aae ("coresight: etm4x: Save/restore state across CPU low power states")
> Signed-off-by: Leo Yan <leo.yan at arm.com>
> ---
>  drivers/hwtracing/coresight/coresight-etm4x-core.c | 28 ++++++++++++++++------
>  drivers/hwtracing/coresight/coresight-etm4x.h      |  3 ---
>  2 files changed, 21 insertions(+), 10 deletions(-)
>
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x-core.c b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> index 999bceef4cd771e46aec891f4c814a95e0921c2f..2d2ef58393db10d058b3e29c5b270dd2d62e1a49 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x-core.c
> +++ b/drivers/hwtracing/coresight/coresight-etm4x-core.c
> @@ -1884,9 +1884,18 @@ static int __etm4_cpu_save(struct etmv4_drvdata *drvdata)
>                 goto out;
>         }
>
> +       if (!drvdata->paused)
> +               etm4_disable_trace_unit(drvdata);
> +
> +       /*
> +        * As recommended by section 4.3.7 (Synchronization of register updates)
> +        * of ARM IHI 0064H.b, the self-hosted trace analyzer always executes an
> +        * ISB instruction after programming the trace unit registers.
> +        */
> +       isb();
> +
>         state = drvdata->save_state;
>
> -       state->trcprgctlr = etm4x_read32(csa, TRCPRGCTLR);
>         if (drvdata->nr_pe)
>                 state->trcprocselr = etm4x_read32(csa, TRCPROCSELR);
>         state->trcconfigr = etm4x_read32(csa, TRCCONFIGR);
> @@ -1996,9 +2005,6 @@ static int etm4_cpu_save(struct etmv4_drvdata *drvdata)
>  {
>         int ret = 0;
>
> -       /* Save the TRFCR irrespective of whether the ETM is ON */
> -       if (drvdata->trfcr)
> -               drvdata->save_trfcr = read_trfcr();
>         /*
>          * Save and restore the ETM Trace registers only if
>          * the ETM is active.
> @@ -2020,7 +2026,6 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
>         etm4_cs_unlock(drvdata, csa);
>         etm4x_relaxed_write32(csa, state->trcclaimset, TRCCLAIMSET);
>
> -       etm4x_relaxed_write32(csa, state->trcprgctlr, TRCPRGCTLR);
>         if (drvdata->nr_pe)
>                 etm4x_relaxed_write32(csa, state->trcprocselr, TRCPROCSELR);
>         etm4x_relaxed_write32(csa, state->trcconfigr, TRCCONFIGR);
> @@ -2105,13 +2110,22 @@ static void __etm4_cpu_restore(struct etmv4_drvdata *drvdata)
>
>         /* Unlock the OS lock to re-enable trace and external debug access */
>         etm4_os_unlock(drvdata);
> +
> +       if (!drvdata->paused)
> +               etm4_enable_trace_unit(drvdata);
> +
> +       /*
> +        * As recommended by section 4.3.7 (Synchronization of register updates)
> +        * of ARM IHI 0064H.b, the self-hosted trace analyzer always executes an
> +        * ISB instruction after programming the trace unit registers.
> +        */
> +       isb();
> +
>         etm4_cs_lock(drvdata, csa);
>  }
>
>  static void etm4_cpu_restore(struct etmv4_drvdata *drvdata)
>  {
> -       if (drvdata->trfcr)
> -               write_trfcr(drvdata->save_trfcr);
>         if (drvdata->state_needs_restore)
>                 __etm4_cpu_restore(drvdata);
>  }
> diff --git a/drivers/hwtracing/coresight/coresight-etm4x.h b/drivers/hwtracing/coresight/coresight-etm4x.h
> index 13ec9ecef46f5b60a38c464e8ebde3ef72e7d50b..b8796b4271025f6aba79fe3cd6e4d17d0b56952d 100644
> --- a/drivers/hwtracing/coresight/coresight-etm4x.h
> +++ b/drivers/hwtracing/coresight/coresight-etm4x.h
> @@ -866,7 +866,6 @@ struct etmv4_config {
>   * struct etm4_save_state - state to be preserved when ETM is without power
>   */
>  struct etmv4_save_state {
> -       u32     trcprgctlr;
>         u32     trcprocselr;
>         u32     trcconfigr;
>         u32     trcauxctlr;
> @@ -980,7 +979,6 @@ struct etmv4_save_state {
>   *             at runtime, due to the additional setting of TRFCR_CX when
>   *             in EL2. Otherwise, 0.
>   * @config:    structure holding configuration parameters.
> - * @save_trfcr:        Saved TRFCR_EL1 register during a CPU PM event.
>   * @save_state:        State to be preserved across power loss
>   * @state_needs_restore: True when there is context to restore after PM exit
>   * @skip_power_up: Indicates if an implementation can skip powering up
> @@ -1037,7 +1035,6 @@ struct etmv4_drvdata {
>         bool                            lpoverride;
>         u64                             trfcr;
>         struct etmv4_config             config;
> -       u64                             save_trfcr;
>         struct etmv4_save_state         *save_state;
>         bool                            state_needs_restore;
>         bool                            skip_power_up;
>
> --
> 2.34.1
>

Reviewed-by: Mike Leach <mike.leach at linaro.org>

-- 
Mike Leach
Principal Engineer, ARM Ltd.
Manchester Design Centre. UK



More information about the linux-arm-kernel mailing list