Matt
Matt

Reputation: 826

How to interpret ARM's SMC calls?

I have been reading Android's kernel to see how dynamic power management for CPU cores (aka DVFS, DCVS) is being done. The code I found here makes some calls to the following function (defined here) which in turn calls the SMC assembly instruction.

ARM has a document that explains SMC calling convention, but I haven't been able to use it to make sense of the following function. How can I track down the SMC instruction further to see what it actually does based on its input operands?

s32 scm_call_atomic4_3(u32 svc, u32 cmd, u32 arg1, u32 arg2,
        u32 arg3, u32 arg4, u32 *ret1, u32 *ret2)
{
    int ret;
    int context_id;
    register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);
    register u32 r1 asm("r1") = (u32)&context_id;
    register u32 r2 asm("r2") = arg1;
    register u32 r3 asm("r3") = arg2;
    register u32 r4 asm("r4") = arg3;
    register u32 r5 asm("r5") = arg4;
    asm volatile(
        __asmeq("%0", "r0")
        __asmeq("%1", "r1")
        __asmeq("%2", "r2")
        __asmeq("%3", "r0")
        __asmeq("%4", "r1")
        __asmeq("%5", "r2")
        __asmeq("%6", "r3")
#ifdef REQUIRES_SEC
            ".arch_extension sec\n"
#endif
        "smc    #0  @ switch to secure world\n"
        : "=r" (r0), "=r" (r1), "=r" (r2)
        : "r" (r0), "r" (r1), "r" (r2), "r" (r3), "r" (r4), "r" (r5));
    ret = r0;
    if (ret1)
        *ret1 = r1;
    if (ret2)
        *ret2 = r2;
    return r0;
}
EXPORT_SYMBOL(scm_call_atomic4_3);

Upvotes: 4

Views: 12342

Answers (2)

Technologeeks
Technologeeks

Reputation: 7907

A couple of additions and corrections to the above:

  1. the secure world image is often called "TZ" or "TEE" (Trusted Execution Environment), and is, in fact very much software code (not in a chip), but closed source and on a different partition. Exact location varies. Usually it's "tz_a" or "tz_b" (on Qcom, accounting for Android slotted boot), but in Samsung Exynos (excluding Pixel "Tensor"s) it's part of shoot, which is in /dev/sdb

  2. (And also Updating this to AArch64):

    • SMC gets an immediate (16-bit) argument. This may be "0" in some cases, but could also hold a "command" or "command class" if non zero. Samsung is known to use multiple commands this way.

    • The arguments are indeed passed in (what is now) X0-X7.

    • The return value is in X0

  3. Entering the secure world, you can disassemble the TZ image and look first for a set of VBAR_EL3. This is the Vector Base Address Register. In ARM32 it's just an array of 7 entries (uint32_ts), so all it is are unconditional branches to the actual handler. In Aarch64 it is a four level array. Each level contains four 128 byte (= 32 instruction) entries. It's easy to also detect these since unhandled cases will usually HALT (B to same address), and there will be NOP sleds after. If the code for the handler can fit in 32 instructions, it will, else it will B(ranch) to somewhere else.

    The handler for SMC will be at the VBAR level 3 (from lower EL), entry #1 (synchronous error), so at offset 0x400 (math: (2 levels * 4 * 0x80) = 8 x 0x80). (For more on this check https://developer.arm.com/documentation/100933/0100/AArch64-exception-vector-table?lang=en). The SMC "command code" will be in ESR_EL3 (The "Exception Syndrome Register") in bits 0:15. The code indicating it is an SMC will be in bits 26:31. The implementation may either use a switch, dispatch table or if/else as the above answer specified.

  4. final note: SMC can only be invoked from kernel (EL1) or higher. Thus Android's user mode, when it needs SMC, will usually go through a vendor kernel module (read: device driver). E.g. /dev/qseecom, /dev/smcinvoke (Qualcomm), /dev/tee (Mediatek), etc. Since said kernel module is commonly open source, you can find at least some of the SMC codes there.

Upvotes: 0

artless-noise-bye-due2AI
artless-noise-bye-due2AI

Reputation: 22430

The SMC calling conventions is a suggestion from ARM on how to implement cross world API, so that multiple vendors can write code in either world and co-exist with a minimum of incompatibility. At least that is the intent. A vendor (Android/Linux in your case) does not have to do this and may not be able to do this if the secure world does not follow it.

but I haven't been able to use it to make sense of the following function

The SMC instruction is a controlled change from the normal world to the secure monitor. The monitor has it's own vector table and the entry for svc is the SMC call. Registers are 'shared' information between worlds. Normally on a world switch the monitor may swap out all register to some context store. In the SMC case, the register can transfer parameter and return results. This is all this function is doing.

register u32 r0 asm("r0") = SCM_ATOMIC(svc, cmd, 4);

This is a bit field like table 2-1 in the SMC calling conventions document. It is from the normal world Linux to the secure monitor to tell which function (and number of arguments to marshal/keep of four).

register u32 r2 asm("r2") = arg1;
register u32 r3 asm("r3") = arg2;
register u32 r4 asm("r4") = arg3;
register u32 r5 asm("r5") = arg4;

If the ARM ABI is fortuitous, the parameters arg1-arg4 will already be in these register, so no code will be generated. The global context_id (to Linux/Android kernel) is also passed.

How can I track down the SMC instruction further to see what it actually does based on its input operands?

To do that, you need the code to the secure world. My guess is that this is some cell phone and base band, etc. are in the secure world and the code is not available. If you have the secure world code, the monitor vector table will have an SMC entry. This will have a switch (or if/then) based on the r0 or 'cmd' value which selects the particular smc function. A generic smc handler may restore secure world registers/context but keep the four arguements as specified in an r0 bit field.

So probably the answer is you can't trace down what it does. You have to rely on the vendor documents or be lucky enough to have code to the secure world.

Upvotes: 3

Related Questions