-
Notifications
You must be signed in to change notification settings - Fork 96
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
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 | ||
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 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Linux? Can we abstract this from the REE OS name? There was a problem hiding this comment. Choose a reason for hiding this commentThe 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] |
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
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.
There was a problem hiding this comment.
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!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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
toextid_end
.Maybe we can define TEE extension with a ID range to be additional function ID which are mapping from ARM's commands w0 ?
There was a problem hiding this comment.
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
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
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.