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

Tracking Issue for the #[cmse_nonsecure_entry] attribute #75835

Open
1 of 2 tasks
hug-dev opened this issue Aug 23, 2020 · 7 comments
Open
1 of 2 tasks

Tracking Issue for the #[cmse_nonsecure_entry] attribute #75835

hug-dev opened this issue Aug 23, 2020 · 7 comments
Labels
A-attributes Area: #[attributes(..)] A-codegen Area: Code generation B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-cmse_nonsecure_entry `#![feature(cmse_nonsecure_entry)]` O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state S-tracking-design-concerns Status: There are blocking ❌ design concerns. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.

Comments

@hug-dev
Copy link
Contributor

hug-dev commented Aug 23, 2020

This is a tracking issue for the PR #75810. It was deemed in that PR that a RFC was not necessary because the changes were small.
The feature gate for the issue is #![feature(cmse_nonsecure_entry)].

Description

The cmse_nonsecure_entry attribute is a target-dependent attribute available for thumbv8m targets. It directly maps to the attribute of the same name in LLVM.

It is to be used under the TrustZone-M technology for Armv8-M architecture.

It will modify code generation of Secure entry functions:

  • add a special symbol on the function which is the __acle_se_ prefix and the
    standard function name
  • constrain the number of parameters to avoid using the Non-Secure stack
  • before returning from the function, clear registers that might contain Secure
    information
  • use the BXNS instruction to return

See section 5.4 of ARMv8-M Security Extensions: Requirements on Development Tools - Engineering Specification for more details.

Example

Having a Secure entry function named entry_function:

#![feature(cmse_nonsecure_entry)]

#[no_mangle]
#[cmse_nonsecure_entry]
pub extern "C" fn entry_function(in: u32) -> u32 {
    in + 6
}

With those commands:

$ rustc --emit obj --crate-type lib --target thumbv8m.main-none-eabi function.rs
$ arm-none-eabi-objdump -D function.o

it will emit the following assembly:

