77#define pr_fmt (fmt ) KBUILD_MODNAME ": " fmt
88
99#include <linux/arm-smccc.h>
10+ #include <linux/cpuhotplug.h>
1011#include <linux/errno.h>
12+ #include <linux/firmware.h>
1113#include <linux/interrupt.h>
1214#include <linux/io.h>
1315#include <linux/irqdomain.h>
16+ #include <linux/kernel.h>
1417#include <linux/mm.h>
1518#include <linux/module.h>
1619#include <linux/of.h>
@@ -1149,6 +1152,22 @@ static bool optee_msg_api_uid_is_optee_api(optee_invoke_fn *invoke_fn)
11491152 return false;
11501153}
11511154
1155+ #ifdef CONFIG_OPTEE_INSECURE_LOAD_IMAGE
1156+ static bool optee_msg_api_uid_is_optee_image_load (optee_invoke_fn * invoke_fn )
1157+ {
1158+ struct arm_smccc_res res ;
1159+
1160+ invoke_fn (OPTEE_SMC_CALLS_UID , 0 , 0 , 0 , 0 , 0 , 0 , 0 , & res );
1161+
1162+ if (res .a0 == OPTEE_MSG_IMAGE_LOAD_UID_0 &&
1163+ res .a1 == OPTEE_MSG_IMAGE_LOAD_UID_1 &&
1164+ res .a2 == OPTEE_MSG_IMAGE_LOAD_UID_2 &&
1165+ res .a3 == OPTEE_MSG_IMAGE_LOAD_UID_3 )
1166+ return true;
1167+ return false;
1168+ }
1169+ #endif
1170+
11521171static void optee_msg_get_os_revision (optee_invoke_fn * invoke_fn )
11531172{
11541173 union {
@@ -1354,6 +1373,120 @@ static void optee_shutdown(struct platform_device *pdev)
13541373 optee_disable_shm_cache (optee );
13551374}
13561375
1376+ #ifdef CONFIG_OPTEE_INSECURE_LOAD_IMAGE
1377+
1378+ #define OPTEE_FW_IMAGE "optee/tee.bin"
1379+
1380+ static optee_invoke_fn * cpuhp_invoke_fn ;
1381+
1382+ static int optee_cpuhp_probe (unsigned int cpu )
1383+ {
1384+ /*
1385+ * Invoking a call on a CPU will cause OP-TEE to perform the required
1386+ * setup for that CPU. Just invoke the call to get the UID since that
1387+ * has no side effects.
1388+ */
1389+ if (optee_msg_api_uid_is_optee_api (cpuhp_invoke_fn ))
1390+ return 0 ;
1391+ else
1392+ return - EINVAL ;
1393+ }
1394+
1395+ static int optee_load_fw (struct platform_device * pdev ,
1396+ optee_invoke_fn * invoke_fn )
1397+ {
1398+ const struct firmware * fw = NULL ;
1399+ struct arm_smccc_res res ;
1400+ phys_addr_t data_pa ;
1401+ u8 * data_buf = NULL ;
1402+ u64 data_size ;
1403+ u32 data_pa_high , data_pa_low ;
1404+ u32 data_size_high , data_size_low ;
1405+ int rc ;
1406+ int hp_state ;
1407+
1408+ if (!optee_msg_api_uid_is_optee_image_load (invoke_fn ))
1409+ return 0 ;
1410+
1411+ rc = request_firmware (& fw , OPTEE_FW_IMAGE , & pdev -> dev );
1412+ if (rc ) {
1413+ /*
1414+ * The firmware in the rootfs will not be accessible until we
1415+ * are in the SYSTEM_RUNNING state, so return EPROBE_DEFER until
1416+ * that point.
1417+ */
1418+ if (system_state < SYSTEM_RUNNING )
1419+ return - EPROBE_DEFER ;
1420+ goto fw_err ;
1421+ }
1422+
1423+ data_size = fw -> size ;
1424+ /*
1425+ * This uses the GFP_DMA flag to ensure we are allocated memory in the
1426+ * 32-bit space since TF-A cannot map memory beyond the 32-bit boundary.
1427+ */
1428+ data_buf = kmalloc (fw -> size , GFP_KERNEL | GFP_DMA );
1429+ if (!data_buf ) {
1430+ rc = - ENOMEM ;
1431+ goto fw_err ;
1432+ }
1433+ memcpy (data_buf , fw -> data , fw -> size );
1434+ data_pa = virt_to_phys (data_buf );
1435+ reg_pair_from_64 (& data_pa_high , & data_pa_low , data_pa );
1436+ reg_pair_from_64 (& data_size_high , & data_size_low , data_size );
1437+ goto fw_load ;
1438+
1439+ fw_err :
1440+ pr_warn ("image loading failed\n" );
1441+ data_pa_high = 0 ;
1442+ data_pa_low = 0 ;
1443+ data_size_high = 0 ;
1444+ data_size_low = 0 ;
1445+
1446+ fw_load :
1447+ /*
1448+ * Always invoke the SMC, even if loading the image fails, to indicate
1449+ * to EL3 that we have passed the point where it should allow invoking
1450+ * this SMC.
1451+ */
1452+ pr_warn ("OP-TEE image loaded from kernel, this can be insecure" );
1453+ invoke_fn (OPTEE_SMC_CALL_LOAD_IMAGE , data_size_high , data_size_low ,
1454+ data_pa_high , data_pa_low , 0 , 0 , 0 , & res );
1455+ if (!rc )
1456+ rc = res .a0 ;
1457+ if (fw )
1458+ release_firmware (fw );
1459+ kfree (data_buf );
1460+
1461+ if (!rc ) {
1462+ /*
1463+ * We need to initialize OP-TEE on all other running cores as
1464+ * well. Any cores that aren't running yet will get initialized
1465+ * when they are brought up by the power management functions in
1466+ * TF-A which are registered by the OP-TEE SPD. Due to that we
1467+ * can un-register the callback right after registering it.
1468+ */
1469+ cpuhp_invoke_fn = invoke_fn ;
1470+ hp_state = cpuhp_setup_state (CPUHP_AP_ONLINE_DYN , "optee:probe" ,
1471+ optee_cpuhp_probe , NULL );
1472+ if (hp_state < 0 ) {
1473+ pr_warn ("Failed with CPU hotplug setup for OP-TEE" );
1474+ return - EINVAL ;
1475+ }
1476+ cpuhp_remove_state (hp_state );
1477+ cpuhp_invoke_fn = NULL ;
1478+ }
1479+
1480+ return rc ;
1481+ }
1482+ #else
1483+ static inline int optee_load_fw (struct platform_device * pdev ,
1484+ optee_invoke_fn * invoke_fn )
1485+ {
1486+ return 0 ;
1487+ }
1488+ #endif
1489+
13571490static int optee_probe (struct platform_device * pdev )
13581491{
13591492 optee_invoke_fn * invoke_fn ;
@@ -1372,6 +1505,10 @@ static int optee_probe(struct platform_device *pdev)
13721505 if (IS_ERR (invoke_fn ))
13731506 return PTR_ERR (invoke_fn );
13741507
1508+ rc = optee_load_fw (pdev , invoke_fn );
1509+ if (rc )
1510+ return rc ;
1511+
13751512 if (!optee_msg_api_uid_is_optee_api (invoke_fn )) {
13761513 pr_warn ("api uid mismatch\n" );
13771514 return - EINVAL ;
0 commit comments