aarch64,fpu,hyp: do not trap CPACR_EL1 acceses

The AArch64 FPU trap helpers were modifying both CPTR_EL2.TFP and
CPTR_EL2.TCPAC when enabling or disabling FPU trapping. However, only
TFP controls trapping of FP/SIMD instructions from EL0/EL1 to EL2.

TCPAC traps accesses to CPACR_EL1 and is unrelated to FPU instruction
execution. Trapping CPACR_EL1 is unnecessary for seL4’s FPU handling
and can interfere with other architectural features that are
controlled via CPACR_EL1.

In particular, CPACR_EL1 is an Architectural Feature Access Control
Register and is not limited to FP/SIMD. For example, Morello uses
CPACR_EL1.CEN to enable CHERI instructions. Trapping CPACR_EL1 via
TCPAC would therefore require special handling or could break guests
that legitimately modify CPACR_EL1 for non-FPU features.

Since seL4 only needs to trap FP/SIMD instructions if FPU is disabled
per TCB/VM, it is sufficient to control CPTR_EL2.TFP alone. Remove the
modification of TCPAC from enableTrapFpu()/disableTrapFpu() and leave
CPACR_EL1 accesses untrapped.

This aligns the implementation with the architectural intent of the
AArch64 FP/SIMD trapping model and avoids assuming that CPACR_EL1 is
used solely for FPU control.

See Issue #1601 for more context and discussion.

Signed-off-by: Hesham Almatary <hesham.almatary@cl.cam.ac.uk>
This commit is contained in:
Hesham Almatary 2026-03-10 08:22:19 +00:00 committed by Indan Zupancic
parent efd9426e17
commit d40bad3a9a

View file

@ -90,7 +90,8 @@ static inline void disableTrapFpu(void)
{
word_t cptr;
MRS("cptr_el2", cptr);
cptr &= ~(BIT(10) | BIT(31));
/* Clear the TFP bit */
cptr &= ~BIT(10);
MSR("cptr_el2", cptr);
isb();
}
@ -128,7 +129,8 @@ static inline void enableTrapFpu(void)
{
word_t cptr;
MRS("cptr_el2", cptr);
cptr |= (BIT(10) | BIT(31));
/* Set the TFP bit */
cptr |= BIT(10);
MSR("cptr_el2", cptr);
/* No ISB because we rely on context switch for synchronisation */
}