Milestone 7
Milestone Status
This milestone is delivered. The floating-point context-switch support and its xtest suite are merged upstream; the vector context-switch support and its xtest suite are implemented, validated on RISC-V, and under review upstream.
Background
OP-TEE's architecture-specific trusted-application context management must preserve floating-point and vector registers in addition to the associated control state. Lazy switching is unsuitable because supervisor mode can modify the FS and VS status bits without reliably revealing actual register use across privilege levels. Hidden state changes can cause correctness failures, data leakage, or side-channel exposure. Frequent floating-point and vector use also reduces the expected performance benefit of trapping lazily, making eager save and restore the preferred approach.
Milestone Description
Milestone 7 extends the architecture-specific trusted-application context so that floating-point and vector registers and their associated control state are preserved across context switches.
Milestone Update
The work splits along two features. Each is an OP-TEE core pull request that adds the floating-point or vector context-switch support, paired with an optee_test pull request that adds the xtest case driving it. The floating-point core change and its test are merged upstream; the vector core change and its test are implemented and validated and remain under review.
PR #7951 adds RISC-V floating-point context switching to the OP-TEE thread architecture. It introduces macro-driven assembly routines that save and restore the complete floating-point state — all 32 floating-point registers and fcsr — and preserves secure, non-secure, kernel and user trusted-application contexts across thread switches, system calls and exceptions. A context is handed the floating-point unit on first use: an illegal-instruction trap from a context whose FP unit is still off is taken as that first use, the unit is handed over, and the instruction retries, so no instruction decode is needed. (Reworked from the earlier PR #7872 and PR #7876.)
PR #828 adds regression_1045, which drives the floating-point context switch from a trusted application. Its sub-cases hold a known pattern in the floating-point registers across a syscall, an RPC and a crypto operation, confirm the state is not carried between trusted-application instances, and exercise concurrent contexts.
PR #7961 adds RISC-V vector context switching, replicating the floating-point effort for the vector unit under CFG_RISCV_ISA_V. It adds low-level save and restore of the v registers and the vector CSRs (vl, vtype, vcsr, vstart) and switches the floating-point and vector units independently. The hand-over is progressive and needs no instruction decode: on an illegal-instruction trap from a context with a unit still off, the next off unit is enabled (floating-point first, then vector) and the instruction retries; an instruction that still faults with every unit on is genuinely illegal and the trusted application panics, with no re-fault loop. The shared vector state is gated on CFG_RISCV_ISA_V rather than a compiler macro so the core and the vector code agree on the structure layout in every translation unit.
PR #827 adds regression_1046, the vector counterpart of regression_1045. Its sub-cases hold a known pattern in the vector registers across a syscall, confirm a trusted application can read the vector CSRs, confirm the state is not carried between instances, and exercise concurrent contexts. The test skips automatically when the trusted application was not built for the vector extension.
Review feedback on the vector pull requests has been incorporated: the public interface was collapsed to the unified vfp_enable() / vfp_disable() / vfp_is_enabled() API that handles the vector status bit next to the floating-point one under CFG_RISCV_ISA_V, the instruction decoder was removed in favour of the progressive hand-over described above, and the hand-over path was restricted to the illegal-instruction cause.
Validation
regression_1045 passes on the QEMU RISC-V runtime-test infrastructure established by Milestone 2, with all sub-cases reporting OK and no panics. The case is RISC-V specific and skips cleanly on Arm under QEMUv8, so it does not disturb the existing matrix. It is merged upstream.
regression_1046 passes on the QEMU RISC-V runtime-test infrastructure, with the trusted-application vector context-switch sub-cases reporting OK: a pattern held in the vector registers survives a syscall, a trusted application reads the vector CSRs, the state is not carried between instances, and concurrent contexts are preserved. The core changes build clean with -Werror for RISC-V with CFG_RISCV_ISA_V both enabled and disabled.
Test Instructions
All deliverables are pushed to the RISE optee_os rp022-m7-vec-v2 and RISE optee_test rp022-m7-vec branches, and can be tested via xtest under the buildroot rp022-m7-vec-v2 branch. The vector branch includes the floating-point work, so one build runs both regression_1045 and regression_1046.
# Fetch buildroot code
$ git clone https://gitlab.com/riseproject/riscv-optee/buildroot.git -b rp022-m7-vec-v2
# Build the default config
$ cd buildroot
$ make qemu_riscv64_virt_optee_defconfig
# Build all components
$ make -j$(nproc)
# Start QEMU
# 'make' regenerates start-qemu.sh with a non-vector CPU; add the vector
# extension so the trusted application and the kernel can use it
$ sed -i 's/-cpu rv64,zkr=on /-cpu rv64,zkr=on,v=true,vlen=128,zvkned=on,zvkb=on /' \
output/images/start-qemu.sh
$ ./output/images/start-qemu.sh
# Open a console and telnet to launch the kernel
$ telnet localhost 64320
# Run the relevant xtest after kernel login to verify FP and vector switching
$ xtest 1045 1046
# Or just run all xtest
$ xtest
The floating-point case passes with all sub-cases reporting OK:
| Test case | Sub-case | Result |
|---|---|---|
regression_1045 — Test floating-point context switching | TA context across a syscall | OK |
| TA context across an RPC | OK | |
| TA context across a crypto operation | OK | |
| TA context is not carried between instances | OK | |
| Concurrent TA contexts | OK |
The vector case passes its trusted-application context-switch sub-cases:
| Test case | Sub-case | Result |
|---|---|---|
regression_1046 — Test RISC-V vector context switching | TA context across a syscall | OK |
| TA reads a vector CSR | OK | |
| TA context is not carried between instances | OK | |
| Concurrent TA contexts | OK |
| Count | Failed | |
|---|---|---|
regression_1045 subtests | 17 | 0 |
regression_1046 subtests | 16 | 0 |
| Test cases | 2 | 0 |
The normal-world half of the vector domain switch (the two REE sub-cases) is
exercised only when xtest itself is built for the vector extension; in this
run xtest was built without it, so regression_1046 reports that half as not
checked and runs the trusted-application sub-cases.
Full output:
# xtest 1045 1046
Test ID: 1045
Test ID: 1046
Run test suite with level=0
TEE test application started over default TEE instance
######################################################
#
# regression
#
######################################################
* regression_1045 Test RISC-V floating-point context switching
o regression_1045.1 TA context across a syscall
regression_1045.1 OK
o regression_1045.2 TA context across an RPC
regression_1045.2 OK
o regression_1045.3 TA context across a crypto operation
regression_1045.3 OK
o regression_1045.4 TA context is not carried between instances
regression_1045.4 OK
o regression_1045.5 Concurrent TA contexts
regression_1045.5 OK
regression_1045 OK
* regression_1046 Test RISC-V vector context switching
vlenb 16, VLEN 128
o regression_1046.1 TA context across a syscall
regression_1046.1 OK
o regression_1046.2 TA reads a vector CSR
regression_1046.2 OK
o regression_1046.3 TA context is not carried between instances
regression_1046.3 OK
xtest built without the RISC-V vector extension - the normal world half of the domain switch is not checked
o regression_1046.4 Concurrent TA contexts
regression_1046.4 OK
regression_1046 OK
+-----------------------------------------------------
Result of testsuite regression filtered by "1045":
Result of testsuite regression filtered by "1046":
regression_1045 OK
regression_1046 OK
+-----------------------------------------------------
33 subtests of which 0 failed
2 test cases of which 0 failed
117 test cases were skipped
TEE test application done!
Upstream Submissions
The following OP-TEE upstream submissions relate to this milestone:
| Date Submitted | Submission | Pull Request | Patchset Status |
|---|---|---|---|
| Aug 25, 2026 | RISC-V floating-point context switching (core) | PR #7951 | Committed (commit) |
| Aug 27, 2026 | RISC-V floating-point context-switch xtest (regression 1045) | PR #828 | Committed (commit) |
| Aug 27, 2026 | RISC-V vector context switching (core) | PR #7961 | Under Review |
| Aug 27, 2026 | RISC-V vector context-switch xtest (regression 1046) | PR #827 | Under Review |
Requirements
- Use eager context switching for floating-point and vector state.
- Save and restore the complete floating-point register state required by a trusted application.
- Save and restore the complete vector register state required by a trusted application.
- Preserve the associated floating-point, vector, and status CSRs.
- Do not rely on lazy switching based only on supervisor-controlled FS and VS status.
- Prevent register contents from leaking between trusted-application contexts or across privilege boundaries.
- Validate repeated switches between contexts with distinct floating-point and vector state.
Deliverables
- OP-TEE changes that eagerly save and restore trusted-application floating-point registers.
- OP-TEE changes that eagerly save and restore trusted-application vector registers.
- Tests demonstrating correct state preservation and isolation.