diff --git a/docs/design/firmware-design.rst b/docs/design/firmware-design.rst index 5fc1335..d0d6ef6 100644 --- a/docs/design/firmware-design.rst +++ b/docs/design/firmware-design.rst @@ -2696,13 +2696,13 @@ -------------- -*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 diff --git a/docs/perf/index.rst b/docs/perf/index.rst index 0f49b48..1482b80 100644 --- a/docs/perf/index.rst +++ b/docs/perf/index.rst @@ -8,7 +8,8 @@ psci-performance-juno tsp + performance-monitoring-unit -------------- -*Copyright (c) 2019, Arm Limited. All rights reserved.* +*Copyright (c) 2019-2020, Arm Limited. All rights reserved.* diff --git a/docs/perf/performance-monitoring-unit.rst b/docs/perf/performance-monitoring-unit.rst new file mode 100644 index 0000000..5dd1af5 --- /dev/null +++ b/docs/perf/performance-monitoring-unit.rst @@ -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``, where ``n`` is ``0`` to + ``30``. +- A dedicated cycle counter: ``PMCCNTR``. + +Architectural mappings +~~~~~~~~~~~~~~~~~~~~~~ + ++--------------+---------+----------------------------+ +| Counters | State | System Register Name | ++==============+=========+============================+ +| | AArch64 | ``PMEVCNTR_EL0[63*:0]`` | +| Programmable +---------+----------------------------+ +| | AArch32 | ``PMEVCNTR[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`` which +configures it. The cycle counter has the ``PMCCFILTR_EL0`` register, which has +an identical function and bit field layout as ``PMEVTYPER``. 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_EL0[63*:0]`` | ``PMEVTYPER[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_EL0``/``PMEVTYPER`` and ``PMCCFILTR_EL0/PMCCFILTR``, the +most important fields are: + +- ``P``: + + - Bit 31. + - If set to ``0``, will increment the associated ``PMEVCNTR`` at EL1. + +- ``NSK``: + + - Bit 29. + - If equal to the ``P`` bit it enables the associated ``PMEVCNTR`` at + Non-secure EL1. + - Reserved if EL3 not implemented. + +- ``NSH``: + + - Bit 27. + - If set to ``1``, will increment the associated ``PMEVCNTR`` at EL2. + - Reserved if EL2 not implemented. + +- ``SH``: + + - Bit 24. + - If different to the ``NSH`` bit it enables the associated ``PMEVCNTR`` + at Secure EL2. + - Reserved if Secure EL2 not implemented. + +- ``M``: + + - Bit 26. + - If equal to the ``P`` bit it enables the associated ``PMEVCNTR`` 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`` will count. + +For ``PMCNTENSET_EL0``/``PMCNTENSET``, the most important fields are: + +- ``P[30:0]``: + + - Setting bit ``P[n]`` to ``1`` enables counter ``PMEVCNTR``. + - The effects of ``PMEVTYPER`` 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``) 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 diff --git a/docs/process/security-hardening.rst b/docs/process/security-hardening.rst index 43a5721..507046f 100644 --- a/docs/process/security-hardening.rst +++ b/docs/process/security-hardening.rst @@ -25,6 +25,99 @@ 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 @@ 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