Skip to content

Commit 7081e76

Browse files
AhmedIsmail02Ahmed Ismailaggarg
authored
Armv8.1-m: Add pacbti support (#1147)
* copyright-checker: Add FreeRTOS Arm collab copyright FreeRTOS Arm collab files shall have both Amazon's and Arm's copyright headers. Hence, the copyright checker is modified to check for both copyrights. Signed-off-by: Gaurav Aggarwal <[email protected]> * armv8-m: Add support for IAR with TFM FREERTOS PORT As the case for ARMClang, and GCC toolchains, IAR with TFM FreeRTOS Port support is added. Signed-off-by: Ahmed Ismail <[email protected]> * armv8-m: Do not overwrite Control register value The current ARMv8-M FreeRTOS-Kernel Port code implementation is modified in a way that allows the CONTROL register's value to be retained rather than being overwritten. This is needed for adding PACBTI support as the special-purpose CONTROL register `PAC_EN`, `UPAC_EN`, `BTI_EN`, and `UBTI_EN` PACBTI enablement bits should be configured before calling `vRestoreContextOfFirstTask()` function which currently overwrite the value inside the CONTROL register. Signed-off-by: Ahmed Ismail <[email protected]> * armv8.1-m: Add PACBTI support to kernel non-secure implementation In this commit, Pointer Authentication, and Branch Target Identification Extension (PACBTI) support is added for Non-Secure and Non-TrustZone variants of Cortex-M85 FreeRTOS-Kernel Port. The PACBTI support is added for Arm Compiler For Embedded, and IAR toolchains only. The support in the kernel is not yet enabled for GNU toolchain due to known issues. Signed-off-by: Ahmed Ismail <[email protected]> * Fix CI check Signed-off-by: Gaurav Aggarwal <[email protected]> --------- Signed-off-by: Gaurav Aggarwal <[email protected]> Signed-off-by: Ahmed Ismail <[email protected]> Co-authored-by: Ahmed Ismail <[email protected]> Co-authored-by: Gaurav Aggarwal <[email protected]>
1 parent e400cc9 commit 7081e76

File tree

81 files changed

+2430
-92
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

81 files changed

+2430
-92
lines changed

.github/.cSpellWords.txt

+5
Original file line numberDiff line numberDiff line change
@@ -448,6 +448,7 @@ MAINRDY
448448
MAIR
449449
Mang
450450
Mbits
451+
mbranch
451452
mcause
452453
MCFR
453454
MCKA
@@ -586,6 +587,8 @@ OWATCOM
586587
OWDR
587588
OWER
588589
OWSR
590+
pacbti
591+
PACBTI
589592
PAGEN
590593
PCDR
591594
PCER
@@ -900,6 +903,7 @@ TXTEN
900903
TXUBR
901904
TXVC
902905
TXVDIS
906+
UBTI
903907
UDCP
904908
UNACKED
905909
uncrustify
@@ -915,6 +919,7 @@ UNSUB
915919
UNSUBACK
916920
unsubscriptions
917921
unsuspended
922+
UPAC
918923
URAD
919924
URAT
920925
URSTEN

.github/scripts/kernel_checker.py

+91-8
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
# */
2929

3030
import os
31+
import re
3132
from common.header_checker import HeaderChecker
3233

3334
#--------------------------------------------------------------------------------------------------
@@ -106,6 +107,15 @@
106107
r'.*portable/GCC/AVR32_UC3/.*',
107108
]
108109

