Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support Sendable sessions for use in multithreaded code #120

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions optee-teec/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ optee-teec-macros = { path = "macros" }
libc = "0.2"
uuid = "0.7"
hex = "0.3"
self_cell = { version = "1.0", optional = true }

[features]
owned = ["self_cell"]
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

how about change the feature name to the more accurate name such as owned_session?


[workspace]
members = ['systest']
59 changes: 55 additions & 4 deletions optee-teec/src/context.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,11 @@ use libc;
use optee_teec_sys as raw;
use std::ptr;

#[cfg(feature = "owned")]
use crate::OwnedSession;
#[cfg(feature = "owned")]
use std::sync::Arc;

/// An abstraction of the logical connection between a client application and a
/// TEE.
pub struct Context {
Expand Down Expand Up @@ -68,8 +73,8 @@ impl Context {
/// let mut ctx = Context::new().unwrap();
/// let mut raw_ptr: *mut optee_teec_sys::TEEC_Context = ctx.as_mut_raw_ptr();
/// ```
pub fn as_mut_raw_ptr(&mut self) -> *mut raw::TEEC_Context {
&mut self.raw
pub(crate) fn as_mut_raw_ptr(&self) -> *mut raw::TEEC_Context {
&self.raw as *const _ as *mut _
}

/// Opens a new session with the specified trusted application.
Expand All @@ -83,14 +88,35 @@ impl Context {
/// let uuid = Uuid::parse_str("8abcf200-2450-11e4-abe2-0002a5d5c51b").unwrap();
/// let session = ctx.open_session(uuid).unwrap();
/// ```
pub fn open_session(&mut self, uuid: Uuid) -> Result<Session> {
pub fn open_session(&self, uuid: Uuid) -> Result<Session> {
Session::new(
self,
uuid,
None::<&mut Operation<ParamNone, ParamNone, ParamNone, ParamNone>>,
)
}

#[cfg(feature = "owned")]
/// Opens a new owned session with the specified trusted application.
///
/// The target trusted application is specified by `uuid`.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
/// let mut ctx = Arc::new(Context::new().unwrap());
/// let uuid = Uuid::parse_str("8abcf200-2450-11e4-abe2-0002a5d5c51b").unwrap();
/// let session = ctx.open_owned_session(uuid).unwrap();
/// ```
pub fn open_owned_session(self: Arc<Self>, uuid: Uuid) -> Result<OwnedSession> {
OwnedSession::new(
self,
uuid,
None::<&mut Operation<ParamNone, ParamNone, ParamNone, ParamNone>>,
)
}

/// Opens a new session with the specified trusted application, pass some
/// parameters to TA by an operation.
///
Expand All @@ -106,12 +132,37 @@ impl Context {
/// let session = ctx.open_session_with_operation(uuid, operation).unwrap();
/// ```
pub fn open_session_with_operation<A: Param, B: Param, C: Param, D: Param>(
&mut self,
&self,
uuid: Uuid,
operation: &mut Operation<A, B, C, D>,
) -> Result<Session> {
Session::new(self, uuid, Some(operation))
}

#[cfg(feature = "owned")]
/// Opens a new owned session with the specified trusted application, pass some
/// parameters to TA by an operation.
///
/// The target trusted application is specified by `uuid`.
///
/// # Examples
///
/// ```
/// use std::sync::Arc;
/// let mut ctx = Arc::new(Context::new().unwrap());
/// let uuid = Uuid::parse_str("8abcf200-2450-11e4-abe2-0002a5d5c51b").unwrap();
/// let p0 = ParamValue(42, 0, ParamType::ValueInout);
/// let mut operation = Operation::new(0, p0, ParamNone, ParamNone, ParamNone);
/// let session = ctx.open_session_with_operation(uuid, operation).unwrap();
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

ctx.open_session_with_operation to ctx.open_owned_session_with_operation?

/// ```
pub fn open_owned_session_with_operation<A: Param, B: Param, C: Param, D: Param>(
self: Arc<Self>,
uuid: Uuid,
operation: &mut Operation<A, B, C, D>,
) -> Result<OwnedSession> {
OwnedSession::new(self, uuid, Some(operation))
}

}

impl Drop for Context {
Expand Down
2 changes: 2 additions & 0 deletions optee-teec/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,8 @@ pub use self::error::{Error, ErrorKind, Result};
pub use self::operation::Operation;
pub use self::parameter::{Param, ParamNone, ParamTmpRef, ParamType, ParamTypes, ParamValue};
pub use self::session::{ConnectionMethods, Session};
#[cfg(feature = "owned")]
pub use self::session::OwnedSession;
pub use self::uuid::Uuid;
pub use self::extension::*;
pub use optee_teec_macros::{plugin_init, plugin_invoke};
Expand Down
50 changes: 48 additions & 2 deletions optee-teec/src/session.rs
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@

use libc;
use optee_teec_sys as raw;
#[cfg(feature = "owned")]
use self_cell::self_cell;
#[cfg(feature = "owned")]
use std::sync::Arc;
use std::ptr;
use std::marker;

Expand All @@ -40,16 +44,58 @@ pub enum ConnectionMethods {
LoginGroupApplication,
}

// Sessions are documented as threadsafe in GP. Sessions with non-static lifetimes
// cannot be send because we cannot ensure that their context lives long enough, but
// sessions with 'static lifetime should be Send.
//
// A few ways to construct a session with static lifetime:
// 1. With the "owned" feature, use an `OwnedSession`
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can we have a hello-world example for multi-thread session? It would be great if the example can be tested on our CI

// 2. Use `once_cell::sync::Lazy` or `lazy_static` or anything similar to produce a global context
// 3. Use `Box::leak` or similar to permanently consume heap resources by creating a &'static
// Context
unsafe impl Send for Session<'static> {}

/// Represents a connection between a client application and a trusted application.
pub struct Session<'ctx> {
raw: raw::TEEC_Session,
_marker: marker::PhantomData<&'ctx mut Context>,
_marker: marker::PhantomData<&'ctx Context>,
}

#[cfg(feature = "owned")]
self_cell! {
struct SessionPair {
owner: Arc<Context>,
#[covariant]
dependent: Session,
}
}

/// Represents an owned variant of `Session`, whose Context is reference counted.
#[cfg(feature = "owned")]
pub struct OwnedSession(SessionPair);

#[cfg(feature = "owned")]
impl OwnedSession {
/// Initializes an owned TEE session object with specified context and uuid.
pub fn new<A: Param, B: Param, C: Param, D: Param>(
context: Arc<Context>,
uuid: Uuid,
operation: Option<&mut Operation<A, B, C, D>>,
) -> Result<Self> {
Ok(Self(SessionPair::try_new(context, |context| Session::new(context, uuid, operation))?))
}

/// Provides access to an unowned session, borrowed from the owned version
pub fn session(&self) -> &Session<'_> {
self.0.borrow_dependent()
}

}

impl<'ctx> Session<'ctx> {
/// Initializes a TEE session object with specified context and uuid.
pub fn new<A: Param, B: Param, C: Param, D: Param>(
context: &'ctx mut Context,
context: &'ctx Context,
uuid: Uuid,
operation: Option<&mut Operation<A, B, C, D>>,
) -> Result<Self> {
Expand Down
Loading