hc
2023-12-11 d2ccde1c8e90d38cee87a1b0309ad2827f3fd30d
kernel/drivers/tee/optee/core.c
....@@ -1,20 +1,12 @@
1
+// SPDX-License-Identifier: GPL-2.0-only
12 /*
23 * Copyright (c) 2015, Linaro Limited
3
- *
4
- * This software is licensed under the terms of the GNU General Public
5
- * License version 2, as published by the Free Software Foundation, and
6
- * may be copied, distributed, and modified under those terms.
7
- *
8
- * This program is distributed in the hope that it will be useful,
9
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
10
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
11
- * GNU General Public License for more details.
12
- *
134 */
145
156 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
167
178 #include <linux/arm-smccc.h>
9
+#include <linux/crash_dump.h>
1810 #include <linux/errno.h>
1911 #include <linux/io.h>
2012 #include <linux/module.h>
....@@ -26,6 +18,7 @@
2618 #include <linux/tee_drv.h>
2719 #include <linux/types.h>
2820 #include <linux/uaccess.h>
21
+#include <linux/workqueue.h>
2922 #include "optee_private.h"
3023 #include "optee_smc.h"
3124 #include "shm_pool.h"
....@@ -214,7 +207,14 @@
214207
215208 if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
216209 v.gen_caps |= TEE_GEN_CAP_REG_MEM;
210
+ if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
211
+ v.gen_caps |= TEE_GEN_CAP_MEMREF_NULL;
217212 *vers = v;
213
+}
214
+
215
+static void optee_bus_scan(struct work_struct *work)
216
+{
217
+ WARN_ON(optee_enumerate_devices(PTA_CMD_GET_DEVICES_SUPP));
218218 }
219219
220220 static int optee_open(struct tee_context *ctx)
....@@ -240,10 +240,25 @@
240240 kfree(ctxdata);
241241 return -EBUSY;
242242 }
243
- }
244243
244
+ if (!optee->scan_bus_done) {
245
+ INIT_WORK(&optee->scan_bus_work, optee_bus_scan);
246
+ optee->scan_bus_wq = create_workqueue("optee_bus_scan");
247
+ if (!optee->scan_bus_wq) {
248
+ kfree(ctxdata);
249
+ return -ECHILD;
250
+ }
251
+ queue_work(optee->scan_bus_wq, &optee->scan_bus_work);
252
+ optee->scan_bus_done = true;
253
+ }
254
+ }
245255 mutex_init(&ctxdata->mutex);
246256 INIT_LIST_HEAD(&ctxdata->sess_list);
257
+
258
+ if (optee->sec_caps & OPTEE_SMC_SEC_CAP_MEMREF_NULL)
259
+ ctx->cap_memref_null = true;
260
+ else
261
+ ctx->cap_memref_null = false;
247262
248263 ctx->data = ctxdata;
249264 return 0;
....@@ -263,7 +278,8 @@
263278 if (!ctxdata)
264279 return;
265280
266
- shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg), TEE_SHM_MAPPED);
281
+ shm = tee_shm_alloc(ctx, sizeof(struct optee_msg_arg),
282
+ TEE_SHM_MAPPED | TEE_SHM_PRIV);
267283 if (!IS_ERR(shm)) {
268284 arg = tee_shm_get_va(shm, 0);
269285 /*
....@@ -295,8 +311,13 @@
295311
296312 ctx->data = NULL;
297313
298
- if (teedev == optee->supp_teedev)
314
+ if (teedev == optee->supp_teedev) {
315
+ if (optee->scan_bus_wq) {
316
+ destroy_workqueue(optee->scan_bus_wq);
317
+ optee->scan_bus_wq = NULL;
318
+ }
299319 optee_supp_release(&optee->supp);
320
+ }
300321 }
301322
302323 static const struct tee_driver_ops optee_ops = {
....@@ -409,9 +430,35 @@
409430 return true;
410431 }
411432
433
+static struct tee_shm_pool *optee_config_dyn_shm(void)
434
+{
435
+ struct tee_shm_pool_mgr *priv_mgr;
436
+ struct tee_shm_pool_mgr *dmabuf_mgr;
437
+ void *rc;
438
+
439
+ rc = optee_shm_pool_alloc_pages();
440
+ if (IS_ERR(rc))
441
+ return rc;
442
+ priv_mgr = rc;
443
+
444
+ rc = optee_shm_pool_alloc_pages();
445
+ if (IS_ERR(rc)) {
446
+ tee_shm_pool_mgr_destroy(priv_mgr);
447
+ return rc;
448
+ }
449
+ dmabuf_mgr = rc;
450
+
451
+ rc = tee_shm_pool_alloc(priv_mgr, dmabuf_mgr);
452
+ if (IS_ERR(rc)) {
453
+ tee_shm_pool_mgr_destroy(priv_mgr);
454
+ tee_shm_pool_mgr_destroy(dmabuf_mgr);
455
+ }
456
+
457
+ return rc;
458
+}
459
+
412460 static struct tee_shm_pool *
413
-optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm,
414
- u32 sec_caps)
461
+optee_config_shm_memremap(optee_invoke_fn *invoke_fn, void **memremaped_shm)
415462 {
416463 union {
417464 struct arm_smccc_res smccc;
....@@ -426,10 +473,11 @@
426473 struct tee_shm_pool_mgr *priv_mgr;
427474 struct tee_shm_pool_mgr *dmabuf_mgr;
428475 void *rc;
476
+ const int sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
429477
430478 invoke_fn(OPTEE_SMC_GET_SHM_CONFIG, 0, 0, 0, 0, 0, 0, 0, &res.smccc);
431479 if (res.result.status != OPTEE_SMC_RETURN_OK) {
432
- pr_info("shm service not available\n");
480
+ pr_err("static shm service not available\n");
433481 return ERR_PTR(-ENOENT);
434482 }
435483
....@@ -455,28 +503,15 @@
455503 }
456504 vaddr = (unsigned long)va;
457505
458
- /*
459
- * If OP-TEE can work with unregistered SHM, we will use own pool
460
- * for private shm
461
- */
462
- if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM) {
463
- rc = optee_shm_pool_alloc_pages();
464
- if (IS_ERR(rc))
465
- goto err_memunmap;
466
- priv_mgr = rc;
467
- } else {
468
- const size_t sz = OPTEE_SHM_NUM_PRIV_PAGES * PAGE_SIZE;
506
+ rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
507
+ 3 /* 8 bytes aligned */);
508
+ if (IS_ERR(rc))
509
+ goto err_memunmap;
510
+ priv_mgr = rc;
469511
470
- rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, sz,
471
- 3 /* 8 bytes aligned */);
472
- if (IS_ERR(rc))
473
- goto err_memunmap;
474
- priv_mgr = rc;
475
-
476
- vaddr += sz;
477
- paddr += sz;
478
- size -= sz;
479
- }
512
+ vaddr += sz;
513
+ paddr += sz;
514
+ size -= sz;
480515
481516 rc = tee_shm_pool_mgr_alloc_res_mem(vaddr, paddr, size, PAGE_SHIFT);
482517 if (IS_ERR(rc))
....@@ -519,13 +554,13 @@
519554 arm_smccc_hvc(a0, a1, a2, a3, a4, a5, a6, a7, res);
520555 }
521556
522
-static optee_invoke_fn *get_invoke_func(struct device_node *np)
557
+static optee_invoke_fn *get_invoke_func(struct device *dev)
523558 {
524559 const char *method;
525560
526
- pr_info("probing for conduit method from DT.\n");
561
+ pr_info("probing for conduit method.\n");
527562
528
- if (of_property_read_string(np, "method", &method)) {
563
+ if (device_property_read_string(dev, "method", &method)) {
529564 pr_warn("missing \"method\" property\n");
530565 return ERR_PTR(-ENXIO);
531566 }
....@@ -539,47 +574,115 @@
539574 return ERR_PTR(-EINVAL);
540575 }
541576
542
-static struct optee *optee_probe(struct device_node *np)
577
+/* optee_remove - Device Removal Routine
578
+ * @pdev: platform device information struct
579
+ *
580
+ * optee_remove is called by platform subsystem to alert the driver
581
+ * that it should release the device
582
+ */
583
+
584
+static int optee_remove(struct platform_device *pdev)
585
+{
586
+ struct optee *optee = platform_get_drvdata(pdev);
587
+
588
+ /* Unregister OP-TEE specific client devices on TEE bus */
589
+ optee_unregister_devices();
590
+
591
+ teedev_close_context(optee->ctx);
592
+ /*
593
+ * Ask OP-TEE to free all cached shared memory objects to decrease
594
+ * reference counters and also avoid wild pointers in secure world
595
+ * into the old shared memory range.
596
+ */
597
+ optee_disable_shm_cache(optee);
598
+
599
+ /*
600
+ * The two devices have to be unregistered before we can free the
601
+ * other resources.
602
+ */
603
+ tee_device_unregister(optee->supp_teedev);
604
+ tee_device_unregister(optee->teedev);
605
+
606
+ tee_shm_pool_free(optee->pool);
607
+ if (optee->memremaped_shm)
608
+ memunmap(optee->memremaped_shm);
609
+ optee_wait_queue_exit(&optee->wait_queue);
610
+ optee_supp_uninit(&optee->supp);
611
+ mutex_destroy(&optee->call_queue.mutex);
612
+
613
+ kfree(optee);
614
+
615
+ return 0;
616
+}
617
+
618
+/* optee_shutdown - Device Removal Routine
619
+ * @pdev: platform device information struct
620
+ *
621
+ * platform_shutdown is called by the platform subsystem to alert
622
+ * the driver that a shutdown, reboot, or kexec is happening and
623
+ * device must be disabled.
624
+ */
625
+static void optee_shutdown(struct platform_device *pdev)
626
+{
627
+ optee_disable_shm_cache(platform_get_drvdata(pdev));
628
+}
629
+
630
+static int optee_probe(struct platform_device *pdev)
543631 {
544632 optee_invoke_fn *invoke_fn;
545
- struct tee_shm_pool *pool;
633
+ struct tee_shm_pool *pool = ERR_PTR(-EINVAL);
546634 struct optee *optee = NULL;
547635 void *memremaped_shm = NULL;
548636 struct tee_device *teedev;
637
+ struct tee_context *ctx;
549638 u32 sec_caps;
550639 int rc;
551640
552
- invoke_fn = get_invoke_func(np);
641
+ /*
642
+ * The kernel may have crashed at the same time that all available
643
+ * secure world threads were suspended and we cannot reschedule the
644
+ * suspended threads without access to the crashed kernel's wait_queue.
645
+ * Therefore, we cannot reliably initialize the OP-TEE driver in the
646
+ * kdump kernel.
647
+ */
648
+ if (is_kdump_kernel())
649
+ return -ENODEV;
650
+
651
+ invoke_fn = get_invoke_func(&pdev->dev);
553652 if (IS_ERR(invoke_fn))
554
- return (void *)invoke_fn;
653
+ return PTR_ERR(invoke_fn);
555654
556655 if (!optee_msg_api_uid_is_optee_api(invoke_fn)) {
557656 pr_warn("api uid mismatch\n");
558
- return ERR_PTR(-EINVAL);
657
+ return -EINVAL;
559658 }
560659
561660 optee_msg_get_os_revision(invoke_fn);
562661
563662 if (!optee_msg_api_revision_is_compatible(invoke_fn)) {
564663 pr_warn("api revision mismatch\n");
565
- return ERR_PTR(-EINVAL);
664
+ return -EINVAL;
566665 }
567666
568667 if (!optee_msg_exchange_capabilities(invoke_fn, &sec_caps)) {
569668 pr_warn("capabilities mismatch\n");
570
- return ERR_PTR(-EINVAL);
669
+ return -EINVAL;
571670 }
572671
573672 /*
574
- * We have no other option for shared memory, if secure world
575
- * doesn't have any reserved memory we can use we can't continue.
673
+ * Try to use dynamic shared memory if possible
576674 */
577
- if (!(sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
578
- return ERR_PTR(-EINVAL);
675
+ if (sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
676
+ pool = optee_config_dyn_shm();
579677
580
- pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm, sec_caps);
678
+ /*
679
+ * If dynamic shared memory is not available or failed - try static one
680
+ */
681
+ if (IS_ERR(pool) && (sec_caps & OPTEE_SMC_SEC_CAP_HAVE_RESERVED_SHM))
682
+ pool = optee_config_shm_memremap(invoke_fn, &memremaped_shm);
683
+
581684 if (IS_ERR(pool))
582
- return (void *)pool;
685
+ return PTR_ERR(pool);
583686
584687 optee = kzalloc(sizeof(*optee), GFP_KERNEL);
585688 if (!optee) {
....@@ -618,6 +721,12 @@
618721 optee_supp_init(&optee->supp);
619722 optee->memremaped_shm = memremaped_shm;
620723 optee->pool = pool;
724
+ ctx = teedev_open(optee->teedev);
725
+ if (IS_ERR(ctx)) {
726
+ rc = PTR_ERR(ctx);
727
+ goto err;
728
+ }
729
+ optee->ctx = ctx;
621730
622731 /*
623732 * Ensure that there are no pre-existing shm objects before enabling
....@@ -630,8 +739,19 @@
630739
631740 optee_enable_shm_cache(optee);
632741
742
+ if (optee->sec_caps & OPTEE_SMC_SEC_CAP_DYNAMIC_SHM)
743
+ pr_info("dynamic shared memory is enabled\n");
744
+
745
+ platform_set_drvdata(pdev, optee);
746
+
747
+ rc = optee_enumerate_devices(PTA_CMD_GET_DEVICES);
748
+ if (rc) {
749
+ optee_remove(pdev);
750
+ return rc;
751
+ }
752
+
633753 pr_info("initialized driver\n");
634
- return optee;
754
+ return 0;
635755 err:
636756 if (optee) {
637757 /*
....@@ -647,83 +767,29 @@
647767 tee_shm_pool_free(pool);
648768 if (memremaped_shm)
649769 memunmap(memremaped_shm);
650
- return ERR_PTR(rc);
770
+ return rc;
651771 }
652772
653
-static void optee_remove(struct optee *optee)
654
-{
655
- /*
656
- * Ask OP-TEE to free all cached shared memory objects to decrease
657
- * reference counters and also avoid wild pointers in secure world
658
- * into the old shared memory range.
659
- */
660
- optee_disable_shm_cache(optee);
661
-
662
- /*
663
- * The two devices has to be unregistered before we can free the
664
- * other resources.
665
- */
666
- tee_device_unregister(optee->supp_teedev);
667
- tee_device_unregister(optee->teedev);
668
-
669
- tee_shm_pool_free(optee->pool);
670
- if (optee->memremaped_shm)
671
- memunmap(optee->memremaped_shm);
672
- optee_wait_queue_exit(&optee->wait_queue);
673
- optee_supp_uninit(&optee->supp);
674
- mutex_destroy(&optee->call_queue.mutex);
675
-
676
- kfree(optee);
677
-}
678
-
679
-static const struct of_device_id optee_match[] = {
773
+static const struct of_device_id optee_dt_match[] = {
680774 { .compatible = "linaro,optee-tz" },
681775 {},
682776 };
777
+MODULE_DEVICE_TABLE(of, optee_dt_match);
683778
684
-static struct optee *optee_svc;
685
-
686
-static int __init optee_driver_init(void)
687
-{
688
- struct device_node *fw_np;
689
- struct device_node *np;
690
- struct optee *optee;
691
-
692
- /* Node is supposed to be below /firmware */
693
- fw_np = of_find_node_by_name(NULL, "firmware");
694
- if (!fw_np)
695
- return -ENODEV;
696
-
697
- np = of_find_matching_node(fw_np, optee_match);
698
- if (!np || !of_device_is_available(np)) {
699
- of_node_put(np);
700
- return -ENODEV;
701
- }
702
-
703
- optee = optee_probe(np);
704
- of_node_put(np);
705
-
706
- if (IS_ERR(optee))
707
- return PTR_ERR(optee);
708
-
709
- optee_svc = optee;
710
-
711
- return 0;
712
-}
713
-module_init(optee_driver_init);
714
-
715
-static void __exit optee_driver_exit(void)
716
-{
717
- struct optee *optee = optee_svc;
718
-
719
- optee_svc = NULL;
720
- if (optee)
721
- optee_remove(optee);
722
-}
723
-module_exit(optee_driver_exit);
779
+static struct platform_driver optee_driver = {
780
+ .probe = optee_probe,
781
+ .remove = optee_remove,
782
+ .shutdown = optee_shutdown,
783
+ .driver = {
784
+ .name = "optee",
785
+ .of_match_table = optee_dt_match,
786
+ },
787
+};
788
+module_platform_driver(optee_driver);
724789
725790 MODULE_AUTHOR("Linaro");
726791 MODULE_DESCRIPTION("OP-TEE driver");
727792 MODULE_SUPPORTED_DEVICE("");
728793 MODULE_VERSION("1.0");
729794 MODULE_LICENSE("GPL v2");
795
+MODULE_ALIAS("platform:optee");