00000000 <entry_function>:
   0:   b580            push    {r7, lr}
   2:   466f            mov     r7, sp
   4:   b082            sub     sp, #8
   6:   9001            str     r0, [sp, #4]
   8:   1d81            adds    r1, r0, #6
   a:   460a            mov     r2, r1
   c:   4281            cmp     r1, r0
   e:   9200            str     r2, [sp, #0]
  10:   d30b            bcc.n   2a <entry_function+0x2a>
  12:   e7ff            b.n     14 <entry_function+0x14>
  14:   9800            ldr     r0, [sp, #0]
  16:   b002            add     sp, #8
  18:   e8bd 4080       ldmia.w sp!, {r7, lr}
  1c:   4671            mov     r1, lr
  1e:   4672            mov     r2, lr
  20:   4673            mov     r3, lr
  22:   46f4            mov     ip, lr
  24:   f38e 8800       msr     CPSR_f, lr
  28:   4774            bxns    lr
  2a:   f240 0000       movw    r0, #0
  2e:   f2c0 0000       movt    r0, #0
  32:   f240 0200       movw    r2, #0
  36:   f2c0 0200       movt    r2, #0
  3a:   211c            movs    r1, #28
  3c:   f7ff fffe       bl      0 <_ZN4core9panicking5panic17h5c028258ca2fb3f5E>
  40:   defe            udf     #254    ; 0xfe

You can see from 1c to 24 the clearing of the registers and the BXNS instruction used on 28.

Steps

@hug-dev hug-dev added the C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. label Aug 23, 2020
@jonas-schievink jonas-schievink added B-unstable Blocker: Implemented in the nightly compiler and unstable. O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue. A-attributes Area: #[attributes(..)] A-codegen Area: Code generation labels Aug 23, 2020
@hug-dev
Copy link
Contributor Author

hug-dev commented Sep 30, 2020

Note: the error produced when an entry function require arguments being passed on the stack is currently a LLVM error. It would be better to have this error being thrown out in Rust ABI, for better user experience.

bors added a commit to rust-lang-ci/rust that referenced this issue Sep 30, 2020
…-schievink

Add support for cmse_nonsecure_entry attribute

This pull request adds the `cmse_nonsecure_entry` attribute under an unstable feature.

I was not sure if it was fine for me to send directly the pull-request or if I should submit a RFC first. I was told on Zulip that it was fine to do so but please close it if I need first submit a RFC or follow another process instead.

The `cmse_nonsecure_entry` attribute is a LLVM attribute that will be available in LLVM 11. I plan to rebase on the [upgrade PR](rust-lang#73526) once merged to make this one compile.

This attribute modifies code generation of the function as explained [here](https://developer.arm.com/documentation/ecm0359818/latest/) to make it work with the TrustZone-M hardware feature. This feature is only available on `thumbv8m` targets so I created an error for that if one tries to use this attribute for another target.

I added this attribute in Rust as any other LLVM attribute are added but since this one is target-dependent I am not sure if it was the best thing to do. Please indicate me if you think of other ways, like isolating target-dependent attributes together.

----------------

Tracking issue: rust-lang#75835
@nihalpasham
Copy link

noticed the current implementation only allows FFI functions (or extern "C" functions) to be decorated with the attribute. I'm assuming this is only required because the implementation needs the function to use a C ABI and the function by itself is actually safe (i.e. no unsafe code here). Is my understanding correct?

@hug-dev
Copy link
Contributor Author

hug-dev commented Oct 2, 2020

The reason the C ABI is forced for entry function is because parameters must only be passed using registers and not using memory. See this comment for reference:

Ah, I think we should definitely forbid using this attribute with non-"C" ABI functions then. Since the Rust ABI is unstable, it can pass arguments either directly in registers, or in memory, and that would be a problem here.

This is because depending where the parameters would be in memory, there would be more work needed in LLVM to access them from Secure. For example if they were pushed on to the Non-Secure stack when NS calls the entry functions, LLVM would have to put them onto the Secure stack as a prelude before the actual function executes so that the parameters are where expected 👌

@jonas-schievink jonas-schievink added the F-cmse_nonsecure_entry `#![feature(cmse_nonsecure_entry)]` label Jan 24, 2021
@hug-dev
Copy link
Contributor Author

hug-dev commented Jan 26, 2021

I am thinking now that this could also be implemented as an ABI, similarly than cmse-nonsecure-call. It could even be the same extern symbol let's say extern "C-cmse-nonsecure" that:

  • when put on function declaration, set the function as an entry function, applying the cmse_nonsecure_entry LLVM attribute on it
  • when put on function pointer, set the function pointer as non-secure function call, applying the cmse_nonsecure_call callsite attribute

We already restrict the C ABI for entry functions anyway!

@joshtriplett joshtriplett added the S-tracking-design-concerns Status: There are blocking ❌ design concerns. label Jul 13, 2022
@joshtriplett
Copy link
Member

We discussed this in today's @rust-lang/lang meeting. We felt like an extern "ABI" does make sense for most of the functionality of this. What's left sounds like the generation of a special symbol, and it's not clear if we should have that as a built-in attribute, a library attribute, or something in a crate.

@StefanHri
Copy link

What is the recommended work around to deal with entry functions that require many arguments, e.g., 5x i32 ? Currently, this is causes an error:

error: <unknown>:0:0: in function fkt i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack

@hug-dev
Copy link
Contributor Author

hug-dev commented Apr 13, 2023

What is the recommended work around to deal with entry functions that require many arguments, e.g., 5x i32 ? Currently, this is causes an error:

error: <unknown>:0:0: in function fkt i32 (i32, i32, i32, i32, i32): secure entry function requires arguments on stack

Hey!
It is possible for you to pass pointers to structures containing more data. The only drawback is that you must check in the Secure function that the address is accessible by the Non-Secure code. You can do that with the TestTarget functions.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
A-attributes Area: #[attributes(..)] A-codegen Area: Code generation B-unstable Blocker: Implemented in the nightly compiler and unstable. C-tracking-issue Category: A tracking issue for an RFC or an unstable feature. F-cmse_nonsecure_entry `#![feature(cmse_nonsecure_entry)]` O-Arm Target: 32-bit Arm processors (armv6, armv7, thumb...), including 64-bit Arm in AArch32 state S-tracking-design-concerns Status: There are blocking ❌ design concerns. T-compiler Relevant to the compiler team, which will review and decide on the PR/issue. T-lang Relevant to the language team, which will review and decide on the PR/issue.
Projects
None yet
Development

No branches or pull requests

5 participants