Skip to content

Adding Vector Context xtest - #827

Open
dave-patel-riscstar wants to merge 3 commits into
OP-TEE:masterfrom
dave-patel-riscstar:rp022-m7-vec
Open

Adding Vector Context xtest#827
dave-patel-riscstar wants to merge 3 commits into
OP-TEE:masterfrom
dave-patel-riscstar:rp022-m7-vec

Conversation

@dave-patel-riscstar

@dave-patel-riscstar dave-patel-riscstar commented Aug 27, 2026

Copy link
Copy Markdown

The xtest changes are for Vector Context Switch Testing used for Vector State changes

@dave-patel-riscstar

Copy link
Copy Markdown
Author

D/TA: TA_CreateEntryPoint:20 TA_CreateEntryPoint
D/TA: TA_OpenSessionEntryPoint:38 TA_OpenSessionEntryPoint
F/TC:? 0 trace_syscall:147 syscall #10 (syscall_unmask_cancellation)
I/TA: TA: Initialising Vector registers with test pattern...
I/TA: Dave TA: Before Context Switch
I/TA: Dave TA: GetSystemTime force a context switch...
F/TC:? 0 trace_syscall:147 syscall #13 (syscall_get_time)
I/TA: Dave TA: First Resumed. Verifying Vector register integrity...
I/TA: Dave TA: After First Context Switch
I/TA: Dave TA: Sleeping for 50ms to force a context switch...
F/TC:? 0 trace_syscall:147 syscall #13 (syscall_get_time)
I/TA: Dave TA: Second Resumed. Verifying Vector register integrity...
I/TA: Dave TA: After Second Context Switch
I/TA: Dave TA: SUCCESS! Vector context switch verified perfectly.

xtest output

Add riscv_vector_ctx.h, a small library shared by the os_test TA and xtest
for looking at what happens to the vector registers across an excursion
out of the caller.

Unlike the floating-point calling convention, the vector one has no
callee-saved vector registers at all: v0..v31 and the vector CSRs may
legitimately be clobbered by any call. Checking the context across an
ordinary C call therefore proves nothing, which is why
riscv_vector_ctx_syscall() reaches the TEE through a bare ecall with no
compiler-generated code between installing the context and reading it
back. That in turn means the whole register file can be checked rather
than the callee-saved subset the floating-point tests are limited to.

The registers are moved with the whole-register forms vl8r.v and vs8r.v,
which are independent of vtype and vl, and vstart is cleared around the
transfer because those forms honour it. vl, vtype and vcsr are carried
too, so a save or restore which drops the CSRs is caught.

VLEN is discovered at run time from vlenb, so the buffers are sized for
the widest register worth carrying and only the first vlenb bytes of each
register are compared.

The routines are in assembly, emitted from this header rather than a .S
file, so that the TA and xtest share one implementation without either
build growing an assembler rule. The vector ISA is enabled per block with
.option arch, so no -march override is needed anywhere.

Everything is compiled out unless the target has the vector extension.

Signed-off-by: Dave Patel <dave.patel@riscstar.com>
(cherry picked from commit 8e130d0198ffe92947c98843ba38f43696e924c9)
Add TA_OS_TEST_CMD_RISCV_VEC_CONTEXT and the sub-tests behind it.

A TA runs with the vector unit disabled and is given it on the first
vector instruction, or vector CSR access, it executes, so every sub-test
starts by taking that trap. What they then cover is:

  SYSCALL      the whole register file and the vector CSRs across
               TEE_SCN_WAIT, issued through a bare ecall so that nothing
               the compiler generated runs in between; the syscall
               suspends the thread, runs the normal world, and resumes
               through thread_resume_from_rpc()
  CSR_FIRST    reads vlenb before issuing any vector instruction, which
               traps with VS Off exactly as an instruction would, so a
               TEE that decodes only the instructions kills the TA here
               instead of handing it a context; then checks the register
               file it was given is clear
  TAINT        leaves a pattern in the registers and returns
  CHECK_TAINT  reads the registers before writing any of them and fails
               if an earlier TA's pattern is still there

On failure the index of the first register that did not survive is
reported back to the caller, along with vlenb, so a failure says which
register was lost and how wide it was.

Everything returns TEE_ERROR_NOT_SUPPORTED on a target without the
vector extension.

Signed-off-by: Dave Patel <dave.patel@riscstar.com>
(cherry picked from commit 609de38a294ee088eadfa02db822d46d082a29ac)
Drive the os_test sub-tests from xtest and add the checks that can only
be made from the normal world.

Alongside the TA side cases the test holds a pattern in this process'
vector registers across a call into the TEE, run twice: once against a TA
command that uses vector and once against one that does not, since the
TEE puts the normal world context back in the first case and skips the
restore in the second, having never disturbed the registers.

That half needs xtest itself to be built for a hart with the vector
extension, which is a property of the toolchain the normal world was
built with rather than of what the TEE supports. Where it is missing the
two sub-cases are compiled out and the test says so rather than passing
quietly.

A concurrency case runs the syscall sub-test from several threads at
once, since the vector bookkeeping is per OP-TEE thread and one thread's
context must not surface in another.

Signed-off-by: Dave Patel <dave.patel@riscstar.com>
(cherry picked from commit 6a0cc5985a38013734db42d6d5d4ca21a580fd31)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant