SMC

釜底谛听發表於2024-03-21

SMC

In the ARM architecture, synchronous control is transferred between the normal Non-secure state to Secure state through System Monitor Call(SMC) exceptions.
SMC exceptions are genrated by SMC instructions and handled by the Secure Monitor.

SMC Calling Conventions

2 types of calls are defined:

  1. Fast Calls to execute secure operations
  2. Standard Calls to start pre-emptible secure operations

2 calling conventions are defined:

  1. SMC32: can be used by 32bit/64bit client code, passes up to 6 32-bit arguments
  2. SMC64: can only be used by 64bit client code, passes up to 6 64-bit arguments

SMC Function Identifier

SMC Function Identifier(32bits, passed into every SMC call in register R0/W0) defines:

  1. The call type in use
  2. The calling convention in use (SMC32/SMC64)
  3. The secure function to be invoked

Table-1 Bit Usage of SMC Function Identifier

Bit Number Description
31 0: Standard Call (pre-emptible)
1: Fast Call (atomic)
30 0: SMC32 calling convention
1: SMC64 calling convention
29-24 0: ARM architecture calls
1: CPU service calls
2: SIP service calls
3: OEM service calls
4: Standard service calls
5-47: Reserved for future use
48-49: Trusted Application calls
50-63: Trusted OS calls
23-16 Must be zero for all Fast calls(when bit31 is 1)
15-0 Function number within the range call type defined by bits 29-24

SMC32 argument passing

When SMC32 convention is used, SMC instructions take up to 7 32-bit arguments in registers and can return up to 4 32-bit values in registers.

When SMC32 call is made from AArch32:

  • arguments are passed in registers R0-R6
  • Results are return in R0-R3
  • Registers R4-R14 are callee-saved and must be preserved over the SMC call

When SMC32 call is made from AArch64:

  • arguments are passed in registers W0-W6
  • Results are return in W0-W3
  • Registers X18-X30 and stack pointers SP_EL0, SP_ELx are callee-saved and must be preserved over the SMC call

When SMC64 call is made from AArch64:

  • arguments are passed in registers X0-X6
  • Results are return in X0-X3
  • Registers X18-X30 and stack pointers SP_EL0, SP_ELx are callee-saved and must be preserved over the SMC call

SMC immediate value

It's time consuming for 32-bit Secure Monitor code to access the immediate value???. Consequently

  • An SMC immediate value of Zero must be used.
  • All other SMC immediate value are reserved.

Hypervisor Client ID

If an implementation includes a hypervisor or similar supervisory software executing at EL2 then it may be necessary to identify which client operating system the SMC call originated from.

  • A 32-bit hypervisor client ID parameter is defined for SMC calls.
  • In AArch32, the hypervisor client ID is passed in the R7 register.
  • In AArch64, the hypervisor client ID is passed in the W7 register.
  • 0x00000000 is designated for SMC calls from hypervisor itself.
    All SMC calls generated by software executing at EL1 should be trapped by the hypervisor. Identification information should be inserted into R7/W7 before forwarding any SMC call on to the Secure Monitor.
    (Hypervisor Client ID is created within the hypervisor and used to register, reference and de-register client operating systems to a Trusted OS, not corresponding to VMIDs used by the MMU)

(Optional) Trusted OS Session ID

To support multiple sessions within the Trusted OS, it may be necessary to identify multiple instances of the same SMC call.

  • An optional 32-bit Session ID is defined for SMC calls.
  • In AArch32, the Session ID is passed in the R6 register.
  • In AArch64, the Session ID is passed in the W6 register.
    It's expected that the session ID is provided by the Trusted OS, and is used by its clients in subsequent calls.

Tips

  • The working size of the register is identified by its name:
    • Xn All 64-bits used.
    • Wn Lower 32-bits used, upper 32-bits are Zero.

SMC Standard Results

Unknown SMC Function Identifier

The Unknown SMC Function Identifier is 0xFFFFFFFF returned in R0, same for SMC32 and SMC64 calls.
An implementation must return this value when it receives an:

  • SMC call with an unkonwn funciton identifier
  • SMC call for a removed funciton identifier
  • SMC64 call from AArch32 state.

Unique Identification(UID) format

This value identifies the owner of a particular sub-range of the API, and therefore who controls the actions of SMCs in that sub-range. (Folliwng UUID standard, 16-byte string)

UIDs are returned as a single 128-bit value using SMC32 calling convention, in R0-R3(AArch32)/W0-W3(AArch64) registers.(Byte15 is the highest-order byte and stored in R3/W3).

Note: UID's with the first 32 bits set to 0xFFFFFFFF(the value in R0/W0) shall be avoided as they are indistinguishable from Unknown SMC Function ID.

Revision information format

The revision information for a sub-range is defined by a 32-bit major version and a 32-bit minor version. Different major revision values indicate possibly incompatible SMC APIs, for the affected SMC range.
For two revisions, A and B, for which the major revision values are identical, if the minor revision value of revision B is greater than the minor revision value of revision A, then every SMC in the affected range that works in revision A must also work, with a compatible effect, in revision B.
When returned by a call, the major version is returned in R0 or W0 and the minor version is returned in R1 or W1. Such an SMC must use the SMC32 calling convention.
The rules for interface updates are:

  • An SMC function identifier once issued must never be re-used.
  • Additional SMC calls must take a new unused SMC identifier.
  • Calls to removed SMC identifiers must return the Unknown SMC Function Identifier value.
  • Incompatible argument changes cannot be made to an existing SMC call, a new call is required.
  • Major revision number must be incremented when:
    • Any SMC call is removed.
  • Minor revision number must be incremented when:
    • Any SMC call is added.
    • Backwards compatible changes are made to existing function arguments