110+
KERNEL_ARM_COLLAB_FILES_PATTERNS = [
111+
r'.*portable/ARMv8M/*',
112+
r'.*portable/.*/ARM_CM23*',
113+
r'.*portable/.*/ARM_CM33*',
114+
r'.*portable/.*/ARM_CM35*',
115+
r'.*portable/.*/ARM_CM55*',
116+
r'.*portable/.*/ARM_CM85*',
117+
]
118+
109119
KERNEL_HEADER = [
110120
'/*\n',
111121
' * FreeRTOS Kernel <DEVELOPMENT BRANCH>\n',
@@ -139,19 +149,92 @@
139149

140150
FREERTOS_COPYRIGHT_REGEX = r"^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$"
141151

152+
FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX = r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright \(C\) 20\d\d Amazon.com, Inc. or its affiliates. All Rights Reserved\.( \*\/)?$)|" + \
153+
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? Copyright 20\d\d Arm Limited and/or its affiliates( \*\/)?$)|" + \
154+
r"(^(;|#)?( *(\/\*|\*|#|\/\/))? <[email protected]>( \*\/)?$)"
155+
156+
157+
class KernelHeaderChecker(HeaderChecker):
158+
def __init__(
159+
self,
160+
header,
161+
padding=1000,
162+
ignored_files=None,
163+
ignored_ext=None,
164+
ignored_patterns=None,
165+
py_ext=None,
166+
asm_ext=None,
167+
third_party_patterns=None,
168+
copyright_regex = None
169+
):
170+
super().__init__(header, padding, ignored_files, ignored_ext, ignored_patterns,
171+
py_ext, asm_ext, third_party_patterns, copyright_regex)
172+
173+
self.armCollabRegex = re.compile(FREERTOS_ARM_COLLAB_COPYRIGHT_REGEX)
174+
175+
self.armCollabFilesPatternList = []
176+
for pattern in KERNEL_ARM_COLLAB_FILES_PATTERNS:
177+
self.armCollabFilesPatternList.append(re.compile(pattern))
178+
179+
def isArmCollabFile(self, path):
180+
for pattern in self.armCollabFilesPatternList:
181+
if pattern.match(path):
182+
return True
183+
return False
184+
185+
def checkArmCollabFile(self, path):
186+
isValid = False
187+
file_ext = os.path.splitext(path)[-1]
188+
189+
with open(path, encoding="utf-8", errors="ignore") as file:
190+
chunk = file.read(len("".join(self.header)) + self.padding)
191+
lines = [("%s\n" % line) for line in chunk.strip().splitlines()][
192+
: len(self.header) + 2
193+
]
194+
if (len(lines) > 0) and (lines[0].find("#!") == 0):
195+
lines.remove(lines[0])
196+
197+
# Split lines in sections.
198+
headers = dict()
199+
headers["text"] = []
200+
headers["copyright"] = []
201+
headers["spdx"] = []
202+
for line in lines:
203+
if self.armCollabRegex.match(line):
204+
headers["copyright"].append(line)
205+
elif "SPDX-License-Identifier:" in line:
206+
headers["spdx"].append(line)
207+
else:
208+
headers["text"].append(line)
209+
210+
text_equal = self.isValidHeaderSection(file_ext, "text", headers["text"])
211+
spdx_equal = self.isValidHeaderSection(file_ext, "spdx", headers["spdx"])
212+
213+
if text_equal and spdx_equal and len(headers["copyright"]) == 3:
214+
isValid = True
215+
216+
return isValid
217+
218+
def customCheck(self, path):
219+
isValid = False
220+
if self.isArmCollabFile(path):
221+
isValid = self.checkArmCollabFile(path)
222+
return isValid
223+
224+
142225
def main():
143226
parser = HeaderChecker.configArgParser()
144227
args = parser.parse_args()
145228

146229
# Configure the checks then run
147-
checker = HeaderChecker(KERNEL_HEADER,
148-
copyright_regex=FREERTOS_COPYRIGHT_REGEX,
149-
ignored_files=KERNEL_IGNORED_FILES,
150-
ignored_ext=KERNEL_IGNORED_EXTENSIONS,
151-
ignored_patterns=KERNEL_IGNORED_PATTERNS,
152-
third_party_patterns=KERNEL_THIRD_PARTY_PATTERNS,
153-
py_ext=KERNEL_PY_EXTENSIONS,
154-
asm_ext=KERNEL_ASM_EXTENSIONS)
230+
checker = KernelHeaderChecker(KERNEL_HEADER,
231+
copyright_regex=FREERTOS_COPYRIGHT_REGEX,
232+
ignored_files=KERNEL_IGNORED_FILES,
233+
ignored_ext=KERNEL_IGNORED_EXTENSIONS,
234+
ignored_patterns=KERNEL_IGNORED_PATTERNS,
235+
third_party_patterns=KERNEL_THIRD_PARTY_PATTERNS,
236+
py_ext=KERNEL_PY_EXTENSIONS,
237+
asm_ext=KERNEL_ASM_EXTENSIONS)
155238
checker.ignoreFile(os.path.split(__file__)[-1])
156239

157240
rc = checker.processArgs(args)

CMakeLists.txt

+3
Original file line numberDiff line numberDiff line change
@@ -138,15 +138,18 @@ if(NOT FREERTOS_PORT)
138138
" IAR_ARM_CM33_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-secure\n"
139139
" IAR_ARM_CM33_SECURE - Compiler: IAR Target: ARM Cortex-M33 secure\n"
140140
" IAR_ARM_CM33_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M33 non-trustzone non-secure\n"
141+
" IAR_ARM_CM33_TFM - Compiler: IAR Target: ARM Cortex-M33 non-secure for TF-M\n"
141142
" IAR_ARM_CM35P_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-secure\n"
142143
" IAR_ARM_CM35P_SECURE - Compiler: IAR Target: ARM Cortex-M35P secure\n"
143144
" IAR_ARM_CM35P_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M35P non-trustzone non-secure\n"
144145
" IAR_ARM_CM55_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-secure\n"
145146
" IAR_ARM_CM55_SECURE - Compiler: IAR Target: ARM Cortex-M55 secure\n"
146147
" IAR_ARM_CM55_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M55 non-trustzone non-secure\n"
148+
" IAR_ARM_CM55_TFM - Compiler: IAR Target: ARM Cortex-M55 non-secure for TF-M\n"
147149
" IAR_ARM_CM85_NONSECURE - Compiler: IAR Target: ARM Cortex-M85 non-secure\n"
148150
" IAR_ARM_CM85_SECURE - Compiler: IAR Target: ARM Cortex-M85 secure\n"
149151
" IAR_ARM_CM85_NTZ_NONSECURE - Compiler: IAR Target: ARM Cortex-M85 non-trustzone non-secure\n"
152+
" IAR_ARM_CM85_TFM - Compiler: IAR Target: ARM Cortex-M85 non-secure for TF-M\n"
150153
" IAR_ARM_CRX_NOGIC - Compiler: IAR Target: ARM Cortex-Rx no GIC\n"
151154
" IAR_ATMEGA323 - Compiler: IAR Target: ATMega323\n"
152155
" IAR_ATMEL_SAM7S64 - Compiler: IAR Target: Atmel SAM7S64\n"

examples/coverity/README.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ files.
1717

