This is an automated email from the ASF dual-hosted git repository.
Donny9 pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/nuttx.git
The following commit(s) were added to refs/heads/master by this push:
new 05eed2703a2 armv8-m: enable PACBTI in CONTROL state
05eed2703a2 is described below
commit 05eed2703a2dec8858d6da56cc4e9569683f4e16
Author: chao an <[email protected]>
AuthorDate: Tue Oct 20 15:10:26 2026 +0800
armv8-m: enable PACBTI in CONTROL state
CONFIG_ARM_PACBTI enables the compiler and library side of the ARMv8.1-M
Pointer Authentication and Branch Target Identification extension, but the
CONTROL PAC/BTI enable bits also need to be set for the processor state that
runs PACBTI-protected code.
Add an ARMv8-M PACBTI configuration helper that enables the privileged and
unprivileged PAC/BTI CONTROL bits. Call it during architecture
initialization
and keep the same bits when constructing saved CONTROL values for new tasks,
protected-mode signal delivery and syscall transitions.
This keeps the runtime CONTROL state aligned with the selected PACBTI build
configuration instead of only relying on compiler code generation flags.
Signed-off-by: chao an <[email protected]>
---
arch/arm/include/armv8-m/irq.h | 7 ++++
arch/arm/src/armv8-m/CMakeLists.txt | 4 +++
arch/arm/src/armv8-m/Make.defs | 4 +++
arch/arm/src/armv8-m/arm_initialstate.c | 3 +-
arch/arm/src/armv8-m/arm_pacbticonfig.c | 51 ++++++++++++++++++++++++++++
arch/arm/src/armv8-m/arm_schedulesigaction.c | 3 +-
arch/arm/src/armv8-m/arm_svcall.c | 15 +++++---
arch/arm/src/common/arm_initialize.c | 6 ++++
arch/arm/src/common/arm_internal.h | 8 +++++
9 files changed, 94 insertions(+), 7 deletions(-)
diff --git a/arch/arm/include/armv8-m/irq.h b/arch/arm/include/armv8-m/irq.h
index a7abf1c7962..25fc6e083b4 100644
--- a/arch/arm/include/armv8-m/irq.h
+++ b/arch/arm/include/armv8-m/irq.h
@@ -203,6 +203,13 @@
#define CONTROL_SPSEL (1 << 1) /* Bit 1: Stack-pointer select */
#define CONTROL_NPRIV (1 << 0) /* Bit 0: Not privileged */
+#ifdef CONFIG_ARM_PACBTI
+# define CONTROL_PACBTI_MASK \
+ (CONTROL_UPAC_EN | CONTROL_PAC_EN | CONTROL_UBTI_EN | CONTROL_BTI_EN)
+#else
+# define CONTROL_PACBTI_MASK 0
+#endif
+
/****************************************************************************
* Public Types
****************************************************************************/
diff --git a/arch/arm/src/armv8-m/CMakeLists.txt
b/arch/arm/src/armv8-m/CMakeLists.txt
index e87185659a7..e20d73802eb 100644
--- a/arch/arm/src/armv8-m/CMakeLists.txt
+++ b/arch/arm/src/armv8-m/CMakeLists.txt
@@ -66,6 +66,10 @@ if(CONFIG_ARCH_FPU)
list(APPEND SRCS arm_fpuconfig.c arm_fpucmp.c)
endif()
+if(CONFIG_ARM_PACBTI)
+ list(APPEND SRCS arm_pacbticonfig.c)
+endif()
+
if(CONFIG_ARCH_RAMVECTORS)
list(APPEND SRCS arm_ramvec_initialize.c arm_ramvec_attach.c)
endif()
diff --git a/arch/arm/src/armv8-m/Make.defs b/arch/arm/src/armv8-m/Make.defs
index 326cdff7c08..df3d9877593 100644
--- a/arch/arm/src/armv8-m/Make.defs
+++ b/arch/arm/src/armv8-m/Make.defs
@@ -59,6 +59,10 @@ ifeq ($(CONFIG_ARCH_FPU),y)
CMN_CSRCS += arm_fpucmp.c
endif
+ifeq ($(CONFIG_ARM_PACBTI),y)
+ CMN_CSRCS += arm_pacbticonfig.c
+endif
+
ifeq ($(CONFIG_ARCH_RAMVECTORS),y)
CMN_CSRCS += arm_ramvec_initialize.c arm_ramvec_attach.c
endif
diff --git a/arch/arm/src/armv8-m/arm_initialstate.c
b/arch/arm/src/armv8-m/arm_initialstate.c
index fc316998ed7..c1da5458149 100644
--- a/arch/arm/src/armv8-m/arm_initialstate.c
+++ b/arch/arm/src/armv8-m/arm_initialstate.c
@@ -163,7 +163,8 @@ void up_initial_state(struct tcb_s *tcb)
xcp->regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
- xcp->regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+ xcp->regs[REG_CONTROL] = (getcontrol() & ~CONTROL_NPRIV) |
+ CONTROL_PACBTI_MASK;
#ifdef CONFIG_ARCH_FPU
xcp->regs[REG_FPSCR] |= ARMV8M_FPSCR_LTPSIZE_NONE;
diff --git a/arch/arm/src/armv8-m/arm_pacbticonfig.c
b/arch/arm/src/armv8-m/arm_pacbticonfig.c
new file mode 100644
index 00000000000..717bef34f6b
--- /dev/null
+++ b/arch/arm/src/armv8-m/arm_pacbticonfig.c
@@ -0,0 +1,51 @@
+/****************************************************************************
+ * arch/arm/src/armv8-m/arm_pacbticonfig.c
+ *
+ * SPDX-License-Identifier: Apache-2.0
+ *
+ * Licensed to the Apache Software Foundation (ASF) under one or more
+ * contributor license agreements. See the NOTICE file distributed with
+ * this work for additional information regarding copyright ownership. The
+ * ASF licenses this file to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance with the
+ * License. You may obtain a copy of the License at
+ *
+ * http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+ * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+ * License for the specific language governing permissions and limitations
+ * under the License.
+ *
+ ****************************************************************************/
+
+/****************************************************************************
+ * Included Files
+ ****************************************************************************/
+
+#include <nuttx/config.h>
+
+#include <nuttx/irq.h>
+
+/****************************************************************************
+ * Public Functions
+ ****************************************************************************/
+
+/****************************************************************************
+ * Name: arm_pacbticonfig
+ *
+ * Description:
+ * Enable Pointer Authentication and Branch Target Identification in the
+ * current CONTROL state.
+ *
+ ****************************************************************************/
+
+void arm_pacbticonfig(void)
+{
+ uint32_t regval;
+
+ regval = getcontrol();
+ regval |= CONTROL_PACBTI_MASK;
+ setcontrol(regval);
+}
diff --git a/arch/arm/src/armv8-m/arm_schedulesigaction.c
b/arch/arm/src/armv8-m/arm_schedulesigaction.c
index 8a166eff217..9217dd54e2d 100644
--- a/arch/arm/src/armv8-m/arm_schedulesigaction.c
+++ b/arch/arm/src/armv8-m/arm_schedulesigaction.c
@@ -144,7 +144,8 @@ void up_schedule_sigaction(struct tcb_s *tcb)
#ifdef CONFIG_BUILD_PROTECTED
tcb->xcp.regs[REG_LR] = EXC_RETURN_THREAD;
tcb->xcp.regs[REG_EXC_RETURN] = EXC_RETURN_THREAD;
- tcb->xcp.regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+ tcb->xcp.regs[REG_CONTROL] = (getcontrol() & ~CONTROL_NPRIV) |
+ CONTROL_PACBTI_MASK;
#endif
}
}
diff --git a/arch/arm/src/armv8-m/arm_svcall.c
b/arch/arm/src/armv8-m/arm_svcall.c
index 5e7a9276126..6e8204c0016 100644
--- a/arch/arm/src/armv8-m/arm_svcall.c
+++ b/arch/arm/src/armv8-m/arm_svcall.c
@@ -177,7 +177,8 @@ int arm_svcall(int irq, void *context, void *arg)
/* Return unprivileged mode */
- regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV |
+ CONTROL_PACBTI_MASK;
/* Change the parameter ordering to match the expectation of struct
* userpace_s task_startup:
@@ -215,7 +216,8 @@ int arm_svcall(int irq, void *context, void *arg)
/* Return unprivileged mode */
- regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV |
+ CONTROL_PACBTI_MASK;
/* Change the parameter ordering to match the expectation of the
* user space pthread_startup:
@@ -260,7 +262,8 @@ int arm_svcall(int irq, void *context, void *arg)
/* Return unprivileged mode */
- regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV;
+ regs[REG_CONTROL] = getcontrol() | CONTROL_NPRIV |
+ CONTROL_PACBTI_MASK;
/* Change the parameter ordering to match the expectation of struct
* userpace_s signal_handler.
@@ -297,7 +300,8 @@ int arm_svcall(int irq, void *context, void *arg)
/* Return privileged mode */
- regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+ regs[REG_CONTROL] = (getcontrol() & ~CONTROL_NPRIV) |
+ CONTROL_PACBTI_MASK;
rtcb->xcp.sigreturn = 0;
}
break;
@@ -339,7 +343,8 @@ int arm_svcall(int irq, void *context, void *arg)
/* Return privileged mode */
- regs[REG_CONTROL] = getcontrol() & ~CONTROL_NPRIV;
+ regs[REG_CONTROL] = (getcontrol() & ~CONTROL_NPRIV) |
+ CONTROL_PACBTI_MASK;
/* Offset R0 to account for the reserved values */
diff --git a/arch/arm/src/common/arm_initialize.c
b/arch/arm/src/common/arm_initialize.c
index 1d8362c5b68..05cf7844fbd 100644
--- a/arch/arm/src/common/arm_initialize.c
+++ b/arch/arm/src/common/arm_initialize.c
@@ -67,6 +67,12 @@ void up_initialize(void)
arm_initialize_stack();
#endif
+ /* Enable pointer authentication and branch target identification if the
+ * architecture configuration requested it.
+ */
+
+ arm_pacbticonfig();
+
/* Add any extra memory fragments to the memory manager */
arm_addregion();
diff --git a/arch/arm/src/common/arm_internal.h
b/arch/arm/src/common/arm_internal.h
index 16c32751f5e..de1c71af826 100644
--- a/arch/arm/src/common/arm_internal.h
+++ b/arch/arm/src/common/arm_internal.h
@@ -404,6 +404,14 @@ void arm_fpuconfig(void);
# define arm_fpuconfig()
#endif
+/* Pointer Authentication and Branch Target Identification ******************/
+
+#ifdef CONFIG_ARM_PACBTI
+void arm_pacbticonfig(void);
+#else
+# define arm_pacbticonfig()
+#endif
+
/* Low level serial output **************************************************/
void arm_lowputc(char ch);