Repository: apache/incubator-teaclave-trustzone-sdk
Pull request #179: Fix ctest
Author: login: ivila
Labels: name: bug
description: Something isn't working
name: ci
Created: 2025-04-14T07:17:37Z | Merged: 2025-04-17T01:05:00Z

This PR fix the systest of optee-teec and optee-utee, fixes #168 

Linked issue #168: Systest broken
I tried `cargo build` in [optee-utee/systest](https://github.com/apache/incubator-teaclave-trustzone-sdk/tree/main/optee-utee/systest), and it ends up with some compilation errors:

![Image](https://github.com/user-attachments/assets/5e57654d-f250-4bf2-8aac-3a0674ff6bee)
Additionally,  I found that [ctest](https://crates.io/crates/ctest) has been unmaintained for years and there is a fork [ctest2](https://crates.io/crates/ctest2) 

After making the following modifications, I finally got it to run:
* Changed `ctest@0.2` to `ctest2@0.4`
* Updated the include path from `env::var("TA_DEV_KIT_DIR").unwrap()` to `Path::new(env::var("TA_DEV_KIT_DIR").unwrap().as_str()).join("include")`

I encountered a bunch of errors, and the strangest one is that it generates a weird type called `signed ize_t` in the output file `all.c`.
I'm quite sure it should be `size_t`, so I suspect there are bugs in `ctest2`, but I haven't investigated further.

![Image](https://github.com/user-attachments/assets/d203fed9-d611-4b3a-aa5e-7b015946733b)

Does anyone know how to fix this? Or should we just leave it unfixed and remove it?
Linked issue comments: user: login: ivila
created_at: 2025-04-11T03:33:22Z
body: Found some bugs while trying to fix `ctest`. Includes:

1. In `tee_api.rs`, `TEE_MemMove` doesn't return a value, but our definition does. Same as other functions like `TEE_MemFill`
    https://github.com/apache/incubator-teaclave-trustzone-sdk/blob/4069aacc76185374d7c9bf21240064a2bbbf6102/optee-utee/optee-utee-sys/src/tee_api.rs#L114
4. In `utee_syscall.rs`, the type of the info argument of `_utee_cryp_obj_get_info` should be `utee_object_info`, not `TEE_ObjectInfo`. Same as other functions like `_utee_storage_next_enum`.
    https://github.com/apache/incubator-teaclave-trustzone-sdk/blob/4069aacc76185374d7c9bf21240064a2bbbf6102/optee-utee/optee-utee-sys/src/utee_syscalls.rs#L97
6. In `tee_client_api.rs`, the type definition of `TEEC_SharedMemory` mismatch with [OP-TEE/optee_client](https://github.com/OP-TEE/optee_client/blob/02e7f9213b0d7db9c35ebf1e41e733fc9c5a3f75/libteec/include/tee_client_api.h#L314-L328).
    In `optee_client`, the flags in imp is uint32_t, while our definition is `a Struct with bool and u8`.
    https://github.com/apache/incubator-teaclave-trustzone-sdk/blob/4069aacc76185374d7c9bf21240064a2bbbf6102/optee-teec/optee-teec-sys/src/tee_client_api.rs#L100-L116
    Even if we fix this issue, we'll still face another problem: a mismatch in field offsets starting from the `imp` fields. This happens because we flatten the fields in Rust, whereas in C, they are grouped into an anonymous struct. As a result, there's a 32-bit padding between `the uint32_t flags field` and `the imp anonymous struct field`.
    ![Image](https://github.com/user-attachments/assets/42ea30b7-6b1b-4e0c-81cb-13e51780999d)

author_association: CONTRIBUTOR
user: login: DemesneGH
created_at: 2025-04-11T03:52:22Z
body: > 3\. In `tee_client_api.rs`, the type definition of `TEEC_SharedMemory` mismatch with [OP-TEE/optee_client](https://github.com/OP-TEE/optee_client/blob/02e7f9213b0d7db9c35ebf1e41e733fc9c5a3f75/libteec/include/tee_client_api.h#L314-L328)

Seems this is caused by the API change in OP-TEE, see: https://github.com/OP-TEE/optee_client/commit/3eac340a781c00ccd61b151b0e9c22a8c6e9f9f0#diff-7463e556a75f1ef36e882ad7a06d36772bfc0b1c3721091b6018ef5be3c780eeL323

Maybe we should re-generate the bindings according to the latest GP API C definition.
author_association: CONTRIBUTOR

Diff:
diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index eae52e44..11cf899b 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -22,6 +22,8 @@ defaults:
     shell: bash
 
 jobs:
+  # Cross-compile for ARM64 on an AMD64 host and run unit-tests of (optee-utee
+  # and optee-teec) on AMD64 host.
   build-utee-teec:
     runs-on: ubuntu-latest
     container: yuanz0/teaclave-trustzone-sdk:ubuntu-24.04
@@ -50,6 +52,15 @@ jobs:
           (cd optee-utee && cargo build --target aarch64-unknown-linux-gnu -vv)
           (cd optee-teec && cargo build --target aarch64-unknown-linux-gnu -vv)
 
+  # Cross-compile on AMD64 and run tests in QEMU
+  #
+  # Cross-compile target pairs:
+  # - (arm32 host, arm32 ta)
+  # - (arm32 host, arm64 ta)
+  # - (arm64 host, arm32 ta)
+  # - (arm64 host, arm64 ta)
+  #
+  # Run tests target: (arm64 host, arm64 ta)
   build-and-test-examples:
     runs-on: ubuntu-latest
     container: yuanz0/teaclave-trustzone-sdk:ubuntu-24.04
@@ -93,6 +104,8 @@ jobs:
         run: |
           source environment
           (cd ci && ./ci.sh)
+
+  # Cross-compile for ARM64 on AMD64 and run tests in QEMU
   build-and-test-examples-for-64bit-std-TAs:
     runs-on: ubuntu-latest
     container: yuanz0/teaclave-trustzone-sdk:ubuntu-24.04
@@ -126,6 +139,8 @@ jobs:
           export STD=y
           source environment
           (cd ci && ./ci.sh)
+
+  # Cross-compile for ARM32 on AMD64 and run tests in QEMU
   build-and-test-examples-for-32bit-std-TAs:
     runs-on: ubuntu-latest
     container: yuanz0/teaclave-trustzone-sdk:ubuntu-24.04
@@ -161,6 +176,9 @@ jobs:
           export STD=y
           source environment
           (cd ci && ./ci.sh)
+
+  # Cross-compile for ARM64 on AMD64 and run tests in QEMU, use the check script
+  # in OP-TEE repo.
   OPTEE-repo-build-and-run-examples-64bit-TAs:
     runs-on: ubuntu-latest
     container: yuanz0/teaclave-trustzone-sdk:ubuntu-24.04
@@ -186,6 +204,8 @@ jobs:
           make -j3 toolchains &&
           make -j`nproc` RUST_ENABLE=y check
 
+  # Cross-compile for ARM32 on AMD64 and run tests in QEMU, use the check script
+  # in OP-TEE repo.
   OPTEE-repo-build-and-run-examples-32bit-TAs:
     runs-on: ubuntu-latest
     container: yuanz0/teaclave-trustzone-sdk:ubuntu-24.04
@@ -211,6 +231,29 @@ jobs:
           make -j3 toolchains &&
           make -j`nproc` RUST_ENABLE=y COMPILE_S_USER=32 check
 
+  # Run systest of optee_teec and build systest of optee_utee on ARM64
+  systest:
+    runs-on: ubuntu-24.04-arm
+    container: ghcr.io/ivila/teaclave-trustzone-sdk-ci-runner:ubuntu-24.04
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Prepare Environment
+        run: |
+          # Setup Rust and toolchains
+          ./setup.sh
+          source "$HOME/.cargo/env"
+          # Build optee_os and optee_client for qemu_v8
+          ./build_optee_libraries.sh $HOME
+          # Setup environment
+          export OPTEE_DIR=$HOME
+          source environment
+          # Run systest
+          export LD_LIBRARY_PATH=$LD_LIBRARY_PATH:$OPTEE_DIR/optee_client/export_arm64/usr/lib
+          (cd optee-teec && cargo run -p systest)
+          (cd optee-utee && cargo build -p systest)
+
   license:
     runs-on: ubuntu-latest
     steps:
diff --git a/optee-teec/optee-teec-sys/src/tee_client_api.rs b/optee-teec/optee-teec-sys/src/tee_client_api.rs
index 0e04ce1c..79ee42b6 100644
--- a/optee-teec/optee-teec-sys/src/tee_client_api.rs
+++ b/optee-teec/optee-teec-sys/src/tee_client_api.rs
@@ -74,15 +74,21 @@ pub const TEEC_LOGIN_APPLICATION: u32       = 0x00000004;
 pub const TEEC_LOGIN_USER_APPLICATION: u32  = 0x00000005;
 pub const TEEC_LOGIN_GROUP_APPLICATION: u32 = 0x00000006;
 
+#[allow(non_camel_case_types)]
 pub type TEEC_Result = u32;
 
 #[repr(C)]
-pub struct TEEC_Context {
+pub struct TEEC_Context__Imp {
     pub fd: c_int,
     pub reg_mem: bool,
     pub memref_null: bool,
 }
 
+#[repr(C)]
+pub struct TEEC_Context {
+    pub imp: TEEC_Context__Imp,
+}
+
 #[repr(C)]
 pub struct TEEC_UUID {
     pub timeLow: u32,
@@ -92,27 +98,31 @@ pub struct TEEC_UUID {
 }
 
 #[repr(C)]
-pub struct TEEC_Session {
+pub struct TEEC_Session__Imp {
     pub ctx: *mut TEEC_Context,
     pub session_id: u32,
 }
 
 #[repr(C)]
-pub union SharedMemoryFlagsCompat {
-    dummy: bool,
-    flags: u8,
+pub struct TEEC_Session {
+    pub imp: TEEC_Session__Imp,
 }
 
 #[repr(C)]
-pub struct TEEC_SharedMemory {
-    pub buffer: *mut c_void,
-    pub size: size_t,
-    pub flags: u32,
+pub struct TEEC_SharedMemory__Imp {
     pub id: c_int,
     pub alloced_size: size_t,
     pub shadow_buffer: *mut c_void,
     pub registered_fd: c_int,
-    pub internal: SharedMemoryFlagsCompat,
+    pub flags: u32,
+}
+
+#[repr(C)]
+pub struct TEEC_SharedMemory {
+    pub buffer: *mut c_void,
+    pub size: size_t,
+    pub flags: u32,
+    pub imp: TEEC_SharedMemory__Imp,
 }
 
 #[derive(Copy, Clone)]
@@ -145,12 +155,17 @@ pub union TEEC_Parameter {
     pub value: TEEC_Value,
 }
 
+#[repr(C)]
+pub struct TEEC_Operation__Imp {
+    pub session: *mut TEEC_Session,
+}
+
 #[repr(C)]
 pub struct TEEC_Operation {
     pub started: u32,
     pub paramTypes: u32,
     pub params: [TEEC_Parameter; TEEC_CONFIG_PAYLOAD_REF_COUNT as usize],
-    pub session: *mut TEEC_Session,
+    pub imp: TEEC_Operation__Imp,
 }
 
 extern "C" {
diff --git a/optee-teec/src/context.rs b/optee-teec/src/context.rs
index 78fd9c2c..6480bdab 100644
--- a/optee-teec/src/context.rs
+++ b/optee-teec/src/context.rs
@@ -56,12 +56,9 @@ impl Context {
     /// # }
     /// ```
     pub fn new() -> Result<Context> {
-        // define an empty TEEC_Context
-        let mut raw_ctx = raw::TEEC_Context {
-            fd: 0,
-            reg_mem: false,
-            memref_null: false,
-        };
+        // SAFETY:
+        // raw_ctx is a C struct(TEEC_Context), which zero value is valid.
+        let mut raw_ctx = unsafe { std::mem::zeroed() };
         match unsafe { raw::TEEC_InitializeContext(ptr::null_mut(), &mut raw_ctx) } {
             raw::TEEC_SUCCESS => Ok(Self {
                 raw: Rc::new(RefCell::new(InnerContext(raw_ctx))),
diff --git a/optee-teec/src/session.rs b/optee-teec/src/session.rs
index 8a24bc51..98bab425 100644
--- a/optee-teec/src/session.rs
+++ b/optee-teec/src/session.rs
@@ -58,11 +58,9 @@ impl Session {
         uuid: Uuid,
         operation: Option<&mut Operation<A, B, C, D>>,
     ) -> Result<Self> {
-        // define an empty TEEC_Session
-        let mut raw_session = raw::TEEC_Session {
-            ctx: ptr::null_mut(),
-            session_id: 0,
-        };
+        // SAFETY:
+        // raw_session is a C struct(TEEC_Session), which zero value is valid.
+        let mut raw_session = unsafe { std::mem::zeroed() };
         // define all parameters for raw::TEEC_OpenSession outside of the unsafe
         // block to maximize Rust's safety checks and leverage the compiler's
         // validation.
diff --git a/optee-teec/systest/Cargo.toml b/optee-teec/systest/Cargo.toml
index f173d6ef..498f1c19 100644
--- a/optee-teec/systest/Cargo.toml
+++ b/optee-teec/systest/Cargo.toml
@@ -29,4 +29,4 @@ optee-teec-sys = { path = "../optee-teec-sys" }
 libc = "0.2"
 
 [build-dependencies]
-ctest = "0.2"
+ctest = "0.4"
diff --git a/optee-teec/systest/build.rs b/optee-teec/systest/build.rs
index e2a76cec..22248a70 100644
--- a/optee-teec/systest/build.rs
+++ b/optee-teec/systest/build.rs
@@ -15,15 +15,38 @@
 // specific language governing permissions and limitations
 // under the License.
 
-use std::env;
+use std::{env, path::PathBuf};
 
 fn main() {
     let mut cfg = ctest::TestGenerator::new();
-    cfg.target("aarch64-unknown-linux-gnu")
-       .header("tee_client_api.h")
-       .include(env::var("OPTEE_CLIENT_EXPORT").unwrap())
-       .type_name(|s, _is_struct, _is_union| {
-            s.to_string()
-    });
+    let path = {
+        let mut tmp = PathBuf::from(env::var("OPTEE_CLIENT_EXPORT").unwrap());
+        tmp.push("usr/include");
+        tmp
+    };
+    cfg.language(ctest::Lang::C)
+        .target("aarch64-unknown-linux-gnu")
+        .header("tee_client_api.h")
+        .include(path.display().to_string())
+        .type_name(|s, _is_struct, _is_union| s.to_string())
+        .field_name(|_s, field| {
+            if field.starts_with("imp__") {
+                return format!("imp.{}", field.strip_prefix("imp__").expect("must ok"));
+            }
+            field.to_string()
+        })
+        .skip_struct(|s| s.ends_with("__Imp"))
+        // The roundtrip implementation in ctest doesn't work with nested
+        // structs —it treats all bytes of TEEC_Session as if there’s no
+        // padding, which causes a mismatch in the last 4 padding bytes
+        // during the roundtrip test.
+        .skip_roundtrip(|s| s == "TEEC_Session")
+        .skip_field_type(|s, field| {
+            (s == "TEEC_SharedMemory"
+                || s == "TEEC_Context"
+                || s == "TEEC_Session"
+                || s == "TEEC_Operation")
+                && field == "imp"
+        });
     cfg.generate("../optee-teec-sys/src/lib.rs", "all.rs");
 }
diff --git a/optee-utee/optee-utee-sys/Cargo.toml b/optee-utee/optee-utee-sys/Cargo.toml
index dd3aa190..a6500740 100644
--- a/optee-utee/optee-utee-sys/Cargo.toml
+++ b/optee-utee/optee-utee-sys/Cargo.toml
@@ -23,4 +23,7 @@ license = "Apache-2.0"
 repository = "https://github.com/apache/incubator-teaclave-trustzone-sdk.git"
 description = "Native bindings to the libutee library."
 edition = "2018"
-links = "utee"
\ No newline at end of file
+links = "utee"
+
+[dependencies]
+libc = "0.2"
diff --git a/optee-utee/optee-utee-sys/src/lib.rs b/optee-utee/optee-utee-sys/src/lib.rs
index 20dab506..6847a6b6 100644
--- a/optee-utee/optee-utee-sys/src/lib.rs
+++ b/optee-utee/optee-utee-sys/src/lib.rs
@@ -16,7 +16,6 @@
 // under the License.
 
 #![cfg_attr(not(target_os = "optee"), no_std)]
-#![feature(c_size_t)]
 #![allow(non_camel_case_types, non_snake_case)]
 
 pub use tee_api::*;
@@ -44,3 +43,17 @@ mod user_ta_header;
 mod utee_syscalls;
 mod utee_types;
 mod tee_ipsocket;
+
+// Currently, the libc crate does not support optee_os, and patching it in
+// Xargo.toml within the TA project does not affect optee-utee-sys. Therefore,
+// we need to define the type directly in the crate to ensure compatibility.
+#[cfg(target_os = "optee")]
+mod libc_compat {
+    pub type size_t = usize;
+    pub type intmax_t = i64;
+}
+
+#[cfg(not(target_os = "optee"))]
+mod libc_compat {
+    pub use libc::{size_t, intmax_t};
+}
diff --git a/optee-utee/optee-utee-sys/src/tee_api.rs b/optee-utee/optee-utee-sys/src/tee_api.rs
index 966cd30c..ac2c8fb9 100644
--- a/optee-utee/optee-utee-sys/src/tee_api.rs
+++ b/optee-utee/optee-utee-sys/src/tee_api.rs
@@ -16,6 +16,7 @@
 // under the License.
 
 use super::*;
+use crate::libc_compat::{intmax_t, size_t};
 use core::ffi::*;
 
 extern "C" {
@@ -111,13 +112,9 @@ extern "C" {
     pub fn TEE_Malloc(size: usize, hint: u32) -> *mut c_void;
     pub fn TEE_Realloc(buffer: *mut c_void, newSize: usize) -> *mut c_void;
     pub fn TEE_Free(buffer: *mut c_void);
-    pub fn TEE_MemMove(dest: *mut c_void, src: *const c_void, size: usize) -> *mut c_void;
-    pub fn TEE_MemCompare(
-        buffer1: *const c_void,
-        buffer2: *const c_void,
-        size: usize,
-    ) -> i32;
-    pub fn TEE_MemFill(buff: *mut c_void, x: u32, size: usize) -> *mut c_void;
+    pub fn TEE_MemMove(dest: *mut c_void, src: *const c_void, size: usize);
+    pub fn TEE_MemCompare(buffer1: *const c_void, buffer2: *const c_void, size: usize) -> i32;
+    pub fn TEE_MemFill(buff: *mut c_void, x: u32, size: usize);
 
     // Data and Key Storage API  - Generic Object Functions
 
@@ -241,7 +238,7 @@ extern "C" {
     pub fn TEE_TruncateObjectData(object: TEE_ObjectHandle, size: usize) -> TEE_Result;
     pub fn TEE_SeekObjectData(
         object: TEE_ObjectHandle,
-        offset: i32, //intmax_t
+        offset: intmax_t,
         whence: TEE_Whence,
     ) -> TEE_Result;
 
@@ -275,10 +272,7 @@ extern "C" {
         dstOperation: TEE_OperationHandle,
         srcOperation: TEE_OperationHandle,
     ) -> c_void;
-    pub fn TEE_IsAlgorithmSupported(
-        algId: u32,
-        element: u32, 
-    ) -> TEE_Result;
+    pub fn TEE_IsAlgorithmSupported(algId: u32, element: u32) -> TEE_Result;
 
     // Cryptographic Operations API - Message Digest Functions
 
@@ -319,11 +313,7 @@ extern "C" {
 
     // Cryptographic Operations API - MAC Functions
 
-    pub fn TEE_MACInit(
-        operation: TEE_OperationHandle,
-        IV: *const c_void,
-        IVLen: usize,
-    ) -> c_void;
+    pub fn TEE_MACInit(operation: TEE_OperationHandle, IV: *const c_void, IVLen: usize) -> c_void;
     pub fn TEE_MACUpdate(
         operation: TEE_OperationHandle,
         chunk: *const c_void,
@@ -483,11 +473,11 @@ extern "C" {
     pub fn TEE_BigIntShiftRight(
         dest: *mut TEE_BigInt,
         op: *const TEE_BigInt,
-        bits: c_size_t,
+        bits: size_t,
     ) -> c_void;
     pub fn TEE_BigIntGetBit(src: *const TEE_BigInt, bitIndex: u32) -> bool;
     pub fn TEE_BigIntGetBitCount(src: *const TEE_BigInt) -> u32;
-    pub fn TEE_BigIntSetBit(src: *const TEE_BigInt, bitIndex: u32, value: bool) -> TEE_Result;
+    pub fn TEE_BigIntSetBit(src: *mut TEE_BigInt, bitIndex: u32, value: bool) -> TEE_Result;
     pub fn TEE_BigIntAssign(dest: *mut TEE_BigInt, src: *const TEE_BigInt) -> TEE_Result;
     pub fn TEE_BigIntAbs(dest: *mut TEE_BigInt, src: *const TEE_BigInt) -> TEE_Result;
     pub fn TEE_BigIntAdd(
diff --git a/optee-utee/optee-utee-sys/src/tee_api_types.rs b/optee-utee/optee-utee-sys/src/tee_api_types.rs
index 6d2da31f..da95338f 100644
--- a/optee-utee/optee-utee-sys/src/tee_api_types.rs
+++ b/optee-utee/optee-utee-sys/src/tee_api_types.rs
@@ -17,8 +17,10 @@
 
 // Common Definitions
 
+use crate::libc_compat::size_t;
 use core::ffi::*;
 
+#[allow(non_camel_case_types)]
 pub type TEE_Result = u32;
 
 #[repr(C)]
@@ -61,34 +63,40 @@ pub union TEE_Param {
 pub struct __TEE_TASessionHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_TASessionHandle = *mut __TEE_TASessionHandle;
 
 #[repr(C)]
 pub struct __TEE_PropSetHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_PropSetHandle = *mut __TEE_PropSetHandle;
 
 #[repr(C)]
 pub struct __TEE_ObjectHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_ObjectHandle = *mut __TEE_ObjectHandle;
 
 #[repr(C)]
 pub struct __TEE_ObjectEnumHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_ObjectEnumHandle = *mut __TEE_ObjectEnumHandle;
 
 #[repr(C)]
 pub struct __TEE_OperationHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_OperationHandle = *mut __TEE_OperationHandle;
 
 // Storage Definitions
 
+#[allow(non_camel_case_types)]
 pub type TEE_ObjectType = u32;
 
 #[repr(C)]
@@ -179,8 +187,11 @@ pub struct TEE_Time {
 
 // TEE Arithmetical APIs
 
+#[allow(non_camel_case_types)]
 pub type TEE_BigInt = u32;
+#[allow(non_camel_case_types)]
 pub type TEE_BigIntFMM = u32;
+#[allow(non_camel_case_types)]
 pub type TEE_BigIntFMMContext = u32;
 
 // Tee Secure Element APIs
@@ -189,21 +200,25 @@ pub type TEE_BigIntFMMContext = u32;
 pub struct __TEE_SEServiceHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_SEServiceHandle = *mut __TEE_SEServiceHandle;
 #[repr(C)]
 pub struct __TEE_SEReaderHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_SEReaderHandle = *mut __TEE_SEReaderHandle;
 #[repr(C)]
 pub struct __TEE_SESessionHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_SESessionHandle = *mut __TEE_SESessionHandle;
 #[repr(C)]
 pub struct __TEE_SEChannelHandle {
     _unused: [u8; 0],
 }
+#[allow(non_camel_case_types)]
 pub type TEE_SEChannelHandle = *mut __TEE_SEChannelHandle;
 
 #[repr(C)]
@@ -216,11 +231,13 @@ pub struct TEE_SEReaderProperties {
 #[repr(C)]
 pub struct TEE_SEAID {
     pub buffer: *mut u8,
-    pub bufferLen: c_size_t,
+    pub bufferLen: size_t,
 }
 
 // Other definitions
+#[allow(non_camel_case_types)]
 pub type TEE_ErrorOrigin = u32;
+#[allow(non_camel_case_types)]
 pub type TEE_Session = *mut c_void;
 
 pub const TEE_MEM_INPUT: u32 = 0x00000001;
diff --git a/optee-utee/optee-utee-sys/src/tee_internal_api_extensions.rs b/optee-utee/optee-utee-sys/src/tee_internal_api_extensions.rs
index 41adc816..90846b11 100644
--- a/optee-utee/optee-utee-sys/src/tee_internal_api_extensions.rs
+++ b/optee-utee/optee-utee-sys/src/tee_internal_api_extensions.rs
@@ -31,7 +31,7 @@ extern "C" {
         uuid: *const TEE_UUID,
         cmd: u32,
         sub_cmd: u32,
-        buf: *mut c_char,
+        buf: *mut c_void,
         len: usize,
         outlen: *mut usize,
     ) -> TEE_Result; 
diff --git a/optee-utee/optee-utee-sys/src/tee_tcpsocket.rs b/optee-utee/optee-utee-sys/src/tee_tcpsocket.rs
index 41acfc06..609c39ce 100644
--- a/optee-utee/optee-utee-sys/src/tee_tcpsocket.rs
+++ b/optee-utee/optee-utee-sys/src/tee_tcpsocket.rs
@@ -22,7 +22,7 @@ pub type TEE_tcpSocket_Setup = TEE_tcpSocket_Setup_s;
 #[repr(C)]
 pub struct TEE_tcpSocket_Setup_s {
     pub ipVersion: TEE_ipSocket_ipVersion,
-    pub server_addr: *const c_char,
+    pub server_addr: *mut c_char,
     pub server_port: u16,
 }
 
diff --git a/optee-utee/optee-utee-sys/src/tee_udpsocket.rs b/optee-utee/optee-utee-sys/src/tee_udpsocket.rs
index c7675e28..3ecf1aff 100644
--- a/optee-utee/optee-utee-sys/src/tee_udpsocket.rs
+++ b/optee-utee/optee-utee-sys/src/tee_udpsocket.rs
@@ -22,7 +22,7 @@ pub type TEE_udpSocket_Setup = TEE_udpSocket_Setup_s;
 #[repr(C)]
 pub struct TEE_udpSocket_Setup_s {
     pub ipVersion: TEE_ipSocket_ipVersion,
-    pub server_addr: *const c_char,
+    pub server_addr: *mut c_char,
     pub server_port: u16,
 }
 
diff --git a/optee-utee/optee-utee-sys/src/utee_syscalls.rs b/optee-utee/optee-utee-sys/src/utee_syscalls.rs
index dfc5c4b6..05abbad0 100644
--- a/optee-utee/optee-utee-sys/src/utee_syscalls.rs
+++ b/optee-utee/optee-utee-sys/src/utee_syscalls.rs
@@ -15,12 +15,14 @@
 // specific language governing permissions and limitations
 // under the License.
 
+use super::utee_types::utee_object_info;
 use super::*;
+use crate::libc_compat::size_t;
 use core::ffi::*;
 
 extern "C" {
     pub fn _utee_return(ret: c_ulong) -> !;
-    pub fn _utee_log(buf: *const c_void, len: c_size_t);
+    pub fn _utee_log(buf: *const c_void, len: size_t);
     pub fn _utee_panic(code: c_ulong);
     pub fn _utee_get_property(
         prop_set: c_ulong,
@@ -52,8 +54,7 @@ extern "C" {
         params: *mut utee_params,
         ret_orig: *mut u32,
     ) -> TEE_Result;
-    pub fn _utee_check_access_rights(flags: u32, buf: *const c_void, len: c_size_t)
-        -> TEE_Result;
+    pub fn _utee_check_access_rights(flags: u32, buf: *const c_void, len: size_t) -> TEE_Result;
     pub fn _utee_get_cancellation_flag(cancel: *mut u32) -> TEE_Result;
     pub fn _utee_unmask_cancellation(old_mask: *mut u32) -> TEE_Result;
     pub fn _utee_mask_cancellation(old_mask: *mut u32) -> TEE_Result;
@@ -69,32 +70,35 @@ extern "C" {
     ) -> TEE_Result;
     pub fn _utee_cryp_state_copy(dst: c_ulong, src: c_ulong) -> TEE_Result;
     pub fn _utee_cryp_state_free(state: c_ulong) -> TEE_Result;
-    pub fn _utee_hash_init(state: c_ulong, iv: *const c_void, iv_len: c_size_t) -> TEE_Result;
-    pub fn _utee_hash_update(state: c_ulong, chunk: *const c_void, chunk_size: c_size_t)
-        -> TEE_Result;
+    pub fn _utee_hash_init(state: c_ulong, iv: *const c_void, iv_len: size_t) -> TEE_Result;
+    pub fn _utee_hash_update(
+        state: c_ulong,
+        chunk: *const c_void,
+        chunk_size: size_t,
+    ) -> TEE_Result;
     pub fn _utee_hash_final(
         state: c_ulong,
         chunk: *const c_void,
-        chunk_size: c_size_t,
+        chunk_size: size_t,
         hash: *mut c_void,
         hash_len: *mut u64,
     ) -> TEE_Result;
-    pub fn _utee_cipher_init(state: c_ulong, iv: *const c_void, iv_len: c_size_t) -> TEE_Result;
+    pub fn _utee_cipher_init(state: c_ulong, iv: *const c_void, iv_len: size_t) -> TEE_Result;
     pub fn _utee_cipher_update(
         state: c_ulong,
         src: *const c_void,
-        src_len: c_size_t,
+        src_len: size_t,
         dest: *mut c_void,
         dest_len: *mut u64,
     ) -> TEE_Result;
     pub fn _utee_cipher_final(
         state: c_ulong,
         src: *const c_void,
-        src_len: c_size_t,
+        src_len: size_t,
         dest: *mut c_void,
         dest_len: *mut u64,
     ) -> TEE_Result;
-    pub fn _utee_cryp_obj_get_info(obj: c_ulong, info: *mut TEE_ObjectInfo) -> TEE_Result;
+    pub fn _utee_cryp_obj_get_info(obj: c_ulong, info: *mut utee_object_info) -> TEE_Result;
     pub fn _utee_cryp_obj_restrict_usage(obj: c_ulong, usage: c_ulong) -> TEE_Result;
     pub fn _utee_cryp_obj_get_attr(
         obj: c_ulong,
@@ -102,8 +106,7 @@ extern "C" {
         buffer: *mut c_void,
         size: *mut u64,
     ) -> TEE_Result;
-    pub fn _utee_cryp_obj_alloc(ttype: c_ulong, max_size: c_ulong, obj: *mut u32)
-        -> TEE_Result;
+    pub fn _utee_cryp_obj_alloc(ttype: c_ulong, max_size: c_ulong, obj: *mut u32) -> TEE_Result;
     pub fn _utee_cryp_obj_close(obj: c_ulong) -> TEE_Result;
     pub fn _utee_cryp_obj_reset(obj: c_ulong) -> TEE_Result;
     pub fn _utee_cryp_obj_populate(
@@ -124,31 +127,31 @@ extern "C" {
         param_count: c_ulong,
         derived_key: c_ulong,
     ) -> TEE_Result;
-    pub fn _utee_cryp_random_number_generate(buf: *mut c_void, blen: c_size_t) -> TEE_Result;
+    pub fn _utee_cryp_random_number_generate(buf: *mut c_void, blen: size_t) -> TEE_Result;
     pub fn _utee_authenc_init(
         state: c_ulong,
         nonce: *const c_void,
-        nonce_len: c_size_t,
-        tag_len: c_size_t,
-        aad_len: c_size_t,
-        payload_len: c_size_t,
+        nonce_len: size_t,
+        tag_len: size_t,
+        aad_len: size_t,
+        payload_len: size_t,
     ) -> TEE_Result;
     pub fn _utee_authenc_update_aad(
         state: c_ulong,
         aad_data: *const c_void,
-        aad_data_len: c_size_t,
+        aad_data_len: size_t,
     ) -> TEE_Result;
     pub fn _utee_authenc_update_payload(
         state: c_ulong,
         src_data: *const c_void,
-        src_len: c_size_t,
+        src_len: size_t,
         dest_data: *mut c_void,
         dest_len: *mut u64,
     ) -> TEE_Result;
     pub fn _utee_authenc_enc_final(
         state: c_ulong,
         src_data: *const c_void,
-        src_len: c_size_t,
+        src_len: size_t,
         dest_data: *mut c_void,
         dest_len: *mut u64,
         tag: *mut c_void,
@@ -157,18 +160,18 @@ extern "C" {
     pub fn _utee_authenc_dec_final(
         state: c_ulong,
         src_data: *const c_void,
-        src_len: c_size_t,
+        src_len: size_t,
         dest_data: *mut c_void,
         dest_len: *mut u64,
         tag: *const c_void,
-        tag_len: c_size_t,
+        tag_len: size_t,
     ) -> TEE_Result;
     pub fn _utee_asymm_operate(
         state: c_ulong,
         params: *const utee_attribute,
         num_params: c_ulong,
         src_data: *const c_void,
-        src_len: c_size_t,
+        src_len: size_t,
         dest_data: *mut c_void,
         dest_len: *mut u64,
     ) -> TEE_Result;
@@ -177,32 +180,32 @@ extern "C" {
         params: *const utee_attribute,
         num_params: c_ulong,
         data: *const c_void,
-        data_len: c_size_t,
+        data_len: size_t,
         sig: *const c_void,
-        sig_len: c_size_t,
+        sig_len: size_t,
     ) -> TEE_Result;
     pub fn _utee_storage_obj_open(
         storage_id: c_ulong,
         object_id: *const c_void,
-        object_id_len: c_size_t,
+        object_id_len: size_t,
         flags: c_ulong,
         obj: *mut u32,
     ) -> TEE_Result;
     pub fn _utee_storage_obj_create(
         storage_id: c_ulong,
         object_id: *const c_void,
-        object_id_len: c_size_t,
+        object_id_len: size_t,
         flags: c_ulong,
         attr: c_ulong,
         data: *const c_void,
-        len: c_size_t,
+        len: size_t,
         obj: *mut u32,
     ) -> TEE_Result;
     pub fn _utee_storage_obj_del(obj: c_ulong) -> TEE_Result;
     pub fn _utee_storage_obj_rename(
         obj: c_ulong,
         new_obj_id: *const c_void,
-        new_obj_id_len: c_size_t,
+        new_obj_id_len: size_t,
     ) -> TEE_Result;
     pub fn _utee_storage_alloc_enum(obj_enum: *mut u32) -> TEE_Result;
     pub fn _utee_storage_free_enum(obj_enum: c_ulong) -> TEE_Result;
@@ -210,20 +213,20 @@ extern "C" {
     pub fn _utee_storage_start_enum(obj_enum: c_ulong, storage_id: c_ulong) -> TEE_Result;
     pub fn _utee_storage_next_enum(
         obj_enum: c_ulong,
-        info: *mut TEE_ObjectInfo,
+        info: *mut utee_object_info,
         obj_id: *mut c_void,
         len: *mut u64,
     ) -> TEE_Result;
     pub fn _utee_storage_obj_read(
         obj: c_ulong,
         data: *mut c_void,
-        len: c_size_t,
+        len: size_t,
         count: *mut u64,
     ) -> TEE_Result;
-    pub fn _utee_storage_obj_write(obj: c_ulong, data: *const c_void, len: c_size_t) -> TEE_Result;
-    pub fn _utee_storage_obj_trunc(obj: c_ulong, len: c_size_t) -> TEE_Result;
+    pub fn _utee_storage_obj_write(obj: c_ulong, data: *const c_void, len: size_t) -> TEE_Result;
+    pub fn _utee_storage_obj_trunc(obj: c_ulong, len: size_t) -> TEE_Result;
     pub fn _utee_storage_obj_seek(obj: c_ulong, offset: i32, whence: c_ulong) -> TEE_Result;
-    pub fn _utee_cache_operation(va: *mut c_void, l: c_size_t, op: c_ulong) -> TEE_Result;
-// unimplemented syscall
-// pub fn utee_gprof_send(buf: *mut c_void, size: c_size_t, id: *mut u32) -> TEE_Result;
+    pub fn _utee_cache_operation(va: *mut c_void, l: size_t, op: c_ulong) -> TEE_Result;
+    // unimplemented syscall
+    // pub fn utee_gprof_send(buf: *mut c_void, size: size_t, id: *mut u32) -> TEE_Result;
 }
diff --git a/optee-utee/optee-utee-sys/src/utee_types.rs b/optee-utee/optee-utee-sys/src/utee_types.rs
index 69430545..2f0f088f 100644
--- a/optee-utee/optee-utee-sys/src/utee_types.rs
+++ b/optee-utee/optee-utee-sys/src/utee_types.rs
@@ -51,3 +51,14 @@ pub struct utee_attribute {
     b: u64,
     attribute_id: u32,
 }
+
+#[repr(C)]
+pub struct utee_object_info {
+    obj_type: u32,
+	obj_size: u32,
+	max_obj_size: u32,
+	obj_usage: u32,
+	data_size: u32,
+	data_pos: u32,
+	handle_flags: u32,
+}
diff --git a/optee-utee/src/object.rs b/optee-utee/src/object.rs
index 5c2bab34..d64c52eb 100644
--- a/optee-utee/src/object.rs
+++ b/optee-utee/src/object.rs
@@ -1369,7 +1369,7 @@ impl PersistentObject {
     /// 2) If the Implementation detects any other error associated with this function which is not
     ///    explicitly associated with a defined return code for this function.
     pub fn seek(&self, offset: i32, whence: Whence) -> Result<()> {
-        match unsafe { raw::TEE_SeekObjectData(self.handle(), offset, whence.into()) } {
+        match unsafe { raw::TEE_SeekObjectData(self.handle(), offset.into(), whence.into()) } {
             raw::TEE_SUCCESS => Ok(()),
             code => Err(Error::from_raw_error(code)),
         }
diff --git a/optee-utee/systest/Cargo.toml b/optee-utee/systest/Cargo.toml
index 4bbd1d99..9f3f080e 100644
--- a/optee-utee/systest/Cargo.toml
+++ b/optee-utee/systest/Cargo.toml
@@ -29,4 +29,5 @@ optee-utee-sys = { path = "../optee-utee-sys" }
 libc = "0.2.59"
 
 [build-dependencies]
-ctest = "0.2"
+ctest = "0.4"
+cc = "1.2.19"
diff --git a/optee-utee/systest/build.rs b/optee-utee/systest/build.rs
index 74369de0..4ef156a6 100644
--- a/optee-utee/systest/build.rs
+++ b/optee-utee/systest/build.rs
@@ -18,24 +18,34 @@
 use std::env;
 use std::fs::File;
 use std::io::Write;
-use std::path::{Path, PathBuf};
-use std::process::Command;
+use std::path::PathBuf;
 
 fn main() {
     let mut cfg = ctest::TestGenerator::new();
-    cfg.target("aarch64-unknown-linux-gnu")
-        .header("tee_api_types.h")
+    let ta_include_path = {
+        let mut tmp_path = PathBuf::from(env::var("TA_DEV_KIT_DIR").unwrap());
+        tmp_path.push("include");
+        tmp_path
+    };
+    cfg.header("tee_api_types.h")
         .header("tee_api_defines.h")
         .header("utee_types.h")
         .header("user_ta_header.h")
         .header("tee_api.h")
         .header("utee_syscalls.h")
-        .include(env::var("TA_DEV_KIT_DIR").unwrap())
+        .header("tee_tcpsocket.h")
+        .header("tee_udpsocket.h")
+        .header("tee_internal_api_extensions.h")
+        .header("__tee_tcpsocket_defines_extensions.h")
+        .include(ta_include_path.display().to_string())
         .type_name(|s, _is_struct, _is_union| {
             if s == "utee_params"
                 || s == "ta_head"
                 || s == "utee_attribute"
+                || s == "utee_object_info"
                 || s == "user_ta_property"
+                || s == "TEE_tcpSocket_Setup_s"
+                || s == "TEE_udpSocket_Setup_s"
             {
                 return format!("struct {}", s);
             }
@@ -48,6 +58,7 @@ fn main() {
             || s.ends_with("Handle")
             || s == "ta_prop"
             || s == "user_ta_property"
+            || s == "TEE_iSocket_s" // untestable due to `const struct`
     });
     cfg.skip_field(|s, field| {
         (s == "ta_head" && field == "entry")
@@ -57,13 +68,15 @@ fn main() {
             || field == "keyInformation"
     });
     cfg.skip_type(|s| s == "Memref" || s == "Value");
-    cfg.skip_fn(|s| s == "TEE_BigIntFMMConvertToBigInt");
+    cfg.skip_fn(|s| s == "TEE_BigIntFMMConvertToBigInt" || s == "__utee_entry");
     cfg.skip_const(|s| s.starts_with("TA_PROP_STR") || s == "TEE_HANDLE_NULL");
     cfg.skip_roundtrip(|s| s.starts_with("TEE_") || s.starts_with("utee_") || s == "ta_head");
+    cfg.skip_static(|s| s == "TEE_tcpSocket" || s == "TEE_udpSocket");
     cfg.generate("../optee-utee-sys/src/lib.rs", "all.rs");
     println!("cargo:rustc-link-lib=static=mbedtls");
     println!("cargo:rustc-link-lib=static=utee");
     println!("cargo:rustc-link-lib=static=utils");
+    println!("cargo:rustc-link-lib=static=dl");
 
     let out_dir = env::var("OUT_DIR").unwrap();
     let undefined_path = PathBuf::from(&out_dir).join("undefined.c");
@@ -72,23 +85,45 @@ fn main() {
     write!(
         buffer,
         "
+        #include <tee_api_types.h>
         void* ta_props = 0;
         void* ta_num_props = 0;
         void* trace_level = 0;
         void* trace_ext_prefix = 0;
-    "
+        void* ta_head = 0;
+        void* ta_heap = 0;
+        size_t ta_heap_size = 0;
+        void TA_DestroyEntryPoint(void) {{}};
+        TEE_Result tee_uuid_from_str(TEE_UUID __unused *uuid, const char __unused *s) {{
+            return TEE_SUCCESS;
+        }};
+        int tahead_get_trace_level(void) {{
+            return 0;
+        }};
+        TEE_Result TA_OpenSessionEntryPoint(uint32_t __unused pt,
+				    TEE_Param __unused params[TEE_NUM_PARAMS],
+				    void __unused **sess_ctx) {{
+            return TEE_SUCCESS;
+        }};
+        void TA_CloseSessionEntryPoint(void *sess __unused) {{}};
+        TEE_Result TA_CreateEntryPoint(void) {{
+	        return TEE_SUCCESS;
+        }}
+        TEE_Result TA_InvokeCommandEntryPoint(void __unused *sess_ctx,
+                    uint32_t __unused cmd_id,
+				    uint32_t __unused pt,
+				    TEE_Param __unused params[TEE_NUM_PARAMS]) {{
+            return TEE_SUCCESS;
+        }};
+     "
     )
     .unwrap();
-    Command::new("aarch64-linux-gnu-gcc")
-        .args(&[undefined_path.to_str().unwrap(), "-c", "-fPIC", "-o"])
-        .arg(&format!("{}/undefined.o", out_dir))
-        .status()
-        .unwrap();
-    Command::new("aarch64-linux-gnu-ar")
-        .args(&["crus", "libundefined.a", "undefined.o"])
-        .current_dir(&Path::new(&out_dir))
-        .status()
-        .unwrap();
+
+    let mut builder = cc::Build::new();
+    builder
+        .include(ta_include_path.display().to_string())
+        .file(&undefined_path.display().to_string())
+        .compile("undefined");
 
     println!("cargo:rustc-link-search=native={}", out_dir);
     println!("cargo:rustc-link-lib=static=undefined");
diff --git a/setup_std_dependencies.sh b/setup_std_dependencies.sh
index fc087662..6f58681e 100755
--- a/setup_std_dependencies.sh
+++ b/setup_std_dependencies.sh
@@ -29,8 +29,8 @@ cargo +stable install xargo
 
 ##########################################
 # initialize submodules: rust / libc
-RUST_COMMIT_ID=7ee181c5199b0769414f0d0fd13f5e959ef84c27
-LIBC_COMMIT_ID=4fa30318ed3175f6ebe22da8f167f9f9b34567c3
+RUST_BRANCH=optee-xargo
+LIBC_BRANCH=optee
 
 if [ -d rust/ ]
 then
@@ -39,14 +39,11 @@ fi
 
 mkdir rust && cd rust
 
-git clone https://github.com/DemesneGH/rust.git && \
+git clone --depth=1 -b $RUST_BRANCH https://github.com/DemesneGH/rust.git && \
 	(cd rust && \
-	git checkout "$RUST_COMMIT_ID" && \
 	git submodule update --init library/stdarch && \
 	git submodule update --init library/backtrace)
 
-git clone https://github.com/DemesneGH/libc.git && \
-	(cd libc && \
-	git checkout "$LIBC_COMMIT_ID")
+git clone --depth=1 -b $LIBC_BRANCH https://github.com/DemesneGH/libc.git
 
 echo "Rust submodules initialized"
diff --git a/tests/test_client_pool.sh b/tests/test_client_pool.sh
index 0569d2bb..176fd9ac 100755
--- a/tests/test_client_pool.sh
+++ b/tests/test_client_pool.sh
@@ -28,8 +28,8 @@ cp ../examples/client_pool-rs/host/target/$TARGET_HOST/release/client_pool-rs sh
 
 # Run script specific commands in QEMU
 run_in_qemu "cp *.ta /lib/optee_armtz/\n"
-run_in_qemu "./client_pool-rs thread -p 2 -c 2\n"
-run_in_qemu "./client_pool-rs async -p 2 -c 2\n"
+run_in_qemu "./client_pool-rs thread -p 2 -c 2 -t 500 -e 2000\n"
+run_in_qemu "./client_pool-rs async -p 2 -c 2 -t 500 -e 2000\n"
 run_in_qemu "^C"
 
 # Script specific checks


Reviews:
user: login: DemesneGH
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T07:48:09Z
user: login: ivila
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T07:52:10Z
user: login: DemesneGH
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T08:08:39Z
user: login: DemesneGH
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:22:24Z
user: login: ivila
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:31:32Z
user: login: DemesneGH
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:44:45Z
user: login: ivila
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:51:50Z
user: login: DemesneGH
state: COMMENTED
author_association: CONTRIBUTOR
submitted_at: 2025-04-16T09:53:10Z

Review comments:
diff_hunk: @@ -211,6 +211,28 @@ jobs:
           make -j3 toolchains &&
           make -j`nproc` RUST_ENABLE=y COMPILE_S_USER=32 check
 
+  systest:
+    runs-on: ubuntu-24.04-arm
+    container: ghcr.io/ivila/teaclave-trustzone-sdk-ci-runner:ubuntu-24.04
path: .github/workflows/ci.yml
user: login: DemesneGH
body: Seems you're using a new image, does our Dockerfile need to change? 
created_at: 2025-04-16T07:48:09Z
author_association: CONTRIBUTOR
diff_hunk: @@ -241,7 +238,7 @@ extern "C" {
     pub fn TEE_TruncateObjectData(object: TEE_ObjectHandle, size: usize) -> TEE_Result;
     pub fn TEE_SeekObjectData(
         object: TEE_ObjectHandle,
-        offset: i32, //intmax_t
+        offset: intmax_t, //intmax_t
path: optee-utee/optee-utee-sys/src/tee_api.rs
user: login: DemesneGH
body: Remove the redundant comment `//intmax_t`
created_at: 2025-04-16T07:50:43Z
author_association: CONTRIBUTOR
diff_hunk: @@ -211,6 +211,28 @@ jobs:
           make -j3 toolchains &&
           make -j`nproc` RUST_ENABLE=y COMPILE_S_USER=32 check
 
+  systest:
+    runs-on: ubuntu-24.04-arm
+    container: ghcr.io/ivila/teaclave-trustzone-sdk-ci-runner:ubuntu-24.04
path: .github/workflows/ci.yml
user: login: ivila
body: > Seems you're using a new image, does our Dockerfile need to change?

No, it uses the same Dockerfile, but this one is built for `linux/arm64`.
It seems that `yuanz0/teaclave-trustzone-sdk:ubuntu-24.04` only built for platform `linux/amd64`.
![image](https://github.com/user-attachments/assets/ff19fbc4-5665-4fba-9639-1efe775ae38b)

created_at: 2025-04-16T07:52:10Z
author_association: CONTRIBUTOR
diff_hunk: @@ -211,6 +211,28 @@ jobs:
           make -j3 toolchains &&
           make -j`nproc` RUST_ENABLE=y COMPILE_S_USER=32 check
 
+  systest:
+    runs-on: ubuntu-24.04-arm
+    container: ghcr.io/ivila/teaclave-trustzone-sdk-ci-runner:ubuntu-24.04
path: .github/workflows/ci.yml
user: login: DemesneGH
body: Got it. Could you help to add some comments on the CI tasks for clarification? Such as:
```
# Cross-compile on AMD64 and run tests in QEMU
build-and-test-examples:

# Run systest of optee_teec and build systest of optee_utee on ARM64
systest:
```
It would help us avoid confusion in the future, as we might forget the differences.
created_at: 2025-04-16T08:08:18Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,11 +57,7 @@ impl Context {
     /// ```
     pub fn new() -> Result<Context> {
         // define an empty TEEC_Context
-        let mut raw_ctx = raw::TEEC_Context {
-            fd: 0,
-            reg_mem: false,
-            memref_null: false,
-        };
+        let mut raw_ctx = unsafe { std::mem::zeroed() };
path: optee-teec/src/context.rs
user: login: DemesneGH
body: Since usage of `unsafe{}` would need a explanation of the safety assumption when we enable `cargo clippy` in the future. I think we need to unify the unsafe usage.
Will all similar initializations use `unsafe { std::mem::zeroed() }` or just fill in default values like this original code?
What's your opinion on it?
created_at: 2025-04-16T09:22:20Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,11 +57,7 @@ impl Context {
     /// ```
     pub fn new() -> Result<Context> {
         // define an empty TEEC_Context
-        let mut raw_ctx = raw::TEEC_Context {
-            fd: 0,
-            reg_mem: false,
-            memref_null: false,
-        };
+        let mut raw_ctx = unsafe { std::mem::zeroed() };
path: optee-teec/src/context.rs
user: login: ivila
body: I prefer using `unsafe { std::mem::zeroed() }` here. While Rust marks this as unsafe because zero isn't a valid bit pattern for all types, we're only applying it to C structs where a zeroed value is always valid (consistent with how we use `memset` in C).

This also avoids unnecessary changes to the `imp` field. While this field (in `TEEC_OPERATION`, `TEEC_Session`, etc) may change over time, we explicitly shouldn't—and don't need to—care about their internal representation.
created_at: 2025-04-16T09:31:32Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,11 +57,7 @@ impl Context {
     /// ```
     pub fn new() -> Result<Context> {
         // define an empty TEEC_Context
-        let mut raw_ctx = raw::TEEC_Context {
-            fd: 0,
-            reg_mem: false,
-            memref_null: false,
-        };
+        let mut raw_ctx = unsafe { std::mem::zeroed() };
path: optee-teec/src/context.rs
user: login: DemesneGH
body: Let's have a SAFETY mark above this line, the format is:
        // SAFETY:
        // some explanation xxxx
        let mut raw_ctx = unsafe { std::mem::zeroed() };
created_at: 2025-04-16T09:44:45Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,11 +57,7 @@ impl Context {
     /// ```
     pub fn new() -> Result<Context> {
         // define an empty TEEC_Context
-        let mut raw_ctx = raw::TEEC_Context {
-            fd: 0,
-            reg_mem: false,
-            memref_null: false,
-        };
+        let mut raw_ctx = unsafe { std::mem::zeroed() };
path: optee-teec/src/context.rs
user: login: ivila
body: Add for `TEEC_Context` and `TEEC_Session`.
created_at: 2025-04-16T09:51:50Z
author_association: CONTRIBUTOR
diff_hunk: @@ -57,11 +57,7 @@ impl Context {
     /// ```
     pub fn new() -> Result<Context> {
         // define an empty TEEC_Context
-        let mut raw_ctx = raw::TEEC_Context {
-            fd: 0,
-            reg_mem: false,
-            memref_null: false,
-        };
+        let mut raw_ctx = unsafe { std::mem::zeroed() };
path: optee-teec/src/context.rs
user: login: DemesneGH
body: LGTM
created_at: 2025-04-16T09:53:10Z
author_association: CONTRIBUTOR

PR comments:
user: login: DemesneGH
created_at: 2025-04-16T08:10:38Z
body: After the tiny comments resolved please feel free to add:
`Reviewed-by: Yuan Zhuang <yuanz@apache.org>`
author_association: CONTRIBUTOR
user: login: DemesneGH
created_at: 2025-04-16T08:14:10Z
body: BTW could the ARM64 image also help on https://github.com/apache/incubator-teaclave-trustzone-sdk/pull/160?
author_association: CONTRIBUTOR
user: login: ivila
created_at: 2025-04-16T08:21:30Z
body: > BTW could the ARM64 image also help on #160?

I'm currently working on this (stuck on the QEMU aarch64 memory expansion issue).

You can review my changes here:: https://github.com/ivila/incubator-teaclave-trustzone-sdk/commit/72145f162dc12ef059f21511d2c2136f49d4c62d

The CI is currently failing due to the expanded memory problem: https://github.com/ivila/incubator-teaclave-trustzone-sdk/actions/runs/14465993903
![image](https://github.com/user-attachments/assets/d58ed467-e54a-470f-ad26-63a445519ac2)

I’ve already fixed this locally after following the documentation you told me here: https://github.com/apache/incubator-teaclave-trustzone-sdk/blob/main/docs/expanding-ta-secure-memory-on-qemuv8.md
author_association: CONTRIBUTOR