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

Added TEE SBI Extension description #106

Open
wants to merge 1 commit 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
Binary file added riscv-sbi-tee1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added riscv-sbi-tee2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
103 changes: 103 additions & 0 deletions riscv-sbi.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -1682,3 +1682,106 @@ Low bits from `mvendorid`.
Low bits is SBI implementation ID. The firmware specific SBI extensions are
for SBI implementations. It provides firmware specific SBI functions which
are defined in the external firmware specification.

== Trusted Execution Environment SBI Extension Space (EID #0x544545 "TEE")
The Trusted Execution Environment Unit Extension divides cpu Execution
Environment into two parts: REE (Rich Execution Environment) and TEE
(Trusted execution environment), As shown in the picture below <<fig_tee1>>.
To enable some applications to perform security-related services,
which are placed in TEE.

[#fig_tee1]
.SBI TEE extensions runtimes
image::riscv-sbi-tee1.png[width=1007,height=464]

Well, one option is REE runs linux, TEE runs optee-os.
When starting a security service, REE needs to convey 8 parameters

Choose a reason for hiding this comment

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

hi @liushiwei007

According to RISCV SBI calling convention(https://github.com/riscv-non-isa/riscv-sbi-doc/blob/master/riscv-sbi.adoc#binary-encoding), a0-a7 is used as parameter between the supervisor and the SEE. a6 is funid, a7: extid.

just like RISCV SBI calling convention, ARM SMC calling convention define parameters passing during SMC exceptions.
(https://documentation-service.arm.com/static/6013e5faeee5236980d08619)
ARM SMC argument passing is x0-x6(or r0-r6 on arch32), x0(or r0) always pass SMC FID(include module name and funid), result is returned in x0-x3.
Arm common parameter is r1-r6, which is same as riscv r0-r5.

So RISCV SBI calling convention a0-a7 is enough for OPTEE,only need to add a2,a3 to result list.

If a5 register is used as security state flag, riscv common data parameter is one less than arm, whether it is sufficient still need to be check. if TEE Extension in opensbi manage the secure state, there is no problem about parameters

thanks!

Copy link
Author

Choose a reason for hiding this comment

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

hi, @matthewgui ,
are you reading 2.6 SMC32/HVC32 argument passing? (https://documentation-service.arm.com/static/6013e5faeee5236980d08619) I see that the document says that R0-R7 is used to pass the argument.
In this case,, one register is missing. The current design is to continue with the ARM-based command code and add the ext id "TEE". These arm commands are processed under the TEE handle, so two riscv registers are used. Unless arm commands are transcoded at the linux driver level or opensbi does not conflict with these commands, riscv's a7 registers are equivalent to arm's a0 register, in which case additional registers may not be used.
On the other hand, state flag management by opensbi is optional.

Choose a reason for hiding this comment

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

hi @liushiwei007 ,
yes, r7 is used for Hypervisor, if using hypervisor, maybe need to encode extid with funcid to a7.

thanks!

Copy link

@gagachang gagachang May 9, 2023

Choose a reason for hiding this comment

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

Unless arm commands are transcoded at the linux driver level or opensbi does not conflict with these commands, riscv's a7 registers are equivalent to arm's a0 register, in which case additional registers may not be used.

Hi @liushiwei007
Do you have any idea about how RISCV's a7 is equivalent to ARM's w0 ?

Seems that each SBI extension has ID range from extid_start to extid_end.
Maybe we can define TEE extension with a ID range to be additional function ID which are mapping from ARM's commands w0 ?

struct sbi_ecall_extension ecall_tee = {
	.extid_start = SBI_EXT_TEE_START,
	.extid_end = SBI_EXT_TEE_END,
	.handle = sbi_ecall_tee_handler,
};

Copy link
Author

Choose a reason for hiding this comment

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

The current design is the same for RISC-V and ARM code at the linux generic level, so the conversion is placed at the architectural level. If pass the value of w0 directly to a7, it will definitely get an error; If you want to convert the value, it is actually feasible, but I worry that the later optee-os function will be added or deleted will involve this part of the modification

Copy link

@gagachang gagachang May 11, 2023

Choose a reason for hiding this comment

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

The current design is the same for RISC-V and ARM code at the linux generic level, so the conversion is placed at the architectural level. If pass the value of w0 directly to a7, it will definitely get an error; If you want to convert the value, it is actually feasible, but I worry that the later optee-os function will be added or deleted will involve this part of the modification

Yes, SMCCC has additional bits such as fast call [30], service call owner [29:24], and function number [15:0].
Maybe we need to define RISC-V own calling convention for optee-os.

to TEE according to optee-os standard,
and TEE needs to return 4 parameters to REE when TEE is finished.
So linux needs to pass 10 parameters to opensbi. I use the a0-a7,
t0, t1 register. the newly added correlation parameters,
one conveying 0x544545 indicating that this is a TEE extension,
and the other conveying the caller status indicating
it is from REE or from TEE. Unlike other SBI extensions contexts saved,
In the tee process, not only sbi_trap_regs but also CSRs of S mode
should be saved including all calls from REE and some calls from TEE.

I added a new structure sbi_save_context, It contains sbi_trap_regs
structure and the csr registers that TEE OS uses in S mode.
[source, C]
----
struct sbi_save_context {
struct sbi_trap_regs regs;
unsigned long sepc;
unsigned long satp;
unsigned long sstatus;
unsigned long sie;
unsigned long stvec;
unsigned long sscratch;
unsigned long scounteren;
unsigned long scause;
unsigned long stval;
unsigned long sip;
};
----
The design needs to define context-saved arrays based on the number of cores.
[source, C]
----
struct sbi_save_context nsec_cpu_context[OPTEED_CORE_COUNT];
struct sbi_save_context sec_cpu_context[OPTEED_CORE_COUNT];
----
nsec_cpu_context holds the context of REE and sec_cpu_context holds the context of TEE.
When REE is called to TEE, opensbi needs to populate the corresponding
nsec_cpu_context structure based on the register value, It then fills registers
according to the sec_cpu_context structure value and enters optee os via the mret instruction.
The optee os calls the ecall instruction to access opensbi after completing its own job.
When TEE is called to REE, opensbi needs to restore the linux context with
Copy link

Choose a reason for hiding this comment

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

Linux? Can we abstract this from the REE OS name?

Copy link
Author

Choose a reason for hiding this comment

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

In fact, yes, but the actual validation of the project is using linux, so the description is somewhat biased.

the value of the nsec_cpu_context structure. In this case, there is no need
to save the optee os context, which is saved when the startup phase returns.
In addition, the entry to optee os is returned on startup.
optee-os has designed nine entry points, three of which have been implemented so far,
and others may be implemented in the future, Therefore, in opensbi also
need to define such a structure and determine which entry to use based on the parameters
[source, C]
----
typedef uint32_t optee_vector_isn_t;
typedef struct optee_vectors {
optee_vector_isn_t yield_smc_entry;
optee_vector_isn_t fast_smc_entry;
optee_vector_isn_t cpu_on_entry;
optee_vector_isn_t cpu_off_entry;
optee_vector_isn_t cpu_resume_entry;
optee_vector_isn_t cpu_suspend_entry;
optee_vector_isn_t fiq_entry;
optee_vector_isn_t system_off_entry;
optee_vector_isn_t system_reset_entry;
} optee_vectors_t;
----

yield_smc_entry means that this function entry optee os will start the thread function
and enter the user state of TEE. It may also switch back to REE with RPC function,
and then return to TEE after REE completes the corresponding function.
For the REE process that sent you this call, it may cause sleep.

fast_smc_entry indicates that this is a quick function that returns after
the optee-os does something, and that it does not cause the caller to sleep.

fiq_entry indicates that a TEE interrupt occurs in the REE environment,
and the TEE needs to be running.

Other entries are not implemented currently.

REE S mode CSRs is derived from linux, and TEE S mode CSRs is derived
from optee os initialization. Upon startup, opensbi will add
a tee_os_init function before sbi_hart_switch_mode.
tee_os_init will jump to optee os for initialization.
The startup address of optee os is configured using configuration items.
After the initialization is complete, it returns to opensbi.
The return parameter holds the optee os entry address of the runtime,
and it gets TEE S mode CSRs. Then go back to the previous execution process
to start linux. The same function is used to boot the secondary hart.
The following figure(<<fig_tee2>>) shows the startup process.

[#fig_tee2]
.SBI TEE extensions boot flow
image::riscv-sbi-tee2.png[width=975,height=527]