Update docs with PMU security information

This patch adds information on the PMU configuration registers
and security considerations related to the PMU.

Signed-off-by: Petre-Ionut Tudor <petre-ionut.tudor@arm.com>
Change-Id: I36b15060b9830a77d3f47f293c0a6dafa3c581fb
This commit is contained in:
Petre-Ionut Tudor 2019-09-27 15:13:21 +01:00
parent fa764c865d
commit 62c9be71d6
4 changed files with 261 additions and 3 deletions

View File

@ -2696,13 +2696,13 @@ kernel at boot time. These can be found in the ``fdts`` directory.
--------------
*Copyright (c) 2013-2019, Arm Limited and Contributors. All rights reserved.*
*Copyright (c) 2013-2020, Arm Limited and Contributors. All rights reserved.*
.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _SMCCC: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
.. _PSCI: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _Power State Coordination Interface PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0022d/Power_State_Coordination_Interface_PDD_v1_1_DEN0022D.pdf
.. _Arm ARM: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.ddi0487a.e/index.html
.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest
.. _SMC Calling Convention PDD: http://infocenter.arm.com/help/topic/com.arm.doc.den0028b/ARM_DEN0028B_SMC_Calling_Convention.pdf
.. _Trusted Board Boot Requirements CLIENT (TBBR-CLIENT) Armv8-A (ARM DEN0006D): https://developer.arm.com/docs/den0006/latest/trusted-board-boot-requirements-client-tbbr-client-armv8-a

View File

@ -8,7 +8,8 @@ Performance & Testing
psci-performance-juno
tsp
performance-monitoring-unit
--------------
*Copyright (c) 2019, Arm Limited. All rights reserved.*
*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*

View File

@ -0,0 +1,158 @@
Performance Monitoring Unit
===========================
The Performance Monitoring Unit (PMU) allows recording of architectural and
microarchitectural events for profiling purposes.
This document gives an overview of the PMU counter configuration to assist with
implementation and to complement the PMU security guidelines given in the
:ref:`Secure Development Guidelines` document.
.. note::
This section applies to Armv8-A implementations which have version 3
of the Performance Monitors Extension (PMUv3).
PMU Counters
------------
The PMU makes 32 counters available at all privilege levels:
- 31 programmable event counters: ``PMEVCNTR<n>``, where ``n`` is ``0`` to
``30``.
- A dedicated cycle counter: ``PMCCNTR``.
Architectural mappings
~~~~~~~~~~~~~~~~~~~~~~
+--------------+---------+----------------------------+
| Counters | State | System Register Name |
+==============+=========+============================+
| | AArch64 | ``PMEVCNTR<n>_EL0[63*:0]`` |
| Programmable +---------+----------------------------+
| | AArch32 | ``PMEVCNTR<n>[31:0]`` |
+--------------+---------+----------------------------+
| | AArch64 | ``PMCCNTR_EL0[63:0]`` |
| Cycle +---------+----------------------------+
| | AArch32 | ``PMCCNTR[63:0]`` |
+--------------+---------+----------------------------+
.. note::
Bits [63:32] are only available if ARMv8.5-PMU is implemented. Refer to the
`Arm ARM`_ for a detailed description of ARMv8.5-PMU features.
Configuring the PMU for counting events
---------------------------------------
Each programmable counter has an associated register, ``PMEVTYPER<n>`` which
configures it. The cycle counter has the ``PMCCFILTR_EL0`` register, which has
an identical function and bit field layout as ``PMEVTYPER<n>``. In addition,
the counters are enabled (permitted to increment) via the ``PMCNTENSET`` and
``PMCR`` registers. These can be accessed at all privilege levels.
Architectural mappings
~~~~~~~~~~~~~~~~~~~~~~
+-----------------------------+------------------------+
| AArch64 | AArch32 |
+=============================+========================+
| ``PMEVTYPER<n>_EL0[63*:0]`` | ``PMEVTYPER<n>[31:0]`` |
+-----------------------------+------------------------+
| ``PMCCFILTR_EL0[63*:0]`` | ``PMCCFILTR[31:0]`` |
+-----------------------------+------------------------+
| ``PMCNTENSET_EL0[63*:0]`` | ``PMCNTENSET[31:0]`` |
+-----------------------------+------------------------+
| ``PMCR_EL0[63*:0]`` | ``PMCR[31:0]`` |
+-----------------------------+------------------------+
.. note::
Bits [63:32] are reserved.
Relevant register fields
~~~~~~~~~~~~~~~~~~~~~~~~
For ``PMEVTYPER<n>_EL0``/``PMEVTYPER<n>`` and ``PMCCFILTR_EL0/PMCCFILTR``, the
most important fields are:
- ``P``:
- Bit 31.
- If set to ``0``, will increment the associated ``PMEVCNTR<n>`` at EL1.
- ``NSK``:
- Bit 29.
- If equal to the ``P`` bit it enables the associated ``PMEVCNTR<n>`` at
Non-secure EL1.
- Reserved if EL3 not implemented.
- ``NSH``:
- Bit 27.
- If set to ``1``, will increment the associated ``PMEVCNTR<n>`` at EL2.
- Reserved if EL2 not implemented.
- ``SH``:
- Bit 24.
- If different to the ``NSH`` bit it enables the associated ``PMEVCNTR<n>``
at Secure EL2.
- Reserved if Secure EL2 not implemented.
- ``M``:
- Bit 26.
- If equal to the ``P`` bit it enables the associated ``PMEVCNTR<n>`` at
EL3.
- ``evtCount[15:10]``:
- Extension to ``evtCount[9:0]``. Reserved unless ARMv8.1-PMU implemented.
- ``evtCount[9:0]``:
- The event number that the associated ``PMEVCNTR<n>`` will count.
For ``PMCNTENSET_EL0``/``PMCNTENSET``, the most important fields are:
- ``P[30:0]``:
- Setting bit ``P[n]`` to ``1`` enables counter ``PMEVCNTR<n>``.
- The effects of ``PMEVTYPER<n>`` are applied on top of this.
In other words, the counter will not increment at any privilege level or
security state unless it is enabled here.
- ``C``:
- Bit 31.
- If set to ``1`` enables the cycle counter ``PMCCNTR``.
For ``PMCR``/``PMCR_EL0``, the most important fields are:
- ``DP``:
- Bit 5.
- If set to ``1`` it disables the cycle counter ``PMCCNTR`` where event
counting (by ``PMEVCNTR<n>``) is prohibited (e.g. EL2 and the Secure
world).
- If set to ``0``, ``PMCCNTR`` will not be affected by this bit and
therefore will be able to count where the programmable counters are
prohibited.
- ``E``:
- Bit 0.
- Enables/disables counting altogether.
- The effects of ``PMCNTENSET`` and ``PMCR.DP`` are applied on top of this.
In other words, if this bit is ``0`` then no counters will increment
regardless of how the other PMU system registers or bit fields are
configured.
.. rubric:: References
- `Arm ARM`_
--------------
*Copyright (c) 2019-2020, Arm Limited and Contributors. All rights reserved.*
.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest

View File

@ -25,6 +25,99 @@ The secure world **should never** crash or become unusable due to receiving too
many normal world requests (a *Denial of Service* or *DoS* attack). It should
have a mechanism for throttling or ignoring normal world requests.
Preventing Secure-world timing information leakage via PMU counters
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
The Secure world needs to implement some defenses to prevent the Non-secure
world from making it leak timing information. In general, higher privilege
levels must defend from those below when the PMU is treated as an attack
vector.
Refer to the :ref:`Performance Monitoring Unit` guide for detailed information
on the PMU registers.
Timing leakage attacks from the Non-secure world
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
Since the Non-secure world has access to the ``PMCR`` register, it can
configure the PMU to increment counters at any exception level and in both
Secure and Non-secure state. Thus, it attempts to leak timing information from
the Secure world.
Shown below is an example of such a configuration:
- ``PMEVTYPER0_EL0`` and ``PMCCFILTR_EL0``:
- Set ``P`` to ``0``.
- Set ``NSK`` to ``1``.
- Set ``M`` to ``0``.
- Set ``NSH`` to ``0``.
- Set ``SH`` to ``1``.
- ``PMCNTENSET_EL0``:
- Set ``P[0]`` to ``1``.
- Set ``C`` to ``1``.
- ``PMCR_EL0``:
- Set ``DP`` to ``0``.
- Set ``E`` to ``1``.
This configuration instructs ``PMEVCNTR0_EL0`` and ``PMCCNTR_EL0`` to increment
at Secure EL1, Secure EL2 (if implemented) and EL3.
Since the Non-secure world has fine-grained control over where (at which
exception levels) it instructs counters to increment, obtaining event counts
would allow it to carry out side-channel timing attacks against the Secure
world. Examples include Spectre, Meltdown, as well as extracting secrets from
cryptographic algorithms with data-dependent variations in their execution
time.
Secure world mitigation strategies
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
The ``MDCR_EL3`` register allows EL3 to configure the PMU (among other things).
The `Arm ARM`_ details all of the bit fields in this register, but for the PMU
there are two bits which determine the permissions of the counters:
- ``SPME`` for the programmable counters.
- ``SCCD`` for the cycle counter.
Depending on the implemented features, the Secure world can prohibit counting
in AArch64 state via the following:
- ARMv8.2-Debug not implemented:
- Prohibit general event counters and the cycle counter:
``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1 && !ExternalSecureNoninvasiveDebugEnabled()``.
- ``MDCR_EL3.SPME`` resets to ``0``, so by default general events should
not be counted in the Secure world.
- The ``PMCR_EL0.DP`` bit therefore needs to be set to ``1`` when EL3 is
entered and ``PMCR_EL0`` needs to be saved and restored in EL3.
- ``ExternalSecureNoninvasiveDebugEnabled()`` is an authentication
interface which is implementation-defined unless ARMv8.4-Debug is
implemented. The `Arm ARM`_ has detailed information on this topic.
- The only other way is to disable the ``PMCR_EL0.E`` bit upon entering
EL3, which disables counting altogether.
- ARMv8.2-Debug implemented:
- Prohibit general event counters: ``MDCR_EL3.SPME == 0``.
- Prohibit cycle counter: ``MDCR_EL3.SPME == 0 && PMCR_EL0.DP == 1``.
``PMCR_EL0`` therefore needs to be saved and restored in EL3.
- ARMv8.5-PMU implemented:
- Prohibit general event counters: as in ARMv8.2-Debug.
- Prohibit cycle counter: ``MDCR_EL3.SCCD == 1``
In Aarch32 execution state the ``MDCR_EL3`` alias is the ``SDCR`` register,
which has some of the bit fields of ``MDCR_EL3``, most importantly the ``SPME``
and ``SCCD`` bits.
Build options
-------------
@ -71,6 +164,12 @@ Several build options can be used to check for security issues. Refer to the
NB: The ``Werror`` flag is enabled by default in TF-A and can be disabled by
setting the ``E`` build flag to 0.
.. rubric:: References
- `Arm ARM`_
--------------
*Copyright (c) 2019-2020, Arm Limited. All rights reserved.*
.. _Arm ARM: https://developer.arm.com/docs/ddi0487/latest