1818
## Getting Started
1919
### Prerequisites
20-
Coverity can be run on any platform mentioned [here](https://sig-docs.synopsys.com/polaris/topics/c_coverity-compatible-platforms.html).
20+
Coverity can be run on any platform mentioned [here](https://documentation.blackduck.com/bundle/coverity-docs/page/deploy-install-guide/topics/supported_platforms_for_coverity_analysis.html).
2121
The following are the prerequisites to generate coverity report:
2222

2323
1. CMake version > 3.13.0 (You can check whether you have this by typing `cmake --version`).

include/FreeRTOS.h

+12
Original file line numberDiff line numberDiff line change
@@ -3032,6 +3032,18 @@
30323032
#define configCONTROL_INFINITE_LOOP()
30333033
#endif
30343034

3035+
/* Set configENABLE_PAC and/or configENABLE_BTI to 1 to enable PAC and/or BTI
3036+
* support and 0 to disable them. These are currently used in ARMv8.1-M ports. */
3037+
#if ( portHAS_PACBTI_FEATURE == 1 )
3038+
#ifndef configENABLE_PAC
3039+
#define configENABLE_PAC 0
3040+
#endif
3041+
3042+
#ifndef configENABLE_BTI
3043+
#define configENABLE_BTI 0
3044+
#endif
3045+
#endif
3046+
30353047
/* Sometimes the FreeRTOSConfig.h settings only allow a task to be created using
30363048
* dynamically allocated RAM, in which case when any task is deleted it is known
30373049
* that both the task's stack and TCB need to be freed. Sometimes the

portable/ARMv8M/non_secure/port.c

+95-2
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*
22
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
33
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* Copyright 2024 Arm Limited and/or its affiliates
5+
46
*
57
* SPDX-License-Identifier: MIT
68
*
@@ -110,6 +112,7 @@ typedef void ( * portISR_t )( void );
110112
#define portSCB_VTOR_REG ( *( ( portISR_t ** ) 0xe000ed08 ) )
111113
#define portSCB_SYS_HANDLER_CTRL_STATE_REG ( *( ( volatile uint32_t * ) 0xe000ed24 ) )
112114
#define portSCB_MEM_FAULT_ENABLE_BIT ( 1UL << 16UL )
115+
#define portSCB_USG_FAULT_ENABLE_BIT ( 1UL << 18UL )
113116
/*-----------------------------------------------------------*/
114117

115118
/**
@@ -373,6 +376,20 @@ typedef void ( * portISR_t )( void );
373376
* any secure calls.
374377
*/
375378
#define portNO_SECURE_CONTEXT 0
379+
380+
/**
381+
* @brief Constants required to check and configure PACBTI security feature implementation.
382+
*/
383+
#if ( portHAS_PACBTI_FEATURE == 1 )
384+
385+
#define portID_ISAR5_REG ( *( ( volatile uint32_t * ) 0xe000ed74 ) )
386+
387+
#define portCONTROL_UPAC_EN ( 1UL << 7UL )
388+
#define portCONTROL_PAC_EN ( 1UL << 6UL )
389+
#define portCONTROL_UBTI_EN ( 1UL << 5UL )
390+
#define portCONTROL_BTI_EN ( 1UL << 4UL )
391+
392+
#endif /* portHAS_PACBTI_FEATURE */
376393
/*-----------------------------------------------------------*/
377394

378395
/**
@@ -410,6 +427,26 @@ static void prvTaskExitError( void );
410427
static void prvSetupFPU( void ) PRIVILEGED_FUNCTION;
411428
#endif /* configENABLE_FPU */
412429

430+
#if ( portHAS_PACBTI_FEATURE == 1 )
431+
432+
/**
433+
* @brief Configures PACBTI features.
434+
*
435+
* This function configures the Pointer Authentication, and Branch Target
436+
* Identification security features as per the user configuration. It returns
437+
* the value of the special purpose CONTROL register accordingly, and optionally
438+
* updates the CONTROL register value. Currently, only Cortex-M85 (ARMv8.1-M
439+
* architecture based) target supports PACBTI security feature.
440+
*
441+
* @param xWriteControlRegister Used to control whether the special purpose
442+
* CONTROL register should be updated or not.
443+
*
444+
* @return CONTROL register value according to the configured PACBTI option.
445+
*/
446+
static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister );
447+
448+
#endif /* portHAS_PACBTI_FEATURE */
449+
413450
/**
414451
* @brief Setup the timer to generate the tick interrupts.
415452
*
@@ -1457,6 +1494,7 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
14571494
xMPU_SETTINGS * xMPUSettings ) /* PRIVILEGED_FUNCTION */
14581495
{
14591496
uint32_t ulIndex = 0;
1497+
uint32_t ulControl = 0x0;
14601498

14611499
xMPUSettings->ulContext[ ulIndex ] = 0x04040404; /* r4. */
14621500
ulIndex++;
@@ -1503,16 +1541,24 @@ void vPortSVCHandler_C( uint32_t * pulCallerStackAddress ) /* PRIVILEGED_FUNCTIO
15031541
xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) pxEndOfStack; /* PSPLIM. */
15041542
ulIndex++;
15051543

1544+
#if ( portHAS_PACBTI_FEATURE == 1 )
1545+
{
1546+
/* Check PACBTI security feature configuration before pushing the
1547+
* CONTROL register's value on task's TCB. */
1548+
ulControl = prvConfigurePACBTI( pdFALSE );
1549+
}
1550+
#endif /* portHAS_PACBTI_FEATURE */
1551+
15061552
if( xRunPrivileged == pdTRUE )
15071553
{
15081554
xMPUSettings->ulTaskFlags |= portTASK_IS_PRIVILEGED_FLAG;
1509-
xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED; /* CONTROL. */
1555+
xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_PRIVILEGED ); /* CONTROL. */
15101556
ulIndex++;
15111557
}
15121558
else
15131559
{
15141560
xMPUSettings->ulTaskFlags &= ( ~portTASK_IS_PRIVILEGED_FLAG );
1515-
xMPUSettings->ulContext[ ulIndex ] = ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED; /* CONTROL. */
1561+
xMPUSettings->ulContext[ ulIndex ] = ( ulControl | ( uint32_t ) portINITIAL_CONTROL_UNPRIVILEGED ); /* CONTROL. */
15161562
ulIndex++;
15171563
}
15181564

@@ -1740,6 +1786,14 @@ BaseType_t xPortStartScheduler( void ) /* PRIVILEGED_FUNCTION */
17401786
portNVIC_SHPR3_REG |= portNVIC_SYSTICK_PRI;
17411787
portNVIC_SHPR2_REG = 0;
17421788

1789+
#if ( portHAS_PACBTI_FEATURE == 1 )
1790+
{
1791+
/* Set the CONTROL register value based on PACBTI security feature
1792+
* configuration before starting the first task. */
1793+
( void) prvConfigurePACBTI( pdTRUE );
1794+
}
1795+
#endif /* portHAS_PACBTI_FEATURE */
1796+
17431797
#if ( configENABLE_MPU == 1 )
17441798
{
17451799
/* Setup the Memory Protection Unit (MPU). */
@@ -2158,3 +2212,42 @@ BaseType_t xPortIsInsideInterrupt( void )
21582212

21592213
#endif /* #if ( ( configENABLE_MPU == 1 ) && ( configUSE_MPU_WRAPPERS_V1 == 0 ) ) */
21602214
/*-----------------------------------------------------------*/
2215+
2216+
#if ( portHAS_PACBTI_FEATURE == 1 )
2217+
2218+
static uint32_t prvConfigurePACBTI( BaseType_t xWriteControlRegister )
2219+
{
2220+
uint32_t ulControl = 0x0;
2221+
2222+
/* Ensure that PACBTI is implemented. */
2223+
configASSERT( portID_ISAR5_REG != 0x0 );
2224+
2225+
/* Enable UsageFault exception if PAC or BTI is enabled. */
2226+
#if( ( configENABLE_PAC == 1 ) || ( configENABLE_BTI == 1 ) )
2227+
{
2228+
portSCB_SYS_HANDLER_CTRL_STATE_REG |= portSCB_USG_FAULT_ENABLE_BIT;
2229+
}
2230+
#endif
2231+
2232+
#if( configENABLE_PAC == 1 )
2233+
{
2234+
ulControl |= ( portCONTROL_UPAC_EN | portCONTROL_PAC_EN );
2235+
}
2236+
#endif
2237+
2238+
#if( configENABLE_BTI == 1 )
2239+
{
2240+
ulControl |= ( portCONTROL_UBTI_EN | portCONTROL_BTI_EN );
2241+
}
2242+
#endif
2243+
2244+
if( xWriteControlRegister == pdTRUE )
2245+
{
2246+
__asm volatile ( "msr control, %0" : : "r" ( ulControl ) );
2247+
}
2248+
2249+
return ulControl;
2250+
}
2251+
2252+
#endif /* #if ( portHAS_PACBTI_FEATURE == 1 ) */
2253+
/*-----------------------------------------------------------*/

portable/ARMv8M/non_secure/portable/GCC/ARM_CM23/portmacro.h

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*
22
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
33
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* Copyright 2024 Arm Limited and/or its affiliates
5+
46
*
57
* SPDX-License-Identifier: MIT
68
*
@@ -51,6 +53,7 @@
5153
#define portARCH_NAME "Cortex-M23"
5254
#define portHAS_ARMV8M_MAIN_EXTENSION 0
5355
#define portARMV8M_MINOR_VERSION 0
56+
#define portHAS_PACBTI_FEATURE 0
5457
#define portDONT_DISCARD __attribute__( ( used ) )
5558
/*-----------------------------------------------------------*/
5659

portable/ARMv8M/non_secure/portable/GCC/ARM_CM23_NTZ/portmacro.h

+3
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
/*
22
* FreeRTOS Kernel <DEVELOPMENT BRANCH>
33
* Copyright (C) 2021 Amazon.com, Inc. or its affiliates. All Rights Reserved.
4+
* Copyright 2024 Arm Limited and/or its affiliates
5+
46
*
57
* SPDX-License-Identifier: MIT
68
*
@@ -51,6 +53,7 @@
5153
#define portARCH_NAME "Cortex-M23"
5254
#define portHAS_ARMV8M_MAIN_EXTENSION 0
5355
#define portARMV8M_MINOR_VERSION 0
56+
#define portHAS_PACBTI_FEATURE 0
5457
#define portDONT_DISCARD __attribute__( ( used ) )
5558
/*-----------------------------------------------------------*/
5659

0 commit comments

Comments
 (0)