Calling OPTEE_SMC_CALL_GET_OS_UUID from driver code

Marc Gonzalez mgonzalez at freebox.fr
Wed Feb 21 08:58:49 PST 2024


On 21/02/2024 08:40, Sumit Garg wrote:

> Hi Marc,
> 
> On Tue, 20 Feb 2024 at 22:59, Marc Gonzalez wrote:
>>
>> Hello,
>>
>> The driver code I'm working on hard-codes
>>
>> #define TEE_SMC_FAST_CALL_VAL(func_num) \
>>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>>             ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
>>
>> #define TEE_SMC_FUNCID_CALLS_UID 0xFF01
>> #define TEE_SMC_CALLS_UID \
>>     ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, \
>>                ARM_SMCCC_OWNER_TRUSTED_OS_END, \
>>                TEE_SMC_FUNCID_CALLS_UID)
>>
>>     arm_smccc_smc(TEE_SMC_CALLS_UID,
>>             0, 0, 0/*is_swap*/, 0, 0, 0, 0, &res);
>>     dev_err(dev, "TEE UID %x %x %x %x\n", res.a0, res.a1, res.a2, res.a3);
>>
>>
>> but it seems I would be required to somehow use
>> OPTEE_SMC_CALL_GET_OS_UUID
>>
>> But it's not exported, and no code seems to use it...?
> 
> Can you describe your use-case to require direct
> OPTEE_SMC_CALL_GET_OS_UUID invocation?

Turns out the GET_OS_UUID call was just debug code to make sure
we were getting the expected reply.

I have removed it from the production code.
Below is the current code.

diff --git a/drivers/staging/media/meson/vdec/vdec_1.c b/drivers/staging/media/meson/vdec/vdec_1.c
index 3fe2de0c9331f..120bb1847aa38 100644
--- a/drivers/staging/media/meson/vdec/vdec_1.c
+++ b/drivers/staging/media/meson/vdec/vdec_1.c
@@ -8,7 +8,10 @@
  */
 
 #include <linux/firmware.h>
+#include <linux/delay.h>
 #include <linux/clk.h>
+#include <linux/arm-smccc.h>
+#include <soc/amlogic/socinfo.h>
 
 #include "vdec_1.h"
 #include "vdec_helpers.h"
@@ -22,6 +25,45 @@
 
 #define MC_SIZE			(4096 * 4)
 
+static int
+vdec_1_load_firmware_optee(struct amvdec_session *sess)
+{
+	struct amvdec_codec_ops *codec_ops = sess->fmt_out->codec_ops;
+	struct amvdec_core *core = sess->core;
+	struct device *dev = core->dev_dec;
+	struct arm_smccc_res res;
+	u32 pixfmt = sess->fmt_out->pixfmt;
+	int fw_id = -1;
+
+#define TEE_SMC_FAST_CALL_VAL(func_num) \
+	ARM_SMCCC_CALL_VAL(ARM_SMCCC_FAST_CALL, ARM_SMCCC_SMC_32, ARM_SMCCC_OWNER_TRUSTED_OS, (func_num))
+
+#define TEE_SMC_FUNCID_LOAD_VIDEO_FW 15
+#define TEE_SMC_LOAD_VIDEO_FW TEE_SMC_FAST_CALL_VAL(TEE_SMC_FUNCID_LOAD_VIDEO_FW)
+#define OPTEE_VDEC_LEGACY 0
+#define VIDEO_DEC_MPEG12 0
+#define VIDEO_DEC_H264 11
+
+	// Load wrong firmware, so that TA will reset hw component for us
+	arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, 1, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
+
+	if (pixfmt == V4L2_PIX_FMT_H264)
+		fw_id = 11;
+
+	if (pixfmt == V4L2_PIX_FMT_MPEG1 || pixfmt == V4L2_PIX_FMT_MPEG2)
+		fw_id = 0;
+
+	arm_smccc_smc(TEE_SMC_LOAD_VIDEO_FW, fw_id, OPTEE_VDEC_LEGACY, 0, 0, 0, 0, 0, &res);
+	dev_info(dev, "Load firmware %d: ret=%d\n", fw_id, res.a0);
+
+	msleep(100);
+
+	if (codec_ops->load_extended_firmware)
+		codec_ops->load_extended_firmware(sess, 0, 0);
+
+	return 0;
+}
+
 static int
 vdec_1_load_firmware(struct amvdec_session *sess, const char *fwname)
 {
@@ -209,7 +251,11 @@ static int vdec_1_start(struct amvdec_session *sess)
 
 	vdec_1_stbuf_power_up(sess);
 
-	ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+	if (meson_get_secure_boot_state() == 1)
+		ret = vdec_1_load_firmware_optee(sess);
+	else
+		ret = vdec_1_load_firmware(sess, sess->fmt_out->firmware_path);
+
 	if (ret)
 		goto stop;
 
@@ -232,6 +278,13 @@ static int vdec_1_start(struct amvdec_session *sess)
 	/* Let the firmware settle */
 	usleep_range(10, 20);
 
+	/*
+	 * When running secure boot, it looks like the codec needs
+	 * more time to settle (perhaps to authenticate the image?)
+	 */
+	if (meson_get_secure_boot_state() == 1)
+		msleep(100);
+
 	return 0;
 
 stop:


>> $ git grep OPTEE_SMC_CALL_GET_OS_UUID
>> Documentation/tee/op-tee.rst:- OPTEE_SMC_CALL_GET_OS_UUID returns the particular OP-TEE implementation, used
>> drivers/tee/optee/optee_smc.h:#define OPTEE_SMC_CALL_GET_OS_UUID \
>>
>> How do I make calls to OP-TEE from driver code?
> 
> The TEE driver API documentation is here [1] and you can refer to the
> existing OP-TEE RNG driver here for reference.
> 
> [1] https://docs.kernel.org/driver-api/tee.html
> [2] https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/tree/drivers/char/hw_random/optee-rng.c

Wow, this looks very different from our code.

Are we not supposed to call arm_smccc_smc() from driver code?
Looks like no one else is calling arm_smccc_smc with an owner
equal to ARM_SMCCC_OWNER_TRUSTED_OS...

Regards




More information about the linux-arm-kernel mailing list