From 08b823c049c47a9fa4f8e366cdcd0a46182d8c11 Mon Sep 17 00:00:00 2001 From: Tao Huang Date: Thu, 5 Aug 2021 21:42:28 +0800 Subject: [PATCH] Revert "OP-TEE: add optee driver from GitHub: optee_linuxdriver" This reverts commit 8e4b2eda3fcee91ba7aa3c9b444d2c47413ee900. optee_linuxdriver is unused. Signed-off-by: Tao Huang Change-Id: I5d092293ccbc26e77e16a141ffaff85020bb9aaa --- security/optee_linuxdriver/Kconfig | 20 - security/optee_linuxdriver/LICENSE | 339 ---- security/optee_linuxdriver/Makefile | 3 - security/optee_linuxdriver/Notice.md | 4 - security/optee_linuxdriver/README.md | 91 - security/optee_linuxdriver/armtz/Makefile | 43 - security/optee_linuxdriver/armtz/handle.c | 87 - security/optee_linuxdriver/armtz/handle.h | 52 - security/optee_linuxdriver/armtz/tee_mem.c | 677 -------- security/optee_linuxdriver/armtz/tee_mem.h | 50 - .../optee_linuxdriver/armtz/tee_smc-arm.S | 29 - .../optee_linuxdriver/armtz/tee_smc-arm64.S | 36 - security/optee_linuxdriver/armtz/tee_tz_drv.c | 1488 ----------------- security/optee_linuxdriver/armtz/tee_tz_op.h | 270 --- .../optee_linuxdriver/armtz/tee_tz_priv.h | 64 - security/optee_linuxdriver/core/Makefile | 36 - security/optee_linuxdriver/core/tee_context.c | 315 ---- security/optee_linuxdriver/core/tee_core.c | 567 ------- .../optee_linuxdriver/core/tee_core_priv.h | 52 - security/optee_linuxdriver/core/tee_debugfs.c | 85 - security/optee_linuxdriver/core/tee_debugfs.h | 24 - .../optee_linuxdriver/core/tee_kernel_api.c | 255 --- .../optee_linuxdriver/core/tee_mutex_wait.c | 144 -- .../optee_linuxdriver/core/tee_mutex_wait.h | 38 - security/optee_linuxdriver/core/tee_session.c | 858 ---------- security/optee_linuxdriver/core/tee_shm.c | 814 --------- security/optee_linuxdriver/core/tee_shm.h | 34 - .../optee_linuxdriver/core/tee_supp_com.c | 275 --- .../optee_linuxdriver/core/tee_supp_com.h | 117 -- security/optee_linuxdriver/core/tee_sysfs.c | 204 --- security/optee_linuxdriver/core/tee_sysfs.h | 21 - .../optee_linuxdriver/core/tee_wait_queue.c | 86 - .../optee_linuxdriver/core/tee_wait_queue.h | 32 - .../fdts/fvp-foundation-gicv2-psci.dts | 211 --- .../fdts/fvp-foundation-motherboard.dtsi | 197 --- security/optee_linuxdriver/fdts/readme.txt | 2 - .../include/arm_common/teesmc.h | 710 -------- .../include/arm_common/teesmc_st.h | 147 -- .../include/linux/tee_client_api.h | 600 ------- .../include/linux/tee_core.h | 205 --- .../optee_linuxdriver/include/linux/tee_ioc.h | 83 - .../include/linux/tee_kernel_api.h | 174 -- 42 files changed, 9539 deletions(-) delete mode 100644 security/optee_linuxdriver/Kconfig delete mode 100644 security/optee_linuxdriver/LICENSE delete mode 100644 security/optee_linuxdriver/Makefile delete mode 100644 security/optee_linuxdriver/Notice.md delete mode 100644 security/optee_linuxdriver/README.md delete mode 100644 security/optee_linuxdriver/armtz/Makefile delete mode 100644 security/optee_linuxdriver/armtz/handle.c delete mode 100644 security/optee_linuxdriver/armtz/handle.h delete mode 100644 security/optee_linuxdriver/armtz/tee_mem.c delete mode 100644 security/optee_linuxdriver/armtz/tee_mem.h delete mode 100644 security/optee_linuxdriver/armtz/tee_smc-arm.S delete mode 100644 security/optee_linuxdriver/armtz/tee_smc-arm64.S delete mode 100644 security/optee_linuxdriver/armtz/tee_tz_drv.c delete mode 100644 security/optee_linuxdriver/armtz/tee_tz_op.h delete mode 100644 security/optee_linuxdriver/armtz/tee_tz_priv.h delete mode 100644 security/optee_linuxdriver/core/Makefile delete mode 100644 security/optee_linuxdriver/core/tee_context.c delete mode 100644 security/optee_linuxdriver/core/tee_core.c delete mode 100644 security/optee_linuxdriver/core/tee_core_priv.h delete mode 100644 security/optee_linuxdriver/core/tee_debugfs.c delete mode 100644 security/optee_linuxdriver/core/tee_debugfs.h delete mode 100644 security/optee_linuxdriver/core/tee_kernel_api.c delete mode 100644 security/optee_linuxdriver/core/tee_mutex_wait.c delete mode 100644 security/optee_linuxdriver/core/tee_mutex_wait.h delete mode 100644 security/optee_linuxdriver/core/tee_session.c delete mode 100644 security/optee_linuxdriver/core/tee_shm.c delete mode 100644 security/optee_linuxdriver/core/tee_shm.h delete mode 100644 security/optee_linuxdriver/core/tee_supp_com.c delete mode 100644 security/optee_linuxdriver/core/tee_supp_com.h delete mode 100644 security/optee_linuxdriver/core/tee_sysfs.c delete mode 100644 security/optee_linuxdriver/core/tee_sysfs.h delete mode 100644 security/optee_linuxdriver/core/tee_wait_queue.c delete mode 100644 security/optee_linuxdriver/core/tee_wait_queue.h delete mode 100644 security/optee_linuxdriver/fdts/fvp-foundation-gicv2-psci.dts delete mode 100644 security/optee_linuxdriver/fdts/fvp-foundation-motherboard.dtsi delete mode 100644 security/optee_linuxdriver/fdts/readme.txt delete mode 100644 security/optee_linuxdriver/include/arm_common/teesmc.h delete mode 100644 security/optee_linuxdriver/include/arm_common/teesmc_st.h delete mode 100644 security/optee_linuxdriver/include/linux/tee_client_api.h delete mode 100644 security/optee_linuxdriver/include/linux/tee_core.h delete mode 100644 security/optee_linuxdriver/include/linux/tee_ioc.h delete mode 100644 security/optee_linuxdriver/include/linux/tee_kernel_api.h diff --git a/security/optee_linuxdriver/Kconfig b/security/optee_linuxdriver/Kconfig deleted file mode 100644 index d1fa087735dc..000000000000 --- a/security/optee_linuxdriver/Kconfig +++ /dev/null @@ -1,20 +0,0 @@ -# -# Copyright (c) 2014, STMicroelectronics International N.V. -# -# This program is free software; you can redistribute it and/or modify -# it under the terms of the GNU General Public License Version 2 as -# published by the Free Software Foundation. -# -# This program is distributed in the hope that it will be useful, -# but WITHOUT ANY WARRANTY; without even the implied warranty of -# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the -# GNU General Public License for more details. -# - -# Trursted Execution Environment Configuration -config TEE_SUPPORT - bool "Trusted Execution Environment Support" - default n - help - This implements the Trusted Execution Environment (TEE) Client - API Specification from GlobalPlatform Device Technology. diff --git a/security/optee_linuxdriver/LICENSE b/security/optee_linuxdriver/LICENSE deleted file mode 100644 index d159169d1050..000000000000 --- a/security/optee_linuxdriver/LICENSE +++ /dev/null @@ -1,339 +0,0 @@ - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Lesser General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License along - with this program; if not, write to the Free Software Foundation, Inc., - 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) year name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Lesser General -Public License instead of this License. diff --git a/security/optee_linuxdriver/Makefile b/security/optee_linuxdriver/Makefile deleted file mode 100644 index 59bfa8004fc0..000000000000 --- a/security/optee_linuxdriver/Makefile +++ /dev/null @@ -1,3 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -obj-$(CONFIG_TEE_SUPPORT) += core/ -obj-$(CONFIG_TEE_SUPPORT) += armtz/ diff --git a/security/optee_linuxdriver/Notice.md b/security/optee_linuxdriver/Notice.md deleted file mode 100644 index 88c6cfa003ac..000000000000 --- a/security/optee_linuxdriver/Notice.md +++ /dev/null @@ -1,4 +0,0 @@ -To avoid duplicating information we link to the Notice.md file in optee_os which -states the contributor agreement rules etc, i.e, optee_linuxdriver follows what -is written in the Notice.md on the URL below -https://github.com/OP-TEE/optee_os/blob/master/Notice.md diff --git a/security/optee_linuxdriver/README.md b/security/optee_linuxdriver/README.md deleted file mode 100644 index d2a0cb4ad64f..000000000000 --- a/security/optee_linuxdriver/README.md +++ /dev/null @@ -1,91 +0,0 @@ -# OP-TEE Linux Driver -The optee_linuxdriver git, containing the source code for the TEE driver -module in Linux. -It is distributed under the GPLv2 open-source license. For a general -overview of OP-TEE, please see the [Notice.md](Notice.md) file. - -In this git, the module to build is optee.ko. -It allows communication between the Rich OS Client Application (unsecure -world), the Trusted OS (secure world) and the tee-supplicant (unsecure -world) which is a daemon serving the Trusted OS in secure world with -miscellaneous features, such as file system access. - -## License -The software is provided under the -[GPL-2.0](http://opensource.org/licenses/GPL-2.0) license. - -## Platforms supported -This software has hardware dependencies. -The software has been tested using: - -- STMicroelectronics b2020-h416 (orly-2) hardware (32-bits) -- Some initial testing has been done using -[Foundation FVP](http://www.arm.com/fvp), which can be downloaded free of -charge. - -## Get and build the software -### Get the compiler -We will strive to use the latest available compiler from Linaro. Start by -downloading and unpacking the compiler. Then export the PATH to the bin folder. - - $ cd $HOME - $ mkdir toolchains - $ cd toolchains - $ wget http://releases.linaro.org/14.05/components/toolchain/binaries/gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux.tar.xz - $ tar xvf gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux.tar.xz - $ export PATH=$HOME/toolchains/gcc-linaro-arm-linux-gnueabihf-4.9-2014.05_linux/bin:$PATH - -### Get the Linux kernel (from www.kernel.org) - $ cd $HOME - $ mkdir devel - $ cd devel - $ tar xf linux-3.10.32.tar.xz - $ mv linux-3.10.32 linux - -### Download the source code - $ cd $HOME - $ cd devel - $ git clone https://github.com/OP-TEE/optee_linuxdriver.git - -### Build - $ cd $HOME/devel/linux - $ make -j3 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- mrproper - $ make -j3 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- defconfig - $ make -j3 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- all - $ make -j3 ARCH=arm CROSS_COMPILE=arm-linux-gnueabihf- M=$HOME/devel/optee_linuxdriver modules - -#### Compiler flags -To be able to see the full command when building you could build using following -flag: - -`$ make V=1` - -## Coding standards -In this project we are trying to adhere to the same coding convention as used in -the Linux kernel (see -[CodingStyle](https://www.kernel.org/doc/Documentation/CodingStyle)). We achieve this by running -[checkpatch](http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/scripts/checkpatch.pl) from Linux kernel. -However there are a few exceptions that we had to make since the code also -follows GlobalPlatform standards. The exceptions are as follows: - -- CamelCase for GlobalPlatform types are allowed. -- And we also exclude checking third party code that we might use in this - project, such as LibTomCrypt, MPA, newlib (not in this particular git, but - those are also part of the complete TEE solution). The reason for excluding - and not fixing third party code is because we would probably deviate too much - from upstream and therefore it would be hard to rebase against those projects - later on (and we don't expect that it is easy to convince other software - projects to change coding style). - -### checkpatch -Since checkpatch is licensed under the terms of GNU GPL License Version 2, we -cannot include this script directly into this project. Therefore we have -written the Makefile so you need to explicitly point to the script by exporting -an environment variable, namely CHECKPATCH. So, suppose that the source code for -the Linux kernel is at `$HOME/devel/linux`, then you have to export like follows: - - $ export CHECKPATCH=$HOME/devel/linux/scripts/checkpatch.pl -thereafter it should be possible to use one of the different checkpatch targets -in the [Makefile](Makefile). There are targets for checking all files, checking -against latest commit, against a certain base-commit etc. For the details, read -the [Makefile](Makefile). diff --git a/security/optee_linuxdriver/armtz/Makefile b/security/optee_linuxdriver/armtz/Makefile deleted file mode 100644 index ba1b38b1816d..000000000000 --- a/security/optee_linuxdriver/armtz/Makefile +++ /dev/null @@ -1,43 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 - -######################################################################### -# Set Internal Variables # -# May be modified to match your setup # -######################################################################### -CFG_TEE_DRV_DEBUGFS?=0 -CFG_TEE_CORE_LOG_LEVEL?=2 -CFG_TEE_TA_LOG_LEVEL?=2 - -M ?= security/optee_linuxdriver - -ccflags-y+=-Werror -ccflags-y+=-I$(M)/include/arm_common -ccflags-y+=-I$(M)/include/linux -ccflags-y+=-I$(M)/include -ccflags-y+=-I$(M)/core - -ccflags-y+=-DCFG_TEE_DRV_DEBUGFS=${CFG_TEE_DRV_DEBUGFS} -ccflags-y+=-DCFG_TEE_CORE_LOG_LEVEL=${CFG_TEE_CORE_LOG_LEVEL} -ccflags-y+=-DCFG_TEE_TA_LOG_LEVEL=${CFG_TEE_TA_LOG_LEVEL} - -obj-y += optee_armtz.o - -optee_armtz-objs:= \ - tee_tz_drv.o \ - tee_mem.o \ - handle.o - - -ifeq ($(CONFIG_ARM),y) -# "smc" assembly intruction requires dedicated "armv7 secure extension" -secext := $(call as-instr,.arch_extension sec,+sec) -AFLAGS_tee_smc-arm.o := -Wa,-march=armv7-a$(secext) -optee_armtz-objs += \ - tee_smc-arm.o -endif - -ifeq ($(CONFIG_ARM64),y) -optee_armtz-objs += \ - tee_smc-arm64.o -endif - diff --git a/security/optee_linuxdriver/armtz/handle.c b/security/optee_linuxdriver/armtz/handle.c deleted file mode 100644 index f40479f466b6..000000000000 --- a/security/optee_linuxdriver/armtz/handle.c +++ /dev/null @@ -1,87 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include "handle.h" - -/* - * Define the initial capacity of the database. It should be a low number - * multiple of 2 since some databases a likely to only use a few handles. - * Since the algorithm is to doubles up when growing it shouldn't cause a - * noticable overhead on large databases. - */ -#define HANDLE_DB_INITIAL_MAX_PTRS 4 - -void handle_db_destroy(struct handle_db *db) -{ - if (db) { - kfree(db->ptrs); - db->ptrs = NULL; - db->max_ptrs = 0; - } -} - -int handle_get(struct handle_db *db, void *ptr) -{ - unsigned n; - void *p; - unsigned new_max_ptrs; - - if (!db || !ptr) - return -1; - - /* Try to find an empty location */ - for (n = 0; n < db->max_ptrs; n++) { - if (!db->ptrs[n]) { - db->ptrs[n] = ptr; - return n; - } - } - - /* No location available, grow the ptrs array */ - if (db->max_ptrs) - new_max_ptrs = db->max_ptrs * 2; - else - new_max_ptrs = HANDLE_DB_INITIAL_MAX_PTRS; - p = krealloc(db->ptrs, new_max_ptrs * sizeof(void *), GFP_KERNEL); - if (!p) - return -1; - db->ptrs = p; - memset(db->ptrs + db->max_ptrs, 0, - (new_max_ptrs - db->max_ptrs) * sizeof(void *)); - db->max_ptrs = new_max_ptrs; - - /* Since n stopped at db->max_ptrs there is an empty location there */ - db->ptrs[n] = ptr; - return n; -} - -void *handle_put(struct handle_db *db, int handle) -{ - void *p; - - if (!db || handle < 0 || (unsigned)handle >= db->max_ptrs) - return NULL; - - p = db->ptrs[handle]; - db->ptrs[handle] = NULL; - return p; -} - -void *handle_lookup(struct handle_db *db, int handle) -{ - if (!db || handle < 0 || (unsigned)handle >= db->max_ptrs) - return NULL; - - return db->ptrs[handle]; -} diff --git a/security/optee_linuxdriver/armtz/handle.h b/security/optee_linuxdriver/armtz/handle.h deleted file mode 100644 index 0d205349e3da..000000000000 --- a/security/optee_linuxdriver/armtz/handle.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef HANDLE_H -#define HANDLE_H - -struct handle_db { - void **ptrs; - unsigned max_ptrs; -}; - -#define HANDLE_DB_INITIALIZER { NULL, 0 } - -/* - * Frees all internal data structures of the database, but does not free - * the db pointer. The database is safe to reuse after it's destroyed, it - * just be empty again. - */ -void handle_db_destroy(struct handle_db *db); - -/* - * Allocates a new handle and assigns the supplied pointer to it, - * ptr must not be NULL. - * The function returns - * >= 0 on success and - * -1 on failure - */ -int handle_get(struct handle_db *db, void *ptr); - -/* - * Deallocates a handle. Returns the associated pointer of the handle - * the the handle was valid or NULL if it's invalid. - */ -void *handle_put(struct handle_db *db, int handle); - -/* - * Returns the associated pointer of the handle if the handle is a valid - * handle. - * Returns NULL on failure. - */ -void *handle_lookup(struct handle_db *db, int handle); - -#endif /*HANDLE_H*/ diff --git a/security/optee_linuxdriver/armtz/tee_mem.c b/security/optee_linuxdriver/armtz/tee_mem.c deleted file mode 100644 index 2c584826c601..000000000000 --- a/security/optee_linuxdriver/armtz/tee_mem.c +++ /dev/null @@ -1,677 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -/** - * \file tee_mem.c - * \brief Functions to manage a pool of memory chunks. - * - * This module provides basic functions to manage dynamically a fixed amount - * of memory (memory region). For this current implementation the provided - * memory region used for the allocations should be physically AND logically - * contiguous (only one region is supported for a given allocator). - * - * Principle of the allocator algorithm: "best fit" - * - */ - -#include - -#include "tee_mem.h" - -#define _DUMP_INFO_ALLOCATOR 0 -#define USE_DEVM_ALLOC 1 - -#ifndef USE_DEVM_ALLOC -#define _KMALLOC(s, f) kmalloc(s, f) -#define _KFREE(a) kfree(a) -#else -#define _KMALLOC(s, f) devm_kzalloc(dev, s, f) -#define _KFREE(a) devm_kfree(dev, a) -#endif - -/** - * \struct mem_chunk - * \brief Elementary descriptor of an allocated memory block - * - * \param node Node for linked list - * \param counter Reference counter - * (0 indicates that the block is not used/freed) - * \param size Total size in bytes - * \param paddr Physical base address - * - * Elementary memory block definition - */ -struct mem_chunk { - struct list_head node; - uint32_t counter; - size_t size; - unsigned long paddr; -}; - -/** - * \struct shm_pool - * \brief Main structure to describe a shared memory pool - * - * \param size Total size in bytes of the associated memory region - * \param vaddr Logical base address - * \param paddr Physical base address - * \param used Total size in bytes of the used memory - * \param mchunks List head for handle the elementary memory blocks - * - * Shared memory pool structure definition - */ -struct shm_pool { - struct mutex lock; - size_t size; /* Size of pool/heap memory segment */ - size_t used; /* Number of bytes allocated */ - void *vaddr; /* Associated Virtual address */ - unsigned long paddr; /* Associated Physical address */ - bool cached; /* true if pool is cacheable */ - struct list_head mchunks; /* Head of memory chunk/block list */ -}; - -#define __CALCULATE_RATIO_MEM_USED(a) (((a->used)*100)/(a->size)) - -/** - * \brief Dumps the information of the shared memory pool - * - * \param pool Pointer on the pool - * \param detailforced Flag to force the log for the detailed informations - * - * Dump/log the meta data of the shared memory pool on the standard output. - * - */ -void tee_shm_pool_dump(struct device *dev, struct shm_pool *pool, bool forced) -{ - struct mem_chunk *chunk; - - if (WARN_ON(!dev || !pool)) - return; - - dev_info(dev, - "tee_shm_pool_dump() poolH(0x%p) pAddr=0x%p vAddr=0x%p size=%zu used=%zu(%zu%%)\n", - (void *)pool, - (void *)pool->paddr, - (void *)pool->vaddr, - pool->size, pool->used, __CALCULATE_RATIO_MEM_USED(pool)); - - if ((pool->used != 0) || (forced == true)) { - dev_info(dev, " \\ HEAD next:[0x%p] prev:[0x%p]\n", - (void *)pool->mchunks.next, - (void *)pool->mchunks.prev); - - dev_info(dev, - " |-[@] next prev pAddr size refCount\n"); - - list_for_each_entry(chunk, &pool->mchunks, node) { - dev_info(dev, " | [0x%p] 0x%p 0x%p 0x%p %08zu %d\n", - (void *)chunk, - (void *)chunk->node.next, - (void *)chunk->node.prev, - (void *)chunk->paddr, - chunk->size, chunk->counter); - } - } -} - -bool tee_shm_pool_is_cached(struct shm_pool *pool) -{ - return pool->cached; -} - -void tee_shm_pool_set_cached(struct shm_pool *pool) -{ - pool->cached = true; -} - -/** - * \brief Creates and returns a new shared memory pool manager structure - * - * \param shm_size Size of the associated memory chunk - * \param shm_vaddr Virtual/logical base address - * \param shm_paddr Physical base address - * - * \return Reference of the created shared memory pool manager - * - * Create and initialize a shared memory pool manager. - * The description of the memory region (shm_size, shm_vaddr, shm_paddr) - * which is passed should be a physically AND virtually contiguous - * (no check is performed by the function). - * If a error is detected returned pool is NULL. - */ -struct shm_pool *tee_shm_pool_create(struct device *dev, size_t shm_size, - void *shm_vaddr, unsigned long shm_paddr) -{ - struct mem_chunk *chunk = NULL; - struct shm_pool *pool = NULL; - - if (WARN_ON(!dev)) - goto alloc_failed; - - dev_dbg(dev, "> vaddr=0x%p, paddr=0x%p, size=%zuKiB\n", - shm_vaddr, (void *)shm_paddr, shm_size / 1024); - - /* Alloc and initialize the shm_pool structure */ - pool = _KMALLOC(sizeof(struct shm_pool), GFP_KERNEL); - if (!pool) { - dev_err(dev, "kmalloc failed\n"); - goto alloc_failed; - } - memset(pool, 0, sizeof(*pool)); - mutex_init(&pool->lock); - mutex_lock(&pool->lock); - - INIT_LIST_HEAD(&(pool->mchunks)); - pool->size = shm_size; - pool->vaddr = shm_vaddr; - pool->paddr = shm_paddr; - - /* Create the initial elementary memory chunk */ - /* which handles the whole memory region */ - chunk = _KMALLOC(sizeof(struct mem_chunk), GFP_KERNEL); - if (!chunk) { - dev_err(dev, "kmalloc failed\n"); - mutex_unlock(&pool->lock); - goto alloc_failed; - } - memset(chunk, 0, sizeof(*chunk)); - chunk->paddr = shm_paddr; - chunk->size = shm_size; - - /* Adds the new entry immediately after the list head */ - list_add(&(chunk->node), &(pool->mchunks)); - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 0) - tee_shm_pool_dump(dev, pool, true); -#endif - dev_dbg(dev, "< poolH(0x%p) chunkH=0x%p\n", - (void *)(pool), (void *)chunk); - - mutex_unlock(&pool->lock); - return pool; - -alloc_failed: - if (chunk) - _KFREE(chunk); - - if (pool) - _KFREE(pool); - - return NULL; -} - -/** - * Local helper function to check that the physical address is valid - */ -static inline int is_valid_paddr(struct shm_pool *pool, unsigned long paddr) -{ - return (paddr >= pool->paddr && paddr < (pool->paddr + pool->size)); -} - -/** - * Local helper function to check that the virtual address is valid - */ -static inline int is_valid_vaddr(struct shm_pool *pool, void *vaddr) -{ - return (vaddr >= pool->vaddr && vaddr < (pool->vaddr + pool->size)); -} - -/** - * \brief Destroy the shared memory pool manager - * - * \param pool Pointer on the pool - * - * Destroy a memory pool manager - * - */ -void tee_shm_pool_destroy(struct device *dev, struct shm_pool *pool) -{ - struct mem_chunk *chunk; - - if (WARN_ON(!dev || !pool)) - return; - - dev_dbg(dev, "> poolH(0x%p)\n", (void *)pool); - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 0) - tee_shm_pool_dump(dev, pool, true); -#endif - - tee_shm_pool_reset(dev, pool); - - chunk = list_first_entry(&pool->mchunks, struct mem_chunk, node); - dev_dbg(dev, "free chunkH=0x%p\n", (void *)chunk); - _KFREE(chunk); - _KFREE(pool); - - dev_dbg(dev, "<\n"); -} - -/** - * \brief Free all reserved chunk if any, and set pool at it initial state - * - * \param pool Pointer on the pool - * - */ -void tee_shm_pool_reset(struct device *dev, struct shm_pool *pool) -{ - struct mem_chunk *chunk; - struct mem_chunk *tmp; - struct mem_chunk *first = NULL; - - if (WARN_ON(!dev || !pool)) - return; - - mutex_lock(&pool->lock); - - list_for_each_entry_safe(chunk, tmp, &pool->mchunks, node) { - if (first != NULL) { - dev_err(dev, "Free lost chunkH=0x%p\n", (void *)chunk); - list_del(&chunk->node); - _KFREE(chunk); - } else { - first = chunk; - } - } - - first->counter = 0; - first->paddr = pool->paddr; - first->size = pool->size; - pool->used = 0; - - mutex_unlock(&pool->lock); -} - -/** - * \brief Return the logical address - * - * \param pool Pointer on the pool - * \param paddr Physical address - * - * \return Virtual/logical address - * - * Return the associated virtual/logical address. The address should be inside - * the range of addresses managed by the shm pool. - * - */ -void *tee_shm_pool_p2v(struct device *dev, struct shm_pool *pool, - unsigned long paddr) -{ - if (WARN_ON(!dev || !pool)) - return NULL; - - mutex_lock(&pool->lock); - if (!is_valid_paddr(pool, paddr)) { - mutex_unlock(&pool->lock); - dev_err(dev, - "tee_shm_pool_p2v() paddr=0x%p not in the shm pool\n", - (void *)paddr); - return NULL; - } else { - unsigned long offset = paddr - pool->paddr; - void *p = (void *)((unsigned long)pool->vaddr + offset); - - mutex_unlock(&pool->lock); - return p; - } -} - -/** - * \brief Return the physical address - * - * \param pool Pointer on the pool - * \param vaddr Logical/Virtual address - * - * \return Physical address - * - * Return the associated physical address. The address should be inside - * the range of addresses managed by the pool. - * - */ -unsigned long tee_shm_pool_v2p(struct device *dev, struct shm_pool *pool, - void *vaddr) -{ - if (WARN_ON(!dev || !pool)) - return 0UL; - - mutex_lock(&pool->lock); - if (!is_valid_vaddr(pool, vaddr)) { - dev_err(dev, - "tee_shm_pool_v2p() vaddr=0x%p not in shm pool\n", - (void *)vaddr); - mutex_unlock(&pool->lock); - return 0UL; - } else { - unsigned long offset = vaddr - pool->vaddr; - unsigned long p = pool->paddr + offset; - - mutex_unlock(&pool->lock); - return p; - } -} - -/** - * \brief Allocate a new block of memory - * - * \param pool Pointer on the pool - * \param size Expected size (in byte) - * \param alignment Alignment constraint (in byte) - * - * \return Physical base address of the allocated block - * - * Allocate a memory chunk inside the memory region managed by the pool. - * - */ -unsigned long rk_tee_shm_pool_alloc(struct device *dev, - struct shm_pool *pool, - size_t size, size_t alignment) -{ - struct mem_chunk *chunk; - struct mem_chunk *betterchunk = NULL; - struct mem_chunk *prev_chunk = NULL; - struct mem_chunk *next_chunk = NULL; - unsigned long begAddr; - unsigned long endAddr; - - if (WARN_ON(!dev || !pool)) - return 0UL; - - dev_dbg(dev, "> poolH(%p:%p:%x) size=0x%zx align=0x%zx\n", - pool, (void *)pool->paddr, (unsigned int)pool->size, size, - alignment); - - /* Align on cache line of the target */ - /* \todo(jmd) Should be defined by a global target specific parameter */ - /* size = (size + (32-1)) & ~(32-1) */ - - if (ALIGN(size, 0x20) < size) - goto failed_out; - - if (alignment == 0) - alignment = 1; - - size = ALIGN(size, 0x20); - - alignment = ALIGN(alignment, 0x20); - - if (size > (pool->size - pool->used)) - goto failed_out; - - mutex_lock(&pool->lock); - - /** - * Algorithm: Smallest waste (best fit): We choose the block that has the - * smallest waste. In other words we choose the block so that - * size(b) - size is as small as possible. - */ - list_for_each_entry(chunk, &pool->mchunks, node) { - if (chunk->counter == 0) { /* Free chunk */ - begAddr = ALIGN(chunk->paddr, alignment); - endAddr = begAddr + size; - - if (begAddr >= chunk->paddr - && endAddr <= (chunk->paddr + chunk->size) - && (betterchunk == NULL - /* Always split smaller block */ - || chunk->size < betterchunk->size)) - betterchunk = chunk; - } - } - - /** - * Update the linked list - */ - if (betterchunk != NULL) { - prev_chunk = _KMALLOC(sizeof(struct mem_chunk), GFP_KERNEL); - next_chunk = _KMALLOC(sizeof(struct mem_chunk), GFP_KERNEL); - - if ((!prev_chunk) || (!next_chunk)) - goto failed_out_unlock; - - begAddr = ALIGN(betterchunk->paddr, alignment); - endAddr = begAddr + size; - - if (betterchunk->paddr < begAddr) { - /* memory between begin of chunk and begin - * of created memory => create a free chunk */ - prev_chunk->counter = 0; - prev_chunk->paddr = betterchunk->paddr; - prev_chunk->size = begAddr - betterchunk->paddr; - - betterchunk->paddr = begAddr; - betterchunk->size -= prev_chunk->size; - - dev_dbg(dev, - "create p_chunkH=0x%p paddr=0x%p (s=%zu)\n", - (void *)prev_chunk, - (void *)prev_chunk->paddr, prev_chunk->size); - - list_add_tail(&(prev_chunk->node), - &(betterchunk->node)); - prev_chunk = NULL; - } else { - _KFREE(prev_chunk); - } - - if (betterchunk->paddr + betterchunk->size > endAddr) { - /* memory between end of chunk and end of - * created memory => create a free chunk */ - next_chunk->counter = 0; - next_chunk->paddr = endAddr; - next_chunk->size = betterchunk->size - size; - - dev_dbg(dev, - "create n_chunkH=0x%p paddr=0x%p (s=%zu)\n", - (void *)next_chunk, - (void *)next_chunk->paddr, next_chunk->size); - - betterchunk->size = size; - - list_add(&(next_chunk->node), &(betterchunk->node)); - next_chunk = NULL; - } else { - _KFREE(next_chunk); - } - - betterchunk->counter = 1; - pool->used += size; - - mutex_unlock(&pool->lock); - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 1) - tee_shm_pool_dump(dev, pool, false); -#endif - - dev_dbg(dev, - "< chunkH=0x%p paddr=%p (s=%zu) align=0x%zx\n", - (void *)betterchunk, - (void *)betterchunk->paddr, - betterchunk->size, alignment); - - return betterchunk->paddr; - } - -failed_out_unlock: - mutex_unlock(&pool->lock); -failed_out: - if (prev_chunk) - _KFREE(prev_chunk); - if (next_chunk) - _KFREE(next_chunk); - - dev_err(dev, - "rk_tee_shm_pool_alloc() FAILED, size=0x%zx, align=0x%zx free=%zu\n", - size, alignment, pool->size - pool->used); - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 1) - tee_shm_pool_dump(dev, pool, true); -#endif - - return 0UL; -} - -/** - * \brief Release a allocated block of memory - * - * \param pool Pointer on the pool - * \param paddr Physical @ of the block which must be released - * \param size Reference to return the size of the block - * - * Free a allocated memory block inside - * the memory region managed by the pool. - * - */ -int rk_tee_shm_pool_free(struct device *dev, struct shm_pool *pool, - unsigned long paddr, size_t *size) -{ - struct mem_chunk *chunk; - - if (WARN_ON(!dev || !pool)) - return -EINVAL; - - dev_dbg(dev, "> Try to free ... poolH(0x%p) paddr=0x%p\n", - (void *)pool, (void *)paddr); - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 1) - tee_shm_pool_dump(dev, pool, false); -#endif - - mutex_lock(&pool->lock); - - if (!is_valid_paddr(pool, paddr)) - goto out_failed; - - list_for_each_entry(chunk, &pool->mchunks, node) { - if (chunk->paddr == paddr) { - if (size != NULL) - *size = chunk->size; - - if (chunk->counter == 0) { - dev_warn(dev, - "< tee_shm_pool_free() WARNING, paddr=0x%p already released\n", - (void *)paddr); - mutex_unlock(&pool->lock); - return -EINVAL; - } else if (--chunk->counter == 0) { - dev_dbg(dev, "paddr=%p\n", (void *)paddr); - - pool->used -= chunk->size; - - /* Merge with previous */ - if (chunk->node.prev != &pool->mchunks) { - struct mem_chunk *prev = - list_entry(chunk->node.prev, - struct mem_chunk, node); - if (prev->counter == 0) { - dev_dbg(dev, - "chunkH=0x%p paddr=0x%p free ok\n", - (void *)chunk, - (void *)paddr); - prev->size += chunk->size; - list_del(&chunk->node); - _KFREE(chunk); - chunk = prev; - } - } - /* Merge with next */ - if (chunk->node.next != &pool->mchunks) { - struct mem_chunk *next = - list_entry(chunk->node.next, - struct mem_chunk, node); - if (next->counter == 0) { - dev_dbg(dev, - "chunkH=0x%p paddr=0x%p free ok\n", - (void *)chunk, - (void *)paddr); - chunk->size += next->size; - list_del(&next->node); - _KFREE(next); - } - } - mutex_unlock(&pool->lock); - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 1) - tee_shm_pool_dump(dev, pool, false); -#endif - dev_dbg(dev, "< freed\n"); - return 0; - - } else { - mutex_unlock(&pool->lock); - dev_dbg(dev, - "< paddr=0x%p (--) refcounter is decremented ret=1\n", - (void *)paddr); - return 1; - } - } - } - -out_failed: - mutex_unlock(&pool->lock); -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 1) - tee_shm_pool_dump(dev, pool, false); -#endif - dev_err(dev, - "< tee_shm_pool_free() FAILED, pAddr=0x%p not found\n", - (void *)paddr); - return -EINVAL; -} - -/** - * \brief Increase the reference count of the memory chunk - * - * \param pool Pointer on the pool - * \param paddr Physical address - * - * \return true if successful (false otherwise) - * - * Increment the reference count of the allocated block of memory. - * paddr should a valid address returned by the tee_shm_pool_alloc(). - * - */ -bool tee_shm_pool_incref(struct device *dev, struct shm_pool *pool, - unsigned long paddr) -{ - struct mem_chunk *chunk; - - if (WARN_ON(!dev || !pool)) - return false; - - mutex_lock(&pool->lock); - - if (!is_valid_paddr(pool, paddr)) - goto out_failed; - - list_for_each_entry(chunk, &pool->mchunks, node) { - if (chunk->paddr == paddr) { - dev_dbg(dev, - "pAddr=%p (++) refcounter is incremented\n", - (void *)paddr); - chunk->counter++; - -#if defined(_DUMP_INFO_ALLOCATOR) && (_DUMP_INFO_ALLOCATOR > 0) - tee_shm_pool_dump(dev, pool, false); -#endif - mutex_unlock(&pool->lock); - return true; - } - } - -out_failed: - mutex_unlock(&pool->lock); - - dev_err(dev, - "tee_shm_pool_incref() FAILED, pAddr=%p is not a valid @\n", - (void *)paddr); - - return false; -} diff --git a/security/optee_linuxdriver/armtz/tee_mem.h b/security/optee_linuxdriver/armtz/tee_mem.h deleted file mode 100644 index 4901ea9f4673..000000000000 --- a/security/optee_linuxdriver/armtz/tee_mem.h +++ /dev/null @@ -1,50 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef TEE_MEM_H -#define TEE_MEM_H - -#include -#include - -struct shm_pool; - -struct shm_pool *tee_shm_pool_create(struct device *dev, size_t shm_size, - void *shm_vaddr, unsigned long shm_paddr); - -void tee_shm_pool_destroy(struct device *dev, struct shm_pool *pool); - -void *tee_shm_pool_p2v(struct device *dev, struct shm_pool *pool, - unsigned long paddr); - -unsigned long tee_shm_pool_v2p(struct device *dev, struct shm_pool *pool, - void *vaddr); - -unsigned long rk_tee_shm_pool_alloc(struct device *dev, - struct shm_pool *pool, - size_t size, size_t alignment); - -int rk_tee_shm_pool_free(struct device *dev, struct shm_pool *pool, - unsigned long paddr, size_t *size); - -bool tee_shm_pool_incref(struct device *dev, struct shm_pool *pool, - unsigned long paddr); - -void tee_shm_pool_dump(struct device *dev, struct shm_pool *pool, bool forced); - -void tee_shm_pool_reset(struct device *dev, struct shm_pool *pool); - -bool tee_shm_pool_is_cached(struct shm_pool *pool); - -void tee_shm_pool_set_cached(struct shm_pool *pool); - -#endif diff --git a/security/optee_linuxdriver/armtz/tee_smc-arm.S b/security/optee_linuxdriver/armtz/tee_smc-arm.S deleted file mode 100644 index 5d1d2ea7a0df..000000000000 --- a/security/optee_linuxdriver/armtz/tee_smc-arm.S +++ /dev/null @@ -1,29 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include - -.text -.balign 4 -.code 32 - - /* void tee_smc_call(struct smc_param *param); */ - .globl tee_smc_call -ENTRY(tee_smc_call) - push {r4-r8, lr} - mov r8, r0 - ldm r8, {r0-r7} -.arch_extension sec - smc #0 - stm r8, {r0-r7} - pop {r4-r8, pc} -ENDPROC(tee_smc_call) diff --git a/security/optee_linuxdriver/armtz/tee_smc-arm64.S b/security/optee_linuxdriver/armtz/tee_smc-arm64.S deleted file mode 100644 index 27224026cc96..000000000000 --- a/security/optee_linuxdriver/armtz/tee_smc-arm64.S +++ /dev/null @@ -1,36 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include - - .text - -#define SMC_PARAM_X0_OFFS 0 -#define SMC_PARAM_X2_OFFS 16 -#define SMC_PARAM_X4_OFFS 32 -#define SMC_PARAM_X6_OFFS 48 - - /* void tee_smc_call(struct smc_param *param); */ - .globl tee_smc_call -ENTRY(tee_smc_call) - stp x28, x30, [sp, #-16]! - mov x28, x0 - ldp x0, x1, [x28, #SMC_PARAM_X0_OFFS] - ldp x2, x3, [x28, #SMC_PARAM_X2_OFFS] - ldp x4, x5, [x28, #SMC_PARAM_X4_OFFS] - ldp x6, x7, [x28, #SMC_PARAM_X6_OFFS] - smc #0 - stp x0, x1, [x28, #SMC_PARAM_X0_OFFS] - stp x2, x3, [x28, #SMC_PARAM_X2_OFFS] - ldp x28, x30, [sp], #16 - ret -ENDPROC(tee_smc_call) diff --git a/security/optee_linuxdriver/armtz/tee_tz_drv.c b/security/optee_linuxdriver/armtz/tee_tz_drv.c deleted file mode 100644 index 1ddf847afa67..000000000000 --- a/security/optee_linuxdriver/armtz/tee_tz_drv.c +++ /dev/null @@ -1,1488 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -/* #define DEBUG */ - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#include -#include -#include -#include -#include - -#include -#include - -#include -#include - -#include "tee_mem.h" -#include "tee_tz_op.h" -#include "tee_tz_priv.h" -#include "handle.h" - -#ifdef CONFIG_ARM -#include -#endif - -#ifdef CONFIG_OUTER_CACHE -#undef CONFIG_OUTER_CACHE -#endif - -/* #define SWITCH_CPU0_DEBUG */ - -#define _TEE_TZ_NAME "armtz" -#define DEV (ptee->tee->dev) - -/* #define TEE_STRESS_OUTERCACHE_FLUSH */ - -/* magic config: bit 1 is set, Secure TEE shall handler NSec IRQs */ -#define SEC_ROM_NO_FLAG_MASK 0x0000 -#define SEC_ROM_IRQ_ENABLE_MASK 0x0001 -#define SEC_ROM_DEFAULT SEC_ROM_IRQ_ENABLE_MASK -#define TEE_RETURN_BUSY 0x3 -#define ALLOC_ALIGN SZ_4K - -#define CAPABLE(tee) !(tee->conf & TEE_CONF_FW_NOT_CAPABLE) - -static struct tee_tz *tee_tz; - -static struct handle_db shm_handle_db = HANDLE_DB_INITIALIZER; - - -/* Temporary workaround until we're only using post 3.13 kernels */ -#ifdef ioremap_cached -#define ioremap_cache ioremap_cached -#endif - - -/******************************************************************* - * Calling TEE - *******************************************************************/ -#ifdef SWITCH_CPU0_DEBUG -#ifdef CONFIG_SMP -static long switch_cpumask_to_cpu0(cpumask_t *saved_cpu_mask) -{ - long ret; - - cpumask_t local_cpu_mask = CPU_MASK_NONE; - cpumask_set_cpu(0, &local_cpu_mask); - cpumask_copy(saved_cpu_mask, tsk_cpus_allowed(current)); - ret = sched_setaffinity(0, &local_cpu_mask); - if (ret) - pr_err("%s:->%ld,cpu:%d\n", __func__, ret, smp_processor_id()); - return ret; -} - -static long restore_cpumask(cpumask_t *saved_cpu_mask) -{ - long ret; - - ret = sched_setaffinity(0, saved_cpu_mask); - if (ret) - pr_err("%s:->%ld,cpu:%d\n", __func__, ret, smp_processor_id()); - return ret; -} -#else -static inline long switch_cpumask_to_cpu0(cpumask_t *saved_cpu_mask) -{ return 0; } -static inline long restore_cpumask(cpumask_t *saved_cpu_mask) -{ return 0; } -#endif -static long tee_smc_call_switchcpu0(struct smc_param *param) -{ - long ret; - cpumask_t saved_cpu_mask; - - ret = switch_cpumask_to_cpu0(&saved_cpu_mask); - if (ret) - return ret; - tee_smc_call(param); - ret = restore_cpumask(&saved_cpu_mask); - if (ret) - return ret; - return ret; -} -#endif /* SWITCH_CPU0_DEBUG */ - -static void wait_completion_teez(struct tee_tz *ptee) -{ - ptee->c_waiters++; - /* - * Wait at most one second. Secure world is normally never busy - * more than that so we should normally never timeout. - */ - wait_for_completion_timeout(&ptee->c, HZ); - ptee->c_waiters--; -} - -static void complete_teez(struct tee_tz *ptee) -{ - /* - * If at least one thread is waiting for "something to happen" let - * one thread know that "something has happened". - */ - if (ptee->c_waiters) - complete(&ptee->c); -} - -static void handle_rpc_func_cmd_mutex_wait(struct tee_tz *ptee, - struct teesmc32_arg *arg32) -{ - struct teesmc32_param *params; - - if (arg32->num_params != 2) - goto bad; - - params = TEESMC32_GET_PARAMS(arg32); - - if ((params[0].attr & TEESMC_ATTR_TYPE_MASK) != - TEESMC_ATTR_TYPE_VALUE_INPUT) - goto bad; - if ((params[1].attr & TEESMC_ATTR_TYPE_MASK) != - TEESMC_ATTR_TYPE_VALUE_INPUT) - goto bad; - - switch (params[0].u.value.a) { - case TEE_MUTEX_WAIT_SLEEP: - tee_mutex_wait_sleep(DEV, &ptee->mutex_wait, - params[1].u.value.a, - params[1].u.value.b); - break; - case TEE_MUTEX_WAIT_WAKEUP: - tee_mutex_wait_wakeup(DEV, &ptee->mutex_wait, - params[1].u.value.a, - params[1].u.value.b); - break; - case TEE_MUTEX_WAIT_DELETE: - tee_mutex_wait_delete(DEV, &ptee->mutex_wait, - params[1].u.value.a); - break; - default: - goto bad; - } - - arg32->ret = TEEC_SUCCESS; - return; -bad: - arg32->ret = TEEC_ERROR_BAD_PARAMETERS; -} - -static void handle_rpc_func_cmd_wait_queue(struct tee_tz *ptee, - struct teesmc32_arg *arg32) -{ - struct teesmc32_param *params; - - if (arg32->num_params != 2) - goto bad; - - params = TEESMC32_GET_PARAMS(arg32); - - if ((params[0].attr & TEESMC_ATTR_TYPE_MASK) != - TEESMC_ATTR_TYPE_VALUE_INPUT) - goto bad; - if ((params[1].attr & TEESMC_ATTR_TYPE_MASK) != - TEESMC_ATTR_TYPE_NONE) - goto bad; - - switch (arg32->cmd) { - case TEE_RPC_WAIT_QUEUE_SLEEP: - tee_wait_queue_sleep(DEV, &ptee->wait_queue, - params[0].u.value.a); - break; - case TEE_RPC_WAIT_QUEUE_WAKEUP: - tee_wait_queue_wakeup(DEV, &ptee->wait_queue, - params[0].u.value.a); - break; - default: - goto bad; - } - - arg32->ret = TEEC_SUCCESS; - return; -bad: - arg32->ret = TEEC_ERROR_BAD_PARAMETERS; -} - - - -static void handle_rpc_func_cmd_wait(struct teesmc32_arg *arg32) -{ - struct teesmc32_param *params; - u32 msec_to_wait; - - if (arg32->num_params != 1) - goto bad; - - params = TEESMC32_GET_PARAMS(arg32); - msec_to_wait = params[0].u.value.a; - - /* set task's state to interruptible sleep */ - set_current_state(TASK_INTERRUPTIBLE); - - /* take a nap */ - schedule_timeout(msecs_to_jiffies(msec_to_wait)); - - arg32->ret = TEEC_SUCCESS; - return; -bad: - arg32->ret = TEEC_ERROR_BAD_PARAMETERS; -} - -static void handle_rpc_func_cmd_to_supplicant(struct tee_tz *ptee, - struct teesmc32_arg *arg32) -{ - struct teesmc32_param *params; - struct tee_rpc_invoke inv; - size_t n; - uint32_t ret; - - if (arg32->num_params > TEE_RPC_BUFFER_NUMBER) { - arg32->ret = TEEC_ERROR_GENERIC; - return; - } - - params = TEESMC32_GET_PARAMS(arg32); - - memset(&inv, 0, sizeof(inv)); - inv.cmd = arg32->cmd; - /* - * Set a suitable error code in case tee-supplicant - * ignores the request. - */ - inv.res = TEEC_ERROR_NOT_IMPLEMENTED; - inv.nbr_bf = arg32->num_params; - for (n = 0; n < arg32->num_params; n++) { - switch (params[n].attr & TEESMC_ATTR_TYPE_MASK) { - case TEESMC_ATTR_TYPE_VALUE_INPUT: - case TEESMC_ATTR_TYPE_VALUE_INOUT: - inv.cmds[n].fd = (int)params[n].u.value.a; - /* Fall through */ - case TEESMC_ATTR_TYPE_VALUE_OUTPUT: - inv.cmds[n].type = TEE_RPC_VALUE; - break; - case TEESMC_ATTR_TYPE_MEMREF_INPUT: - case TEESMC_ATTR_TYPE_MEMREF_OUTPUT: - case TEESMC_ATTR_TYPE_MEMREF_INOUT: - inv.cmds[n].buffer = - (void *)(uintptr_t)params[n].u.memref.buf_ptr; - inv.cmds[n].size = params[n].u.memref.size; - inv.cmds[n].type = TEE_RPC_BUFFER; - break; - default: - arg32->ret = TEEC_ERROR_GENERIC; - return; - } - } - - ret = tee_supp_cmd(ptee->tee, TEE_RPC_ICMD_INVOKE, - &inv, sizeof(inv)); - if (ret == TEEC_RPC_OK) - arg32->ret = inv.res; - - for (n = 0; n < arg32->num_params; n++) { - switch (params[n].attr & TEESMC_ATTR_TYPE_MASK) { - case TEESMC_ATTR_TYPE_MEMREF_OUTPUT: - case TEESMC_ATTR_TYPE_MEMREF_INOUT: - /* - * Allow supplicant to assign a new pointer - * to an out-buffer. Needed when the - * supplicant allocates a new buffer, for - * instance when loading a TA. - */ - params[n].u.memref.buf_ptr = - (uint32_t)(uintptr_t)inv.cmds[n].buffer; - params[n].u.memref.size = inv.cmds[n].size; - break; - case TEESMC_ATTR_TYPE_VALUE_OUTPUT: - case TEESMC_ATTR_TYPE_VALUE_INOUT: - params[n].u.value.a = inv.cmds[n].fd; - break; - default: - break; - } - } -} - -static void handle_rpc_func_cmd(struct tee_tz *ptee, u32 parg32) -{ - struct teesmc32_arg *arg32; - - arg32 = tee_shm_pool_p2v(DEV, ptee->shm_pool, parg32); - if (!arg32) - return; - - switch (arg32->cmd) { - case TEE_RPC_MUTEX_WAIT: - handle_rpc_func_cmd_mutex_wait(ptee, arg32); - break; - case TEE_RPC_WAIT_QUEUE_SLEEP: - case TEE_RPC_WAIT_QUEUE_WAKEUP: - handle_rpc_func_cmd_wait_queue(ptee, arg32); - break; - case TEE_RPC_WAIT: - handle_rpc_func_cmd_wait(arg32); - break; - default: - handle_rpc_func_cmd_to_supplicant(ptee, arg32); - } -} - -static struct tee_shm *handle_rpc_alloc(struct tee_tz *ptee, size_t size) -{ - struct tee_rpc_alloc rpc_alloc; - - rpc_alloc.size = size; - tee_supp_cmd(ptee->tee, TEE_RPC_ICMD_ALLOCATE, - &rpc_alloc, sizeof(rpc_alloc)); - return rpc_alloc.shm; -} - -static void handle_rpc_free(struct tee_tz *ptee, struct tee_shm *shm) -{ - struct tee_rpc_free rpc_free; - - if (!shm) - return; - rpc_free.shm = shm; - tee_supp_cmd(ptee->tee, TEE_RPC_ICMD_FREE, &rpc_free, sizeof(rpc_free)); -} - -static u32 handle_rpc(struct tee_tz *ptee, struct smc_param *param) -{ - struct tee_shm *shm; - int cookie; - - switch (TEESMC_RETURN_GET_RPC_FUNC(param->a0)) { - case TEESMC_RPC_FUNC_ALLOC_ARG: - param->a1 = rk_tee_shm_pool_alloc(DEV, ptee->shm_pool, - param->a1, 4); - break; - case TEESMC_RPC_FUNC_ALLOC_PAYLOAD: - /* Can't support payload shared memory with this interface */ - param->a2 = 0; - break; - case TEESMC_RPC_FUNC_FREE_ARG: - rk_tee_shm_pool_free(DEV, ptee->shm_pool, param->a1, 0); - break; - case TEESMC_RPC_FUNC_FREE_PAYLOAD: - /* Can't support payload shared memory with this interface */ - break; - case TEESMC_ST_RPC_FUNC_ALLOC_PAYLOAD: - shm = handle_rpc_alloc(ptee, param->a1); - if (IS_ERR_OR_NULL(shm)) { - param->a1 = 0; - break; - } - cookie = handle_get(&shm_handle_db, shm); - if (cookie < 0) { - handle_rpc_free(ptee, shm); - param->a1 = 0; - break; - } - param->a1 = shm->paddr; - param->a2 = cookie; - break; - case TEESMC_ST_RPC_FUNC_FREE_PAYLOAD: - shm = handle_put(&shm_handle_db, param->a1); - handle_rpc_free(ptee, shm); - break; - case TEESMC_RPC_FUNC_IRQ: - break; - case TEESMC_RPC_FUNC_CMD: - handle_rpc_func_cmd(ptee, param->a1); - break; - default: - dev_warn(DEV, "Unknown RPC func 0x%x\n", - (u32)TEESMC_RETURN_GET_RPC_FUNC(param->a0)); - break; - } - - if (irqs_disabled()) - return TEESMC32_FASTCALL_RETURN_FROM_RPC; - else - return TEESMC32_CALL_RETURN_FROM_RPC; -} - -static void call_tee(struct tee_tz *ptee, - uintptr_t parg32, struct teesmc32_arg *arg32) -{ - u32 ret; - u32 funcid; - struct smc_param param = { 0 }; - - if (irqs_disabled()) - funcid = TEESMC32_FASTCALL_WITH_ARG; - else - funcid = TEESMC32_CALL_WITH_ARG; - - /* - * Commented out elements used to visualize the layout dynamic part - * of the struct. Note that these fields are not available at all - * if num_params == 0. - * - * params is accessed through the macro TEESMC32_GET_PARAMS - */ - - /* struct teesmc32_param params[num_params]; */ - - - param.a1 = parg32; - while (true) { - param.a0 = funcid; - -#ifdef SWITCH_CPU0_DEBUG - if (tee_smc_call_switchcpu0(¶m)) - break; -#else - tee_smc_call(¶m); -#endif - ret = param.a0; - - if (ret == TEESMC_RETURN_ETHREAD_LIMIT) { - /* - * Since secure world is out of threads, release the - * lock we had when entering this function and wait - * for "something to happen" (something else to - * exit from secure world and needed resources may - * have become available). - */ - wait_completion_teez(ptee); - } else if (TEESMC_RETURN_IS_RPC(ret)) { - /* Wake up waiting task */ - complete_teez(ptee); - /* Process the RPC. */ - funcid = handle_rpc(ptee, ¶m); - } else { - break; - } - } - - /* Wake up waiting task */ - complete_teez(ptee); - - switch (ret) { - case TEESMC_RETURN_UNKNOWN_FUNCTION: - break; - case TEESMC_RETURN_OK: - /* arg32->ret set by secure world */ - break; - default: - /* Should not happen */ - arg32->ret = TEEC_ERROR_COMMUNICATION; - arg32->ret_origin = TEEC_ORIGIN_COMMS; - break; - } -} - -/******************************************************************* - * TEE service invoke formating - *******************************************************************/ - -/* allocate tee service argument buffer and return virtual address */ -static void *alloc_tee_arg(struct tee_tz *ptee, unsigned long *p, size_t l) -{ - void *vaddr; - dev_dbg(DEV, ">\n"); - BUG_ON(!CAPABLE(ptee->tee)); - - if ((p == NULL) || (l == 0)) - return NULL; - - /* assume a 4 bytes aligned is sufficient */ - *p = rk_tee_shm_pool_alloc(DEV, ptee->shm_pool, l, ALLOC_ALIGN); - if (*p == 0) - return NULL; - - vaddr = tee_shm_pool_p2v(DEV, ptee->shm_pool, *p); - - dev_dbg(DEV, "< %p\n", vaddr); - - return vaddr; -} - -/* free tee service argument buffer (from its physical address) */ -static void free_tee_arg(struct tee_tz *ptee, unsigned long p) -{ - dev_dbg(DEV, ">\n"); - BUG_ON(!CAPABLE(ptee->tee)); - - if (p) - rk_tee_shm_pool_free(DEV, ptee->shm_pool, p, 0); - - dev_dbg(DEV, "<\n"); -} - -static uint32_t get_cache_attrs(struct tee_tz *ptee) -{ - if (tee_shm_pool_is_cached(ptee->shm_pool)) - return TEESMC_ATTR_CACHE_DEFAULT << TEESMC_ATTR_CACHE_SHIFT; - else - return TEESMC_ATTR_CACHE_NONCACHE << TEESMC_ATTR_CACHE_SHIFT; -} - -static uint32_t param_type_teec2teesmc(uint8_t type) -{ - switch (type) { - case TEEC_NONE: - return TEESMC_ATTR_TYPE_NONE; - case TEEC_VALUE_INPUT: - return TEESMC_ATTR_TYPE_VALUE_INPUT; - case TEEC_VALUE_OUTPUT: - return TEESMC_ATTR_TYPE_VALUE_OUTPUT; - case TEEC_VALUE_INOUT: - return TEESMC_ATTR_TYPE_VALUE_INOUT; - case TEEC_MEMREF_TEMP_INPUT: - case TEEC_MEMREF_PARTIAL_INPUT: - return TEESMC_ATTR_TYPE_MEMREF_INPUT; - case TEEC_MEMREF_TEMP_OUTPUT: - case TEEC_MEMREF_PARTIAL_OUTPUT: - return TEESMC_ATTR_TYPE_MEMREF_OUTPUT; - case TEEC_MEMREF_WHOLE: - case TEEC_MEMREF_TEMP_INOUT: - case TEEC_MEMREF_PARTIAL_INOUT: - return TEESMC_ATTR_TYPE_MEMREF_INOUT; - default: - WARN_ON(true); - return 0; - } -} - -static void set_params(struct tee_tz *ptee, - struct teesmc32_param params32[TEEC_CONFIG_PAYLOAD_REF_COUNT], - uint32_t param_types, - struct tee_data *data) -{ - size_t n; - struct tee_shm *shm; - TEEC_Value *value; - - for (n = 0; n < TEEC_CONFIG_PAYLOAD_REF_COUNT; n++) { - uint32_t type = TEEC_PARAM_TYPE_GET(param_types, n); - - params32[n].attr = param_type_teec2teesmc(type); - if (params32[n].attr == TEESMC_ATTR_TYPE_NONE) - continue; - if (params32[n].attr < TEESMC_ATTR_TYPE_MEMREF_INPUT) { - value = (TEEC_Value *)&data->params[n]; - params32[n].u.value.a = value->a; - params32[n].u.value.b = value->b; - continue; - } - shm = data->params[n].shm; - params32[n].attr |= get_cache_attrs(ptee); - params32[n].u.memref.buf_ptr = shm->paddr; - params32[n].u.memref.size = shm->size_req; - } -} - -static void get_params(struct tee_data *data, - struct teesmc32_param params32[TEEC_CONFIG_PAYLOAD_REF_COUNT]) -{ - size_t n; - struct tee_shm *shm; - TEEC_Value *value; - - for (n = 0; n < TEEC_CONFIG_PAYLOAD_REF_COUNT; n++) { - if (params32[n].attr == TEESMC_ATTR_TYPE_NONE) - continue; - if (params32[n].attr < TEESMC_ATTR_TYPE_MEMREF_INPUT) { - value = &data->params[n].value; - value->a = params32[n].u.value.a; - value->b = params32[n].u.value.b; - continue; - } - shm = data->params[n].shm; - shm->size_req = params32[n].u.memref.size; - } -} - - -/* - * tee_open_session - invoke TEE to open a GP TEE session - */ -static int tz_open(struct tee_session *sess, struct tee_cmd *cmd) -{ - struct tee *tee; - struct tee_tz *ptee; - int ret = 0; - - struct teesmc32_arg *arg32; - struct teesmc32_param *params32; - struct teesmc_meta_open_session *meta; - uintptr_t parg32; - uintptr_t pmeta; - size_t num_meta = 1; - uint8_t *ta; - TEEC_UUID *uuid; - - BUG_ON(!sess->ctx->tee); - BUG_ON(!sess->ctx->tee->priv); - tee = sess->ctx->tee; - ptee = tee->priv; - - if (cmd->uuid) - uuid = cmd->uuid->kaddr; - else - uuid = NULL; - - dev_dbg(tee->dev, "> ta kaddr %p, uuid=%08x-%04x-%04x\n", - (cmd->ta) ? cmd->ta->kaddr : NULL, - ((uuid) ? uuid->timeLow : 0xDEAD), - ((uuid) ? uuid->timeMid : 0xDEAD), - ((uuid) ? uuid->timeHiAndVersion : 0xDEAD)); - - if (!CAPABLE(ptee->tee)) { - dev_dbg(tee->dev, "< not capable\n"); - return -EBUSY; - } - - /* case ta binary is inside the open request */ - ta = NULL; - if (cmd->ta) - ta = cmd->ta->kaddr; - if (ta) - num_meta++; - - arg32 = alloc_tee_arg(ptee, &parg32, TEESMC32_GET_ARG_SIZE( - TEEC_CONFIG_PAYLOAD_REF_COUNT + num_meta)); - meta = alloc_tee_arg(ptee, &pmeta, sizeof(*meta)); - - if ((arg32 == NULL) || (meta == NULL)) { - free_tee_arg(ptee, parg32); - free_tee_arg(ptee, pmeta); - return TEEC_ERROR_OUT_OF_MEMORY; - } - - memset(arg32, 0, sizeof(*arg32)); - memset(meta, 0, sizeof(*meta)); - arg32->num_params = TEEC_CONFIG_PAYLOAD_REF_COUNT + num_meta; - params32 = TEESMC32_GET_PARAMS(arg32); - - arg32->cmd = TEESMC_CMD_OPEN_SESSION; - - params32[0].u.memref.buf_ptr = pmeta; - params32[0].u.memref.size = sizeof(*meta); - params32[0].attr = TEESMC_ATTR_TYPE_MEMREF_INPUT | - TEESMC_ATTR_META | get_cache_attrs(ptee); - - if (ta) { - params32[1].u.memref.buf_ptr = - tee_shm_pool_v2p(DEV, ptee->shm_pool, cmd->ta->kaddr); - params32[1].u.memref.size = cmd->ta->size_req; - params32[1].attr = TEESMC_ATTR_TYPE_MEMREF_INPUT | - TEESMC_ATTR_META | get_cache_attrs(ptee); - } - - if (uuid != NULL) - memcpy(meta->uuid, uuid, TEESMC_UUID_LEN); - meta->clnt_login = 0; /* FIXME: is this reliable ? used ? */ - - params32 += num_meta; - set_params(ptee, params32, cmd->param.type, &cmd->param); - - call_tee(ptee, parg32, arg32); - - get_params(&cmd->param, params32); - - if (arg32->ret != TEEC_ERROR_COMMUNICATION) { - sess->sessid = arg32->session; - cmd->err = arg32->ret; - cmd->origin = arg32->ret_origin; - } else - ret = -EBUSY; - - free_tee_arg(ptee, parg32); - free_tee_arg(ptee, pmeta); - - dev_dbg(DEV, "< %x:%d\n", arg32->ret, ret); - return ret; -} - -/* - * tee_invoke_command - invoke TEE to invoke a GP TEE command - */ -static int tz_invoke(struct tee_session *sess, struct tee_cmd *cmd) -{ - struct tee *tee; - struct tee_tz *ptee; - int ret = 0; - - struct teesmc32_arg *arg32; - uintptr_t parg32; - struct teesmc32_param *params32; - - BUG_ON(!sess->ctx->tee); - BUG_ON(!sess->ctx->tee->priv); - tee = sess->ctx->tee; - ptee = tee->priv; - - dev_dbg(DEV, "> sessid %x cmd %x type %x\n", - sess->sessid, cmd->cmd, cmd->param.type); - - if (!CAPABLE(tee)) { - dev_dbg(tee->dev, "< not capable\n"); - return -EBUSY; - } - - arg32 = (typeof(arg32))alloc_tee_arg(ptee, &parg32, - TEESMC32_GET_ARG_SIZE(TEEC_CONFIG_PAYLOAD_REF_COUNT)); - if (!arg32) { - free_tee_arg(ptee, parg32); - return TEEC_ERROR_OUT_OF_MEMORY; - } - - memset(arg32, 0, sizeof(*arg32)); - arg32->num_params = TEEC_CONFIG_PAYLOAD_REF_COUNT; - params32 = TEESMC32_GET_PARAMS(arg32); - - arg32->cmd = TEESMC_CMD_INVOKE_COMMAND; - arg32->session = sess->sessid; - arg32->ta_func = cmd->cmd; - - set_params(ptee, params32, cmd->param.type, &cmd->param); - - call_tee(ptee, parg32, arg32); - - get_params(&cmd->param, params32); - - if (arg32->ret != TEEC_ERROR_COMMUNICATION) { - cmd->err = arg32->ret; - cmd->origin = arg32->ret_origin; - } else - ret = -EBUSY; - - free_tee_arg(ptee, parg32); - - dev_dbg(DEV, "< %x:%d\n", arg32->ret, ret); - return ret; -} - -/* - * tee_cancel_command - invoke TEE to cancel a GP TEE command - */ -static int tz_cancel(struct tee_session *sess, struct tee_cmd *cmd) -{ - struct tee *tee; - struct tee_tz *ptee; - int ret = 0; - - struct teesmc32_arg *arg32; - uintptr_t parg32; - - BUG_ON(!sess->ctx->tee); - BUG_ON(!sess->ctx->tee->priv); - tee = sess->ctx->tee; - ptee = tee->priv; - - dev_dbg(DEV, "cancel on sessid=%08x\n", sess->sessid); - - arg32 = alloc_tee_arg(ptee, &parg32, TEESMC32_GET_ARG_SIZE(0)); - if (arg32 == NULL) { - free_tee_arg(ptee, parg32); - return TEEC_ERROR_OUT_OF_MEMORY; - } - - memset(arg32, 0, sizeof(*arg32)); - arg32->cmd = TEESMC_CMD_CANCEL; - arg32->session = sess->sessid; - - call_tee(ptee, parg32, arg32); - - if (arg32->ret == TEEC_ERROR_COMMUNICATION) - ret = -EBUSY; - - free_tee_arg(ptee, parg32); - - dev_dbg(DEV, "< %x:%d\n", arg32->ret, ret); - return ret; -} - -/* - * tee_close_session - invoke TEE to close a GP TEE session - */ -static int tz_close(struct tee_session *sess) -{ - struct tee *tee; - struct tee_tz *ptee; - int ret = 0; - - struct teesmc32_arg *arg32; - uintptr_t parg32; - - BUG_ON(!sess->ctx->tee); - BUG_ON(!sess->ctx->tee->priv); - tee = sess->ctx->tee; - ptee = tee->priv; - - dev_dbg(DEV, "close on sessid=%08x\n", sess->sessid); - - if (!CAPABLE(tee)) { - dev_dbg(tee->dev, "< not capable\n"); - return -EBUSY; - } - - arg32 = alloc_tee_arg(ptee, &parg32, TEESMC32_GET_ARG_SIZE(0)); - if (arg32 == NULL) { - free_tee_arg(ptee, parg32); - return TEEC_ERROR_OUT_OF_MEMORY; - } - - dev_dbg(DEV, "> [%x]\n", sess->sessid); - - memset(arg32, 0, sizeof(*arg32)); - arg32->cmd = TEESMC_CMD_CLOSE_SESSION; - arg32->session = sess->sessid; - - call_tee(ptee, parg32, arg32); - - if (arg32->ret == TEEC_ERROR_COMMUNICATION) - ret = -EBUSY; - - free_tee_arg(ptee, parg32); - - dev_dbg(DEV, "< %x:%d\n", arg32->ret, ret); - return ret; -} - -static struct tee_shm *tz_alloc(struct tee *tee, size_t size, uint32_t flags) -{ - struct tee_shm *shm = NULL; - struct tee_tz *ptee; - size_t size_aligned; - BUG_ON(!tee->priv); - ptee = tee->priv; - - dev_dbg(DEV, "%s: s=%d,flags=0x%08x\n", __func__, (int)size, flags); - -/* comment due to #6357 - * if ( (flags & ~(tee->shm_flags | TEE_SHM_MAPPED - * | TEE_SHM_TEMP | TEE_SHM_FROM_RPC)) != 0 ) { - dev_err(tee->dev, "%s: flag parameter is invalid\n", __func__); - return ERR_PTR(-EINVAL); - }*/ - - size_aligned = ((size / SZ_4K) + 1) * SZ_4K; - if (unlikely(size_aligned == 0)) { - dev_err(DEV, "[%s] requested size too big\n", __func__); - return NULL; - } - - shm = devm_kzalloc(tee->dev, sizeof(struct tee_shm), GFP_KERNEL); - if (!shm) { - dev_err(tee->dev, "%s: kzalloc failed\n", __func__); - return ERR_PTR(-ENOMEM); - } - - shm->size_alloc = ((size / SZ_4K) + 1) * SZ_4K; - shm->size_req = size; - shm->paddr = rk_tee_shm_pool_alloc(tee->dev, ptee->shm_pool, - shm->size_alloc, ALLOC_ALIGN); - if (!shm->paddr) { - dev_err(tee->dev, "%s: cannot alloc memory, size 0x%lx\n", - __func__, (unsigned long)shm->size_alloc); - devm_kfree(tee->dev, shm); - return ERR_PTR(-ENOMEM); - } - shm->kaddr = tee_shm_pool_p2v(tee->dev, ptee->shm_pool, shm->paddr); - if (!shm->kaddr) { - dev_err(tee->dev, "%s: p2v(%pad)=0\n", __func__, - &shm->paddr); - rk_tee_shm_pool_free(tee->dev, ptee->shm_pool, shm->paddr, NULL); - devm_kfree(tee->dev, shm); - return ERR_PTR(-EFAULT); - } - shm->flags = flags; - if (ptee->shm_cached) - shm->flags |= TEE_SHM_CACHED; - - dev_dbg(tee->dev, "%s: kaddr=%p, paddr=%pad, shm=%p, size %x:%x\n", - __func__, shm->kaddr, &shm->paddr, shm, - (unsigned int)shm->size_req, (unsigned int)shm->size_alloc); - - return shm; -} - -static void tz_free(struct tee_shm *shm) -{ - size_t size; - int ret; - struct tee *tee; - struct tee_tz *ptee; - - BUG_ON(!shm->tee); - BUG_ON(!shm->tee->priv); - tee = shm->tee; - ptee = tee->priv; - - dev_dbg(tee->dev, "%s: shm=%p\n", __func__, shm); - - ret = rk_tee_shm_pool_free(tee->dev, ptee->shm_pool, shm->paddr, &size); - if (!ret) { - devm_kfree(tee->dev, shm); - shm = NULL; - } -} - -static int tz_shm_inc_ref(struct tee_shm *shm) -{ - struct tee *tee; - struct tee_tz *ptee; - - BUG_ON(!shm->tee); - BUG_ON(!shm->tee->priv); - tee = shm->tee; - ptee = tee->priv; - - return tee_shm_pool_incref(tee->dev, ptee->shm_pool, shm->paddr); -} - -/******************************************************************************/ -/* -static void tee_get_status(struct tee_tz *ptee) -{ - TEEC_Result ret; - struct tee_msg_send *arg; - struct tee_core_status_out *res; - unsigned long parg, pres; - - if (!CAPABLE(ptee->tee)) - return; - - arg = (typeof(arg))alloc_tee_arg(ptee, &parg, sizeof(*arg)); - res = (typeof(res))alloc_tee_arg(ptee, &pres, sizeof(*res)); - - if ((arg == NULL) || (res == NULL)) { - dev_err(DEV, "TZ outercache mutex error: alloc shm failed\n"); - goto out; - } - - memset(arg, 0, sizeof(*arg)); - memset(res, 0, sizeof(*res)); - arg->service = ISSWAPI_TEE_GET_CORE_STATUS; - ret = send_and_wait(ptee, ISSWAPI_TEE_GET_CORE_STATUS, SEC_ROM_DEFAULT, - parg, pres); - if (ret != TEEC_SUCCESS) { - dev_warn(DEV, "get statuc failed\n"); - goto out; - } - - pr_info("TEETZ Firmware status:\n"); - pr_info("%s", res->raw); - -out: - free_tee_arg(ptee, parg); - free_tee_arg(ptee, pres); -}*/ - -#ifdef CONFIG_OUTER_CACHE -/* - * Synchronised outer cache maintenance support - */ -#ifndef CONFIG_ARM_TZ_SUPPORT -/* weak outer_tz_mutex in case not supported by kernel */ -bool __weak outer_tz_mutex(unsigned long *p) -{ - pr_err("weak outer_tz_mutex"); - if (p != NULL) - return false; - return true; -} -#endif - -/* register_outercache_mutex - Negotiate/Disable outer cache shared mutex */ -static int register_outercache_mutex(struct tee_tz *ptee, bool reg) -{ - unsigned long *vaddr = NULL; - int ret = 0; - struct smc_param param; - uintptr_t paddr = 0; - - dev_dbg(ptee->tee->dev, ">\n"); - BUG_ON(!CAPABLE(ptee->tee)); - - if ((reg == true) && (ptee->tz_outer_cache_mutex != NULL)) { - dev_err(DEV, "outer cache shared mutex already registered\n"); - return -EINVAL; - } - if ((reg == false) && (ptee->tz_outer_cache_mutex == NULL)) - return 0; - - mutex_lock(&ptee->mutex); - - if (reg == false) { - vaddr = ptee->tz_outer_cache_mutex; - ptee->tz_outer_cache_mutex = NULL; - goto out; - } - - memset(¶m, 0, sizeof(param)); - param.a0 = TEESMC32_ST_FASTCALL_L2CC_MUTEX; - param.a1 = TEESMC_ST_L2CC_MUTEX_GET_ADDR; -#ifdef SWITCH_CPU0_DEBUG - ret = tee_smc_call_switchcpu0(¶m); - if (ret) - goto out; -#else - tee_smc_call(¶m); -#endif - - if (param.a0 != TEESMC_RETURN_OK) { - dev_warn(DEV, "no TZ l2cc mutex service supported\n"); - goto out; - } - paddr = param.a2; - dev_dbg(DEV, "outer cache shared mutex paddr 0x%lx\n", paddr); - - vaddr = ioremap_cache(paddr, sizeof(u32)); - if (vaddr == NULL) { - dev_warn(DEV, "TZ l2cc mutex disabled: ioremap failed\n"); - ret = -ENOMEM; - goto out; - } - - dev_dbg(DEV, "outer cache shared mutex vaddr %p\n", vaddr); - if (outer_tz_mutex(vaddr) == false) { - dev_warn(DEV, "TZ l2cc mutex disabled: outer cache refused\n"); - goto out; - } - - memset(¶m, 0, sizeof(param)); - param.a0 = TEESMC32_ST_FASTCALL_L2CC_MUTEX; - param.a1 = TEESMC_ST_L2CC_MUTEX_ENABLE; -#ifdef SWITCH_CPU0_DEBUG - ret = tee_smc_call_switchcpu0(¶m); - if (ret) - goto out; -#else - tee_smc_call(¶m); -#endif - - if (param.a0 != TEESMC_RETURN_OK) { - - dev_warn(DEV, "TZ l2cc mutex disabled: TZ enable failed\n"); - goto out; - } - ptee->tz_outer_cache_mutex = vaddr; - -out: - if (ptee->tz_outer_cache_mutex == NULL) { - memset(¶m, 0, sizeof(param)); - param.a0 = TEESMC32_ST_FASTCALL_L2CC_MUTEX; - param.a1 = TEESMC_ST_L2CC_MUTEX_DISABLE; -#ifdef SWITCH_CPU0_DEBUG - ret = tee_smc_call_switchcpu0(¶m); - if (ret) { - mutex_unlock(&ptee->mutex); - return ret; - } -#else - tee_smc_call(¶m); -#endif - outer_tz_mutex(NULL); - if (vaddr) - iounmap(vaddr); - dev_dbg(DEV, "outer cache shared mutex disabled\n"); - } - - mutex_unlock(&ptee->mutex); - dev_dbg(DEV, "< teetz outer mutex: ret=%d pa=0x%lX va=0x%p %sabled\n", - ret, paddr, vaddr, ptee->tz_outer_cache_mutex ? "en" : "dis"); - return ret; -} -#endif - -/* configure_shm - Negotiate Shared Memory configuration with teetz. */ -static int configure_shm(struct tee_tz *ptee) -{ - struct smc_param param = { 0 }; - size_t shm_size = -1; - int ret = 0; - - dev_dbg(DEV, ">\n"); - BUG_ON(!CAPABLE(ptee->tee)); - - mutex_lock(&ptee->mutex); - param.a0 = TEESMC32_ST_FASTCALL_GET_SHM_CONFIG; -#ifdef SWITCH_CPU0_DEBUG - ret = tee_smc_call_switchcpu0(¶m); - if (ret) { - mutex_unlock(&ptee->mutex); - goto out; - } -#else - tee_smc_call(¶m); -#endif - mutex_unlock(&ptee->mutex); - - if (param.a0 != TEESMC_RETURN_OK) { - dev_err(DEV, "shm service not available: %X", (uint)param.a0); - ret = -EINVAL; - goto out; - } - - ptee->shm_paddr = param.a1; - shm_size = param.a2; - ptee->shm_cached = (bool)param.a3; - - if (ptee->shm_cached) - ptee->shm_vaddr = ioremap_cache(ptee->shm_paddr, shm_size); - else - ptee->shm_vaddr = ioremap(ptee->shm_paddr, shm_size); - - if (ptee->shm_vaddr == NULL) { - dev_err(DEV, "shm ioremap failed\n"); - ret = -ENOMEM; - goto out; - } - - ptee->shm_pool = tee_shm_pool_create(DEV, shm_size, - ptee->shm_vaddr, ptee->shm_paddr); - - if (!ptee->shm_pool) { - dev_err(DEV, "shm pool creation failed (%zu)", shm_size); - ret = -EINVAL; - goto out; - } - - if (ptee->shm_cached) - tee_shm_pool_set_cached(ptee->shm_pool); -out: - dev_dbg(DEV, "< ret=%d pa=0x%lX va=0x%p size=%zu, %scached", - ret, ptee->shm_paddr, ptee->shm_vaddr, shm_size, - (ptee->shm_cached == 1) ? "" : "un"); - return ret; -} - -static int rk_set_uart_port(struct tee_tz *ptee) -{ - struct smc_param param = {0}; - struct device_node *np; - int serial_id; - int ret = 0; - - np = of_find_node_by_name(NULL, "fiq-debugger"); - if (!np) - return -ENODEV; - - if (of_device_is_available(np)) { - if (of_property_read_u32(np, "rockchip,serial-id", &serial_id)) - return -EINVAL; - } else { - serial_id = 0xffffffff; - } - - dev_dbg(DEV, "optee set uart port id: %d\n", serial_id); - param.a0 = TEESMC32_ROCKCHIP_FASTCALL_SET_UART_PORT; - param.a1 = serial_id; - - mutex_lock(&ptee->mutex); -#ifdef SWITCH_CPU0_DEBUG - ret = tee_smc_call_switchcpu0(¶m); -#else - tee_smc_call(¶m); -#endif - mutex_unlock(&ptee->mutex); - - return ret; -} - -/******************************************************************************/ - -static int tz_start(struct tee *tee) -{ - struct tee_tz *ptee; - int ret; - - BUG_ON(!tee || !tee->priv); - dev_dbg(tee->dev, ">\n"); - if (!CAPABLE(tee)) { - dev_dbg(tee->dev, "< not capable\n"); - return -EBUSY; - } - - ptee = tee->priv; - BUG_ON(ptee->started); - ptee->started = true; - - ret = configure_shm(ptee); - if (ret) - goto exit; - - -#ifdef CONFIG_OUTER_CACHE - ret = register_outercache_mutex(ptee, true); - if (ret) - goto exit; -#endif - -exit: - if (ret) - ptee->started = false; - - dev_dbg(tee->dev, "< ret=%d dev=%s\n", ret, tee->name); - return ret; -} - -static int tz_stop(struct tee *tee) -{ - struct tee_tz *ptee; - - BUG_ON(!tee || !tee->priv); - - ptee = tee->priv; - - dev_dbg(tee->dev, "> dev=%s\n", tee->name); - if (!CAPABLE(tee)) { - dev_dbg(tee->dev, "< not capable\n"); - return -EBUSY; - } - -#ifdef CONFIG_OUTER_CACHE - register_outercache_mutex(ptee, false); -#endif - tee_shm_pool_destroy(tee->dev, ptee->shm_pool); - iounmap(ptee->shm_vaddr); - ptee->started = false; - - dev_dbg(tee->dev, "< ret=0 dev=%s\n", tee->name); - return 0; -} - -/******************************************************************************/ - -static const struct tee_ops tee_fops = { - .type = "tz", - .owner = THIS_MODULE, - .start = tz_start, - .stop = tz_stop, - .invoke = tz_invoke, - .cancel = tz_cancel, - .open = tz_open, - .close = tz_close, - .alloc = tz_alloc, - .free = tz_free, - .shm_inc_ref = tz_shm_inc_ref, -}; - -static int tz_tee_init(struct platform_device *pdev) -{ - int ret = 0; - - struct tee *tee = platform_get_drvdata(pdev); - struct tee_tz *ptee = tee->priv; - - tee_tz = ptee; - -#if 0 - /* To replace by a syscall */ -#ifndef CONFIG_ARM_TZ_SUPPORT - dev_err(tee->dev, - "%s: dev=%s, TZ fw is not loaded: TEE TZ is not supported.\n", - __func__, tee->name); - tee->conf = TEE_CONF_FW_NOT_CAPABLE; - return 0; -#endif -#endif - - ptee->started = false; - ptee->sess_id = 0xAB000000; - mutex_init(&ptee->mutex); - init_completion(&ptee->c); - ptee->c_waiters = 0; - - tee_wait_queue_init(&ptee->wait_queue); - ret = tee_mutex_wait_init(&ptee->mutex_wait); - - if (ret) - dev_err(tee->dev, "%s: dev=%s, Secure armv7 failed (%d)\n", - __func__, tee->name, ret); - else - dev_dbg(tee->dev, "%s: dev=%s, Secure armv7\n", - __func__, tee->name); - return ret; -} - -static void tz_tee_deinit(struct platform_device *pdev) -{ - struct tee *tee = platform_get_drvdata(pdev); - struct tee_tz *ptee = tee->priv; - - if (!CAPABLE(tee)) - return; - - tee_mutex_wait_exit(&ptee->mutex_wait); - tee_wait_queue_exit(&ptee->wait_queue); - - dev_dbg(tee->dev, "%s: dev=%s, Secure armv7 started=%d\n", __func__, - tee->name, ptee->started); -} - -static int tz_tee_probe(struct platform_device *pdev) -{ - int ret = 0; - struct device *dev = &pdev->dev; - struct tee *tee; - struct tee_tz *ptee; - - pr_info("%s: name=\"%s\", id=%d, pdev_name=\"%s\"\n", __func__, - pdev->name, pdev->id, dev_name(dev)); -#ifdef _TEE_DEBUG - pr_debug("- dev=%p\n", dev); - pr_debug("- dev->parent=%p\n", dev->ctx); - pr_debug("- dev->driver=%p\n", dev->driver); -#endif - - tee = tee_core_alloc(dev, _TEE_TZ_NAME, pdev->id, &tee_fops, - sizeof(struct tee_tz)); - if (!tee) - return -ENOMEM; - - ptee = tee->priv; - ptee->tee = tee; - - platform_set_drvdata(pdev, tee); - - ret = tz_tee_init(pdev); - if (ret) - goto bail0; - - ret = tee_core_add(tee); - if (ret) - goto bail1; - - rk_set_uart_port(ptee); - -#ifdef _TEE_DEBUG - pr_debug("- tee=%p, id=%d, iminor=%d\n", tee, tee->id, - tee->miscdev.minor); -#endif - return 0; - -bail1: - tz_tee_deinit(pdev); -bail0: - tee_core_free(tee); - return ret; -} - -static int tz_tee_remove(struct platform_device *pdev) -{ - struct tee *tee = platform_get_drvdata(pdev); - struct device *dev = &pdev->dev; - /*struct tee_tz *ptee;*/ - - pr_info("%s: name=\"%s\", id=%d, pdev_name=\"%s\"\n", __func__, - pdev->name, pdev->id, dev_name(dev)); -#ifdef _TEE_DEBUG - pr_debug("- tee=%p, id=%d, iminor=%d, name=%s\n", - tee, tee->id, tee->miscdev.minor, tee->name); -#endif - -/* ptee = tee->priv; - tee_get_status(ptee);*/ - - tz_tee_deinit(pdev); - tee_core_del(tee); - return 0; -} - -static struct of_device_id tz_tee_match[] = { - { - .compatible = "stm,armv7sec", - }, - {}, -}; - -static struct platform_driver tz_tee_driver = { - .probe = tz_tee_probe, - .remove = tz_tee_remove, - .driver = { - .name = "armv7sec", - .owner = THIS_MODULE, - .of_match_table = tz_tee_match, - }, -}; - -static struct platform_device tz_0_plt_device = { - .name = "armv7sec", - .id = 0, - .dev = { -/* .platform_data = tz_0_tee_data,*/ - }, -}; - -static int __init tee_tz_init(void) -{ - int rc; - -#ifdef CONFIG_ARM - if (!psci_smp_available()) { - pr_info("tee: kernel is running in secure mode, tee service unavailable.\n"); - return -EACCES; - } -#endif - - pr_info("TEE armv7 Driver initialization\n"); - -#ifdef _TEE_DEBUG - pr_debug("- Register the platform_driver \"%s\" %p\n", - tz_tee_driver.driver.name, &tz_tee_driver.driver); -#endif - - rc = platform_driver_register(&tz_tee_driver); - if (rc != 0) { - pr_err("failed to register the platform driver (rc=%d)\n", rc); - goto bail0; - } - - rc = platform_device_register(&tz_0_plt_device); - if (rc != 0) { - pr_err("failed to register the platform devices 0 (rc=%d)\n", - rc); - goto bail1; - } - - return rc; - -bail1: - platform_driver_unregister(&tz_tee_driver); -bail0: - return rc; -} - -static void __exit tee_tz_exit(void) -{ - pr_info("TEE ARMV7 Driver de-initialization\n"); - - platform_device_unregister(&tz_0_plt_device); - platform_driver_unregister(&tz_tee_driver); -} - -module_init(tee_tz_init); -module_exit(tee_tz_exit); - -MODULE_AUTHOR("STMicroelectronics"); -MODULE_DESCRIPTION("STM Secure TEE ARMV7 TZ driver"); -MODULE_SUPPORTED_DEVICE(""); -MODULE_LICENSE("GPL"); -MODULE_VERSION("1.0"); diff --git a/security/optee_linuxdriver/armtz/tee_tz_op.h b/security/optee_linuxdriver/armtz/tee_tz_op.h deleted file mode 100644 index 7f8f0aff500c..000000000000 --- a/security/optee_linuxdriver/armtz/tee_tz_op.h +++ /dev/null @@ -1,270 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_ARMV7_OP_H__ -#define __TEE_ARMV7_OP_H__ - -enum t_issw_service_id { - /* - * ("SSAPI_PRE_INIT_SERV") - */ - SSAPI_PRE_INIT_SERV = 1, - - /* - * ("SSAPI_POST_SPEEDUP_INIT_SERV") - * Reserved, Not used - */ - SSAPI_POST_SPEEDUP_INIT_SERV = 2, - - /* - * ("SSAPI_ISSW_IMPORT_SERV") - */ - SSAPI_ISSW_IMPORT_SERV = 3, - - /* - * ("SSAPI_RET_FROM_INT_SERV") - */ - SSAPI_RET_FROM_INT_SERV = 4, - - /* - * ("SSAPI_RET_FROM_RPC_SERV") - */ - SSAPI_RET_FROM_RPC_SERV = 5, - - /* - * "ISSWAPI_ISSW_EXECUTE_SERV" is linked to ROM code - * ("SSAPI_ISSW_EXECUTE_SERV") - */ - ISSWAPI_ISSW_EXECUTE_SERV = 6, - ISSWAPI_PROT_APPL_MSG_SEND = 0x10000000, - ISSWAPI_EXTERNAL_CODE_CHECK = 0x10000001, - ISSWAPI_SECURE_LOAD = 0x10000002, - ISSWAPI_ISSW_REIMPORT_PUB_KEYS = 0x10000003, - - /* Accessible only on request */ - ISSWAPI_WRITE_L2CC = 0x10000004, - ISSWAPI_WRITE_CP15_SCTLR = 0x10000005, - ISSWAPI_READ_CP15_SCTLR = 0x10000006, - ISSWAPI_WRITE_CP15_ACTLR = 0x10000007, - ISSWAPI_READ_CP15_ACTLR = 0x10000008, - ISSWAPI_WRITE_CP15_DIAGR = 0x10000009, - ISSWAPI_READ_CP15_DIAGR = 0x1000000A, - - ISSWAPI_EXECUTE_TA = 0x11000001, - ISSWAPI_CLOSE_TA = 0x11000002, - ISSWAPI_FLUSH_BOOT_CODE = 0x11000003, - /* Generic, restricted to be used by u-boot */ - ISSWAPI_VERIFY_SIGNED_HEADER = 0x11000005, - ISSWAPI_VERIFY_HASH = 0x11000006, - /* 8500 only, restricted to be used by u-boot */ - ISSWAPI_GET_RT_FLAGS = 0x11000007, - - /* For TEE Client API 1.0 */ - ISSWAPI_TEEC_OPEN_SESSION = 0x11000008, - ISSWAPI_TEEC_CLOSE_SESSION = 0x11000009, - ISSWAPI_TEEC_INVOKE_COMMAND = 0x1100000a, - ISSWAPI_REGISTER_RPC = 0x1100000b, /* this is NOT a GP TEE API ! */ - ISSWAPI_SET_SEC_DDR = 0x1100000c, /* this is NOT a GP TEE API ! */ - ISSWAPI_TEEC_CANCEL_COMMAND = 0x1100000d, - ISSWAPI_TEEC_REGISTER_MEMORY = 0x1100000e, - ISSWAPI_TEEC_UNREGISTER_MEMORY = 0x1100000f, - - /* Internal command */ - ISSWAPI_TEE_DEINIT_CPU = 0x11000010, - ISSWAPI_TEE_CRASH_CPU = 0x11000011, - ISSWAPI_TEE_SET_CORE_TRACE_LEVEL = 0x11000012, - ISSWAPI_TEE_GET_CORE_TRACE_LEVEL = 0x11000013, - ISSWAPI_TEE_SET_TA_TRACE_LEVEL = 0x11000014, - ISSWAPI_TEE_GET_TA_TRACE_LEVEL = 0x11000015, - ISSWAPI_TEE_GET_CORE_STATUS = 0x11000016, - ISSWAPI_TEE_FLUSH_CACHE = 0x11000017, - - ISSWAPI_REGISTER_DEF_SHM = 0x11000020, - ISSWAPI_UNREGISTER_DEF_SHM = 0x11000021, - ISSWAPI_REGISTER_IRQFWD = 0x11000022, - ISSWAPI_UNREGISTER_IRQFWD = 0x11000023, - ISSWAPI_GET_SHM_START = 0x11000024, - ISSWAPI_GET_SHM_SIZE = 0x11000025, - ISSWAPI_GET_SHM_CACHED = 0x11000026, - - ISSWAPI_ENABLE_L2CC_MUTEX = 0x20000000, - ISSWAPI_DISABLE_L2CC_MUTEX = 0x20000001, - ISSWAPI_GET_L2CC_MUTEX = 0x20000002, - ISSWAPI_SET_L2CC_MUTEX = 0x20000003, - - ISSWAPI_LOAD_TEE = 0x20000004, - -}; - -/* - * tee_msg_send - generic part of the msg sent to the TEE - */ -struct tee_msg_send { - unsigned int service; -}; - -/* - * tee_msg_recv - default strcutre of TEE service output message - */ -struct tee_msg_recv { - int duration; - uint32_t res; - uint32_t origin; -}; - -/* - * tee_register_irqfwd_xxx - (un)register callback for interrupt forwarding - */ -struct tee_register_irqfwd_send { - struct tee_msg_send header; - struct { - unsigned long cb; - } data; -}; -struct tee_register_irqfwd_recv { - struct tee_msg_recv header; -}; - -/* - * tee_get_l2cc_mutex - input/output argument structures - */ -struct tee_get_l2cc_mutex_send { - struct tee_msg_send header; -}; -struct tee_get_l2cc_mutex_recv { - struct tee_msg_recv header; - struct { - unsigned long paddr; - } data; -}; - -/** - * struct tee_identity - Represents the identity of the client - * @login: Login id - * @uuid: UUID as defined above - */ -struct tee_identity { - uint32_t login; - TEEC_UUID uuid; -}; - -/* - * tee_open_session_data - input arg structure for TEE open session service - */ -struct tee_open_session_data { - struct ta_signed_header_t *ta; - TEEC_UUID uuid; - uint32_t param_types; - TEEC_Value params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; - struct tee_identity client_id; - uint32_t params_flags[TEEC_CONFIG_PAYLOAD_REF_COUNT]; -}; - -/* - * tee_open_session_send - input arg msg for TEE open session service - */ -struct tee_open_session_send { - struct tee_msg_send header; - struct tee_open_session_data data; -}; - -/* - * tee_open_session_recv - output arg structure for TEE open session service - */ -struct tee_open_session_recv { - struct tee_msg_recv header; - uint32_t sess; - TEEC_Value params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; -}; - -/* - * tee_invoke_command_data - input arg structure for TEE invoke cmd service - */ -struct tee_invoke_command_data { - uint32_t sess; - uint32_t cmd; - uint32_t param_types; - TEEC_Value params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; - uint32_t params_flags[TEEC_CONFIG_PAYLOAD_REF_COUNT]; -}; - -struct tee_invoke_command_send { - struct tee_msg_send header; - struct tee_invoke_command_data data; -}; - -/* - * tee_invoke_command_recv - output arg structure for TEE invoke cmd service - */ -struct tee_invoke_command_recv { - struct tee_msg_recv header; - TEEC_Value params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; -}; - -/* - * tee_cancel_command_data - input arg structure for TEE cancel service - */ -struct tee_cancel_command_data { - uint32_t sess; -}; - -/* - * tee_cancel_command_send - input msg structure for TEE cancel service - */ -struct tee_cancel_command_send { - struct tee_msg_send header; - struct tee_cancel_command_data data; -}; - -/* - * tee_close_session_data - input arg structure for TEE close session service - */ -struct tee_close_session_data { - uint32_t sess; -}; - -/* - * tee_close_session_send - input arg msg for TEE close session service - */ -struct tee_close_session_send { - struct tee_msg_send header; - struct tee_close_session_data data; -}; - -/* - * tee_register_rpc_send_data - input arg structure for TEE register rpc service - */ -struct tee_register_rpc_send_data { - uint32_t fnk; - uint32_t bf; - uint32_t nbr_bf; -}; - -/* - * tee_register_rpc_send - input msg structure for TEE register rpc service - */ -struct tee_register_rpc_send { - struct tee_msg_send header; - struct tee_register_rpc_send_data data; -}; - -/* - * tee_core_status_out - output arg structure for TEE status service - */ -#define TEEC_STATUS_MSG_SIZE 80 - -struct tee_core_status_out { - struct tee_msg_recv header; - char raw[TEEC_STATUS_MSG_SIZE]; -}; - -#endif /* __TEE_ARMV7_OP_H__ */ diff --git a/security/optee_linuxdriver/armtz/tee_tz_priv.h b/security/optee_linuxdriver/armtz/tee_tz_priv.h deleted file mode 100644 index 707c72e49c4a..000000000000 --- a/security/optee_linuxdriver/armtz/tee_tz_priv.h +++ /dev/null @@ -1,64 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_TZ_PRIV__ -#define __TEE_TZ_PRIV__ - -struct tee; -struct shm_pool; -struct tee_rpc_bf; - -#ifdef CONFIG_ARM -struct smc_param { - uint32_t a0; - uint32_t a1; - uint32_t a2; - uint32_t a3; - uint32_t a4; - uint32_t a5; - uint32_t a6; - uint32_t a7; -}; -#endif -#ifdef CONFIG_ARM64 -struct smc_param { - uint64_t a0; - uint64_t a1; - uint64_t a2; - uint64_t a3; - uint64_t a4; - uint64_t a5; - uint64_t a6; - uint64_t a7; -}; -#endif - -struct tee_tz { - uint32_t sess_id; - bool started; - struct tee *tee; - unsigned long shm_paddr; - void *shm_vaddr; - struct shm_pool *shm_pool; - struct mutex mutex; - struct completion c; - int c_waiters; - void *tz_outer_cache_mutex; - struct tee_rpc_bf *rpc_buffers; - bool shm_cached; - struct tee_mutex_wait_private mutex_wait; - struct tee_wait_queue_private wait_queue; -}; - -int tee_smc_call(struct smc_param *param); - -#endif /* __TEE_TZ_PRIV__ */ diff --git a/security/optee_linuxdriver/core/Makefile b/security/optee_linuxdriver/core/Makefile deleted file mode 100644 index a80221dc790e..000000000000 --- a/security/optee_linuxdriver/core/Makefile +++ /dev/null @@ -1,36 +0,0 @@ -# SPDX-License-Identifier: GPL-2.0 -CFG_TEE_CORE_CORE_TARGET := armv7 - -######################################################################### -# Set Internal Variables # -# May be modified to match your setup # -######################################################################### -CFG_TEE_DRV_DEBUGFS?=0 -CFG_TEE_CORE_LOG_LEVEL?=2 -CFG_TEE_TA_LOG_LEVEL?=2 - -M ?= security/optee_linuxdriver - -ccflags-y+=-Werror -ccflags-y+=-I$(M)/include/linux -ccflags-y+=-I$(M)/include - -ccflags-y+=-DCFG_TEE_DRV_DEBUGFS=${CFG_TEE_DRV_DEBUGFS} -ccflags-y+=-DCFG_TEE_CORE_LOG_LEVEL=${CFG_TEE_CORE_LOG_LEVEL} -ccflags-y+=-DCFG_TEE_TA_LOG_LEVEL=${CFG_TEE_TA_LOG_LEVEL} - -obj-y += optee_v1.o - -optee_v1-objs:= \ - tee_core.o \ - tee_context.o \ - tee_session.o \ - tee_shm.o \ - tee_supp_com.o \ - tee_sysfs.o \ - tee_debugfs.o \ - tee_kernel_api.o \ - tee_mutex_wait.o \ - tee_wait_queue.o \ - - diff --git a/security/optee_linuxdriver/core/tee_context.c b/security/optee_linuxdriver/core/tee_context.c deleted file mode 100644 index 7fae11aea9b9..000000000000 --- a/security/optee_linuxdriver/core/tee_context.c +++ /dev/null @@ -1,315 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "tee_shm.h" -#include "tee_core_priv.h" - - -/** - * tee_context_dump - Dump in a buffer the informations (ctx, sess & shm) - * associated to a tee. - */ -int tee_context_dump(struct tee *tee, char *buff, size_t len) -{ - struct list_head *ptr_ctx, *ptr_sess, *ptr_shm; - struct tee_context *ctx; - struct tee_session *sess; - struct tee_shm *shm; - int i = 0; - int j = 0; - - int pos = 0; - - BUG_ON(!tee); - - if (len < 80 || list_empty(&tee->list_ctx)) - return 0; - - mutex_lock(&tee->lock); - - list_for_each(ptr_ctx, &tee->list_ctx) { - ctx = list_entry(ptr_ctx, struct tee_context, entry); - - pos += sprintf(buff + pos, - "[%02d] ctx=%p (refcount=%d) (usr=%d)", - i, ctx, - (int)refcount_read(&ctx->refcount. - refcount), - ctx->usr_client); - pos += sprintf(buff + pos, "name=\"%s\" (tgid=%d)\n", - ctx->name, - ctx->tgid); - if ((len - pos) < 80) { - pos = 0; - goto out; - } - - if (list_empty(&ctx->list_sess)) - goto out; - - j = 0; - list_for_each(ptr_sess, &ctx->list_sess) { - sess = list_entry(ptr_sess, - struct tee_session, - entry); - - pos += sprintf(buff + pos, - "[%02d.%d] sess=%p sessid=%08x\n", - i, j, sess, - sess->sessid); - - if ((len - pos) < 80) { - pos = 0; - goto out; - } - - j++; - } - - if (list_empty(&ctx->list_shm)) - goto out; - - j = 0; - list_for_each(ptr_shm, &ctx->list_shm) { - shm = list_entry(ptr_shm, struct tee_shm, entry); - - pos += sprintf(buff + pos, - "[%02d.%d] shm=%p paddr=%p kaddr=%p", - i, j, shm, - &shm->paddr, - shm->kaddr); - pos += sprintf(buff + pos, - " s=%zu(%zu)\n", - shm->size_req, - shm->size_alloc); - if ((len - pos) < 80) { - pos = 0; - goto out; - } - - j++; - } - - i++; - } - -out: - mutex_unlock(&tee->lock); - return pos; -} - -/** - * tee_context_create - Allocate and create a new context. - * Reference on the back-end is requested. - */ -struct tee_context *tee_context_create(struct tee *tee) -{ - int ret; - struct tee_context *ctx; - - dev_dbg(_DEV(tee), "%s: >\n", __func__); - - ctx = devm_kzalloc(_DEV(tee), sizeof(struct tee_context), GFP_KERNEL); - if (!ctx) { - dev_err(_DEV(tee), "%s: tee_context allocation failed\n", - __func__); - return ERR_PTR(-ENOMEM); - } - - kref_init(&ctx->refcount); - INIT_LIST_HEAD(&ctx->list_sess); - INIT_LIST_HEAD(&ctx->list_shm); - - ctx->tee = tee; - snprintf(ctx->name, sizeof(ctx->name), "%s", current->comm); - ctx->tgid = current->tgid; - - ret = tee_get(tee); - if (ret) { - devm_kfree(_DEV(tee), ctx); - return ERR_PTR(ret); - } - - mutex_lock(&tee->lock); - tee_inc_stats(&tee->stats[TEE_STATS_CONTEXT_IDX]); - list_add_tail(&ctx->entry, &tee->list_ctx); - mutex_unlock(&tee->lock); - - dev_dbg(_DEV(ctx->tee), "%s: < ctx=%p is created\n", __func__, ctx); - return ctx; -} - -/** - * _tee_context_do_release - Final function to release - * and free a context. - */ -static void _tee_context_do_release(struct kref *kref) -{ - struct tee_context *ctx; - struct tee *tee; - - ctx = container_of(kref, struct tee_context, refcount); - - BUG_ON(!ctx || !ctx->tee); - - tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: > ctx=%p\n", __func__, ctx); - - tee_dec_stats(&tee->stats[TEE_STATS_CONTEXT_IDX]); - list_del(&ctx->entry); - - devm_kfree(_DEV(tee), ctx); - tee_put(tee); - - dev_dbg(_DEV(tee), "%s: < ctx=%p is destroyed\n", __func__, ctx); -} - -/** - * tee_context_get - Increase the reference count of - * the context. - */ -void tee_context_get(struct tee_context *ctx) -{ - BUG_ON(!ctx || !ctx->tee); - - kref_get(&ctx->refcount); - - dev_dbg(_DEV(ctx->tee), "%s: ctx=%p, kref=%d\n", __func__, - ctx, (int)refcount_read(&ctx->refcount.refcount)); -} - -static int is_in_list(struct tee *tee, struct list_head *entry) -{ - int present = 1; - - if ((entry->next == LIST_POISON1) && (entry->prev == LIST_POISON2)) - present = 0; - return present; -} - -/** - * tee_context_put - Decreases the reference count of - * the context. If 0, the final - * release function is called. - */ -void tee_context_put(struct tee_context *ctx) -{ - struct tee_context *_ctx = ctx; - struct tee *tee; - - BUG_ON(!ctx || !ctx->tee); - tee = ctx->tee; - - if (!is_in_list(tee, &ctx->entry)) - return; - - kref_put(&ctx->refcount, _tee_context_do_release); - - dev_dbg(_DEV(tee), "%s: ctx=%p, kref=%d\n", __func__, - _ctx, (int)refcount_read(&ctx->refcount.refcount)); -} - -/** - * tee_context_destroy - Request to destroy a context. - */ -void tee_context_destroy(struct tee_context *ctx) -{ - struct tee *tee; - - if (!ctx || !ctx->tee) - return; - - tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: ctx=%p\n", __func__, ctx); - - mutex_lock(&tee->lock); - tee_context_put(ctx); - mutex_unlock(&tee->lock); -} - -int tee_context_copy_from_client(const struct tee_context *ctx, - void *dest, const void *src, size_t size) -{ - int res = 0; - - if (dest && src && (size > 0)) { - if (ctx->usr_client) - res = copy_from_user(dest, src, size); - else - memcpy(dest, src, size); - } - return res; -} - -struct tee_shm *tee_context_alloc_shm_tmp(struct tee_context *ctx, - size_t size, const void *src, - int type) -{ - struct tee_shm *shm; - - type &= (TEEC_MEM_INPUT | TEEC_MEM_OUTPUT); - - shm = rk_tee_shm_alloc(ctx->tee, size, - TEE_SHM_MAPPED | TEE_SHM_TEMP | type); - if (IS_ERR_OR_NULL(shm)) { - dev_err(_DEV(ctx->tee), "%s: buffer allocation failed (%ld)\n", - __func__, PTR_ERR(shm)); - return shm; - } - - shm->ctx = ctx; - - if (type & TEEC_MEM_INPUT) { - if (tee_context_copy_from_client(ctx, shm->kaddr, src, size)) { - dev_err(_DEV(ctx->tee), - "%s: tee_context_copy_from_client failed\n", - __func__); - rk_tee_shm_free(shm); - shm = NULL; - } - } - return shm; -} - -struct tee_shm *tee_context_create_tmpref_buffer(struct tee_context *ctx, - size_t size, - const void *buffer, int type) -{ - struct tee_shm *shm = NULL; - int flags; - - switch (type) { - case TEEC_MEMREF_TEMP_OUTPUT: - flags = TEEC_MEM_OUTPUT; - break; - case TEEC_MEMREF_TEMP_INPUT: - flags = TEEC_MEM_INPUT; - break; - case TEEC_MEMREF_TEMP_INOUT: - flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; - break; - default: - BUG_ON(1); - }; - shm = tee_context_alloc_shm_tmp(ctx, size, buffer, flags); - return shm; -} diff --git a/security/optee_linuxdriver/core/tee_core.c b/security/optee_linuxdriver/core/tee_core.c deleted file mode 100644 index ef949c583e32..000000000000 --- a/security/optee_linuxdriver/core/tee_core.c +++ /dev/null @@ -1,567 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -/* #define DEBUG */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "linux/tee_core.h" -#include "linux/tee_ioc.h" - -#include "tee_core_priv.h" - -#include "tee_sysfs.h" -#include "tee_debugfs.h" -#include "tee_shm.h" -#include "tee_supp_com.h" - -#define _TEE_CORE_FW_VER "1:0.1" - -static char *_tee_supp_app_name = "tee-supplicant"; - -/* Store the class misc reference */ -static struct class *misc_class; - -static int device_match(struct device *device, const void *devname) -{ - struct tee *tee = dev_get_drvdata(device); - int ret = strncmp(devname, tee->name, sizeof(tee->name)); - - BUG_ON(!tee); - if (ret == 0) - return 1; - else - return 0; -} - -/* - * For the kernel api. - * Get a reference on a device tee from the device needed - */ -struct tee *tee_get_tee(const char *devname) -{ - struct device *device; - - if (!devname) - return NULL; - device = class_find_device(misc_class, NULL, devname, device_match); - if (!device) { - pr_err("%s:%d - can't find device [%s]\n", __func__, __LINE__, - devname); - return NULL; - } - - return dev_get_drvdata(device); -} - -void tee_inc_stats(struct tee_stats_entry *entry) -{ - entry->count++; - if (entry->count > entry->max) - entry->max = entry->count; -} - -void tee_dec_stats(struct tee_stats_entry *entry) -{ - entry->count--; -} - -/** - * tee_get - increases refcount of the tee - * @tee: [in] tee to increase refcount of - * - * @note: If tee.ops.start() callback function is available, - * it is called when refcount is equal at 1. - */ -int tee_get(struct tee *tee) -{ - int ret = 0; - - BUG_ON(!tee); - - if (atomic_inc_return(&tee->refcount) == 1) { - BUG_ON(!try_module_get(tee->ops->owner)); - dev_dbg(_DEV(tee), "%s: refcount=1 call %s::start()...\n", - __func__, tee->name); - get_device(tee->dev); - if (tee->ops->start) - ret = tee->ops->start(tee); - } - if (ret) { - put_device(tee->dev); - module_put(tee->ops->owner); - dev_err(_DEV(tee), "%s: %s::start() failed, err=%d\n", - __func__, tee->name, ret); - atomic_dec(&tee->refcount); - } else { - int count = (int)atomic_read(&tee->refcount); - - dev_dbg(_DEV(tee), "%s: refcount=%d\n", __func__, count); - if (count > tee->max_refcount) - tee->max_refcount = count; - } - return ret; -} - -/** - * tee_put - decreases refcount of the tee - * @tee: [in] tee to reduce refcount of - * - * @note: If tee.ops.stop() callback function is available, - * it is called when refcount is equal at 0. - */ -int tee_put(struct tee *tee) -{ - int ret = 0; - int count; - - BUG_ON(!tee); - - if (atomic_dec_and_test(&tee->refcount)) { - dev_dbg(_DEV(tee), "%s: refcount=0 call %s::stop()...\n", - __func__, tee->name); - if (tee->ops->stop) - ret = tee->ops->stop(tee); - module_put(tee->ops->owner); - put_device(tee->dev); - } - if (ret) { - dev_err(_DEV(tee), "%s: %s::stop() has failed, ret=%d\n", - __func__, tee->name, ret); - } - - count = (int)atomic_read(&tee->refcount); - dev_dbg(_DEV(tee), "%s: refcount=%d\n", __func__, count); - return ret; -} - -static int tee_supp_open(struct tee *tee) -{ - int ret = 0; - - dev_dbg(_DEV(tee), "%s: appclient=\"%s\" pid=%d\n", __func__, - current->comm, current->pid); - - BUG_ON(!tee->rpc); - - if (strncmp(_tee_supp_app_name, current->comm, - strlen(_tee_supp_app_name)) == 0) { - if (atomic_add_return(1, &tee->rpc->used) > 1) { - ret = -EBUSY; - dev_err(tee->dev, "%s: ERROR Only one Supplicant is allowed\n", - __func__); - atomic_sub(1, &tee->rpc->used); - } - } else { - if (atomic_read(&tee->rpc->used) == 0) { - ret = -EPERM; - dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n", - __func__); - } - } - - return ret; -} - -static void tee_supp_release(struct tee *tee) -{ - dev_dbg(_DEV(tee), "%s: appclient=\"%s\" pid=%d\n", __func__, - current->comm, current->pid); - - BUG_ON(!tee->rpc); - - if ((atomic_read(&tee->rpc->used) == 1) && - (strncmp(_tee_supp_app_name, current->comm, - strlen(_tee_supp_app_name)) == 0)) - atomic_sub(1, &tee->rpc->used); -} - -static int tee_ctx_open(struct inode *inode, struct file *filp) -{ - struct tee_context *ctx; - struct tee *tee; - int ret; - - tee = container_of(filp->private_data, struct tee, miscdev); - - BUG_ON(!tee); - BUG_ON(tee->miscdev.minor != iminor(inode)); - - dev_dbg(_DEV(tee), "%s: > name=\"%s\"\n", __func__, tee->name); - - ret = tee_supp_open(tee); - if (ret) - return ret; - - ctx = tee_context_create(tee); - if (IS_ERR_OR_NULL(ctx)) - return PTR_ERR(ctx); - - ctx->usr_client = 1; - filp->private_data = ctx; - - dev_dbg(_DEV(tee), "%s: < ctx=%p is created\n", __func__, (void *)ctx); - - return 0; -} - -static int tee_ctx_release(struct inode *inode, struct file *filp) -{ - struct tee_context *ctx = filp->private_data; - struct tee *tee; - - if (!ctx) - return -EINVAL; - - BUG_ON(!ctx->tee); - tee = ctx->tee; - BUG_ON(tee->miscdev.minor != iminor(inode)); - - dev_dbg(_DEV(tee), "%s: > ctx=%p\n", __func__, ctx); - - tee_context_destroy(ctx); - tee_supp_release(tee); - - dev_dbg(_DEV(tee), "%s: < ctx=%p is destroyed\n", __func__, ctx); - return 0; -} - -static int tee_do_create_session(struct tee_context *ctx, - struct tee_cmd_io __user *u_cmd) -{ - int ret = -EINVAL; - struct tee_cmd_io k_cmd; - struct tee *tee; - - tee = ctx->tee; - BUG_ON(!ctx->usr_client); - - dev_dbg(_DEV(tee), "%s: >\n", __func__); - - if (copy_from_user(&k_cmd, (void *)u_cmd, sizeof(struct tee_cmd_io))) { - dev_err(_DEV(tee), "%s: copy_from_user failed\n", __func__); - goto exit; - } - - if (k_cmd.fd_sess > 0) { - dev_err(_DEV(tee), "%s: invalid fd_sess %d\n", __func__, - k_cmd.fd_sess); - goto exit; - } - - if ((k_cmd.op == NULL) || (k_cmd.uuid == NULL) || - ((k_cmd.data != NULL) && (k_cmd.data_size == 0)) || - ((k_cmd.data == NULL) && (k_cmd.data_size != 0))) { - dev_err(_DEV(tee), - "%s: op or/and data parameters are not valid\n", - __func__); - goto exit; - } - - ret = tee_session_create_fd(ctx, &k_cmd); - put_user(k_cmd.err, &u_cmd->err); - put_user(k_cmd.origin, &u_cmd->origin); - if (ret) - goto exit; - - put_user(k_cmd.fd_sess, &u_cmd->fd_sess); - -exit: - dev_dbg(_DEV(tee), "%s: < ret=%d, sessfd=%d\n", __func__, ret, - k_cmd.fd_sess); - return ret; -} - -static int tee_do_shm_alloc(struct tee_context *ctx, - struct tee_shm_io __user *u_shm) -{ - int ret = -EINVAL; - struct tee_shm_io k_shm; - struct tee *tee = ctx->tee; - - BUG_ON(!ctx->usr_client); - - dev_dbg(_DEV(tee), "%s: >\n", __func__); - - if (copy_from_user(&k_shm, (void *)u_shm, sizeof(struct tee_shm_io))) { - dev_err(_DEV(tee), "%s: copy_from_user failed\n", __func__); - goto exit; - } - - if ((k_shm.buffer != NULL) || (k_shm.fd_shm != 0) || - /*(k_shm.flags & ~(tee->shm_flags)) ||*/ - ((k_shm.flags & tee->shm_flags) == 0) || (k_shm.registered != 0)) { - dev_err(_DEV(tee), - "%s: shm parameters are not valid %p %d %08x %08x %d\n", - __func__, (void *)k_shm.buffer, k_shm.fd_shm, - (unsigned int)k_shm.flags, (unsigned int)tee->shm_flags, - k_shm.registered); - goto exit; - } - - ret = tee_shm_alloc_io(ctx, &k_shm); - if (ret) - goto exit; - - put_user(k_shm.fd_shm, &u_shm->fd_shm); - put_user(k_shm.flags, &u_shm->flags); - -exit: - dev_dbg(_DEV(tee), "%s: < ret=%d, shmfd=%d\n", __func__, ret, - k_shm.fd_shm); - return ret; -} - -static int tee_do_get_fd_for_rpc_shm(struct tee_context *ctx, - struct tee_shm_io __user *u_shm) -{ - int ret = -EINVAL; - struct tee_shm_io k_shm; - struct tee *tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: >\n", __func__); - BUG_ON(!ctx->usr_client); - - if (copy_from_user(&k_shm, (void *)u_shm, sizeof(struct tee_shm_io))) { - dev_err(_DEV(tee), "%s: copy_from_user failed\n", __func__); - goto exit; - } - - if ((k_shm.buffer == NULL) || (k_shm.size == 0) || (k_shm.fd_shm != 0) - || (k_shm.flags & ~(tee->shm_flags)) - || ((k_shm.flags & tee->shm_flags) == 0) - || (k_shm.registered != 0)) { - dev_err(_DEV(tee), "%s: shm parameters are not valid\n", - __func__); - goto exit; - } - - ret = tee_shm_fd_for_rpc(ctx, &k_shm); - if (ret) - goto exit; - - put_user(k_shm.fd_shm, &u_shm->fd_shm); - -exit: - dev_dbg(_DEV(tee), "%s: < ret=%d, shmfd=%d\n", __func__, ret, - k_shm.fd_shm); - return ret; -} - -static long tee_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) -{ - int ret = -EINVAL; - struct tee_context *ctx = filp->private_data; - void __user *u_arg; - - BUG_ON(!ctx); - BUG_ON(!ctx->tee); - - dev_dbg(_DEV(ctx->tee), "%s: > cmd nr=%d\n", __func__, _IOC_NR(cmd)); - -#ifdef CONFIG_COMPAT - if (is_compat_task()) - u_arg = compat_ptr(arg); - else - u_arg = (void __user *)arg; -#else - u_arg = (void __user *)arg; -#endif - - switch (cmd) { - case TEE_OPEN_SESSION_IOC: - ret = tee_do_create_session(ctx, - (struct tee_cmd_io __user *)u_arg); - break; - case TEE_ALLOC_SHM_IOC: - ret = tee_do_shm_alloc(ctx, (struct tee_shm_io __user *)u_arg); - break; - case TEE_GET_FD_FOR_RPC_SHM_IOC: - ret = tee_do_get_fd_for_rpc_shm(ctx, - (struct tee_shm_io __user *)u_arg); - break; - default: - ret = -ENOSYS; - break; - } - - dev_dbg(_DEV(ctx->tee), "%s: < ret=%d\n", __func__, ret); - - return ret; -} - -static const struct file_operations tee_file_fops = { - .owner = THIS_MODULE, - .read = tee_supp_read, - .write = tee_supp_write, - .open = tee_ctx_open, - .release = tee_ctx_release, -#ifdef CONFIG_COMPAT - .compat_ioctl = tee_ioctl, -#endif - .unlocked_ioctl = tee_ioctl -}; - -static void tee_plt_device_release(struct device *dev) -{ - pr_debug("%s: (dev=%p)....\n", __func__, dev); -} - -struct tee *tee_core_alloc(struct device *dev, char *name, int id, - const struct tee_ops *ops, size_t len) -{ - struct tee *tee; - - if (!dev || !name || !ops || - !ops->open || !ops->close || !ops->alloc || !ops->free) - return NULL; - - tee = devm_kzalloc(dev, sizeof(struct tee) + len, GFP_KERNEL); - if (!tee) { - dev_err(dev, "%s: kzalloc failed\n", __func__); - return NULL; - } - - if (!dev->release) - dev->release = tee_plt_device_release; - - tee->dev = dev; - tee->id = id; - tee->ops = ops; - tee->priv = &tee[1]; - - snprintf(tee->name, sizeof(tee->name), "optee%s%02d", name, tee->id); - pr_info("TEE core: Alloc the misc device \"%s\" (id=%d)\n", tee->name, - tee->id); - - tee->miscdev.parent = dev; - tee->miscdev.minor = MISC_DYNAMIC_MINOR; - tee->miscdev.name = tee->name; - tee->miscdev.fops = &tee_file_fops; - - mutex_init(&tee->lock); - atomic_set(&tee->refcount, 0); - INIT_LIST_HEAD(&tee->list_ctx); - INIT_LIST_HEAD(&tee->list_rpc_shm); - - tee->state = TEE_OFFLINE; - tee->shm_flags = TEEC_MEM_INPUT | TEEC_MEM_OUTPUT; - tee->test = 0; - - tee_supp_init(tee); - - return tee; -} -EXPORT_SYMBOL(tee_core_alloc); - -int tee_core_free(struct tee *tee) -{ - if (tee) { - tee_supp_deinit(tee); - devm_kfree(tee->dev, tee); - } - return 0; -} -EXPORT_SYMBOL(tee_core_free); - -int tee_core_add(struct tee *tee) -{ - int rc = 0; - - if (!tee) - return -EINVAL; - - rc = misc_register(&tee->miscdev); - if (rc != 0) { - pr_err("TEE Core: misc_register() failed name=\"%s\"\n", - tee->name); - return rc; - } - - dev_set_drvdata(tee->miscdev.this_device, tee); - - tee_init_sysfs(tee); - tee_create_debug_dir(tee); - - /* Register a static reference on the class misc - * to allow finding device by class */ - BUG_ON(!tee->miscdev.this_device->class); - if (misc_class) - BUG_ON(misc_class != tee->miscdev.this_device->class); - else - misc_class = tee->miscdev.this_device->class; - - pr_info("TEE Core: Register the misc device \"%s\" (id=%d,minor=%d)\n", - dev_name(tee->miscdev.this_device), tee->id, - tee->miscdev.minor); - return rc; -} -EXPORT_SYMBOL(tee_core_add); - -int tee_core_del(struct tee *tee) -{ - if (tee) { - pr_info("TEE Core: Destroy the misc device \"%s\" (id=%d)\n", - dev_name(tee->miscdev.this_device), tee->id); - - tee_cleanup_sysfs(tee); - tee_delete_debug_dir(tee); - - if (tee->miscdev.minor != MISC_DYNAMIC_MINOR) { - pr_info("TEE Core: Deregister the misc device \"%s\" (id=%d)\n", - dev_name(tee->miscdev.this_device), tee->id); - misc_deregister(&tee->miscdev); - } - } - - tee_core_free(tee); - - return 0; -} -EXPORT_SYMBOL(tee_core_del); - -static int __init tee_core_init(void) -{ - pr_info("\nTEE Core Framework initialization (ver %s)\n", - _TEE_CORE_FW_VER); - tee_init_debugfs(); - - return 0; -} - -static void __exit tee_core_exit(void) -{ - tee_exit_debugfs(); - pr_info("TEE Core Framework unregistered\n"); -} - -module_init(tee_core_init); -module_exit(tee_core_exit); - -MODULE_AUTHOR("STMicroelectronics"); -MODULE_DESCRIPTION("STM Secure TEE Framework/Core TEEC v1.0"); -MODULE_SUPPORTED_DEVICE(""); -MODULE_VERSION(_TEE_CORE_FW_VER); -MODULE_LICENSE("GPL"); diff --git a/security/optee_linuxdriver/core/tee_core_priv.h b/security/optee_linuxdriver/core/tee_core_priv.h deleted file mode 100644 index 933f55fc0c68..000000000000 --- a/security/optee_linuxdriver/core/tee_core_priv.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_CORE_PRIV_H__ -#define __TEE_CORE_PRIV_H__ - -#include "linux/tee_core.h" -#include "linux/tee_ioc.h" - -/* from tee_core_module.c */ -int tee_get(struct tee *tee); -int tee_put(struct tee *tee); - -void tee_inc_stats(struct tee_stats_entry *entry); -void tee_dec_stats(struct tee_stats_entry *entry); - -/* from tee_context.c */ -int tee_context_dump(struct tee *tee, char *buff, size_t len); - -struct tee_context *tee_context_create(struct tee *tee); -void tee_context_destroy(struct tee_context *ctx); - -void tee_context_get(struct tee_context *ctx); -void tee_context_put(struct tee_context *ctx); - -struct tee_shm *tee_context_create_tmpref_buffer(struct tee_context *ctx, - size_t size, - const void *buffer, int type); -struct tee_shm *tee_context_alloc_shm_tmp(struct tee_context *ctx, size_t size, - const void *data, int type); -int tee_context_copy_from_client(const struct tee_context *ctx, void *dest, - const void *src, size_t size); - -/* from tee_session.c */ -int tee_session_create_fd(struct tee_context *ctx, struct tee_cmd_io *cmd_io); -struct tee_session *tee_session_create_and_open(struct tee_context *ctx, - struct tee_cmd_io *cmd_io); -int tee_session_close_and_destroy(struct tee_session *sess); - -struct tee *tee_get_tee(const char *devname); -int tee_session_invoke_be(struct tee_session *sess, struct tee_cmd_io *cmd_io); - -#endif diff --git a/security/optee_linuxdriver/core/tee_debugfs.c b/security/optee_linuxdriver/core/tee_debugfs.c deleted file mode 100644 index 95b44b8a2272..000000000000 --- a/security/optee_linuxdriver/core/tee_debugfs.c +++ /dev/null @@ -1,85 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include - -#include "linux/tee_core.h" -#include "tee_debugfs.h" - -static struct dentry *tee_debugfs_dir; - -static ssize_t tee_trace_read(struct file *filp, char __user *userbuf, - size_t count, loff_t *ppos) -{ - struct tee *tee = filp->private_data; - - char buff[258]; - int len = sprintf(buff, "device=%s\n NO LOG AVAILABLE\n", tee->name); - - return simple_read_from_buffer(userbuf, count, ppos, buff, len); -} - -static const struct file_operations log_tee_ops = { - .read = tee_trace_read, - .open = simple_open, - .llseek = generic_file_llseek, -}; - -void tee_create_debug_dir(struct tee *tee) -{ - struct dentry *entry; - struct device *dev = tee->miscdev.this_device; - - if (!tee_debugfs_dir) - return; - - tee->dbg_dir = debugfs_create_dir(dev_name(dev), tee_debugfs_dir); - if (!tee->dbg_dir) - goto error_create_file; - - entry = debugfs_create_file("log", S_IRUGO, tee->dbg_dir, - tee, &log_tee_ops); - if (!entry) - goto error_create_file; - - return; - -error_create_file: - dev_err(dev, "can't create debugfs file\n"); - tee_delete_debug_dir(tee); -} - -void tee_delete_debug_dir(struct tee *tee) -{ - if (!tee || !tee->dbg_dir) - return; - - debugfs_remove_recursive(tee->dbg_dir); -} - -void __init tee_init_debugfs(void) -{ - if (debugfs_initialized()) { - tee_debugfs_dir = debugfs_create_dir("tee", NULL); - if (IS_ERR(tee_debugfs_dir)) - pr_err("can't create debugfs dir\n"); - } -} - -void __exit tee_exit_debugfs(void) -{ - if (tee_debugfs_dir) - debugfs_remove(tee_debugfs_dir); -} diff --git a/security/optee_linuxdriver/core/tee_debugfs.h b/security/optee_linuxdriver/core/tee_debugfs.h deleted file mode 100644 index 36f1da76d2cd..000000000000 --- a/security/optee_linuxdriver/core/tee_debugfs.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_DEBUGFS_H__ -#define __TEE_DEBUGFS_H__ - -struct tee; - -void tee_create_debug_dir(struct tee *tee); -void tee_delete_debug_dir(struct tee *tee); - -void __init tee_init_debugfs(void); -void __exit tee_exit_debugfs(void); - -#endif /* __TEE_DEBUGFS_H__ */ diff --git a/security/optee_linuxdriver/core/tee_kernel_api.c b/security/optee_linuxdriver/core/tee_kernel_api.c deleted file mode 100644 index 41568c8e9ec0..000000000000 --- a/security/optee_linuxdriver/core/tee_kernel_api.c +++ /dev/null @@ -1,255 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include - -#include "linux/tee_kernel_api.h" -#include "linux/tee_core.h" -#include "linux/tee_ioc.h" - -#include "tee_core_priv.h" -#include "tee_shm.h" -#include "tee_supp_com.h" - -#define TEE_TZ_DEVICE_NAME "opteearmtz00" - -static void reset_tee_cmd(struct tee_cmd_io *cmd) -{ - memset(cmd, 0, sizeof(struct tee_cmd_io)); - cmd->fd_sess = -1; - cmd->cmd = 0; - cmd->uuid = NULL; - cmd->origin = TEEC_ORIGIN_API; - cmd->err = TEEC_SUCCESS; - cmd->data = NULL; - cmd->data_size = 0; - cmd->op = NULL; -} - -TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context) -{ - struct tee *tee; - struct tee_context *ctx; - pr_cont("%s: > name=\"%s\"\n", __func__, name); - - if (!context) - return TEEC_ERROR_BAD_PARAMETERS; - - context->fd = 0; - - if (name == NULL) - strncpy(context->devname, TEE_TZ_DEVICE_NAME, - sizeof(context->devname)); - else - strncpy(context->devname, name, sizeof(context->devname)); - - tee = tee_get_tee(context->devname); - if (!tee) { - pr_err("%s - can't get device [%s]\n", __func__, name); - return TEEC_ERROR_BAD_PARAMETERS; - } - - ctx = tee_context_create(tee); - if (IS_ERR_OR_NULL(ctx)) - return TEEC_ERROR_BAD_PARAMETERS; - - ctx->usr_client = 0; - - /* TODO fixme will not work on 64-bit platform */ - context->fd = (int)(uintptr_t)ctx; - BUG_ON(ctx != (struct tee_context *)(uintptr_t)context->fd); - - pr_cont("%s: < ctx=%p is created\n", __func__, (void *)ctx); - return TEEC_SUCCESS; -} -EXPORT_SYMBOL(TEEC_InitializeContext); - -void TEEC_FinalizeContext(TEEC_Context *context) -{ - if (!context || !context->fd) { - pr_err("%s - can't release context %p:[%s]\n", __func__, - context, context ? context->devname : ""); - return; - } - /* TODO fixme will not work on 64-bit platform */ - tee_context_destroy((struct tee_context *)(uintptr_t)context->fd); - return; -} -EXPORT_SYMBOL(TEEC_FinalizeContext); - -TEEC_Result TEEC_OpenSession(TEEC_Context *context, - TEEC_Session *session, - const TEEC_UUID *destination, - uint32_t connectionMethod, - const void *connectionData, - TEEC_Operation *operation, - uint32_t *return_origin) -{ - TEEC_Operation dummy_op; - struct tee_cmd_io cmd; - struct tee_session *sess; - struct tee_context *ctx; - - if (!operation) { - /* - * The code here exist because Global Platform API states that - * it is allowed to give operation as a NULL pointer. - * In kernel and secure world we in most cases don't want - * this to be NULL, hence we use this dummy operation when - * a client doesn't provide any operation. - */ - memset(&dummy_op, 0, sizeof(TEEC_Operation)); - operation = &dummy_op; - } - - if (!context || !session || !destination || !operation - || !return_origin) - return TEEC_ERROR_BAD_PARAMETERS; - - session->fd = 0; - - /* TODO fixme will not work on 64-bit platform */ - ctx = (struct tee_context *)(uintptr_t)context->fd; - reset_tee_cmd(&cmd); - cmd.op = operation; - cmd.uuid = (TEEC_UUID *) destination; - - sess = tee_session_create_and_open(ctx, &cmd); - if (IS_ERR_OR_NULL(sess)) { - if (cmd.origin) - *return_origin = cmd.origin; - else - *return_origin = TEEC_ORIGIN_COMMS; - if (cmd.err) - return cmd.err; - else - return TEEC_ERROR_COMMUNICATION; - } else { - *return_origin = cmd.origin; - /* TODO fixme will not work on 64-bit platform */ - session->fd = (int)(uintptr_t)sess; - BUG_ON(sess != (struct tee_session *)(uintptr_t)session->fd); - return cmd.err; - } -} -EXPORT_SYMBOL(TEEC_OpenSession); - -void TEEC_CloseSession(TEEC_Session *session) -{ - if (session && session->fd) { - /* TODO fixme will not work on 64-bit platform */ - struct tee_session *sess = - (struct tee_session *)(uintptr_t)session->fd; - tee_session_close_and_destroy(sess); - } -} -EXPORT_SYMBOL(TEEC_CloseSession); - -TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, - uint32_t commandID, - TEEC_Operation *operation, - uint32_t *return_origin) -{ - int ret = 0; - struct tee_cmd_io cmd; - struct tee_session *sess; - - if (!session || !operation || !return_origin || !session->fd) - return TEEC_ERROR_BAD_PARAMETERS; - - /* TODO fixme will not work on 64-bit platform */ - sess = (struct tee_session *)(uintptr_t)session->fd; - reset_tee_cmd(&cmd); - cmd.cmd = commandID; - cmd.op = operation; - - ret = tee_session_invoke_be(sess, &cmd); - if (ret) { - if (cmd.origin) - *return_origin = cmd.origin; - else - *return_origin = TEEC_ORIGIN_COMMS; - if (cmd.err) - return cmd.err; - else - return TEEC_ERROR_COMMUNICATION; - } else { - *return_origin = cmd.origin; - return cmd.err; - } -} -EXPORT_SYMBOL(TEEC_InvokeCommand); - -TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, - TEEC_SharedMemory *sharedMem) -{ - if (!sharedMem) - return TEEC_ERROR_BAD_PARAMETERS; - - sharedMem->registered = 1; - return TEEC_SUCCESS; -} -EXPORT_SYMBOL(TEEC_RegisterSharedMemory); - -TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, - TEEC_SharedMemory *shared_memory) -{ - struct tee_shm_io shm_io; - int ret; - struct tee_shm *shm; - - if (!context || !context->ctx || !shared_memory) - return TEEC_ERROR_BAD_PARAMETERS; - - shm_io.size = shared_memory->size; - shm_io.flags = shared_memory->flags | TEEC_MEM_KAPI; - ret = tee_shm_alloc_io(context->ctx, &shm_io); - if (ret) { - pr_err("%s: tee_shm_alloc_io(%zd) failed\n", __func__, - shared_memory->size); - return TEEC_ERROR_OUT_OF_MEMORY; - } - - shared_memory->registered = 0; - shared_memory->flags = shm_io.flags; - shared_memory->d.fd = shm_io.fd_shm; - - shm = (struct tee_shm *)(long)shm_io.fd_shm; - shared_memory->buffer = shm->kaddr; - - pr_debug("%s(%d) => fd=%d, kaddr=%p\n", __func__, - shm_io.size, shm_io.fd_shm, (void *)shared_memory->buffer); - - return TEEC_SUCCESS; -} -EXPORT_SYMBOL(TEEC_AllocateSharedMemory); - -void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *shared_memory) -{ - struct tee_shm *shm; - - if (!shared_memory || shared_memory->registered) - return; - - pr_debug("%s (vaddr = %p)\n", __func__, shared_memory->buffer); - - shm = (struct tee_shm *)(long)shared_memory->d.fd; - tee_shm_free_io(shm); - - shared_memory->buffer = NULL; - shared_memory->d.fd = 0; -} -EXPORT_SYMBOL(TEEC_ReleaseSharedMemory); diff --git a/security/optee_linuxdriver/core/tee_mutex_wait.c b/security/optee_linuxdriver/core/tee_mutex_wait.c deleted file mode 100644 index 17049f5eff08..000000000000 --- a/security/optee_linuxdriver/core/tee_mutex_wait.c +++ /dev/null @@ -1,144 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include "tee_mutex_wait.h" - -struct tee_mutex_wait { - struct list_head link; - struct completion comp; - struct mutex mu; - u32 wait_after; - u32 key; -}; - -/* - * Compares two serial numbers using Serial Number Arithmetic - * (https://www.ietf.org/rfc/rfc1982.txt). - */ -#define TICK_GT(t1, t2) \ - (((t1) < (t2) && (t2) - (t1) > 0xFFFFFFFFu) || \ - ((t1) > (t2) && (t1) - (t2) < 0xFFFFFFFFu)) - -static struct tee_mutex_wait *tee_mutex_wait_get(struct device *dev, - struct tee_mutex_wait_private *priv, u32 key) -{ - struct tee_mutex_wait *w; - - mutex_lock(&priv->mu); - - list_for_each_entry(w, &priv->db, link) - if (w->key == key) - goto out; - - w = kmalloc(sizeof(struct tee_mutex_wait), GFP_KERNEL); - if (!w) { - dev_err(dev, "kmalloc failed\n"); - goto out; - } - - init_completion(&w->comp); - mutex_init(&w->mu); - w->wait_after = 0; - w->key = key; - list_add_tail(&w->link, &priv->db); -out: - mutex_unlock(&priv->mu); - return w; -} - -static void tee_mutex_wait_delete_entry(struct tee_mutex_wait *w) -{ - list_del(&w->link); - mutex_destroy(&w->mu); - kfree(w); -} - -void tee_mutex_wait_delete(struct device *dev, - struct tee_mutex_wait_private *priv, - u32 key) -{ - struct tee_mutex_wait *w; - - mutex_lock(&priv->mu); - - list_for_each_entry(w, &priv->db, link) { - if (w->key == key) { - tee_mutex_wait_delete_entry(w); - break; - } - } - - mutex_unlock(&priv->mu); -} -EXPORT_SYMBOL(tee_mutex_wait_delete); - -void tee_mutex_wait_wakeup(struct device *dev, - struct tee_mutex_wait_private *priv, - u32 key, u32 wait_after) -{ - struct tee_mutex_wait *w = tee_mutex_wait_get(dev, priv, key); - - if (!w) - return; - - mutex_lock(&w->mu); - w->wait_after = wait_after; - mutex_unlock(&w->mu); - complete(&w->comp); -} -EXPORT_SYMBOL(tee_mutex_wait_wakeup); - -void tee_mutex_wait_sleep(struct device *dev, - struct tee_mutex_wait_private *priv, - u32 key, u32 wait_tick) -{ - struct tee_mutex_wait *w = tee_mutex_wait_get(dev, priv, key); - u32 wait_after; - - if (!w) - return; - - mutex_lock(&w->mu); - wait_after = w->wait_after; - mutex_unlock(&w->mu); - - if (TICK_GT(wait_tick, wait_after)) - wait_for_completion_timeout(&w->comp, HZ); -} -EXPORT_SYMBOL(tee_mutex_wait_sleep); - -int tee_mutex_wait_init(struct tee_mutex_wait_private *priv) -{ - mutex_init(&priv->mu); - INIT_LIST_HEAD(&priv->db); - return 0; -} -EXPORT_SYMBOL(tee_mutex_wait_init); - -void tee_mutex_wait_exit(struct tee_mutex_wait_private *priv) -{ - /* - * It's the callers responibility to ensure that no one is using - * anything inside priv. - */ - - mutex_destroy(&priv->mu); - while (!list_empty(&priv->db)) { - struct tee_mutex_wait *w = - list_first_entry(&priv->db, - struct tee_mutex_wait, - link); - tee_mutex_wait_delete_entry(w); - } -} -EXPORT_SYMBOL(tee_mutex_wait_exit); diff --git a/security/optee_linuxdriver/core/tee_mutex_wait.h b/security/optee_linuxdriver/core/tee_mutex_wait.h deleted file mode 100644 index 19f9b0d43e70..000000000000 --- a/security/optee_linuxdriver/core/tee_mutex_wait.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef TEE_MUTEX_WAIT_H -#define TEE_MUTEX_WAIT_H - -#include -#include -#include - -struct tee_mutex_wait_private { - struct mutex mu; - struct list_head db; -}; - -int tee_mutex_wait_init(struct tee_mutex_wait_private *priv); -void tee_mutex_wait_exit(struct tee_mutex_wait_private *priv); - -void tee_mutex_wait_delete(struct device *dev, - struct tee_mutex_wait_private *priv, - u32 key); -void tee_mutex_wait_wakeup(struct device *dev, - struct tee_mutex_wait_private *priv, - u32 key, u32 wait_after); -void tee_mutex_wait_sleep(struct device *dev, - struct tee_mutex_wait_private *priv, - u32 key, u32 wait_tick); - -#endif /*TEE_MUTEX_WAIT_H*/ diff --git a/security/optee_linuxdriver/core/tee_session.c b/security/optee_linuxdriver/core/tee_session.c deleted file mode 100644 index a12d8a08415e..000000000000 --- a/security/optee_linuxdriver/core/tee_session.c +++ /dev/null @@ -1,858 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include - -#include "tee_shm.h" -#include "tee_core_priv.h" - -static int _init_tee_cmd(struct tee_session *sess, struct tee_cmd_io *cmd_io, - struct tee_cmd *cmd); -static void _update_client_tee_cmd(struct tee_session *sess, - struct tee_cmd_io *cmd_io, - struct tee_cmd *cmd); -static void _release_tee_cmd(struct tee_session *sess, struct tee_cmd *cmd); - -#define _DEV_TEE _DEV(sess->ctx->tee) - -#define INMSG dev_dbg(_DEV_TEE, "%s: >\n", __func__) -#define OUTMSG(val) dev_dbg(_DEV_TEE, "%s: < %d\n", __func__, (int)val) - -/******************************************************************************/ - -static inline bool flag_set(int val, int flags) -{ - return (val & flags) == flags; -} - -static inline bool is_mapped_temp(int flags) -{ - return flag_set(flags, TEE_SHM_MAPPED | TEE_SHM_TEMP); -} - - -/******************************************************************************/ - -#define _UUID_STR_SIZE 36 -static char *_uuid_to_str(const TEEC_UUID *uuid) -{ - static char uuid_str[_UUID_STR_SIZE]; - - if (uuid) { - sprintf(uuid_str, - "%08x-%04x-%04x-%02x%02x%02x%02x%02x%02x%02x%02x", - uuid->timeLow, uuid->timeMid, uuid->timeHiAndVersion, - uuid->clockSeqAndNode[0], uuid->clockSeqAndNode[1], - uuid->clockSeqAndNode[2], uuid->clockSeqAndNode[3], - uuid->clockSeqAndNode[4], uuid->clockSeqAndNode[5], - uuid->clockSeqAndNode[6], uuid->clockSeqAndNode[7]); - } else { - sprintf(uuid_str, "NULL"); - } - - return uuid_str; -} - -static int tee_copy_from_user(struct tee_context *ctx, void *to, void *from, - size_t size) -{ - if ((!to) || (!from) || (!size)) - return 0; - if (ctx->usr_client) - return copy_from_user(to, from, size); - else { - memcpy(to, from, size); - return 0; - } -} - -static int tee_copy_to_user(struct tee_context *ctx, void *to, void *from, - size_t size) -{ - if ((!to) || (!from) || (!size)) - return 0; - if (ctx->usr_client) - return copy_to_user(to, from, size); - else { - memcpy(to, from, size); - return 0; - } -} - -/* Defined as macro to let the put_user macro see the types */ -#define tee_put_user(ctx, from, to) \ - do { \ - if ((ctx)->usr_client) \ - put_user(from, to); \ - else \ - *to = from; \ - } while (0) - -static inline int tee_session_is_opened(struct tee_session *sess) -{ - if (sess && sess->sessid) - return (sess->sessid != 0); - return 0; -} - -static int tee_session_open_be(struct tee_session *sess, - struct tee_cmd_io *cmd_io) -{ - int ret = -EINVAL; - struct tee *tee; - struct tee_cmd cmd; - - BUG_ON(!sess || !sess->ctx || !sess->ctx->tee); - - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > open a new session", __func__); - - sess->sessid = 0; - ret = _init_tee_cmd(sess, cmd_io, &cmd); - if (ret) - goto out; - - if (cmd.uuid) { - dev_dbg(_DEV(tee), "%s: UUID=%s\n", __func__, - _uuid_to_str((TEEC_UUID *) cmd.uuid->kaddr)); - } - - ret = tee->ops->open(sess, &cmd); - if (ret == 0) - _update_client_tee_cmd(sess, cmd_io, &cmd); - else { - /* propagate the reason of the error */ - cmd_io->origin = cmd.origin; - cmd_io->err = cmd.err; - } - -out: - _release_tee_cmd(sess, &cmd); - dev_dbg(_DEV(tee), "%s: < ret=%d, sessid=%08x", __func__, ret, - sess->sessid); - return ret; -} - -int tee_session_invoke_be(struct tee_session *sess, struct tee_cmd_io *cmd_io) -{ - int ret = -EINVAL; - struct tee *tee; - struct tee_cmd cmd; - - BUG_ON(!sess || !sess->ctx || !sess->ctx->tee); - - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > sessid=%08x, cmd=0x%08x\n", __func__, - sess->sessid, cmd_io->cmd); - - ret = _init_tee_cmd(sess, cmd_io, &cmd); - if (ret) - goto out; - - ret = tee->ops->invoke(sess, &cmd); - if (!ret) - _update_client_tee_cmd(sess, cmd_io, &cmd); - else { - /* propagate the reason of the error */ - cmd_io->origin = cmd.origin; - cmd_io->err = cmd.err; - } - -out: - _release_tee_cmd(sess, &cmd); - dev_dbg(_DEV(tee), "%s: < ret=%d", __func__, ret); - return ret; -} - -static int tee_session_close_be(struct tee_session *sess) -{ - int ret = -EINVAL; - struct tee *tee; - - BUG_ON(!sess || !sess->ctx || !sess->ctx->tee); - - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > sessid=%08x", __func__, sess->sessid); - - ret = tee->ops->close(sess); - sess->sessid = 0; - - dev_dbg(_DEV(tee), "%s: < ret=%d", __func__, ret); - return ret; -} - -static int tee_session_cancel_be(struct tee_session *sess, - struct tee_cmd_io *cmd_io) -{ - int ret = -EINVAL; - struct tee *tee; - struct tee_cmd cmd; - - BUG_ON(!sess || !sess->ctx || !sess->ctx->tee); - - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > sessid=%08x, cmd=0x%08x\n", __func__, - sess->sessid, cmd_io->cmd); - - ret = _init_tee_cmd(sess, cmd_io, &cmd); - if (ret) - goto out; - - ret = tee->ops->cancel(sess, &cmd); - -out: - _release_tee_cmd(sess, &cmd); - dev_dbg(_DEV(tee), "%s: < ret=%d", __func__, ret); - return ret; -} - -static int tee_do_invoke_command(struct tee_session *sess, - struct tee_cmd_io __user *u_cmd) -{ - int ret = -EINVAL; - struct tee *tee; - struct tee_cmd_io k_cmd; - struct tee_context *ctx; - - BUG_ON(!sess->ctx); - BUG_ON(!sess->ctx->tee); - ctx = sess->ctx; - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > sessid=%08x\n", __func__, sess->sessid); - - BUG_ON(!sess->sessid); - - if (tee_copy_from_user - (ctx, &k_cmd, (void *)u_cmd, sizeof(struct tee_cmd_io))) { - dev_err(_DEV(tee), "%s: tee_copy_from_user failed\n", __func__); - goto exit; - } - - if ((k_cmd.op == NULL) || (k_cmd.uuid != NULL) || - (k_cmd.data != NULL) || (k_cmd.data_size != 0)) { - dev_err(_DEV(tee), - "%s: op or/and data parameters are not valid\n", - __func__); - goto exit; - } - - ret = tee_session_invoke_be(sess, &k_cmd); - if (ret) - dev_err(_DEV(tee), "%s: tee_invoke_command failed\n", __func__); - - tee_put_user(ctx, k_cmd.err, &u_cmd->err); - tee_put_user(ctx, k_cmd.origin, &u_cmd->origin); - -exit: - dev_dbg(_DEV(tee), "%s: < ret=%d\n", __func__, ret); - return ret; -} - -static int tee_do_cancel_cmd(struct tee_session *sess, - struct tee_cmd_io __user *u_cmd) -{ - int ret = -EINVAL; - struct tee *tee; - struct tee_cmd_io k_cmd; - struct tee_context *ctx; - - BUG_ON(!sess->ctx); - BUG_ON(!sess->ctx->tee); - ctx = sess->ctx; - tee = sess->ctx->tee; - - dev_dbg(sess->ctx->tee->dev, "%s: > sessid=%08x\n", __func__, - sess->sessid); - - BUG_ON(!sess->sessid); - - if (tee_copy_from_user - (ctx, &k_cmd, (void *)u_cmd, sizeof(struct tee_cmd_io))) { - dev_err(_DEV(tee), "%s: tee_copy_from_user failed\n", __func__); - goto exit; - } - - if ((k_cmd.op == NULL) || (k_cmd.uuid != NULL) || - (k_cmd.data != NULL) || (k_cmd.data_size != 0)) { - dev_err(_DEV(tee), - "%s: op or/and data parameters are not valid\n", - __func__); - goto exit; - } - - ret = tee_session_cancel_be(sess, &k_cmd); - if (ret) - dev_err(_DEV(tee), "%s: tee_invoke_command failed\n", __func__); - - tee_put_user(ctx, k_cmd.err, &u_cmd->err); - tee_put_user(ctx, k_cmd.origin, &u_cmd->origin); - -exit: - dev_dbg(_DEV(tee), "%s: < ret=%d", __func__, ret); - return ret; -} - -static long tee_session_ioctl(struct file *filp, unsigned int cmd, - unsigned long arg) -{ - struct tee *tee; - struct tee_session *sess = filp->private_data; - int ret; - - BUG_ON(!sess || !sess->ctx || !sess->ctx->tee); - - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > cmd nr=%d\n", __func__, _IOC_NR(cmd)); - - switch (cmd) { - case TEE_INVOKE_COMMAND_IOC: - ret = - tee_do_invoke_command(sess, - (struct tee_cmd_io __user *)arg); - break; - case TEE_REQUEST_CANCELLATION_IOC: - ret = tee_do_cancel_cmd(sess, (struct tee_cmd_io __user *)arg); - break; - default: - ret = -ENOSYS; - break; - } - - dev_dbg(_DEV(tee), "%s: < ret=%d\n", __func__, ret); - - return ret; -} - -static int tee_session_release(struct inode *inode, struct file *filp) -{ - struct tee_session *sess = filp->private_data; - int ret = 0; - struct tee *tee; - - BUG_ON(!sess || !sess->ctx || !sess->ctx->tee); - tee = sess->ctx->tee; - - ret = tee_session_close_and_destroy(sess); - return ret; -} - -const struct file_operations tee_session_fops = { - .owner = THIS_MODULE, -#ifdef CONFIG_COMPAT - .compat_ioctl = tee_session_ioctl, -#endif - .unlocked_ioctl = tee_session_ioctl, - .compat_ioctl = tee_session_ioctl, - .release = tee_session_release, -}; - -int tee_session_close_and_destroy(struct tee_session *sess) -{ - int ret; - struct tee *tee; - struct tee_context *ctx; - - if (!sess || !sess->ctx || !sess->ctx->tee) - return -EINVAL; - - ctx = sess->ctx; - tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: > sess=%p\n", __func__, sess); - - if (!tee_session_is_opened(sess)) - return -EINVAL; - - ret = tee_session_close_be(sess); - - mutex_lock(&tee->lock); - tee_dec_stats(&tee->stats[TEE_STATS_SESSION_IDX]); - list_del(&sess->entry); - - devm_kfree(_DEV(tee), sess); - tee_context_put(ctx); - tee_put(tee); - mutex_unlock(&tee->lock); - - dev_dbg(_DEV(tee), "%s: <\n", __func__); - return ret; -} - -struct tee_session *tee_session_create_and_open(struct tee_context *ctx, - struct tee_cmd_io *cmd_io) -{ - int ret = 0; - struct tee_session *sess; - struct tee *tee; - - BUG_ON(!ctx->tee); - - tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: >\n", __func__); - ret = tee_get(tee); - if (ret) - return ERR_PTR(-EBUSY); - - sess = devm_kzalloc(_DEV(tee), sizeof(struct tee_session), GFP_KERNEL); - if (!sess) { - dev_err(_DEV(tee), "%s: tee_session allocation() failed\n", - __func__); - tee_put(tee); - return ERR_PTR(-ENOMEM); - } - - tee_context_get(ctx); - sess->ctx = ctx; - - ret = tee_session_open_be(sess, cmd_io); - mutex_lock(&tee->lock); - if (ret || !sess->sessid || cmd_io->err) { - dev_err(_DEV(tee), "%s: ERROR ret=%d (err=0x%08x, org=%d, sessid=0x%08x)\n", - __func__, ret, cmd_io->err, - cmd_io->origin, sess->sessid); - tee_put(tee); - tee_context_put(ctx); - devm_kfree(_DEV(tee), sess); - mutex_unlock(&tee->lock); - if (ret) - return ERR_PTR(ret); - else - return NULL; - } - - tee_inc_stats(&tee->stats[TEE_STATS_SESSION_IDX]); - list_add_tail(&sess->entry, &ctx->list_sess); - mutex_unlock(&tee->lock); - - dev_dbg(_DEV(tee), "%s: < sess=%p\n", __func__, sess); - return sess; -} - -int tee_session_create_fd(struct tee_context *ctx, struct tee_cmd_io *cmd_io) -{ - int ret; - struct tee_session *sess; - struct tee *tee = ctx->tee; - - BUG_ON(cmd_io->fd_sess > 0); - - dev_dbg(_DEV(tee), "%s: >\n", __func__); - - sess = tee_session_create_and_open(ctx, cmd_io); - if (IS_ERR_OR_NULL(sess)) { - ret = PTR_ERR(sess); - dev_dbg(_DEV(tee), "%s: ERROR can't create the session (ret=%d, err=0x%08x, org=%d)\n", - __func__, ret, cmd_io->err, cmd_io->origin); - cmd_io->fd_sess = -1; - goto out; - } - - /* Retrieve a fd */ - cmd_io->fd_sess = -1; - ret = - anon_inode_getfd("tee_session", &tee_session_fops, sess, O_CLOEXEC); - if (ret < 0) { - dev_err(_DEV(tee), "%s: ERROR can't get a fd (ret=%d)\n", - __func__, ret); - tee_session_close_and_destroy(sess); - goto out; - } - cmd_io->fd_sess = ret; - ret = 0; - -out: - dev_dbg(_DEV(tee), "%s: < ret=%d, sess=%p, fd=%d\n", __func__, - ret, sess, cmd_io->fd_sess); - return ret; -} - -static bool tee_session_is_supported_type(struct tee_session *sess, int type) -{ - switch (type) { - case TEEC_NONE: - case TEEC_VALUE_INPUT: - case TEEC_VALUE_OUTPUT: - case TEEC_VALUE_INOUT: - case TEEC_MEMREF_TEMP_INPUT: - case TEEC_MEMREF_TEMP_OUTPUT: - case TEEC_MEMREF_TEMP_INOUT: - case TEEC_MEMREF_WHOLE: - case TEEC_MEMREF_PARTIAL_INPUT: - case TEEC_MEMREF_PARTIAL_OUTPUT: - case TEEC_MEMREF_PARTIAL_INOUT: - return true; - default: - dev_err(_DEV_TEE, "type is invalid (type %02x)\n", type); - return false; - } -} - -static int to_memref_type(int flags) -{ - if (flag_set(flags, TEEC_MEM_INPUT | TEEC_MEM_OUTPUT)) - return TEEC_MEMREF_TEMP_INOUT; - - if (flag_set(flags, TEEC_MEM_INPUT)) - return TEEC_MEMREF_TEMP_INPUT; - - if (flag_set(flags, TEEC_MEM_OUTPUT)) - return TEEC_MEMREF_TEMP_OUTPUT; - - pr_err("%s: bad flags=%x\n", __func__, flags); - return 0; -} - -static int _init_tee_cmd(struct tee_session *sess, struct tee_cmd_io *cmd_io, - struct tee_cmd *cmd) -{ - int ret = -EINVAL; - int idx; - TEEC_Operation op; - struct tee_data *param = &cmd->param; - struct tee *tee; - struct tee_context *ctx; - - BUG_ON(!sess->ctx); - BUG_ON(!sess->ctx->tee); - ctx = sess->ctx; - tee = sess->ctx->tee; - - dev_dbg(_DEV(tee), "%s: > sessid=%08x\n", __func__, sess->sessid); - - memset(cmd, 0, sizeof(struct tee_cmd)); - - cmd->cmd = cmd_io->cmd; - cmd->origin = TEEC_ORIGIN_TEE; - cmd->err = TEEC_ERROR_BAD_PARAMETERS; - cmd_io->origin = cmd->origin; - cmd_io->err = cmd->err; - - if (tee_context_copy_from_client(ctx, &op, cmd_io->op, sizeof(op))) - goto out; - - cmd->param.type_original = op.paramTypes; - - for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { - uint32_t offset = 0; - uint32_t size = 0; - int type = TEEC_PARAM_TYPE_GET(op.paramTypes, idx); - - switch (type) { - case TEEC_NONE: - break; - - case TEEC_VALUE_INPUT: - case TEEC_VALUE_OUTPUT: - case TEEC_VALUE_INOUT: - param->params[idx].value = op.params[idx].value; - dev_dbg(_DEV_TEE, - "%s: param[%d]:type=%d,a=%08x,b=%08x (VALUE)\n", - __func__, idx, type, param->params[idx].value.a, - param->params[idx].value.b); - break; - - case TEEC_MEMREF_TEMP_INPUT: - case TEEC_MEMREF_TEMP_OUTPUT: - case TEEC_MEMREF_TEMP_INOUT: - dev_dbg(_DEV_TEE, - "> param[%d]:type=%d,buffer=%p,s=%zu (TMPREF)\n", - idx, type, op.params[idx].tmpref.buffer, - op.params[idx].tmpref.size); - - param->params[idx].shm = - tee_context_create_tmpref_buffer(ctx, - op.params[idx].tmpref.size, - op.params[idx].tmpref.buffer, - type); - if (IS_ERR_OR_NULL(param->params[idx].shm)) - goto out; - - dev_dbg(_DEV_TEE, "< %d %pad:%zd\n", idx, - ¶m->params[idx].shm->paddr, - param->params[idx].shm->size_alloc); - break; - - case TEEC_MEMREF_PARTIAL_INPUT: - case TEEC_MEMREF_PARTIAL_OUTPUT: - case TEEC_MEMREF_PARTIAL_INOUT: - case TEEC_MEMREF_WHOLE: - if (tee_copy_from_user(ctx, ¶m->c_shm[idx], - op.params[idx].memref.parent, - sizeof(param->c_shm[idx]))) { - goto out; - } - - if (type == TEEC_MEMREF_WHOLE) { - offset = 0; - size = param->c_shm[idx].size; - } else { /* for PARTIAL, check the size */ - offset = op.params[idx].memref.offset; - size = op.params[idx].memref.size; - if (param->c_shm[idx].size < size + offset) { - dev_err(_DEV(tee), "A PARTIAL parameter is bigger than the parent %zd < %d + %d\n", - param->c_shm[idx].size, size, - offset); - goto out; - } - } - - dev_dbg(_DEV_TEE, "> param[%d]:type=%d,buffer=%p, offset=%d size=%d\n", - idx, type, param->c_shm[idx].buffer, - offset, size); - - type = to_memref_type(param->c_shm[idx].flags); - if (type == 0) - goto out; - - param->params[idx].shm = tee_shm_get(ctx, - ¶m->c_shm[idx], size, offset); - - if (IS_ERR_OR_NULL(param->params[idx].shm)) { - param->params[idx].shm = - tee_context_create_tmpref_buffer(ctx, size, - param->c_shm[idx].buffer + offset, type); - - if (IS_ERR_OR_NULL(param->params[idx].shm)) - goto out; - } - - dev_dbg(_DEV_TEE, "< %d %pad:%zd\n", idx, - ¶m->params[idx].shm->paddr, - param->params[idx].shm->size_req); - break; - - default: - BUG_ON(1); - } - - param->type |= (type << (idx * 4)); - } - - if (cmd_io->uuid != NULL) { - dev_dbg(_DEV_TEE, "%s: copy UUID value...\n", __func__); - cmd->uuid = tee_context_alloc_shm_tmp(sess->ctx, - sizeof(*cmd_io->uuid), cmd_io->uuid, TEEC_MEM_INPUT); - if (IS_ERR_OR_NULL(cmd->uuid)) { - ret = -EINVAL; - goto out; - } - } - - ret = 0; - -out: - if (ret) - _release_tee_cmd(sess, cmd); - - dev_dbg(_DEV_TEE, "%s: < ret=%d\n", __func__, ret); - return ret; -} - -static void _update_client_tee_cmd(struct tee_session *sess, - struct tee_cmd_io *cmd_io, - struct tee_cmd *cmd) -{ - int idx; - struct tee_context *ctx; - TEEC_Operation op; - - BUG_ON(!cmd_io); - BUG_ON(!cmd_io->op); - BUG_ON(!cmd); - BUG_ON(!sess->ctx); - ctx = sess->ctx; - - dev_dbg(_DEV_TEE, "%s: returned err=0x%08x (origin=%d)\n", __func__, - cmd->err, cmd->origin); - - cmd_io->origin = cmd->origin; - cmd_io->err = cmd->err; - - if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, - TEEC_NONE, TEEC_NONE, TEEC_NONE)) - return; - - if (tee_context_copy_from_client(ctx, &op, cmd_io->op, sizeof(op))) - return; - - for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { - int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx); - int offset = 0; - size_t size; - size_t size_new; - TEEC_SharedMemory *parent; - - dev_dbg(_DEV_TEE, "%s: id %d type %d\n", __func__, idx, type); - BUG_ON(!tee_session_is_supported_type(sess, type)); - switch (type) { - case TEEC_NONE: - case TEEC_VALUE_INPUT: - case TEEC_MEMREF_TEMP_INPUT: - case TEEC_MEMREF_PARTIAL_INPUT: - break; - case TEEC_VALUE_OUTPUT: - case TEEC_VALUE_INOUT: - dev_dbg(_DEV_TEE, "%s: a=%08x, b=%08x\n", - __func__, - cmd->param.params[idx].value.a, - cmd->param.params[idx].value.b); - if (tee_copy_to_user - (ctx, &cmd_io->op->params[idx].value, - &cmd->param.params[idx].value, - sizeof(cmd_io->op->params[idx].value))) - dev_err(_DEV_TEE, - "%s:%d: can't update %d result to user\n", - __func__, __LINE__, idx); - break; - case TEEC_MEMREF_TEMP_OUTPUT: - case TEEC_MEMREF_TEMP_INOUT: - /* Returned updated size */ - size_new = cmd->param.params[idx].shm->size_req; - if (size_new != - op.params[idx].tmpref.size) { - dev_dbg(_DEV_TEE, - "Size has been updated by the TA %zd != %zd\n", - size_new, - op.params[idx].tmpref.size); - tee_put_user(ctx, size_new, - &cmd_io->op->params[idx].tmpref.size); - } - - dev_dbg(_DEV_TEE, "%s: tmpref %p\n", __func__, - cmd->param.params[idx].shm->kaddr); - - /* ensure we do not exceed the shared buffer length */ - if (size_new > op.params[idx].tmpref.size) - dev_err(_DEV_TEE, - " *** Wrong returned size from %d:%zd > %zd\n", - idx, size_new, - op.params[idx].tmpref.size); - - else if (tee_copy_to_user - (ctx, - op.params[idx].tmpref.buffer, - cmd->param.params[idx].shm->kaddr, - size_new)) - dev_err(_DEV_TEE, - "%s:%d: can't update %d result to user\n", - __func__, __LINE__, idx); - break; - - case TEEC_MEMREF_PARTIAL_OUTPUT: - case TEEC_MEMREF_PARTIAL_INOUT: - case TEEC_MEMREF_WHOLE: - parent = &cmd->param.c_shm[idx]; - if (type == TEEC_MEMREF_WHOLE) { - offset = 0; - size = parent->size; - } else { - offset = op.params[idx].memref.offset; - size = op.params[idx].memref.size; - } - - /* Returned updated size */ - size_new = cmd->param.params[idx].shm->size_req; - tee_put_user(ctx, size_new, - &cmd_io->op->params[idx].memref.size); - - /* - * If we allocated a tmpref buffer, - * copy back data to the user buffer - */ - if (is_mapped_temp(cmd->param.params[idx].shm->flags)) { - if (parent->buffer && - offset + size_new <= parent->size) { - if (tee_copy_to_user(ctx, - parent->buffer + offset, - cmd->param.params[idx].shm->kaddr, - size_new)) - dev_err(_DEV_TEE, - "%s: can't update %d data to user\n", - __func__, idx); - } - } - break; - default: - BUG_ON(1); - } - } - -} - -static void _release_tee_cmd(struct tee_session *sess, struct tee_cmd *cmd) -{ - int idx; - struct tee_context *ctx; - - BUG_ON(!cmd); - BUG_ON(!sess); - BUG_ON(!sess->ctx); - BUG_ON(!sess->ctx->tee); - - ctx = sess->ctx; - - dev_dbg(_DEV_TEE, "%s: > free the temporary objects...\n", __func__); - - rk_tee_shm_free(cmd->uuid); - - if (cmd->param.type_original == TEEC_PARAM_TYPES(TEEC_NONE, - TEEC_NONE, TEEC_NONE, TEEC_NONE)) - goto out; - - for (idx = 0; idx < TEEC_CONFIG_PAYLOAD_REF_COUNT; ++idx) { - int type = TEEC_PARAM_TYPE_GET(cmd->param.type_original, idx); - struct tee_shm *shm; - switch (type) { - case TEEC_NONE: - case TEEC_VALUE_INPUT: - case TEEC_VALUE_OUTPUT: - case TEEC_VALUE_INOUT: - break; - case TEEC_MEMREF_TEMP_INPUT: - case TEEC_MEMREF_TEMP_OUTPUT: - case TEEC_MEMREF_TEMP_INOUT: - case TEEC_MEMREF_WHOLE: - case TEEC_MEMREF_PARTIAL_INPUT: - case TEEC_MEMREF_PARTIAL_OUTPUT: - case TEEC_MEMREF_PARTIAL_INOUT: - if (IS_ERR_OR_NULL(cmd->param.params[idx].shm)) - break; - - shm = cmd->param.params[idx].shm; - - if (is_mapped_temp(shm->flags)) - rk_tee_shm_free(shm); - else - rk_tee_shm_put(ctx, shm); - break; - default: - BUG_ON(1); - } - } - -out: - memset(cmd, 0, sizeof(struct tee_cmd)); - dev_dbg(_DEV_TEE, "%s: <\n", __func__); -} diff --git a/security/optee_linuxdriver/core/tee_shm.c b/security/optee_linuxdriver/core/tee_shm.c deleted file mode 100644 index f5e5c2e904ce..000000000000 --- a/security/optee_linuxdriver/core/tee_shm.c +++ /dev/null @@ -1,814 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include - -#include -#include - -#include "tee_core_priv.h" -#include "tee_shm.h" - -#define INMSG() dev_dbg(_DEV(tee), "%s: >\n", __func__) -#define OUTMSG(val) dev_dbg(_DEV(tee), "%s: < %ld\n", __func__, (long)val) -#define OUTMSGX(val) dev_dbg(_DEV(tee), "%s: < %08x\n",\ - __func__, (unsigned int)(long)val) - -/* TODO -#if (sizeof(TEEC_SharedMemory) != sizeof(tee_shm)) -#error "sizeof(TEEC_SharedMemory) != sizeof(tee_shm))" -#endif -*/ -struct tee_shm_attach { - struct sg_table sgt; - enum dma_data_direction dir; - bool is_mapped; -}; - -struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size) -{ - struct tee_shm *shm; - - INMSG(); - - mutex_lock(&tee->lock); - shm = rk_tee_shm_alloc(tee, size, TEE_SHM_TEMP | TEE_SHM_FROM_RPC); - if (IS_ERR_OR_NULL(shm)) { - dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n", - __func__, PTR_ERR(shm)); - goto out; - } - - tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]); - list_add_tail(&shm->entry, &tee->list_rpc_shm); - - shm->ctx = NULL; - -out: - mutex_unlock(&tee->lock); - OUTMSGX(shm); - return shm; -} - -void tee_shm_free_from_rpc(struct tee_shm *shm) -{ - struct tee *tee; - - if (shm == NULL) - return; - tee = shm->tee; - mutex_lock(&tee->lock); - if (shm->ctx == NULL) { - tee_dec_stats(&shm->tee->stats[TEE_STATS_SHM_IDX]); - list_del(&shm->entry); - } - - rk_tee_shm_free(shm); - mutex_unlock(&tee->lock); -} - -struct tee_shm *rk_tee_shm_alloc(struct tee *tee, size_t size, uint32_t flags) -{ - struct tee_shm *shm; - unsigned long pfn; - unsigned int nr_pages; - struct page *page; - int ret; - - INMSG(); - - shm = tee->ops->alloc(tee, size, flags); - if (IS_ERR_OR_NULL(shm)) { - dev_err(_DEV(tee), - "%s: allocation failed (s=%d,flags=0x%08x) err=%ld\n", - __func__, (int)size, flags, PTR_ERR(shm)); - goto exit; - } - - shm->tee = tee; - - dev_dbg(_DEV(tee), "%s: shm=%p, paddr=%pad,s=%d/%d app=\"%s\" pid=%d\n", - __func__, shm, &shm->paddr, (int)shm->size_req, - (int)shm->size_alloc, current->comm, current->pid); - - pfn = shm->paddr >> PAGE_SHIFT; - page = pfn_to_page(pfn); - if (IS_ERR_OR_NULL(page)) { - dev_err(_DEV(tee), "%s: pfn_to_page(%lx) failed\n", - __func__, pfn); - tee->ops->free(shm); - return (struct tee_shm *)page; - } - - /* Only one page of contiguous physical memory */ - nr_pages = 1; - - ret = sg_alloc_table_from_pages(&shm->sgt, &page, - nr_pages, 0, nr_pages * PAGE_SIZE, GFP_KERNEL); - if (ret < 0) { - dev_err(_DEV(tee), "%s: sg_alloc_table_from_pages() failed\n", - __func__); - tee->ops->free(shm); - shm = ERR_PTR(ret); - } -exit: - OUTMSGX(shm); - return shm; -} - -void rk_tee_shm_free(struct tee_shm *shm) -{ - struct tee *tee; - - if (IS_ERR_OR_NULL(shm)) - return; - tee = shm->tee; - if (tee == NULL) - pr_warn("invalid call to tee_shm_free(%p): NULL tee\n", shm); - else if (shm->tee == NULL) - dev_warn(_DEV(tee), "tee_shm_free(%p): NULL tee\n", shm); - else { - sg_free_table(&shm->sgt); - shm->tee->ops->free(shm); - } -} - -static int _tee_shm_attach_dma_buf(struct dma_buf *dmabuf, - struct dma_buf_attachment *attach) -{ - struct tee_shm_attach *tee_shm_attach; - struct tee_shm *shm; - struct tee *tee; - - shm = dmabuf->priv; - tee = shm->tee; - - INMSG(); - - tee_shm_attach = devm_kzalloc(_DEV(tee), - sizeof(*tee_shm_attach), GFP_KERNEL); - if (!tee_shm_attach) { - OUTMSG(-ENOMEM); - return -ENOMEM; - } - - tee_shm_attach->dir = DMA_NONE; - attach->priv = tee_shm_attach; - - OUTMSG(0); - return 0; -} - -static void _tee_shm_detach_dma_buf(struct dma_buf *dmabuf, - struct dma_buf_attachment *attach) -{ - struct tee_shm_attach *tee_shm_attach = attach->priv; - struct sg_table *sgt; - struct tee_shm *shm; - struct tee *tee; - - shm = dmabuf->priv; - tee = shm->tee; - - INMSG(); - - if (!tee_shm_attach) { - OUTMSG(0); - return; - } - - sgt = &tee_shm_attach->sgt; - - if (tee_shm_attach->dir != DMA_NONE) - dma_unmap_sg(attach->dev, sgt->sgl, sgt->nents, - tee_shm_attach->dir); - - sg_free_table(sgt); - devm_kfree(_DEV(tee), tee_shm_attach); - attach->priv = NULL; - OUTMSG(0); -} - -static struct sg_table *_tee_shm_dma_buf_map_dma_buf( - struct dma_buf_attachment *attach, enum dma_data_direction dir) -{ - struct tee_shm_attach *tee_shm_attach = attach->priv; - struct tee_shm *tee_shm = attach->dmabuf->priv; - struct sg_table *sgt = NULL; - struct scatterlist *rd, *wr; - unsigned int i; - int nents, ret; - struct tee *tee; - - tee = tee_shm->tee; - - INMSG(); - - /* just return current sgt if already requested. */ - if (tee_shm_attach->dir == dir && tee_shm_attach->is_mapped) { - OUTMSGX(&tee_shm_attach->sgt); - return &tee_shm_attach->sgt; - } - - sgt = &tee_shm_attach->sgt; - - ret = sg_alloc_table(sgt, tee_shm->sgt.orig_nents, GFP_KERNEL); - if (ret) { - dev_err(_DEV(tee), "failed to alloc sgt.\n"); - return ERR_PTR(-ENOMEM); - } - - rd = tee_shm->sgt.sgl; - wr = sgt->sgl; - for (i = 0; i < sgt->orig_nents; ++i) { - sg_set_page(wr, sg_page(rd), rd->length, rd->offset); - rd = sg_next(rd); - wr = sg_next(wr); - } - - if (dir != DMA_NONE) { - nents = dma_map_sg(attach->dev, sgt->sgl, sgt->orig_nents, dir); - if (!nents) { - dev_err(_DEV(tee), "failed to map sgl with iommu.\n"); - sg_free_table(sgt); - sgt = ERR_PTR(-EIO); - goto err_unlock; - } - } - - tee_shm_attach->is_mapped = true; - tee_shm_attach->dir = dir; - attach->priv = tee_shm_attach; - -err_unlock: - OUTMSGX(sgt); - return sgt; -} - -static void _tee_shm_dma_buf_unmap_dma_buf(struct dma_buf_attachment *attach, - struct sg_table *table, - enum dma_data_direction dir) -{ - return; -} - -static void _tee_shm_dma_buf_release(struct dma_buf *dmabuf) -{ - struct tee_shm *shm = dmabuf->priv; - struct tee_context *ctx; - struct tee *tee; - - tee = shm->ctx->tee; - - INMSG(); - - ctx = shm->ctx; - dev_dbg(_DEV(ctx->tee), "%s: shm=%p, paddr=%pad,s=%d/%d app=\"%s\" pid=%d\n", - __func__, shm, &shm->paddr, (int)shm->size_req, - (int)shm->size_alloc, current->comm, current->pid); - - tee_shm_free_io(shm); - - OUTMSG(0); -} - -static int _tee_shm_dma_buf_mmap(struct dma_buf *dmabuf, - struct vm_area_struct *vma) -{ - struct tee_shm *shm = dmabuf->priv; - size_t size = vma->vm_end - vma->vm_start; - struct tee *tee; - int ret; - pgprot_t prot; - unsigned long pfn; - - tee = shm->ctx->tee; - - pfn = shm->paddr >> PAGE_SHIFT; - - INMSG(); - - if (shm->flags & TEE_SHM_CACHED) - prot = vma->vm_page_prot; - else - prot = pgprot_noncached(vma->vm_page_prot); - - ret = - remap_pfn_range(vma, vma->vm_start, pfn, size, prot); - if (!ret) - vma->vm_private_data = (void *)shm; - - dev_dbg(_DEV(shm->ctx->tee), "%s: map the shm (p@=%pad,s=%dKiB) => %x\n", - __func__, &shm->paddr, (int)size / 1024, - (unsigned int)vma->vm_start); - - OUTMSG(ret); - return ret; -} - -static void *_tee_shm_dma_buf_kmap(struct dma_buf *db, unsigned long pgnum) -{ - struct tee_shm *shm = db->priv; - - dev_dbg(_DEV(shm->ctx->tee), "%s: kmap the shm (p@=%pad, v@=%p, s=%zdKiB)\n", - __func__, &shm->paddr, (void *)shm->kaddr, - shm->size_alloc / 1024); - /* - * A this stage, a shm allocated by the tee - * must be have a kernel address - */ - return shm->kaddr; -} - -static void _tee_shm_dma_buf_kunmap( - struct dma_buf *db, unsigned long pfn, void *kaddr) -{ - /* unmap is done at the de init of the shm pool */ -} - -struct dma_buf_ops _tee_shm_dma_buf_ops = { - .attach = _tee_shm_attach_dma_buf, - .detach = _tee_shm_detach_dma_buf, - .map_dma_buf = _tee_shm_dma_buf_map_dma_buf, - .unmap_dma_buf = _tee_shm_dma_buf_unmap_dma_buf, - .release = _tee_shm_dma_buf_release, - .map = _tee_shm_dma_buf_kmap, - .unmap = _tee_shm_dma_buf_kunmap, - .mmap = _tee_shm_dma_buf_mmap, -}; - -/******************************************************************************/ - -static int export_buf(struct tee *tee, struct tee_shm *shm, int *export) -{ - struct dma_buf *dmabuf; - int ret = 0; - /* Temporary fix to support both older and newer kernel versions. */ -#if defined(DEFINE_DMA_BUF_EXPORT_INFO) - DEFINE_DMA_BUF_EXPORT_INFO(exp_info); - - exp_info.priv = shm; - exp_info.ops = &_tee_shm_dma_buf_ops; - exp_info.size = shm->size_alloc; - exp_info.flags = O_RDWR; - - dmabuf = dma_buf_export(&exp_info); -#else - dmabuf = dma_buf_export(shm, &_tee_shm_dma_buf_ops, shm->size_alloc, - O_RDWR); -#endif - if (IS_ERR_OR_NULL(dmabuf)) { - dev_err(_DEV(tee), "%s: dmabuf: couldn't export buffer (%ld)\n", - __func__, PTR_ERR(dmabuf)); - ret = -EINVAL; - goto out; - } - - *export = dma_buf_fd(dmabuf, O_CLOEXEC); -out: - OUTMSG(ret); - return ret; -} - -int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io) -{ - struct tee_shm *shm; - struct tee *tee = ctx->tee; - int ret; - - INMSG(); - - if (ctx->usr_client) - shm_io->fd_shm = 0; - - mutex_lock(&tee->lock); - shm = rk_tee_shm_alloc(tee, shm_io->size, shm_io->flags); - if (IS_ERR_OR_NULL(shm)) { - dev_err(_DEV(tee), "%s: buffer allocation failed (%ld)\n", - __func__, PTR_ERR(shm)); - ret = PTR_ERR(shm); - goto out; - } - - if (ctx->usr_client) { - ret = export_buf(tee, shm, &shm_io->fd_shm); - if (ret) { - rk_tee_shm_free(shm); - ret = -ENOMEM; - goto out; - } - - shm->flags |= TEEC_MEM_DMABUF; - } - - shm->ctx = ctx; - shm->dev = get_device(_DEV(tee)); - ret = tee_get(tee); - BUG_ON(ret); /* tee_core_get must not issue */ - tee_context_get(ctx); - - tee_inc_stats(&tee->stats[TEE_STATS_SHM_IDX]); - list_add_tail(&shm->entry, &ctx->list_shm); -out: - mutex_unlock(&tee->lock); - OUTMSG(ret); - return ret; -} - -void tee_shm_free_io(struct tee_shm *shm) -{ - struct tee_context *ctx = shm->ctx; - struct tee *tee = ctx->tee; - struct device *dev = shm->dev; - - mutex_lock(&ctx->tee->lock); - tee_dec_stats(&tee->stats[TEE_STATS_SHM_IDX]); - list_del(&shm->entry); - - rk_tee_shm_free(shm); - tee_put(ctx->tee); - tee_context_put(ctx); - if (dev) - put_device(dev); - mutex_unlock(&ctx->tee->lock); -} - -/* Buffer allocated by rpc from fw and to be accessed by the user - * Not need to be registered as it is not allocated by the user */ -int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io) -{ - struct tee_shm *shm = NULL; - struct tee *tee = ctx->tee; - int ret; - struct list_head *pshm; - - INMSG(); - - shm_io->fd_shm = 0; - - mutex_lock(&tee->lock); - if (!list_empty(&tee->list_rpc_shm)) { - list_for_each(pshm, &tee->list_rpc_shm) { - shm = list_entry(pshm, struct tee_shm, entry); - if ((void *)(unsigned long)shm->paddr == shm_io->buffer) - goto found; - } - } - - dev_err(_DEV(tee), "Can't find shm for %p\n", (void *)shm_io->buffer); - ret = -ENOMEM; - goto out; - -found: - ret = export_buf(tee, shm, &shm_io->fd_shm); - if (ret) { - ret = -ENOMEM; - goto out; - } - - shm->ctx = ctx; - list_move(&shm->entry, &ctx->list_shm); - - shm->dev = get_device(_DEV(tee)); - ret = tee_get(tee); - BUG_ON(ret); - tee_context_get(ctx); - - BUG_ON(!tee->ops->shm_inc_ref(shm)); -out: - mutex_unlock(&tee->lock); - OUTMSG(ret); - return ret; -} - -/******************************************************************************/ - -static int tee_shm_db_get(struct tee *tee, struct tee_shm *shm, int fd, - unsigned int flags, size_t size, int offset) -{ - struct tee_shm_dma_buf *sdb; - struct dma_buf *dma_buf; - int ret = 0; - - dev_dbg(_DEV(tee), "%s: > fd=%d flags=%08x\n", __func__, fd, flags); - - dma_buf = dma_buf_get(fd); - if (IS_ERR(dma_buf)) { - ret = PTR_ERR(dma_buf); - goto exit; - } - - sdb = kzalloc(sizeof(*sdb), GFP_KERNEL); - if (IS_ERR_OR_NULL(sdb)) { - dev_err(_DEV(tee), "can't alloc tee_shm_dma_buf\n"); - ret = PTR_ERR(sdb); - goto buf_put; - } - shm->sdb = sdb; - - if (dma_buf->size < size + offset) { - dev_err(_DEV(tee), "dma_buf too small %zd < %zd + %d\n", - dma_buf->size, size, offset); - ret = -EINVAL; - goto free_sdb; - } - - sdb->attach = dma_buf_attach(dma_buf, _DEV(tee)); - if (IS_ERR_OR_NULL(sdb->attach)) { - ret = PTR_ERR(sdb->attach); - goto free_sdb; - } - - sdb->sgt = dma_buf_map_attachment(sdb->attach, DMA_NONE); - if (IS_ERR_OR_NULL(sdb->sgt)) { - ret = PTR_ERR(sdb->sgt); - goto buf_detach; - } - - if (sg_nents(sdb->sgt->sgl) != 1) { - ret = -EINVAL; - goto buf_unmap; - } - - shm->paddr = sg_phys(sdb->sgt->sgl) + offset; - if (dma_buf->ops->attach == _tee_shm_attach_dma_buf) - sdb->tee_allocated = true; - else - sdb->tee_allocated = false; - - shm->flags |= TEEC_MEM_DMABUF; - - dev_dbg(_DEV(tee), "fd=%d @p=%pad is_tee=%d db=%p\n", fd, - &shm->paddr, sdb->tee_allocated, dma_buf); - goto exit; - -buf_unmap: - dma_buf_unmap_attachment(sdb->attach, sdb->sgt, DMA_NONE); -buf_detach: - dma_buf_detach(dma_buf, sdb->attach); -free_sdb: - kfree(sdb); -buf_put: - dma_buf_put(dma_buf); -exit: - OUTMSG(ret); - return ret; -} - -#ifdef VA_GET_ENABLED -static unsigned int tee_shm_get_phy_from_kla( - struct mm_struct *mm, unsigned int kla) -{ - pgd_t *pgd; - pud_t *pud; - pmd_t *pmd; - pte_t *ptep, pte; - unsigned int pa = 0; - - /* stolen from kernel3.10:mm/memory.c:__follow_pte */ - - pgd = pgd_offset(mm, kla); - if (pgd_none(*pgd) || pgd_bad(*pgd)) - return 0; - - pud = pud_offset(pgd, kla); - if (pud_none(*pud) || pud_bad(*pud)) - return 0; - - pmd = pmd_offset(pud, kla); - VM_BUG_ON(pmd_trans_huge(*pmd)); - if (pmd_none(*pmd) || pmd_bad(*pmd)) - return 0; - - /* We cannot handle huge page PFN maps. - * Luckily they don't exist. */ - if (pmd_huge(*pmd)) - return 0; - - ptep = pte_offset_map(pmd, kla); - - if (!ptep) - return 0; - - pte = *ptep; - - if (pte_present(pte)) - pa = __pa(page_address(pte_page(pte))); - - if (!pa) - return 0; - - return pa; - -} - -static int tee_shm_va_get(struct tee_context *ctx, struct tee_shm *shm, - void *buffer, unsigned int flags, size_t size, int offset) -{ - int ret = 0; - struct mm_struct *mm = current->mm; - unsigned long va = (unsigned long)buffer; - unsigned int virt_base = (va / PAGE_SIZE) * PAGE_SIZE; - unsigned int offset_in_page = va - virt_base; - unsigned int offset_total = offset_in_page + offset; - struct vm_area_struct *vma; - struct tee *tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: > %p\n", __func__, buffer); - /* if the caller is the kernel api, active_mm is mm */ - if (!mm) - mm = current->active_mm; - - BUG_ON(!mm); - - vma = find_vma(mm, virt_base); - - if (vma) { - unsigned long pfn; - /* It's a VMA => consider it a a user address */ - - if (follow_pfn(vma, virt_base, &pfn)) { - dev_err(_DEV(tee), "%s can't get pfn for %p\n", - __func__, buffer); - ret = -EINVAL; - goto out; - } - - shm->paddr = PFN_PHYS(pfn) + offset_total; - - if (vma->vm_end - vma->vm_start - offset_total < size) { - dev_err(_DEV(tee), "%s %p:%x not big enough: %lx - %d < %x\n", - __func__, buffer, shm->paddr, - vma->vm_end - vma->vm_start, - offset_total, size); - shm->paddr = 0; - ret = -EINVAL; - goto out; - } - } else if (!ctx->usr_client) { - /* It's not a VMA => consider it as a kernel address - * And look if it's an internal known phys addr - * Note: virt_to_phys is not usable since it can be a direct - * map or a vremap address - */ - unsigned int phys_base; - int nb_page = (PAGE_SIZE - 1 + size + offset_total) / PAGE_SIZE; - int i; - - spin_lock(&mm->page_table_lock); - phys_base = tee_shm_get_phy_from_kla(mm, virt_base); - - if (!phys_base) { - spin_unlock(&mm->page_table_lock); - dev_err(_DEV(tee), "%s can't get physical address for %p\n", - __func__, buffer); - goto err; - } - - /* Check continuity on size */ - for (i = 1; i < nb_page; i++) { - unsigned int pa = tee_shm_get_phy_from_kla(mm, - virt_base + i*PAGE_SIZE); - if (pa != phys_base + i*PAGE_SIZE) { - spin_unlock(&mm->page_table_lock); - dev_err(_DEV(tee), "%s %p:%x not big enough: %lx - %d < %x\n", - __func__, buffer, phys_base, - i*PAGE_SIZE, - offset_total, size); - goto err; - } - } - spin_unlock(&mm->page_table_lock); - - shm->paddr = phys_base + offset_total; - goto out; -err: - ret = -EINVAL; - } - -out: - dev_dbg(_DEV(tee), "%s: < %d shm=%p vaddr=%p paddr=%x\n", - __func__, ret, (void *)shm, buffer, shm->paddr); - return ret; -} -#endif - -struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm, - size_t size, int offset) -{ - struct tee_shm *shm; - struct tee *tee = ctx->tee; - int ret; - - dev_dbg(_DEV(tee), "%s: > fd=%d flags=%08x\n", - __func__, c_shm->d.fd, c_shm->flags); - - mutex_lock(&tee->lock); - shm = kzalloc(sizeof(*shm), GFP_KERNEL); - if (IS_ERR_OR_NULL(shm)) { - dev_err(_DEV(tee), "can't alloc tee_shm\n"); - ret = -ENOMEM; - goto err; - } - - shm->ctx = ctx; - shm->tee = tee; - shm->dev = _DEV(tee); - shm->flags = c_shm->flags | TEE_SHM_MEMREF; - shm->size_req = size; - shm->size_alloc = 0; - - if (c_shm->flags & TEEC_MEM_KAPI) { - struct tee_shm *kc_shm = (struct tee_shm *)c_shm->d.ptr; - - if (!kc_shm) { - dev_err(_DEV(tee), "kapi fd null\n"); - ret = -EINVAL; - goto err; - } - shm->paddr = kc_shm->paddr; - - if (kc_shm->size_alloc < size + offset) { - dev_err(_DEV(tee), "kapi buff too small %zd < %zd + %d\n", - kc_shm->size_alloc, size, offset); - ret = -EINVAL; - goto err; - } - - dev_dbg(_DEV(tee), "fd=%d @p=%pad\n", - c_shm->d.fd, &shm->paddr); - } else if (c_shm->d.fd) { - ret = tee_shm_db_get(tee, shm, - c_shm->d.fd, c_shm->flags, size, offset); - if (ret) - goto err; - } else if (!c_shm->buffer) { - dev_dbg(_DEV(tee), "null buffer, pass 'as is'\n"); - } else { -#ifdef VA_GET_ENABLED - ret = tee_shm_va_get(ctx, shm, - c_shm->buffer, c_shm->flags, size, offset); - if (ret) - goto err; -#else - ret = -EINVAL; - goto err; -#endif - } - - mutex_unlock(&tee->lock); - OUTMSGX(shm); - return shm; - -err: - kfree(shm); - mutex_unlock(&tee->lock); - OUTMSGX(ERR_PTR(ret)); - return ERR_PTR(ret); -} - -void rk_tee_shm_put(struct tee_context *ctx, struct tee_shm *shm) -{ - struct tee *tee = ctx->tee; - - dev_dbg(_DEV(tee), "%s: > shm=%p flags=%08x paddr=%pad\n", - __func__, (void *)shm, shm->flags, &shm->paddr); - - BUG_ON(!shm); - BUG_ON(!(shm->flags & TEE_SHM_MEMREF)); - - mutex_lock(&tee->lock); - if (shm->flags & TEEC_MEM_DMABUF) { - struct tee_shm_dma_buf *sdb; - struct dma_buf *dma_buf; - - sdb = shm->sdb; - dma_buf = sdb->attach->dmabuf; - - dev_dbg(_DEV(tee), "%s: db=%p\n", __func__, (void *)dma_buf); - - dma_buf_unmap_attachment(sdb->attach, sdb->sgt, DMA_NONE); - dma_buf_detach(dma_buf, sdb->attach); - dma_buf_put(dma_buf); - - kfree(sdb); - sdb = 0; - } - - kfree(shm); - mutex_unlock(&tee->lock); - OUTMSG(0); -} - diff --git a/security/optee_linuxdriver/core/tee_shm.h b/security/optee_linuxdriver/core/tee_shm.h deleted file mode 100644 index 7593081235a7..000000000000 --- a/security/optee_linuxdriver/core/tee_shm.h +++ /dev/null @@ -1,34 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_SHM_H__ -#define __TEE_SHM_H__ - -#include -struct tee_context; -struct tee_shm; -struct tee_shm_io; -struct tee; - -int tee_shm_alloc_io(struct tee_context *ctx, struct tee_shm_io *shm_io); -void tee_shm_free_io(struct tee_shm *shm); - -int tee_shm_fd_for_rpc(struct tee_context *ctx, struct tee_shm_io *shm_io); - -struct tee_shm *rk_tee_shm_alloc(struct tee *tee, size_t size, uint32_t flags); -void rk_tee_shm_free(struct tee_shm *shm); - -struct tee_shm *tee_shm_get(struct tee_context *ctx, TEEC_SharedMemory *c_shm, - size_t size, int offset); -void rk_tee_shm_put(struct tee_context *ctx, struct tee_shm *shm); - -#endif /* __TEE_SHM_H__ */ diff --git a/security/optee_linuxdriver/core/tee_supp_com.c b/security/optee_linuxdriver/core/tee_supp_com.c deleted file mode 100644 index 490cae784cd6..000000000000 --- a/security/optee_linuxdriver/core/tee_supp_com.c +++ /dev/null @@ -1,275 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include "tee_shm.h" -#include "tee_core.h" -#include "tee_supp_com.h" - -#define TEE_RPC_BUFFER 0x00000001 -#define TEE_RPC_VALUE 0x00000002 - -enum teec_rpc_result tee_supp_cmd(struct tee *tee, - uint32_t id, void *data, size_t datalen) -{ - struct tee_rpc *rpc = tee->rpc; - enum teec_rpc_result res = TEEC_RPC_FAIL; - size_t size; - struct task_struct *task = current; - - dev_dbg(tee->dev, "> tgid:[%d] id:[0x%08x]\n", task->tgid, id); - - if (atomic_read(&rpc->used) == 0) { - dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n" - , __func__); - goto out; - } - - switch (id) { - case TEE_RPC_ICMD_ALLOCATE: - { - struct tee_rpc_alloc *alloc; - struct tee_shm *shmint; - - alloc = (struct tee_rpc_alloc *)data; - size = alloc->size; - memset(alloc, 0, sizeof(struct tee_rpc_alloc)); - shmint = tee_shm_alloc_from_rpc(tee, size); - if (IS_ERR_OR_NULL(shmint)) - break; - - alloc->size = size; - alloc->data = (void *)(unsigned long)shmint->paddr; - alloc->shm = shmint; - res = TEEC_RPC_OK; - - break; - } - case TEE_RPC_ICMD_FREE: - { - struct tee_rpc_free *free; - - free = (struct tee_rpc_free *)data; - tee_shm_free_from_rpc(free->shm); - res = TEEC_RPC_OK; - break; - } - case TEE_RPC_ICMD_INVOKE: - { - if (sizeof(rpc->commToUser) < datalen) - break; - - /* - * Other threads blocks here until we've copied our - * answer from the supplicant - */ - mutex_lock(&rpc->thrd_mutex); - - mutex_lock(&rpc->outsync); - memcpy(&rpc->commToUser, data, datalen); - mutex_unlock(&rpc->outsync); - - dev_dbg(tee->dev, - "Supplicant Cmd: %x. Give hand to supplicant\n", - rpc->commToUser.cmd); - - up(&rpc->datatouser); - - down(&rpc->datafromuser); - - dev_dbg(tee->dev, - "Supplicant Cmd: %x. Give hand to fw\n", - rpc->commToUser.cmd); - - mutex_lock(&rpc->insync); - memcpy(data, &rpc->commFromUser, datalen); - mutex_unlock(&rpc->insync); - - mutex_unlock(&rpc->thrd_mutex); - - res = TEEC_RPC_OK; - - break; - } - default: - /* not supported */ - break; - } - -out: - dev_dbg(tee->dev, "< res: [%d]\n", res); - - return res; -} -EXPORT_SYMBOL(tee_supp_cmd); - -ssize_t tee_supp_read(struct file *filp, char __user *buffer, - size_t length, loff_t *offset) -{ - struct tee_context *ctx = (struct tee_context *)(filp->private_data); - struct tee *tee; - struct tee_rpc *rpc; - struct task_struct *task = current; - int ret; - - BUG_ON(!ctx); - tee = ctx->tee; - BUG_ON(!tee); - BUG_ON(!tee->dev); - BUG_ON(!tee->rpc); - - dev_dbg(tee->dev, "> ctx %p\n", ctx); - - rpc = tee->rpc; - - if (atomic_read(&rpc->used) == 0) { - dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n" - , __func__); - ret = -EPERM; - goto out; - } - - if (down_interruptible(&rpc->datatouser)) - return -ERESTARTSYS; - - dev_dbg(tee->dev, "> tgid:[%d]\n", task->tgid); - - mutex_lock(&rpc->outsync); - - ret = - sizeof(rpc->commToUser) - sizeof(rpc->commToUser.cmds) + - sizeof(rpc->commToUser.cmds[0]) * rpc->commToUser.nbr_bf; - if (length < ret) { - ret = -EINVAL; - } else { - if (copy_to_user(buffer, &rpc->commToUser, ret)) { - dev_err(tee->dev, - "[%s] error, copy_to_user failed!\n", __func__); - ret = -EINVAL; - } - } - - mutex_unlock(&rpc->outsync); - -out: - dev_dbg(tee->dev, "< [%d]\n", ret); - return ret; -} - -ssize_t tee_supp_write(struct file *filp, const char __user *buffer, - size_t length, loff_t *offset) -{ - struct tee_context *ctx = (struct tee_context *)(filp->private_data); - struct tee *tee; - struct tee_rpc *rpc; - struct task_struct *task = current; - int ret = 0; - - BUG_ON(!ctx); - BUG_ON(!ctx->tee); - BUG_ON(!ctx->tee->rpc); - tee = ctx->tee; - rpc = tee->rpc; - dev_dbg(tee->dev, "> tgid:[%d]\n", task->tgid); - - if (atomic_read(&rpc->used) == 0) { - dev_err(tee->dev, "%s: ERROR Supplicant application NOT ready\n" - , __func__); - goto out; - } - - if (length > 0 && length < sizeof(rpc->commFromUser)) { - uint32_t i; - - mutex_lock(&rpc->insync); - - if (copy_from_user(&rpc->commFromUser, buffer, length)) { - dev_err(tee->dev, - "%s: ERROR, tee_session copy_from_user failed\n", - __func__); - mutex_unlock(&rpc->insync); - ret = -EINVAL; - goto out; - } - - /* Translate virtual address of caller into physical address */ - for (i = 0; i < rpc->commFromUser.nbr_bf; i++) { - if (rpc->commFromUser.cmds[i].type == TEE_RPC_BUFFER - && rpc->commFromUser.cmds[i].buffer) { - struct vm_area_struct *vma = - find_vma(current->mm, - (unsigned long)rpc-> - commFromUser.cmds[i].buffer); - if (vma != NULL) { - struct tee_shm *shm = - vma->vm_private_data; - BUG_ON(!shm); - dev_dbg(tee->dev, - "%d gid2pa(0x%p => %x)\n", i, - rpc->commFromUser.cmds[i]. - buffer, - (unsigned int)shm->paddr); - rpc->commFromUser.cmds[i].buffer = - (void *)(unsigned long)shm->paddr; - } else - dev_dbg(tee->dev, - " gid2pa(0x%p => NULL\n)", - rpc->commFromUser.cmds[i]. - buffer); - } - } - - mutex_unlock(&rpc->insync); - up(&rpc->datafromuser); - ret = length; - } - -out: - dev_dbg(tee->dev, "< [%d]\n", ret); - return ret; -} - -int tee_supp_init(struct tee *tee) -{ - struct tee_rpc *rpc = - devm_kzalloc(tee->dev, sizeof(struct tee_rpc), GFP_KERNEL); - if (!rpc) { - dev_err(tee->dev, "%s: can't allocate tee_rpc structure\n", - __func__); - return -ENOMEM; - } - - sema_init(&rpc->datafromuser, 0); - sema_init(&rpc->datatouser, 0); - mutex_init(&rpc->thrd_mutex); - mutex_init(&rpc->outsync); - mutex_init(&rpc->insync); - atomic_set(&rpc->used, 0); - tee->rpc = rpc; - return 0; -} - -void tee_supp_deinit(struct tee *tee) -{ - devm_kfree(tee->dev, tee->rpc); - tee->rpc = NULL; -} diff --git a/security/optee_linuxdriver/core/tee_supp_com.h b/security/optee_linuxdriver/core/tee_supp_com.h deleted file mode 100644 index e5117e8357cc..000000000000 --- a/security/optee_linuxdriver/core/tee_supp_com.h +++ /dev/null @@ -1,117 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef TEE_SUPP_COMM_H -#define TEE_SUPP_COMM_H - -#define TEE_RPC_ICMD_ALLOCATE 0x1001 -#define TEE_RPC_ICMD_FREE 0x1002 -#define TEE_RPC_ICMD_INVOKE 0x1003 - -#define TEE_RPC_NBR_BUFF 1 -#define TEE_RPC_DATA_SIZE 64 -#define TEE_RPC_BUFFER_NUMBER 5 - -#define TEE_RPC_STATE_IDLE 0x00 -#define TEE_RPC_STATE_ACTIVE 0x01 - -/* Keep aligned with optee_client (user space) */ -#define TEE_RPC_BUFFER 0x00000001 -#define TEE_RPC_VALUE 0x00000002 -#define TEE_RPC_LOAD_TA 0x10000001 -/* - * Handled within the driver only - * Keep aligned with optee_os (secure space) - */ -#define TEE_RPC_MUTEX_WAIT 0x20000000 -#define TEE_RPC_WAIT_QUEUE_SLEEP 0x20000001 -#define TEE_RPC_WAIT_QUEUE_WAKEUP 0x20000002 -#define TEE_RPC_WAIT 0x30000000 - -/* Parameters for TEE_RPC_WAIT_MUTEX above */ -#define TEE_MUTEX_WAIT_SLEEP 0 -#define TEE_MUTEX_WAIT_WAKEUP 1 -#define TEE_MUTEX_WAIT_DELETE 2 - -#include - -/** - * struct tee_rpc_bf - Contains definition of the tee com buffer - * @state: Buffer state - * @data: Command data - */ -struct tee_rpc_bf { - uint32_t state; - uint8_t data[TEE_RPC_DATA_SIZE]; -}; - -struct tee_rpc_alloc { - uint32_t size; /* size of block */ - void *data; /* pointer to data */ - void *shm; /* pointer to an opaque data, being shm structure */ -}; - -struct tee_rpc_free { - void *shm; /* pointer to an opaque data, being shm structure */ -}; - -struct tee_rpc_cmd { - union { - void *buffer; - uint64_t padding_buf; - }; - uint32_t size; - uint32_t type; - int fd; - int reserved; -}; - -struct tee_rpc_invoke { - uint32_t cmd; - uint32_t res; - uint32_t nbr_bf; - uint32_t reserved; - struct tee_rpc_cmd cmds[TEE_RPC_BUFFER_NUMBER]; -}; - -struct tee_rpc { - struct tee_rpc_invoke commToUser; - struct tee_rpc_invoke commFromUser; - struct semaphore datatouser; - struct semaphore datafromuser; - struct mutex thrd_mutex; /* Block the thread to wait for supp answer */ - struct mutex outsync; /* Out sync mutex */ - struct mutex insync; /* In sync mutex */ - struct mutex reqsync; /* Request sync mutex */ - atomic_t used; -}; - -enum teec_rpc_result { - TEEC_RPC_OK, - TEEC_RPC_FAIL -}; - -struct tee; - -int tee_supp_init(struct tee *tee); -void tee_supp_deinit(struct tee *tee); - -enum teec_rpc_result tee_supp_cmd(struct tee *tee, - uint32_t id, void *data, size_t datalen); - -ssize_t tee_supp_read(struct file *filp, char __user *buffer, - size_t length, loff_t *offset); - -ssize_t tee_supp_write(struct file *filp, const char __user *buffer, - size_t length, loff_t *offset); - -#endif diff --git a/security/optee_linuxdriver/core/tee_sysfs.c b/security/optee_linuxdriver/core/tee_sysfs.c deleted file mode 100644 index c9512ad67db2..000000000000 --- a/security/optee_linuxdriver/core/tee_sysfs.c +++ /dev/null @@ -1,204 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include -#include - -#include "tee_core_priv.h" - -static ssize_t dump_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - int len; - char *tmp_buf; - - tmp_buf = kzalloc(PAGE_SIZE, GFP_KERNEL); - if (!tmp_buf) { - printk(KERN_ALERT "%s : Unable to get buf memory\n", __func__); - return -ENOMEM; - } - - len = tee_context_dump(tee, tmp_buf, PAGE_SIZE - 128); - - if (len > 0) - len = snprintf(buf, PAGE_SIZE, "%s", tmp_buf); - kfree(tmp_buf); - - return len; -} - -static ssize_t stat_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "%d/%d %d/%d %d/%d %d/%d\n", - atomic_read(&tee->refcount), - tee->max_refcount, - tee->stats[TEE_STATS_CONTEXT_IDX].count, - tee->stats[TEE_STATS_CONTEXT_IDX].max, - tee->stats[TEE_STATS_SESSION_IDX].count, - tee->stats[TEE_STATS_SESSION_IDX].max, - tee->stats[TEE_STATS_SHM_IDX].count, - tee->stats[TEE_STATS_SHM_IDX].max); -} - -static ssize_t info_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "%s iminor=%d dev=\"%s\" state=%d\n", - dev_name(tee->dev), tee->miscdev.minor, - dev_name(tee->miscdev.this_device), tee->state); -} - -static ssize_t name_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "%s\n", tee->name); -} - -static ssize_t type_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "%s\n", tee->ops->type); -} - -static ssize_t refcount_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "%d\n", atomic_read(&tee->refcount)); -} - -static ssize_t conf_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "0x%08x\n", tee->conf); -} - -static ssize_t test_show(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - return snprintf(buf, PAGE_SIZE, "%08X\n", tee->test); -} - -static ssize_t test_store(struct device *device, - struct device_attribute *attr, const char *buf, - size_t count) -{ - struct tee *tee = dev_get_drvdata(device); - unsigned long val; - int status; - - status = kstrtoul(buf, 0, &val); - if (status) - return status; - - if ((tee->conf & TEE_CONF_TEST_MODE) == TEE_CONF_TEST_MODE) - tee->test = val; - - return count; -} - -/* - * A state-to-string lookup table, for exposing a human readable state - * via sysfs. Always keep in sync with enum tee_state - */ -static const char *const tee_state_string[] = { - "offline", - "online", - "suspended", - "running", - "crashed", - "invalid", -}; - -static ssize_t tee_show_state(struct device *device, - struct device_attribute *attr, char *buf) -{ - struct tee *tee = dev_get_drvdata(device); - - int state = tee->state > TEE_LAST ? TEE_LAST : tee->state; - - return snprintf(buf, PAGE_SIZE, "%s (%d)\n", tee_state_string[state], - tee->state); -} - -/* - * In the following, 0660 is (S_IWUGO | S_IRUGO) - */ -static struct device_attribute device_attrs[] = { - __ATTR_RO(dump), - __ATTR_RO(stat), - __ATTR_RO(info), - __ATTR(test, (0660), test_show, test_store), - __ATTR(state, S_IRUGO, tee_show_state, NULL), - __ATTR(name, S_IRUGO, name_show, NULL), - __ATTR(refcount, S_IRUGO, refcount_show, NULL), - __ATTR(type, S_IRUGO, type_show, NULL), - __ATTR(conf, S_IRUGO, conf_show, NULL), -}; - -void tee_init_sysfs(struct tee *tee) -{ - int i, error = 0; - - if (!tee) - return; - - if (dev_get_drvdata(tee->miscdev.this_device) != tee) { - dev_err(_DEV(tee), "drvdata is not valid\n"); - return; - } - - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) { - error = - device_create_file(tee->miscdev.this_device, - &device_attrs[i]); - if (error) - break; - } - - if (error) { - while (--i >= 0) - device_remove_file(tee->miscdev.this_device, - &device_attrs[i]); - } - /* location /sys/class/// -> - * /sys/class/misc/teelx00/info */ -} - -void tee_cleanup_sysfs(struct tee *tee) -{ - int i; - - if (!tee) - return; - - for (i = 0; i < ARRAY_SIZE(device_attrs); i++) - device_remove_file(tee->miscdev.this_device, &device_attrs[i]); -} diff --git a/security/optee_linuxdriver/core/tee_sysfs.h b/security/optee_linuxdriver/core/tee_sysfs.h deleted file mode 100644 index fbd797b5c870..000000000000 --- a/security/optee_linuxdriver/core/tee_sysfs.h +++ /dev/null @@ -1,21 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_SYSFS_H__ -#define __TEE_SYSFS_H__ - -struct tee; - -void tee_init_sysfs(struct tee *tee); -void tee_cleanup_sysfs(struct tee *tee); - -#endif diff --git a/security/optee_linuxdriver/core/tee_wait_queue.c b/security/optee_linuxdriver/core/tee_wait_queue.c deleted file mode 100644 index 16770401392b..000000000000 --- a/security/optee_linuxdriver/core/tee_wait_queue.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * Copyright (c) 2015, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#include -#include -#include -#include "tee_wait_queue.h" - -struct tee_wait_queue { - struct list_head link; - struct completion comp; - u32 key; -}; - -void tee_wait_queue_init(struct tee_wait_queue_private *priv) -{ - mutex_init(&priv->mu); - INIT_LIST_HEAD(&priv->db); -} -EXPORT_SYMBOL(tee_wait_queue_init); - -void tee_wait_queue_exit(struct tee_wait_queue_private *priv) -{ - mutex_destroy(&priv->mu); -} -EXPORT_SYMBOL(tee_wait_queue_exit); - -static struct tee_wait_queue *tee_wait_queue_get(struct device *dev, - struct tee_wait_queue_private *priv, u32 key) -{ - struct tee_wait_queue *w; - - mutex_lock(&priv->mu); - - list_for_each_entry(w, &priv->db, link) - if (w->key == key) - goto out; - - w = kmalloc(sizeof(struct tee_wait_queue), GFP_KERNEL); - if (!w) - goto out; - - init_completion(&w->comp); - w->key = key; - list_add_tail(&w->link, &priv->db); -out: - mutex_unlock(&priv->mu); - return w; -} - -void tee_wait_queue_sleep(struct device *dev, - struct tee_wait_queue_private *priv, u32 key) -{ - struct tee_wait_queue *w = tee_wait_queue_get(dev, priv, key); - - if (!w) - return; - - wait_for_completion(&w->comp); - mutex_lock(&priv->mu); - list_del(&w->link); - mutex_unlock(&priv->mu); - kfree(w); -} -EXPORT_SYMBOL(tee_wait_queue_sleep); - -void tee_wait_queue_wakeup(struct device *dev, - struct tee_wait_queue_private *priv, u32 key) -{ - struct tee_wait_queue *w = tee_wait_queue_get(dev, priv, key); - - if (!w) - return; - - complete(&w->comp); -} -EXPORT_SYMBOL(tee_wait_queue_wakeup); diff --git a/security/optee_linuxdriver/core/tee_wait_queue.h b/security/optee_linuxdriver/core/tee_wait_queue.h deleted file mode 100644 index 2ba619bc5310..000000000000 --- a/security/optee_linuxdriver/core/tee_wait_queue.h +++ /dev/null @@ -1,32 +0,0 @@ -/* - * Copyright (c) 2015, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef TEE_WAIT_QUEUE_H -#define TEE_WAIT_QUEUE_H - -#include -#include -#include - -struct tee_wait_queue_private { - struct mutex mu; - struct list_head db; -}; - -void tee_wait_queue_init(struct tee_wait_queue_private *priv); -void tee_wait_queue_exit(struct tee_wait_queue_private *priv); -void tee_wait_queue_sleep(struct device *dev, - struct tee_wait_queue_private *priv, u32 key); -void tee_wait_queue_wakeup(struct device *dev, - struct tee_wait_queue_private *priv, u32 key); - -#endif /*TEE_WAIT_QUEUE_H*/ diff --git a/security/optee_linuxdriver/fdts/fvp-foundation-gicv2-psci.dts b/security/optee_linuxdriver/fdts/fvp-foundation-gicv2-psci.dts deleted file mode 100644 index c2de12ba9a63..000000000000 --- a/security/optee_linuxdriver/fdts/fvp-foundation-gicv2-psci.dts +++ /dev/null @@ -1,211 +0,0 @@ -/* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - -/dts-v1/; - -/memreserve/ 0x80000000 0x00010000; - -/ { -}; - -/ { - model = "FVP Foundation"; - compatible = "arm,fvp-base", "arm,vexpress"; - interrupt-parent = <&gic>; - #address-cells = <2>; - #size-cells = <2>; - - chosen { }; - - aliases { - serial0 = &v2m_serial0; - serial1 = &v2m_serial1; - serial2 = &v2m_serial2; - serial3 = &v2m_serial3; - }; - - psci { - compatible = "arm,psci"; - method = "smc"; - cpu_suspend = <0xc4000001>; - cpu_off = <0x84000002>; - cpu_on = <0xc4000003>; - }; - - cpus { - #address-cells = <2>; - #size-cells = <0>; - - cpu@0 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x0>; - enable-method = "psci"; - }; - cpu@1 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x1>; - enable-method = "psci"; - }; - cpu@2 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x2>; - enable-method = "psci"; - }; - cpu@3 { - device_type = "cpu"; - compatible = "arm,armv8"; - reg = <0x0 0x3>; - enable-method = "psci"; - }; - }; - - memory@80000000 { - device_type = "memory"; - reg = <0x00000000 0x80000000 0 0x7F000000>, - <0x00000008 0x80000000 0 0x80000000>; - }; - - reserved-memory { - #address-cells = <2>; - #size-cells = <2>; - ranges; - - optee@0x83000000 { - reg = <0x00000000 0x83000000 0 0x01000000>; - }; - }; - - gic: interrupt-controller@2f000000 { - compatible = "arm,cortex-a15-gic", "arm,cortex-a9-gic"; - #interrupt-cells = <3>; - #address-cells = <0>; - interrupt-controller; - reg = <0x0 0x2f000000 0 0x10000>, - <0x0 0x2c000000 0 0x2000>, - <0x0 0x2c010000 0 0x2000>, - <0x0 0x2c02F000 0 0x2000>; - interrupts = <1 9 0xf04>; - }; - - timer { - compatible = "arm,armv8-timer"; - interrupts = <1 13 0xff01>, - <1 14 0xff01>, - <1 11 0xff01>, - <1 10 0xff01>; - clock-frequency = <100000000>; - }; - - timer@2a810000 { - compatible = "arm,armv7-timer-mem"; - reg = <0x0 0x2a810000 0x0 0x10000>; - clock-frequency = <100000000>; - #address-cells = <2>; - #size-cells = <2>; - ranges; - frame@2a830000 { - frame-number = <1>; - interrupts = <0 26 4>; - reg = <0x0 0x2a830000 0x0 0x10000>; - }; - }; - - pmu { - compatible = "arm,armv8-pmuv3"; - interrupts = <0 60 4>, - <0 61 4>, - <0 62 4>, - <0 63 4>; - }; - - smb { - compatible = "simple-bus"; - - #address-cells = <2>; - #size-cells = <1>; - ranges = <0 0 0 0x08000000 0x04000000>, - <1 0 0 0x14000000 0x04000000>, - <2 0 0 0x18000000 0x04000000>, - <3 0 0 0x1c000000 0x04000000>, - <4 0 0 0x0c000000 0x04000000>, - <5 0 0 0x10000000 0x04000000>; - - #interrupt-cells = <1>; - interrupt-map-mask = <0 0 63>; - interrupt-map = <0 0 0 &gic 0 0 4>, - <0 0 1 &gic 0 1 4>, - <0 0 2 &gic 0 2 4>, - <0 0 3 &gic 0 3 4>, - <0 0 4 &gic 0 4 4>, - <0 0 5 &gic 0 5 4>, - <0 0 6 &gic 0 6 4>, - <0 0 7 &gic 0 7 4>, - <0 0 8 &gic 0 8 4>, - <0 0 9 &gic 0 9 4>, - <0 0 10 &gic 0 10 4>, - <0 0 11 &gic 0 11 4>, - <0 0 12 &gic 0 12 4>, - <0 0 13 &gic 0 13 4>, - <0 0 14 &gic 0 14 4>, - <0 0 15 &gic 0 15 4>, - <0 0 16 &gic 0 16 4>, - <0 0 17 &gic 0 17 4>, - <0 0 18 &gic 0 18 4>, - <0 0 19 &gic 0 19 4>, - <0 0 20 &gic 0 20 4>, - <0 0 21 &gic 0 21 4>, - <0 0 22 &gic 0 22 4>, - <0 0 23 &gic 0 23 4>, - <0 0 24 &gic 0 24 4>, - <0 0 25 &gic 0 25 4>, - <0 0 26 &gic 0 26 4>, - <0 0 27 &gic 0 27 4>, - <0 0 28 &gic 0 28 4>, - <0 0 29 &gic 0 29 4>, - <0 0 30 &gic 0 30 4>, - <0 0 31 &gic 0 31 4>, - <0 0 32 &gic 0 32 4>, - <0 0 33 &gic 0 33 4>, - <0 0 34 &gic 0 34 4>, - <0 0 35 &gic 0 35 4>, - <0 0 36 &gic 0 36 4>, - <0 0 37 &gic 0 37 4>, - <0 0 38 &gic 0 38 4>, - <0 0 39 &gic 0 39 4>, - <0 0 40 &gic 0 40 4>, - <0 0 41 &gic 0 41 4>, - <0 0 42 &gic 0 42 4>; - - /include/ "fvp-foundation-motherboard.dtsi" - }; -}; diff --git a/security/optee_linuxdriver/fdts/fvp-foundation-motherboard.dtsi b/security/optee_linuxdriver/fdts/fvp-foundation-motherboard.dtsi deleted file mode 100644 index fd41c8ae25c0..000000000000 --- a/security/optee_linuxdriver/fdts/fvp-foundation-motherboard.dtsi +++ /dev/null @@ -1,197 +0,0 @@ -/* - * Copyright (c) 2013-2014, ARM Limited and Contributors. All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * Redistributions of source code must retain the above copyright notice, this - * list of conditions and the following disclaimer. - * - * Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * Neither the name of the ARM nor the names of its contributors may be used - * to endorse or promote products derived from this software without specific - * prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ - - motherboard { - arm,v2m-memory-map = "rs1"; - compatible = "arm,vexpress,v2m-p1", "simple-bus"; - #address-cells = <2>; /* SMB chipselect number and offset */ - #size-cells = <1>; - #interrupt-cells = <1>; - ranges; - - ethernet@2,02000000 { - compatible = "smsc,lan91c111"; - reg = <2 0x02000000 0x10000>; - interrupts = <15>; - }; - - v2m_clk24mhz: clk24mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <24000000>; - clock-output-names = "v2m:clk24mhz"; - }; - - v2m_refclk1mhz: refclk1mhz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <1000000>; - clock-output-names = "v2m:refclk1mhz"; - }; - - v2m_refclk32khz: refclk32khz { - compatible = "fixed-clock"; - #clock-cells = <0>; - clock-frequency = <32768>; - clock-output-names = "v2m:refclk32khz"; - }; - - iofpga@3,00000000 { - compatible = "arm,amba-bus", "simple-bus"; - #address-cells = <1>; - #size-cells = <1>; - ranges = <0 3 0 0x200000>; - - v2m_sysreg: sysreg@010000 { - compatible = "arm,vexpress-sysreg"; - reg = <0x010000 0x1000>; - gpio-controller; - #gpio-cells = <2>; - }; - - v2m_sysctl: sysctl@020000 { - compatible = "arm,sp810", "arm,primecell"; - reg = <0x020000 0x1000>; - clocks = <&v2m_refclk32khz>, <&v2m_refclk1mhz>, <&v2m_clk24mhz>; - clock-names = "refclk", "timclk", "apb_pclk"; - #clock-cells = <1>; - clock-output-names = "timerclken0", "timerclken1", "timerclken2", "timerclken3"; - }; - - v2m_serial0: uart@090000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x090000 0x1000>; - interrupts = <5>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial1: uart@0a0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0a0000 0x1000>; - interrupts = <6>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial2: uart@0b0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0b0000 0x1000>; - interrupts = <7>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - v2m_serial3: uart@0c0000 { - compatible = "arm,pl011", "arm,primecell"; - reg = <0x0c0000 0x1000>; - interrupts = <8>; - clocks = <&v2m_clk24mhz>, <&v2m_clk24mhz>; - clock-names = "uartclk", "apb_pclk"; - }; - - wdt@0f0000 { - compatible = "arm,sp805", "arm,primecell"; - reg = <0x0f0000 0x1000>; - interrupts = <0>; - clocks = <&v2m_refclk32khz>, <&v2m_clk24mhz>; - clock-names = "wdogclk", "apb_pclk"; - }; - - v2m_timer01: timer@110000 { - compatible = "arm,sp804", "arm,primecell"; - reg = <0x110000 0x1000>; - interrupts = <2>; - clocks = <&v2m_sysctl 0>, <&v2m_sysctl 1>, <&v2m_clk24mhz>; - clock-names = "timclken1", "timclken2", "apb_pclk"; - }; - - v2m_timer23: timer@120000 { - compatible = "arm,sp804", "arm,primecell"; - reg = <0x120000 0x1000>; - interrupts = <3>; - clocks = <&v2m_sysctl 2>, <&v2m_sysctl 3>, <&v2m_clk24mhz>; - clock-names = "timclken1", "timclken2", "apb_pclk"; - }; - - rtc@170000 { - compatible = "arm,pl031", "arm,primecell"; - reg = <0x170000 0x1000>; - interrupts = <4>; - clocks = <&v2m_clk24mhz>; - clock-names = "apb_pclk"; - }; - - virtio_block@0130000 { - compatible = "virtio,mmio"; - reg = <0x130000 0x1000>; - interrupts = <0x2a>; - }; - }; - - v2m_fixed_3v3: fixedregulator@0 { - compatible = "regulator-fixed"; - regulator-name = "3V3"; - regulator-min-microvolt = <3300000>; - regulator-max-microvolt = <3300000>; - regulator-always-on; - }; - - - mcc { - compatible = "arm,vexpress,config-bus", "simple-bus"; - arm,vexpress,config-bridge = <&v2m_sysreg>; - - reset@0 { - compatible = "arm,vexpress-reset"; - arm,vexpress-sysreg,func = <5 0>; - }; - - muxfpga@0 { - compatible = "arm,vexpress-muxfpga"; - arm,vexpress-sysreg,func = <7 0>; - }; - - shutdown@0 { - compatible = "arm,vexpress-shutdown"; - arm,vexpress-sysreg,func = <8 0>; - }; - - reboot@0 { - compatible = "arm,vexpress-reboot"; - arm,vexpress-sysreg,func = <9 0>; - }; - - dvimode@0 { - compatible = "arm,vexpress-dvimode"; - arm,vexpress-sysreg,func = <11 0>; - }; - }; - }; diff --git a/security/optee_linuxdriver/fdts/readme.txt b/security/optee_linuxdriver/fdts/readme.txt deleted file mode 100644 index e3fb4740b159..000000000000 --- a/security/optee_linuxdriver/fdts/readme.txt +++ /dev/null @@ -1,2 +0,0 @@ -These files is a temporary workaround until the driver has switched -to use CMA to allocate shared memory. diff --git a/security/optee_linuxdriver/include/arm_common/teesmc.h b/security/optee_linuxdriver/include/arm_common/teesmc.h deleted file mode 100644 index 83e85bdc8386..000000000000 --- a/security/optee_linuxdriver/include/arm_common/teesmc.h +++ /dev/null @@ -1,710 +0,0 @@ -/* - * Copyright (c) 2014, Linaro Limited - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef TEESMC_H -#define TEESMC_H - -#ifndef ASM -/* - * This section depends on uint64_t, uint32_t uint8_t already being - * defined. Since this file is used in several different environments - * (secure world OS and normal world Linux kernel to start with) where - * stdint.h may not be available it's the responsibility of the one - * including this file to provide those types. - */ - -/* - * Trusted OS SMC interface. - * - * The SMC interface follows SMC Calling Convention - * (ARM_DEN0028A_SMC_Calling_Convention). - * - * The primary objective of this API is to provide a transport layer on - * which a Global Platform compliant TEE interfaces can be deployed. But the - * interface can also be used for other implementations. - * - * This file is divided in two parts. - * Part 1 deals with passing parameters to Trusted Applications running in - * a trusted OS in secure world. - * Part 2 deals with the lower level handling of the SMC. - */ - -/* - ******************************************************************************* - * Part 1 - passing parameters to Trusted Applications - ******************************************************************************* - */ - -/* - * Same values as TEE_PARAM_* from TEE Internal API - */ -#define TEESMC_ATTR_TYPE_NONE 0 -#define TEESMC_ATTR_TYPE_VALUE_INPUT 1 -#define TEESMC_ATTR_TYPE_VALUE_OUTPUT 2 -#define TEESMC_ATTR_TYPE_VALUE_INOUT 3 -#define TEESMC_ATTR_TYPE_MEMREF_INPUT 5 -#define TEESMC_ATTR_TYPE_MEMREF_OUTPUT 6 -#define TEESMC_ATTR_TYPE_MEMREF_INOUT 7 - -#define TEESMC_ATTR_TYPE_MASK 0x7 - -/* - * Meta parameter to be absorbed by the Secure OS and not passed - * to the Trusted Application. - * - * One example of this is a struct teesmc_meta_open_session which - * is added to TEESMC{32,64}_CMD_OPEN_SESSION. - */ -#define TEESMC_ATTR_META 0x8 - -/* - * Used as an indication from normal world of compatible cache usage. - * 'I' stands for inner cache and 'O' for outer cache. - */ -#define TEESMC_ATTR_CACHE_I_NONCACHE 0x0 -#define TEESMC_ATTR_CACHE_I_WRITE_THR 0x1 -#define TEESMC_ATTR_CACHE_I_WRITE_BACK 0x2 -#define TEESMC_ATTR_CACHE_O_NONCACHE 0x0 -#define TEESMC_ATTR_CACHE_O_WRITE_THR 0x4 -#define TEESMC_ATTR_CACHE_O_WRITE_BACK 0x8 - -#define TEESMC_ATTR_CACHE_NONCACHE (TEESMC_ATTR_CACHE_I_NONCACHE | \ - TEESMC_ATTR_CACHE_O_NONCACHE) -#define TEESMC_ATTR_CACHE_DEFAULT (TEESMC_ATTR_CACHE_I_WRITE_BACK | \ - TEESMC_ATTR_CACHE_O_WRITE_BACK) - -#define TEESMC_ATTR_CACHE_SHIFT 4 -#define TEESMC_ATTR_CACHE_MASK 0xf - -#define TEESMC_CMD_OPEN_SESSION 0 -#define TEESMC_CMD_INVOKE_COMMAND 1 -#define TEESMC_CMD_CLOSE_SESSION 2 -#define TEESMC_CMD_CANCEL 3 - -/** - * struct teesmc32_param_memref - memory reference - * @buf_ptr: Address of the buffer - * @size: Size of the buffer - * - * Secure and normal world communicates pointer via physical address instead of - * the virtual address with is usually used for pointers. This is because - * Secure and normal world has completely independant memory mapping. Normal - * world can even have a hypervisor which need to translate the guest - * physical address (AKA IPA in ARM lingo) to a real physical address - * before passing the structure to secure world. - */ -struct teesmc32_param_memref { - uint32_t buf_ptr; - uint32_t size; -}; - -/** - * struct teesmc32_param_memref - memory reference - * @buf_ptr: Address of the buffer - * @size: Size of the buffer - * - * See description of struct teesmc32_param_memref. - */ -struct teesmc64_param_memref { - uint64_t buf_ptr; - uint64_t size; -}; - -/** - * struct teesmc32_param_value - values - * @a: first value - * @b: second value - */ -struct teesmc32_param_value { - uint32_t a; - uint32_t b; -}; - -/** - * struct teesmc64_param_value - values - * @a: first value - * @b: second value - */ -struct teesmc64_param_value { - uint64_t a; - uint64_t b; -}; - -/** - * struct teesmc32_param - parameter - * @attr: attributes - * @memref: a memory reference - * @value: a value - * - * attr & TEESMC_ATTR_TYPE_MASK indicates if memref or value is used in the - * union. TEESMC_ATTR_TYPE_VALUE_* indicates value and - * TEESMC_ATTR_TYPE_MEMREF_* indicates memref. TEESMC_ATTR_TYPE_NONE - * indicates that none of the members are used. - */ -struct teesmc32_param { - uint32_t attr; - union { - struct teesmc32_param_memref memref; - struct teesmc32_param_value value; - } u; -}; - -/** - * struct teesmc64_param - parameter - * @attr: attributes - * @memref: a memory reference - * @value: a value - * - * See description of union teesmc32_param. - */ -struct teesmc64_param { - uint64_t attr; - union { - struct teesmc64_param_memref memref; - struct teesmc64_param_value value; - } u; -}; - -/** - * struct teesmc32_arg - SMC argument for Trusted OS - * @cmd: Command, one of TEESMC_CMD_* - * @ta_func: Trusted Application function, specific to the Trusted Application, - * used if cmd == TEESMC_CMD_INVOKE_COMMAND - * @session: In parameter for all TEESMC_CMD_* except - * TEESMC_CMD_OPEN_SESSION where it's an output paramter instead - * @ret: return value - * @ret_origin: origin of the return value - * @num_params: number of parameters supplied to the OS Command - * @params: the parameters supplied to the OS Command - * - * All normal SMC calls to Trusted OS uses this struct. If cmd requires - * further information than what these field holds it can be passed as a - * parameter tagged as meta (setting the TEESMC_ATTR_META bit in - * corresponding param_attrs). This is used for TEESMC_CMD_OPEN_SESSION - * to pass a struct teesmc32_meta_open_session which is needed find the - * Trusted Application and to indicate the credentials of the client. - */ -struct teesmc32_arg { - uint32_t cmd; - uint32_t ta_func; - uint32_t session; - uint32_t ret; - uint32_t ret_origin; - uint32_t num_params; - /* - * Commented out elements used to visualize the layout dynamic part - * of the struct. Note that these fields are not available at all - * if num_params == 0. - * - * params is accessed through the macro TEESMC32_GET_PARAMS - */ - - /* struct teesmc32_param params[num_params]; */ -}; - -/** - * TEESMC32_GET_PARAMS - return pointer to union teesmc32_param * - * - * @x: Pointer to a struct teesmc32_arg - * - * Returns a pointer to the params[] inside a struct teesmc32_arg. - */ -#define TEESMC32_GET_PARAMS(x) \ - (struct teesmc32_param *)(((struct teesmc32_arg *)(x)) + 1) - -/** - * TEESMC32_GET_ARG_SIZE - return size of struct teesmc32_arg - * - * @num_params: Number of parameters embedded in the struct teesmc32_arg - * - * Returns the size of the struct teesmc32_arg together with the number - * of embedded paramters. - */ -#define TEESMC32_GET_ARG_SIZE(num_params) \ - (sizeof(struct teesmc32_arg) + \ - sizeof(struct teesmc32_param) * (num_params)) - -/** - * struct teesmc64_arg - SMC argument for Trusted OS - * @cmd: OS Command, one of TEESMC_CMD_* - * @ta_func: Trusted Application function, specific to the Trusted Application - * @session: In parameter for all TEESMC_CMD_* but - * TEESMC_CMD_OPEN_SESSION - * @ret: return value - * @ret_origin: origin of the return value - * @num_params: number of parameters supplied to the OS Command - * @params: the parameters supplied to the OS Command - * - * See description of struct teesmc32_arg. - */ -struct teesmc64_arg { - uint64_t cmd; - uint64_t ta_func; - uint64_t session; - uint64_t ret; - uint64_t ret_origin; - uint64_t num_params; - /* - * Commented out elements used to visualize the layout dynamic part - * of the struct. Note that these fields are not available at all - * if num_params == 0. - * - * params is accessed through the macro TEESMC64_GET_PARAMS - */ - - /* struct teesmc64_param params[num_params]; */ -}; - -/** - * TEESMC64_GET_PARAMS - return pointer to union teesmc64_param * - * - * @x: Pointer to a struct teesmc64_arg - * - * Returns a pointer to the params[] inside a struct teesmc64_arg. - */ -#define TEESMC64_GET_PARAMS(x) \ - (struct teesmc64_param *)(((struct teesmc64_arg *)(x)) + 1) - -/** - * TEESMC64_GET_ARG_SIZE - return size of struct teesmc64_arg - * - * @num_params: Number of parameters embedded in the struct teesmc64_arg - * - * Returns the size of the struct teesmc64_arg together with the number - * of embedded paramters. - */ -#define TEESMC64_GET_ARG_SIZE(num_params) \ - (sizeof(struct teesmc64_arg) + \ - sizeof(union teesmc64_param) * (num_params)) - -#define TEESMC_UUID_LEN 16 - -/** - * struct teesmc_meta_open_session - additional parameters for - * TEESMC32_CMD_OPEN_SESSION and - * TEESMC64_CMD_OPEN_SESSION - * @uuid: UUID of the Trusted Application - * @clnt_uuid: UUID of client - * @clnt_login: Login class of client, TEE_LOGIN_* if being Global Platform - * compliant - * - * This struct is passed in the first parameter as an input memref tagged - * as meta on an TEESMC{32,64}_CMD_OPEN_SESSION cmd. It's important - * that it really is the first parameter to make it easy for an eventual - * hypervisor to inspect and possibly update clnt_* values. - */ -struct teesmc_meta_open_session { - uint8_t uuid[TEESMC_UUID_LEN]; - uint8_t clnt_uuid[TEESMC_UUID_LEN]; - uint32_t clnt_login; -}; - - -#endif /*!ASM*/ - -/* - ******************************************************************************* - * Part 2 - low level SMC interaction - ******************************************************************************* - */ - -#define TEESMC_32 0 -#define TEESMC_64 0x40000000 -#define TEESMC_FAST_CALL 0x80000000 -#define TEESMC_STD_CALL 0 - -#define TEESMC_OWNER_MASK 0x3F -#define TEESMC_OWNER_SHIFT 24 - -#define TEESMC_FUNC_MASK 0xFFFF - -#define TEESMC_IS_FAST_CALL(smc_val) ((smc_val) & TEESMC_FAST_CALL) -#define TEESMC_IS_64(smc_val) ((smc_val) & TEESMC_64) -#define TEESMC_FUNC_NUM(smc_val) ((smc_val) & TEESMC_FUNC_MASK) -#define TEESMC_OWNER_NUM(smc_val) (((smc_val) >> TEESMC_OWNER_SHIFT) & \ - TEESMC_OWNER_MASK) - -#define TEESMC_CALL_VAL(type, calling_convention, owner, func_num) \ - ((type) | (calling_convention) | \ - (((owner) & TEESMC_OWNER_MASK) << TEESMC_OWNER_SHIFT) |\ - ((func_num) & TEESMC_FUNC_MASK)) - -#define TEESMC_OWNER_ARCH 0 -#define TEESMC_OWNER_CPU 1 -#define TEESMC_OWNER_SIP 2 -#define TEESMC_OWNER_OEM 3 -#define TEESMC_OWNER_STANDARD 4 -#define TEESMC_OWNER_TRUSTED_APP 48 -#define TEESMC_OWNER_TRUSTED_OS 50 - -/* Rockchip define trusted os call */ -#define TEESMC_OWNER_TRUSTED_OS_ROCKCHIP 55 - -#define TEESMC_OWNER_TRUSTED_OS_API 63 - -/* - * Function specified by SMC Calling convention. - */ -#define TEESMC32_FUNCID_CALLS_COUNT 0xFF00 -#define TEESMC32_CALLS_COUNT \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ - TEESMC_OWNER_TRUSTED_OS_API, \ - TEESMC32_FUNCID_CALLS_COUNT) - -/* - * Function specified by SMC Calling convention - * - * Return one of the following UIDs if using API specified in this file - * without further extentions: - * 65cb6b93-af0c-4617-8ed6-644a8d1140f8 : Only 32 bit calls are supported - * 65cb6b93-af0c-4617-8ed6-644a8d1140f9 : Both 32 and 64 bit calls are supported - */ -#define TEESMC_UID_R0 0x65cb6b93 -#define TEESMC_UID_R1 0xaf0c4617 -#define TEESMC_UID_R2 0x8ed6644a -#define TEESMC_UID32_R3 0x8d1140f8 -#define TEESMC_UID64_R3 0x8d1140f9 -#define TEESMC32_FUNCID_CALLS_UID 0xFF01 -#define TEESMC32_CALLS_UID \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ - TEESMC_OWNER_TRUSTED_OS_API, \ - TEESMC32_FUNCID_CALLS_UID) - -/* - * Function specified by SMC Calling convention - * - * Returns 1.0 if using API specified in this file without further extentions. - */ -#define TEESMC_REVISION_MAJOR 1 -#define TEESMC_REVISION_MINOR 0 -#define TEESMC32_FUNCID_CALLS_REVISION 0xFF03 -#define TEESMC32_CALLS_REVISION \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, \ - TEESMC_OWNER_TRUSTED_OS_API, \ - TEESMC32_FUNCID_CALLS_REVISION) - -/* - * Get UUID of Trusted OS. - * - * Used by non-secure world to figure out which Trusted OS is installed. - * Note that returned UUID is the UUID of the Trusted OS, not of the API. - * - * Returns UUID in r0-4/w0-4 in the same way as TEESMC32_CALLS_UID - * described above. - */ -#define TEESMC_FUNCID_GET_OS_UUID 0 -#define TEESMC32_CALL_GET_OS_UUID \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_GET_OS_UUID) - -/* - * Get revision of Trusted OS. - * - * Used by non-secure world to figure out which version of the Trusted OS - * is installed. Note that the returned revision is the revision of the - * Trusted OS, not of the API. - * - * Returns revision in r0-1/w0-1 in the same way as TEESMC32_CALLS_REVISION - * described above. - */ -#define TEESMC_FUNCID_GET_OS_REVISION 1 -#define TEESMC32_CALL_GET_OS_REVISION \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_GET_OS_REVISION) - - - -/* - * Call with struct teesmc32_arg as argument - * - * Call register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_WITH_ARG - * r1/x1 Physical pointer to a struct teesmc32_arg - * r2-6/x2-6 Not used - * r7/x7 Hypervisor Client ID register - * - * Normal return register usage: - * r0/x0 Return value, TEESMC_RETURN_* - * r1-3/x1-3 Not used - * r4-7/x4-7 Preserved - * - * Ebusy return register usage: - * r0/x0 Return value, TEESMC_RETURN_ETHREAD_LIMIT - * r1-3/x1-3 Preserved - * r4-7/x4-7 Preserved - * - * RPC return register usage: - * r0/x0 Return value, TEESMC_RETURN_IS_RPC(val) - * r1-2/x1-2 RPC parameters - * r3-7/x3-7 Resume information, must be preserved - * - * Possible return values: - * TEESMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this - * function. - * TEESMC_RETURN_OK Call completed, result updated in - * the previously supplied struct - * teesmc32_arg. - * TEESMC_RETURN_ETHREAD_LIMIT Trusted OS out of threads, - * try again later. - * TEESMC_RETURN_EBADADDR Bad physcial pointer to struct - * teesmc32_arg. - * TEESMC_RETURN_EBADCMD Bad/unknown cmd in struct teesmc32_arg - * TEESMC_RETURN_IS_RPC() Call suspended by RPC call to normal - * world. - */ -#define TEESMC_FUNCID_CALL_WITH_ARG 2 -#define TEESMC32_CALL_WITH_ARG \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_CALL_WITH_ARG) -/* Same as TEESMC32_CALL_WITH_ARG but a "fast call". */ -#define TEESMC32_FASTCALL_WITH_ARG \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_CALL_WITH_ARG) - -/* - * Call with struct teesmc64_arg as argument - * - * See description of TEESMC32_CALL_WITH_ARG above, uses struct - * teesmc64_arg in x1 instead. - */ -#define TEESMC64_CALL_WITH_ARG \ - TEESMC_CALL_VAL(TEESMC_64, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_CALL_WITH_ARG) -/* Same as TEESMC64_CALL_WITH_ARG but a "fast call". */ -#define TEESMC64_FASTCALL_WITH_ARG \ - TEESMC_CALL_VAL(TEESMC_64, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_CALL_WITH_ARG) - -/* - * Resume from RPC (for example after processing an IRQ) - * - * Call register usage: - * r0/x0 SMC Function ID, - * TEESMC32_CALL_RETURN_FROM_RPC or - * TEESMC32_FASTCALL_RETURN_FROM_RPC - * r1-3/x1-3 Value of r1-3/x1-3 when TEESMC32_CALL_WITH_ARG returned - * TEESMC_RETURN_RPC in r0/x0 - * - * Return register usage is the same as for TEESMC32_CALL_WITH_ARG above. - * - * Possible return values - * TEESMC_RETURN_UNKNOWN_FUNCTION Trusted OS does not recognize this - * function. - * TEESMC_RETURN_OK Original call completed, result - * updated in the previously supplied. - * struct teesmc32_arg - * TEESMC_RETURN_RPC Call suspended by RPC call to normal - * world. - * TEESMC_RETURN_ETHREAD_LIMIT Trusted OS out of threads, - * try again later. - * TEESMC_RETURN_ERESUME Resume failed, the opaque resume - * information was corrupt. - */ -#define TEESMC_FUNCID_RETURN_FROM_RPC 3 -#define TEESMC32_CALL_RETURN_FROM_RPC \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_RETURN_FROM_RPC) -/* Same as TEESMC32_CALL_RETURN_FROM_RPC but a "fast call". */ -#define TEESMC32_FASTCALL_RETURN_FROM_RPC \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_RETURN_FROM_RPC) - -/* - * Resume from RPC (for example after processing an IRQ) - * - * See description of TEESMC32_CALL_RETURN_FROM_RPC above, used when - * it's a 64bit call that has returned. - */ -#define TEESMC64_CALL_RETURN_FROM_RPC \ - TEESMC_CALL_VAL(TEESMC_64, TEESMC_STD_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_RETURN_FROM_RPC) -/* Same as TEESMC64_CALL_RETURN_FROM_RPC but a "fast call". */ -#define TEESMC64_FASTCALL_RETURN_FROM_RPC \ - TEESMC_CALL_VAL(TEESMC_64, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_RETURN_FROM_RPC) - -/* - * From secure monitor to Trusted OS, handle FIQ - * - * A virtual call which is injected by the Secure Monitor when an FIQ is - * raised while in normal world (SCR_NS is set). The monitor restores - * secure architecture registers and secure EL_SP1 and jumps to previous - * secure EL3_ELR. Trusted OS should preserve all general purpose - * registers. - * - * Call register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_HANDLE_FIQ - * r1-7/x1-7 Not used, but must be preserved - * - * Return register usage: - * Note used - */ -#define TEESMC_FUNCID_CALL_HANDLE_FIQ 0xf000 -#define TEESMC32_CALL_HANDLE_FIQ \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_FUNCID_CALL_HANDLE_FIQ) - -#define TEESMC_RETURN_RPC_PREFIX_MASK 0xFFFF0000 -#define TEESMC_RETURN_RPC_PREFIX 0xFFFF0000 -#define TEESMC_RETURN_RPC_FUNC_MASK 0x0000FFFF - -#define TEESMC_RETURN_GET_RPC_FUNC(ret) ((ret) & TEESMC_RETURN_RPC_FUNC_MASK) - -#define TEESMC_RPC_VAL(func) ((func) | TEESMC_RETURN_RPC_PREFIX) - -/* - * Allocate argument memory for RPC parameter passing. - * Argument memory is used to hold a struct teesmc32_arg. - * - * "Call" register usage: - * r0/x0 This value, TEESMC_RETURN_RPC_ALLOC - * r1/x1 Size in bytes of required argument memory - * r2-7/x2-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1/x1 Physical pointer to allocated argument memory, 0 if size - * was 0 or if memory can't be allocated - * r2-7/x2-7 Preserved - */ -#define TEESMC_RPC_FUNC_ALLOC_ARG 0 -#define TEESMC_RETURN_RPC_ALLOC_ARG \ - TEESMC_RPC_VAL(TEESMC_RPC_FUNC_ALLOC_ARG) - -/* - * Allocate payload memory for RPC parameter passing. - * Payload memory is used to hold the memory referred to by struct - * teesmc32_param_memref. - * - * "Call" register usage: - * r0/x0 This value, TEESMC_RETURN_RPC_ALLOC - * r1/x1 Size in bytes of required payload memory - * r2-7/x2-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1/x1 Physical pointer to allocated payload memory, 0 if size - * was 0 or if memory can't be allocated - * r2-7/x2-7 Preserved - */ -#define TEESMC_RPC_FUNC_ALLOC_PAYLOAD 1 -#define TEESMC_RETURN_RPC_ALLOC_PAYLOAD \ - TEESMC_RPC_VAL(TEESMC_RPC_FUNC_ALLOC_PAYLOAD) - -/* - * Free memory previously allocated by TEESMC_RETURN_RPC_ALLOC_ARG. - * - * "Call" register usage: - * r0/x0 This value, TEESMC_RETURN_RPC_FREE - * r1/x1 Physical pointer to previously allocated argument memory - * r2-7/x2-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1/x1 Not used - * r2-7/x2-7 Preserved - */ -#define TEESMC_RPC_FUNC_FREE_ARG 2 -#define TEESMC_RETURN_RPC_FREE_ARG TEESMC_RPC_VAL(TEESMC_RPC_FUNC_FREE_ARG) - -/* - * Free memory previously allocated by TEESMC_RETURN_RPC_ALLOC_PAYLOAD. - * - * "Call" register usage: - * r0/x0 This value, TEESMC_RETURN_RPC_FREE - * r1/x1 Physical pointer to previously allocated payload memory - * r3-7/x3-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1-2/x1-2 Not used - * r3-7/x3-7 Preserved - */ -#define TEESMC_RPC_FUNC_FREE_PAYLOAD 3 -#define TEESMC_RETURN_RPC_FREE_PAYLOAD \ - TEESMC_RPC_VAL(TEESMC_RPC_FUNC_FREE_PAYLOAD) - -/* - * Deliver an IRQ in normal world. - * - * "Call" register usage: - * r0/x0 TEESMC_RETURN_RPC_IRQ - * r1-7/x1-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1-7/x1-7 Preserved - */ -#define TEESMC_RPC_FUNC_IRQ 4 -#define TEESMC_RETURN_RPC_IRQ TEESMC_RPC_VAL(TEESMC_RPC_FUNC_IRQ) - -/* - * Do an RPC request. The supplied struct teesmc{32,64}_arg tells which - * request to do and the paramters for the request. The following fields - * are used (the rest are unused): - * - cmd the Request ID - * - ret return value of the request, filled in by normal world - * - num_params number of parameters for the request - * - params the parameters - * - param_attrs attributes of the parameters - * - * "Call" register usage: - * r0/x0 TEESMC_RETURN_RPC_CMD - * r1/x1 Physical pointer to a struct teesmc32_arg if returning from - * a AArch32 SMC or a struct teesmc64_arg if returning from a - * AArch64 SMC, must be preserved, only the data should - * be updated - * r2-7/x2-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1-7/x1-7 Preserved - */ -#define TEESMC_RPC_FUNC_CMD 5 -#define TEESMC_RETURN_RPC_CMD TEESMC_RPC_VAL(TEESMC_RPC_FUNC_CMD) - - -/* Returned in r0 */ -#define TEESMC_RETURN_UNKNOWN_FUNCTION 0xFFFFFFFF - -/* Returned in r0 only from Trusted OS functions */ -#define TEESMC_RETURN_OK 0x0 -#define TEESMC_RETURN_ETHREAD_LIMIT 0x1 -#define TEESMC_RETURN_ERESUME 0x2 -#define TEESMC_RETURN_EBADADDR 0x3 -#define TEESMC_RETURN_EBADCMD 0x4 -#define TEESMC_RETURN_IS_RPC(ret) \ - (((ret) & TEESMC_RETURN_RPC_PREFIX_MASK) == TEESMC_RETURN_RPC_PREFIX) - -/* - * Returned in r1 by Trusted OS functions if r0 = TEESMC_RETURN_RPC - */ -#define TEESMC_RPC_REQUEST_IRQ 0x0 - -#define TEESMC_ROCKCHIP_FUNCID_SET_UART_PORT 0x0000 -#define TEESMC32_ROCKCHIP_FASTCALL_SET_UART_PORT \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS_ROCKCHIP, \ - TEESMC_ROCKCHIP_FUNCID_SET_UART_PORT) - -#endif /* TEESMC_H */ diff --git a/security/optee_linuxdriver/include/arm_common/teesmc_st.h b/security/optee_linuxdriver/include/arm_common/teesmc_st.h deleted file mode 100644 index 05173919c6c9..000000000000 --- a/security/optee_linuxdriver/include/arm_common/teesmc_st.h +++ /dev/null @@ -1,147 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef TEESMC_ST_H -#define TEESMC_ST_H - -#define TEESMC_ST_RETURN_NOTAVAIL 0x5700 - -/* - * Get Shared Memory Config - * - * Returns the Secure/Non-secure shared memory config. - * - * Call register usage: - * r0 SMC Function ID, TEESMC32_ST_FASTCALL_GET_SHM_CONFIG - * r1-6 Not used - * r7 Hypervisor Client ID register - * - * Have config return register usage: - * r0 TEESMC_RETURN_OK - * r1 Physical address of start of SHM - * r2 Size of of SHM - * r3 1 if SHM is cached, 0 if uncached. - * r4-7 Preserved - * - * Not available register usage: - * r0 TEESMC_ST_RETURN_NOTAVAIL - * r1-3 Not used - * r4-7 Preserved - */ -#define TEESMC_ST_FUNCID_GET_SHM_CONFIG 0x5700 -#define TEESMC32_ST_FASTCALL_GET_SHM_CONFIG \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_ST_FUNCID_GET_SHM_CONFIG) - -/* - * Configures TZ/NS shared mutex for outer cache maintenance - * - * Disables, enables usage of outercache mutex. - * Returns or sets physical address of outercache mutex. - * - * Call register usage: - * r0 SMC Function ID, TEESMC32_ST_FASTCALL_L2CC_MUTEX - * r1 TEESMC_ST_L2CC_MUTEX_GET_ADDR Get physical address of mutex - * TEESMC_ST_L2CC_MUTEX_SET_ADDR Set physical address of mutex - * TEESMC_ST_L2CC_MUTEX_ENABLE Enable usage of mutex - * TEESMC_ST_L2CC_MUTEX_DISABLE Disable usage of mutex - * r2 if r1 == TEESMC_ST_L2CC_MUTEX_SET_ADDR, physical address of mutex - * r3-6 Not used - * r7 Hypervisor Client ID register - * - * Have config return register usage: - * r0 TEESMC_RETURN_OK - * r1 Preserved - * r2 if r1 == 0, physical address of L2CC mutex - * r3-7 Preserved - * - * Error return register usage: - * r0 TEESMC_ST_RETURN_NOTAVAIL Physical address not available - * TEESMC_RETURN_EBADADDR Bad supplied physical address - * TEESMC_RETURN_EBADCMD Unsupported value in r1 - * r1-7 Preserved - */ -#define TEESMC_ST_L2CC_MUTEX_GET_ADDR 0 -#define TEESMC_ST_L2CC_MUTEX_SET_ADDR 1 -#define TEESMC_ST_L2CC_MUTEX_ENABLE 2 -#define TEESMC_ST_L2CC_MUTEX_DISABLE 3 -#define TEESMC_ST_FUNCID_L2CC_MUTEX 0x5701 -#define TEESMC32_ST_FASTCALL_L2CC_MUTEX \ - TEESMC_CALL_VAL(TEESMC_32, TEESMC_FAST_CALL, TEESMC_OWNER_TRUSTED_OS, \ - TEESMC_ST_FUNCID_L2CC_MUTEX) - -/* - * Allocate payload memory for RPC parameter passing. - * - * "Call" register usage: - * r0/x0 This value, TEESMC_RETURN_ST_RPC_ALLOC_PAYLOAD - * r1/x1 Size in bytes of required payload memory - * r2/x2 Not used - * r3-7/x3-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r1/x1 Physical pointer to allocated payload memory, 0 if size - * was 0 or if memory can't be allocated - * r2/x2 Shared memory cookie used when freeing the memory - * r3-7/x3-7 Preserved - */ -#define TEESMC_ST_RPC_FUNC_ALLOC_PAYLOAD 0x5700 -#define TEESMC_RETURN_ST_RPC_ALLOC_PAYLOAD \ - TEESMC_RPC_VAL(TEESMC_ST_RPC_FUNC_ALLOC_PAYLOAD) - - -/* - * Free memory previously allocated by TEESMC_RETURN_ST_RPC_ALLOC_PAYLOAD - * - * "Call" register usage: - * r0/x0 This value, TEESMC_RETURN_ST_RPC_FREE_PAYLOAD - * r1/x1 Shared memory cookie belonging to this payload memory - * r2-7/x2-7 Resume information, must be preserved - * - * "Return" register usage: - * r0/x0 SMC Function ID, TEESMC32_CALL_RETURN_FROM_RPC if it was an - * AArch32 SMC return or TEESMC64_CALL_RETURN_FROM_RPC for - * AArch64 SMC return - * r2-7/x2-7 Preserved - */ -#define TEESMC_ST_RPC_FUNC_FREE_PAYLOAD 0x5701 -#define TEESMC_RETURN_ST_RPC_FREE_PAYLOAD \ - TEESMC_RPC_VAL(TEESMC_ST_RPC_FUNC_FREE_PAYLOAD) - -/* Overriding default UID since the interface is extended - * 384fb3e0-e7f8-11e3-af63-0002a5d5c51b - */ -#define TEESMC_ST_UID_R0 0x384fb3e0 -#define TEESMC_ST_UID_R1 0xe7f811e3 -#define TEESMC_ST_UID_R2 0xaf630002 -#define TEESMC_ST_UID32_R3 0xa5d5c51b -#define TEESMC_ST_UID64_R3 0xa5d5c51c - -#define TEESMC_ST_REVISION_MAJOR 1 -#define TEESMC_ST_REVISION_MINOR 0 - -/* - * UUID for OP-TEE - * 486178e0-e7f8-11e3-bc5e-0002a5d5c51b - */ -#define TEESMC_OS_OPTEE_UUID_R0 0x486178e0 -#define TEESMC_OS_OPTEE_UUID_R1 0xe7f811e3 -#define TEESMC_OS_OPTEE_UUID_R2 0xbc5e0002 -#define TEESMC_OS_OPTEE_UUID_R3 0xa5d5c51b - -#define TEESMC_OS_OPTEE_REVISION_MAJOR 1 -#define TEESMC_OS_OPTEE_REVISION_MINOR 0 - -#endif /*TEESMC_ST_H*/ diff --git a/security/optee_linuxdriver/include/linux/tee_client_api.h b/security/optee_linuxdriver/include/linux/tee_client_api.h deleted file mode 100644 index 89d137b24096..000000000000 --- a/security/optee_linuxdriver/include/linux/tee_client_api.h +++ /dev/null @@ -1,600 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" - * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE - * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR - * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF - * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS - * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN - * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) - * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - */ -#ifndef TEE_CLIENT_API_H -#define TEE_CLIENT_API_H - -#ifndef __KERNEL__ -#include -#include -#endif /* __KERNEL__ */ - -/* - * Defines the number of available memory references in an open session or - * invoke command operation payload. - */ -#define TEEC_CONFIG_PAYLOAD_REF_COUNT 4 - -/** - * Defines the maximum size of a single shared memory block, in bytes, of both - * API allocated and API registered memory. The size is currently set to - * 512 * kB (512 * 1024). - */ -#define TEEC_CONFIG_SHAREDMEM_MAX_SIZE 0x8000 - -/** - * Flag constants indicating the type of parameters encoded inside the - * operation payload (TEEC_Operation), Type is uint32_t. - * - * TEEC_NONE The Parameter is not used - * - * TEEC_VALUE_INPUT The Parameter is a TEEC_Value tagged as input. - * - * TEEC_VALUE_OUTPUT The Parameter is a TEEC_Value tagged as output. - * - * TEEC_VALUE_INOUT The Parameter is a TEEC_Value tagged as both as - * input and output, i.e., for which both the - * behaviors of TEEC_VALUE_INPUT and - * TEEC_VALUE_OUTPUT apply. - * - * TEEC_MEMREF_TEMP_INPUT The Parameter is a TEEC_TempMemoryReference - * describing a region of memory which needs to be - * temporarily registered for the duration of the - * Operation and is tagged as input. - * - * TEEC_MEMREF_TEMP_OUTPUT Same as TEEC_MEMREF_TEMP_INPUT, but the Memory - * Reference is tagged as output. The - * Implementation may update the size field to - * reflect the required output size in some use - * cases. - * - * TEEC_MEMREF_TEMP_INOUT A Temporary Memory Reference tagged as both - * input and output, i.e., for which both the - * behaviors of TEEC_MEMREF_TEMP_INPUT and - * TEEC_MEMREF_TEMP_OUTPUT apply. - * - * TEEC_MEMREF_WHOLE The Parameter is a Registered Memory Reference - * that refers to the entirety of its parent Shared - * Memory block. The parameter structure is a - * TEEC_MemoryReference. In this structure, the - * Implementation MUST read only the parent field - * and MAY update the size field when the operation - * completes. - * - * TEEC_MEMREF_PARTIAL_INPUT A Registered Memory Reference structure that - * refers to a partial region of its parent Shared - * Memory block and is tagged as input. - * - * TEEC_MEMREF_PARTIAL_OUTPUT Registered Memory Reference structure that - * refers to a partial region of its parent Shared - * Memory block and is tagged as output. - * - * TEEC_MEMREF_PARTIAL_INOUT The Registered Memory Reference structure that - * refers to a partial region of its parent Shared - * Memory block and is tagged as both input and - * output, i.e., for which both the behaviors of - * TEEC_MEMREF_PARTIAL_INPUT and - * TEEC_MEMREF_PARTIAL_OUTPUT apply. - */ -#define TEEC_NONE 0x00000000 -#define TEEC_VALUE_INPUT 0x00000001 -#define TEEC_VALUE_OUTPUT 0x00000002 -#define TEEC_VALUE_INOUT 0x00000003 -#define TEEC_MEMREF_TEMP_INPUT 0x00000005 -#define TEEC_MEMREF_TEMP_OUTPUT 0x00000006 -#define TEEC_MEMREF_TEMP_INOUT 0x00000007 -#define TEEC_MEMREF_WHOLE 0x0000000C -#define TEEC_MEMREF_PARTIAL_INPUT 0x0000000D -#define TEEC_MEMREF_PARTIAL_OUTPUT 0x0000000E -#define TEEC_MEMREF_PARTIAL_INOUT 0x0000000F - -/** - * Flag constants indicating the data transfer direction of memory in - * TEEC_Parameter. TEEC_MEM_INPUT signifies data transfer direction from the - * client application to the TEE. TEEC_MEM_OUTPUT signifies data transfer - * direction from the TEE to the client application. Type is uint32_t. - * - * TEEC_MEM_INPUT The Shared Memory can carry data from the client - * application to the Trusted Application. - * TEEC_MEM_OUTPUT The Shared Memory can carry data from the Trusted - * Application to the client application. - * TEEC_MEM_DMABUF The Shared Memory is allocated with the dma buf api and - * not necessarly user mapped. - * Handle of the memory pass to drivers is the implementation - * fd field instead of the buffer field. - * TEEC_MEM_KAPI Shared memory is required from another linux module. - * Dma buf file descriptor is not created. - */ -#define TEEC_MEM_INPUT 0x00000001 -#define TEEC_MEM_OUTPUT 0x00000002 -#define TEEC_MEM_DMABUF 0x00010000 -#define TEEC_MEM_KAPI 0x00020000 - -/** - * Return values. Type is TEEC_Result - * - * TEEC_SUCCESS The operation was successful. - * TEEC_ERROR_GENERIC Non-specific cause. - * TEEC_ERROR_ACCESS_DENIED Access privileges are not sufficient. - * TEEC_ERROR_CANCEL The operation was canceled. - * TEEC_ERROR_ACCESS_CONFLICT Concurrent accesses caused conflict. - * TEEC_ERROR_EXCESS_DATA Too much data for the requested operation was - * passed. - * TEEC_ERROR_BAD_FORMAT Input data was of invalid format. - * TEEC_ERROR_BAD_PARAMETERS Input parameters were invalid. - * TEEC_ERROR_BAD_STATE Operation is not valid in the current state. - * TEEC_ERROR_ITEM_NOT_FOUND The requested data item is not found. - * TEEC_ERROR_NOT_IMPLEMENTED The requested operation should exist but is not - * yet implemented. - * TEEC_ERROR_NOT_SUPPORTED The requested operation is valid but is not - * supported in this implementation. - * TEEC_ERROR_NO_DATA Expected data was missing. - * TEEC_ERROR_OUT_OF_MEMORY System ran out of resources. - * TEEC_ERROR_BUSY The system is busy working on something else. - * TEEC_ERROR_COMMUNICATION Communication with a remote party failed. - * TEEC_ERROR_SECURITY A security fault was detected. - * TEEC_ERROR_SHORT_BUFFER The supplied buffer is too short for the - * generated output. - * TEEC_ERROR_TARGET_DEAD Trusted Application has panicked - * during the operation. - */ - -/** - * Standard defined error codes. - */ -#define TEEC_SUCCESS 0x00000000 -#define TEEC_ERROR_GENERIC 0xFFFF0000 -#define TEEC_ERROR_ACCESS_DENIED 0xFFFF0001 -#define TEEC_ERROR_CANCEL 0xFFFF0002 -#define TEEC_ERROR_ACCESS_CONFLICT 0xFFFF0003 -#define TEEC_ERROR_EXCESS_DATA 0xFFFF0004 -#define TEEC_ERROR_BAD_FORMAT 0xFFFF0005 -#define TEEC_ERROR_BAD_PARAMETERS 0xFFFF0006 -#define TEEC_ERROR_BAD_STATE 0xFFFF0007 -#define TEEC_ERROR_ITEM_NOT_FOUND 0xFFFF0008 -#define TEEC_ERROR_NOT_IMPLEMENTED 0xFFFF0009 -#define TEEC_ERROR_NOT_SUPPORTED 0xFFFF000A -#define TEEC_ERROR_NO_DATA 0xFFFF000B -#define TEEC_ERROR_OUT_OF_MEMORY 0xFFFF000C -#define TEEC_ERROR_BUSY 0xFFFF000D -#define TEEC_ERROR_COMMUNICATION 0xFFFF000E -#define TEEC_ERROR_SECURITY 0xFFFF000F -#define TEEC_ERROR_SHORT_BUFFER 0xFFFF0010 -#define TEEC_ERROR_TARGET_DEAD 0xFFFF3024 - -/** - * Function error origins, of type TEEC_ErrorOrigin. These indicate where in - * the software stack a particular return value originates from. - * - * TEEC_ORIGIN_API The error originated within the TEE Client API - * implementation. - * TEEC_ORIGIN_COMMS The error originated within the underlying - * communications stack linking the rich OS with - * the TEE. - * TEEC_ORIGIN_TEE The error originated within the common TEE code. - * TEEC_ORIGIN_TRUSTED_APP The error originated within the Trusted Application - * code. - */ -#define TEEC_ORIGIN_API 0x00000001 -#define TEEC_ORIGIN_COMMS 0x00000002 -#define TEEC_ORIGIN_TEE 0x00000003 -#define TEEC_ORIGIN_TRUSTED_APP 0x00000004 - -/** - * Session login methods, for use in TEEC_OpenSession() as parameter - * connectionMethod. Type is uint32_t. - * - * TEEC_LOGIN_PUBLIC No login data is provided. - * TEEC_LOGIN_USER Login data about the user running the Client - * Application process is provided. - * TEEC_LOGIN_GROUP Login data about the group running the Client - * Application process is provided. - * TEEC_LOGIN_APPLICATION Login data about the running Client Application - * itself is provided. - */ -#define TEEC_LOGIN_PUBLIC 0x00000000 -#define TEEC_LOGIN_USER 0x00000001 -#define TEEC_LOGIN_GROUP 0x00000002 -#define TEEC_LOGIN_APPLICATION 0x00000004 - -/** - * Encode the paramTypes according to the supplied types. - * - * @param p0 The first param type. - * @param p1 The second param type. - * @param p2 The third param type. - * @param p3 The fourth param type. - */ -#define TEEC_PARAM_TYPES(p0, p1, p2, p3) \ - ((p0) | ((p1) << 4) | ((p2) << 8) | ((p3) << 12)) - -/** - * Get the i_th param type from the paramType. - * - * @param p The paramType. - * @param i The i-th parameter to get the type for. - */ -#define TEEC_PARAM_TYPE_GET(p, i) (((p) >> (i * 4)) & 0xF) - -typedef uint32_t TEEC_Result; - -/** - * struct TEEC_Context - Represents a connection between a client application - * and a TEE. - * - * Context identifier can be a handle (when opened from user land) - * or a structure pointer (when opened from kernel land). - * Identifier is defined as an union to match type sizes on all architectures. - */ -typedef struct { - char devname[256]; - union { - struct tee_context *ctx; - int fd; - }; -} TEEC_Context; - -/** - * This type contains a Universally Unique Resource Identifier (UUID) type as - * defined in RFC4122. These UUID values are used to identify Trusted - * Applications. - */ -typedef struct { - uint32_t timeLow; - uint16_t timeMid; - uint16_t timeHiAndVersion; - uint8_t clockSeqAndNode[8]; -} TEEC_UUID; - -/** - * In terms of compatible kernel, the data struct shared by client application - * and TEE driver should be restructrued in "compatible" rules. To keep GP's - * standard in compatibility mode, the anonymous padding members are filled - * in the struct definition below. - */ - - -/** - * struct TEEC_SharedMemory - Memory to transfer data between a client - * application and trusted code. - * - * @param buffer The memory buffer which is to be, or has been, shared - * with the TEE. - * @param size The size, in bytes, of the memory buffer. - * @param flags Bit-vector which holds properties of buffer. - * The bit-vector can contain either or both of the - * TEEC_MEM_INPUT and TEEC_MEM_OUTPUT flags. - * - * A shared memory block is a region of memory allocated in the context of the - * client application memory space that can be used to transfer data between - * that client application and a trusted application. The user of this struct - * is responsible to populate the buffer pointer. - */ -typedef struct { - union { - void *buffer; - uint64_t padding_ptr; - }; - union { - size_t size; - uint64_t padding_sz; - }; - uint32_t flags; - /* - * identifier can store a handle (int) or a structure pointer (void *). - * define this union to match case where sizeof(int)!=sizeof(void *). - */ - uint32_t reserved; - union { - int fd; - void *ptr; - uint64_t padding_d; - } d; - uint64_t registered; -} TEEC_SharedMemory; - -/** - * struct TEEC_TempMemoryReference - Temporary memory to transfer data between - * a client application and trusted code, only used for the duration of the - * operation. - * - * @param buffer The memory buffer which is to be, or has been shared with - * the TEE. - * @param size The size, in bytes, of the memory buffer. - * - * A memory buffer that is registered temporarily for the duration of the - * operation to be called. - */ -typedef struct { - union { - void *buffer; - uint64_t padding_ptr; - }; - union { - size_t size; - uint64_t padding_sz; - }; -} TEEC_TempMemoryReference; - -/** - * struct TEEC_RegisteredMemoryReference - use a pre-registered or - * pre-allocated shared memory block of memory to transfer data between - * a client application and trusted code. - * - * @param parent Points to a shared memory structure. The memory reference - * may utilize the whole shared memory or only a part of it. - * Must not be NULL - * - * @param size The size, in bytes, of the memory buffer. - * - * @param offset The offset, in bytes, of the referenced memory region from - * the start of the shared memory block. - * - */ -typedef struct { - union { - TEEC_SharedMemory *parent; - uint64_t padding_ptr; - }; - union { - size_t size; - uint64_t padding_sz; - }; - union { - size_t offset; - uint64_t padding_off; - }; -} TEEC_RegisteredMemoryReference; - -/** - * struct TEEC_Value - Small raw data container - * - * Instead of allocating a shared memory buffer this structure can be used - * to pass small raw data between a client application and trusted code. - * - * @param a The first integer value. - * - * @param b The second second value. - */ -typedef struct { - uint32_t a; - uint32_t b; -} TEEC_Value; - -/** - * union TEEC_Parameter - Memory container to be used when passing data between - * client application and trusted code. - * - * Either the client uses a shared memory reference, parts of it or a small raw - * data container. - * - * @param tmpref A temporary memory reference only valid for the duration - * of the operation. - * - * @param memref The entire shared memory or parts of it. - * - * @param value The small raw data container to use - */ -typedef union { - TEEC_TempMemoryReference tmpref; - TEEC_RegisteredMemoryReference memref; - TEEC_Value value; -} TEEC_Parameter; - -/** - * struct TEEC_Session - Represents a connection between a client application - * and a trusted application. - */ -typedef struct { - int fd; -} TEEC_Session; - -/** - * struct TEEC_Operation - Holds information and memory references used in - * TEEC_InvokeCommand(). - * - * @param started Client must initialize to zero if it needs to cancel - * an operation about to be performed. - * @param paramTypes Type of data passed. Use TEEC_PARAMS_TYPE macro to - * create the correct flags. - * 0 means TEEC_NONE is passed for all params. - * @param params Array of parameters of type TEEC_Parameter. - * @param session Internal pointer to the last session used by - * TEEC_InvokeCommand with this operation. - * - */ -typedef struct { - uint32_t started; - uint32_t paramTypes; - TEEC_Parameter params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; - /* Implementation-Defined */ - union { - TEEC_Session *session; - uint64_t padding_ptr; - }; - TEEC_SharedMemory memRefs[TEEC_CONFIG_PAYLOAD_REF_COUNT]; - uint64_t flags; -} TEEC_Operation; - -/** - * TEEC_InitializeContext() - Initializes a context holding connection - * information on the specific TEE, designated by the name string. - - * @param name A zero-terminated string identifying the TEE to connect to. - * If name is set to NULL, the default TEE is connected to. NULL - * is the only supported value in this version of the API - * implementation. - * - * @param context The context structure which is to be initialized. - * - * @return TEEC_SUCCESS The initialization was successful. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context); - -/** - * TEEC_FinalizeContext() - Destroys a context holding connection information - * on the specific TEE. - * - * This function destroys an initialized TEE context, closing the connection - * between the client application and the TEE. This function must only be - * called when all sessions related to this TEE context have been closed and - * all shared memory blocks have been released. - * - * @param context The context to be destroyed. - */ -void TEEC_FinalizeContext(TEEC_Context *context); - -/** - * TEEC_OpenSession() - Opens a new session with the specified trusted - * application. - * - * @param context The initialized TEE context structure in which - * scope to open the session. - * @param session The session to initialize. - * @param destination A structure identifying the trusted application - * with which to open a session. - * - * @param connectionMethod The connection method to use. - * @param connectionData Any data necessary to connect with the chosen - * connection method. Not supported, should be set to - * NULL. - * @param operation An operation structure to use in the session. May - * be set to NULL to signify no operation structure - * needed. - * - * @param returnOrigin A parameter which will hold the error origin if - * this function returns any value other than - * TEEC_SUCCESS. - * - * @return TEEC_SUCCESS OpenSession successfully opened a new session. - * @return TEEC_Result Something failed. - * - */ -TEEC_Result TEEC_OpenSession(TEEC_Context *context, - TEEC_Session *session, - const TEEC_UUID *destination, - uint32_t connectionMethod, - const void *connectionData, - TEEC_Operation *operation, - uint32_t *returnOrigin); - -/** - * TEEC_CloseSession() - Closes the session which has been opened with the - * specific trusted application. - * - * @param session The opened session to close. - */ -void TEEC_CloseSession(TEEC_Session *session); - -/** - * TEEC_InvokeCommand() - Executes a command in the specified trusted - * application. - * - * @param session A handle to an open connection to the trusted - * application. - * @param commandID Identifier of the command in the trusted application - * to invoke. - * @param operation An operation structure to use in the invoke command. - * May be set to NULL to signify no operation structure - * needed. - * @param returnOrigin A parameter which will hold the error origin if this - * function returns any value other than TEEC_SUCCESS. - * - * @return TEEC_SUCCESS OpenSession successfully opened a new session. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, - uint32_t commandID, - TEEC_Operation *operation, - uint32_t *returnOrigin); - -/** - * TEEC_RegisterSharedMemory() - Register a block of existing memory as a - * shared block within the scope of the specified context. - * - * @param context The initialized TEE context structure in which scope to - * open the session. - * @param sharedMem pointer to the shared memory structure to register. - * - * @return TEEC_SUCCESS The registration was successful. - * @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, - TEEC_SharedMemory *sharedMem); - -/** - * TEEC_AllocateSharedMemory() - Allocate shared memory for TEE. - * - * @param context The initialized TEE context structure in which scope to - * open the session. - * @param sharedMem Pointer to the allocated shared memory. - * - * @return TEEC_SUCCESS The registration was successful. - * @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, - TEEC_SharedMemory *sharedMem); - -/** - * TEEC_ReleaseSharedMemory() - Free or deregister the shared memory. - * - * @param sharedMem Pointer to the shared memory to be freed. - */ -void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMemory); - -/** - * TEEC_RequestCancellation() - Request the cancellation of a pending open - * session or command invocation. - * - * @param operation Pointer to an operation previously passed to open session - * or invoke. - */ -void TEEC_RequestCancellation(TEEC_Operation *operation); - -/** - * Register a pre-allocated Trusted Application This is mainly intended for - * OS-FREE contexts or when a filesystem is not available. - * - * @param ta Pointer to the trusted application binary - * @param size The size of the TA binary - * - * @return TEEC_SUCCESS if successful. - * @return TEEC_Result something failed. - */ -TEEC_Result TEEC_RegisterTA(const void *ta, const size_t size); - -/** - * Unregister a pre-allocated Trusted Application This is mainly intended for - * OS-FREE contexts or when a filesystem is not available. - * - * @param ta Pointer to the trusted application binary - */ -void TEEC_UnregisterTA(const void *ta); - -#endif diff --git a/security/optee_linuxdriver/include/linux/tee_core.h b/security/optee_linuxdriver/include/linux/tee_core.h deleted file mode 100644 index 672b21253052..000000000000 --- a/security/optee_linuxdriver/include/linux/tee_core.h +++ /dev/null @@ -1,205 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef __TEE_CORE_DRV_H__ -#define __TEE_CORE_DRV_H__ - -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -#include - -struct tee_cmd_io; -struct tee_shm_io; -struct tee_rpc; - -enum tee_state { - TEE_OFFLINE = 0, - TEE_ONLINE = 1, - TEE_SUSPENDED = 2, - TEE_RUNNING = 3, - TEE_CRASHED = 4, - TEE_LAST = 5, -}; - -#define TEE_CONF_TEST_MODE 0x01000000 -#define TEE_CONF_FW_NOT_CAPABLE 0x00000001 - -struct tee_stats_entry { - int count; - int max; -}; - -#define TEE_STATS_CONTEXT_IDX 0 -#define TEE_STATS_SESSION_IDX 1 -#define TEE_STATS_SHM_IDX 2 - -#define TEE_MAX_TEE_DEV_NAME (64) -struct tee { - struct klist_node node; - char name[TEE_MAX_TEE_DEV_NAME]; - int id; - void *priv; - const struct tee_ops *ops; - struct device *dev; - struct miscdevice miscdev; - struct tee_rpc *rpc; - struct dentry *dbg_dir; - atomic_t refcount; - int max_refcount; - struct tee_stats_entry stats[3]; - struct list_head list_ctx; - struct list_head list_rpc_shm; - struct mutex lock; - unsigned int state; - uint32_t shm_flags; /* supported flags for shm allocation */ - uint32_t conf; - uint32_t test; -}; - -#define _DEV(tee) (tee->miscdev.this_device) - -#define TEE_MAX_CLIENT_NAME (128) - -/** - * struct tee_context - internal structure to store a TEE context. - * - * @tee: tee attached to the tee_context - * @usr_client: flag to known if the client is user side client - * @entry: list of tee_context - * @list_sess: list of tee_session that denotes all tee_session attached - * @list_shm: list of tee_shm that denotes all tee_shm attached - * @refcount: number of objects which reference it (including itself) - */ -struct tee_context { - struct tee *tee; - char name[TEE_MAX_CLIENT_NAME]; - int tgid; - int usr_client; - struct list_head entry; - struct list_head list_sess; - struct list_head list_shm; - struct kref refcount; -}; - -/** - * struct tee_session - internal structure to store a TEE session. - * - * @entry: list of tee_context - * @ctx: tee_context attached to the tee_session - * @sessid: session ID returned by the secure world - * @priv: exporter specific private data for this buffer object - */ -struct tee_session { - struct list_head entry; - struct tee_context *ctx; - uint32_t sessid; - void *priv; -}; - -struct tee_shm_dma_buf { - struct dma_buf_attachment *attach; - struct sg_table *sgt; - bool tee_allocated; -}; - -/** - * struct tee_shm - internal structure to store a shm object. - * - * @ctx: tee_context attached to the buffer. - * @tee: tee attached to the buffer. - * @dev: device attached to the buffer. - * @size_req: requested size for the buffer - * @size_alloc: effective size of the buffer - * @kaddr: kernel address if mapped kernel side - * @paddr: physical address - * @flags: flags which denote the type of the buffer - * @entry: list of tee_shm - */ -struct tee_shm { - struct list_head entry; - struct tee_context *ctx; - struct tee *tee; - struct device *dev; - size_t size_req; - size_t size_alloc; - uint32_t flags; - void *kaddr; - dma_addr_t paddr; - struct sg_table sgt; - struct tee_shm_dma_buf *sdb; -}; - -#define TEE_SHM_MAPPED 0x01000000 -#define TEE_SHM_TEMP 0x02000000 -#define TEE_SHM_FROM_RPC 0x04000000 -#define TEE_SHM_REGISTERED 0x08000000 -#define TEE_SHM_MEMREF 0x10000000 -#define TEE_SHM_CACHED 0x20000000 - -#define TEE_SHM_DRV_PRIV_MASK 0xFF000000 - -struct tee_data { - uint32_t type; - uint32_t type_original; - TEEC_SharedMemory c_shm[TEEC_CONFIG_PAYLOAD_REF_COUNT]; - union { - struct tee_shm *shm; - TEEC_Value value; - } params[TEEC_CONFIG_PAYLOAD_REF_COUNT]; -}; - -struct tee_cmd { - TEEC_Result err; - uint32_t origin; - uint32_t cmd; - struct tee_shm *uuid; - struct tee_shm *ta; - struct tee_data param; -}; - -struct tee_shm *tee_shm_alloc_from_rpc(struct tee *tee, size_t size); -void tee_shm_free_from_rpc(struct tee_shm *); - -int tee_core_add(struct tee *tee); -int tee_core_del(struct tee *tee); - -struct tee *tee_core_alloc(struct device *dev, char *name, int id, - const struct tee_ops *ops, size_t len); -int tee_core_free(struct tee *tee); - -struct tee_ops { - struct module *owner; - const char *type; - - int (*start)(struct tee *tee); - int (*stop)(struct tee *tee); - int (*open)(struct tee_session *sess, struct tee_cmd *cmd); - int (*close)(struct tee_session *sess); - int (*invoke)(struct tee_session *sess, struct tee_cmd *cmd); - int (*cancel)(struct tee_session *sess, struct tee_cmd *cmd); - struct tee_shm *(*alloc)(struct tee *tee, size_t size, - uint32_t flags); - void (*free)(struct tee_shm *shm); - int (*shm_inc_ref)(struct tee_shm *shm); -}; - -#endif /* __TEE_CORE_DRV_H__ */ diff --git a/security/optee_linuxdriver/include/linux/tee_ioc.h b/security/optee_linuxdriver/include/linux/tee_ioc.h deleted file mode 100644 index 69df95439827..000000000000 --- a/security/optee_linuxdriver/include/linux/tee_ioc.h +++ /dev/null @@ -1,83 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef _TEE_IOC_H -#define _TEE_IOC_H - -#include - -#ifndef __KERNEL__ -#define __user -#endif - -/** - * struct tee_cmd_io - The command sent to an open tee device. - * @err: Error code (as in Global Platform TEE Client API spec) - * @origin: Origin for the error code (also from spec). - * @cmd: The command to be executed in the trusted application. - * @uuid: The uuid for the trusted application. - * @data: The trusted application or memory block. - * @data_size: The size of the trusted application or memory block. - * @op: The cmd payload operation for the trusted application. - * - * This structure is mainly used in the Linux kernel for communication - * with the user space. - */ -struct tee_cmd_io { - TEEC_Result err; - uint32_t origin; - uint32_t cmd; - int fd_sess; - /* - * Here fd_sess is 32-bit variable. Since TEEC_Result also is defined as - * "uint32_t", this structure is aligned. - */ - union { - TEEC_UUID __user *uuid; - uint64_t padding_uuid; - }; - union { - void __user *data; - uint64_t padding_data; - }; - union { - TEEC_Operation __user *op; - uint64_t padding_op; - }; - uint32_t data_size; - int32_t reserved; -}; - -struct tee_shm_io { - union { - void __user *buffer; - uint64_t padding_buf; - }; - uint32_t size; - uint32_t flags; - /* - * Here fd_shm is 32-bit. To be compliant with the convention of file - * descriptor definition, fd_shm is defined as "int" type other - * than "int32_t". Even though using "int32_t" is more obvious to - * indicate that we intend to keep this structure aligned. - */ - int fd_shm; - uint32_t registered; -}; - -#define TEE_OPEN_SESSION_IOC _IOWR('t', 161, struct tee_cmd_io) -#define TEE_INVOKE_COMMAND_IOC _IOWR('t', 163, struct tee_cmd_io) -#define TEE_REQUEST_CANCELLATION_IOC _IOWR('t', 164, struct tee_cmd_io) -#define TEE_ALLOC_SHM_IOC _IOWR('t', 165, struct tee_shm_io) -#define TEE_GET_FD_FOR_RPC_SHM_IOC _IOWR('t', 167, struct tee_shm_io) - -#endif /* _TEE_IOC_H */ diff --git a/security/optee_linuxdriver/include/linux/tee_kernel_api.h b/security/optee_linuxdriver/include/linux/tee_kernel_api.h deleted file mode 100644 index 3447daf203dd..000000000000 --- a/security/optee_linuxdriver/include/linux/tee_kernel_api.h +++ /dev/null @@ -1,174 +0,0 @@ -/* - * Copyright (c) 2014, STMicroelectronics International N.V. - * - * This program is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License Version 2 as - * published by the Free Software Foundation. - * - * This program is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - */ -#ifndef _TEE_KERNEL_API_H -#define _TEE_KERNEL_API_H - -#include - -/** - * struct TEEC_Context - Represents a connection between a client application - * and a TEE. - */ -/*typedef struct { - char devname[256]; -} TEEC_Context;*/ - -/** - * struct TEEC_Session - Represents a connection between a client application - * and a trusted application. - */ -/*typedef struct { - void *session; -} TEEC_Session;*/ - -/** - * TEEC_InitializeContext() - Initializes a context holding connection - * information on the specific TEE, designated by the name string. - - * @param name A zero-terminated string identifying the TEE to connect to. - * If name is set to NULL, the default TEE is connected to. NULL - * is the only supported value in this version of the API - * implementation. - * - * @param context The context structure which is to be initialized. - * - * @return TEEC_SUCCESS The initialization was successful. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_InitializeContext(const char *name, TEEC_Context *context); - -/** - * TEEC_FinalizeContext() - Destroys a context holding connection information - * on the specific TEE. - * - * This function destroys an initialized TEE context, closing the connection - * between the client application and the TEE. This function must only be - * called when all sessions related to this TEE context have been closed and - * all shared memory blocks have been released. - * - * @param context The context to be destroyed. - */ -void TEEC_FinalizeContext(TEEC_Context *context); - -/** - * TEEC_OpenSession() - Opens a new session with the specified trusted - * application. - * - * @param context The initialized TEE context structure in which - * scope to open the session. - * @param session The session to initialize. - * @param destination A structure identifying the trusted application - * with which to open a session. - * - * @param connectionMethod The connection method to use. - * @param connectionData Any data necessary to connect with the chosen - * connection method. Not supported, should be set to - * NULL. - * @param operation An operation structure to use in the session. May - * be set to NULL to signify no operation structure - * needed. - * - * @param returnOrigin A parameter which will hold the error origin if - * this function returns any value other than - * TEEC_SUCCESS. - * - * @return TEEC_SUCCESS OpenSession successfully opened a new session. - * @return TEEC_Result Something failed. - * - */ -TEEC_Result TEEC_OpenSession(TEEC_Context *context, - TEEC_Session *session, - const TEEC_UUID *destination, - uint32_t connectionMethod, - const void *connectionData, - TEEC_Operation *operation, - uint32_t *returnOrigin); - -/** - * TEEC_CloseSession() - Closes the session which has been opened with the - * specific trusted application. - * - * @param session The opened session to close. - */ -void TEEC_CloseSession(TEEC_Session *session); - -/** - * TEEC_InvokeCommand() - Executes a command in the specified trusted - * application. - * - * @param session A handle to an open connection to the trusted - * application. - * @param commandID Identifier of the command in the trusted application - * to invoke. - * @param operation An operation structure to use in the invoke command. - * May be set to NULL to signify no operation structure - * needed. - * @param returnOrigin A parameter which will hold the error origin if this - * function returns any value other than TEEC_SUCCESS. - * - * @return TEEC_SUCCESS OpenSession successfully opened a new session. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_InvokeCommand(TEEC_Session *session, - uint32_t commandID, - TEEC_Operation *operation, - uint32_t *returnOrigin); - -/** - * TEEC_RegisterSharedMemory() - Register a block of existing memory as a - * shared block within the scope of the specified context. - * - * @param context The initialized TEE context structure in which scope to - * open the session. - * @param sharedMem pointer to the shared memory structure to register. - * - * @return TEEC_SUCCESS The registration was successful. - * @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_RegisterSharedMemory(TEEC_Context *context, - TEEC_SharedMemory *sharedMem); - -/** - * TEEC_AllocateSharedMemory() - Allocate shared memory for TEE. - * - * @param context The initialized TEE context structure in which scope to - * open the session. - * @param sharedMem Pointer to the allocated shared memory. - * - * @return TEEC_SUCCESS The registration was successful. - * @return TEEC_ERROR_OUT_OF_MEMORY Memory exhaustion. - * @return TEEC_Result Something failed. - */ -TEEC_Result TEEC_AllocateSharedMemory(TEEC_Context *context, - TEEC_SharedMemory *sharedMem); - -/** - * TEEC_ReleaseSharedMemory() - Free or deregister the shared memory. - * - * @param sharedMem Pointer to the shared memory to be freed. - */ -void TEEC_ReleaseSharedMemory(TEEC_SharedMemory *sharedMemory); - -#if 0 -/** - * TEEC_RequestCancellation() - Request the cancellation of a pending open - * session or command invocation. - * - * @param operation Pointer to an operation previously passed to open session - * or invoke. - */ -void TEEC_RequestCancellation(TEEC_Operation *operation); -#endif - -#endif