Hi all,
In this email I would like to discuss number of things related to
OP-TEE virtual memory management (and virtualization).
(Note about terminology: I will use "VM" for "virtual memory"
and "guest" for "virtual machine" in this email)
I want to begin with motivation. As you know, I'm working on
virtualization support in OP-TEE. My current approach is total
isolation of different guests from each other. To implement this I
want to divide all OP-TEE program state into two big parts: kernel and
TEE.
Kernel data (or kernel state) is a guest-agnostic data needed for a
core services. Examples: temporary stacks used by entry points (used
before thread_alloc_and_run() invocation), list of known guests,
device drivers state and so on. This kind of data is not
guest-specific, so naturally it should exist in one copy.
TEE data (or TEE state) is guest-bound information: threads (with
stack and state), opened sessions, loaded TAs, mutexes, pobjs and
such. This kind of data have a meaning only regarding to a certain
guest.
So, memory layout can look like this:
+----------+
| .reset |
+----------+
| .text |
+----------+
| .ro |
+----------+
| .kdata |
+----------+
| .kbss |
+----------+
| .kheap |
+----------+
+----------+
| .data |
+----------+
| .bss |
+----------+
| .heap |
+----------+
| TA SPACE |
+----------+
(This is just an illustration, I aware that actual OP-TEE layout is
more complex).
Sections starting with "k" belong to kernel data. I also extended
bget. Now it supports multiple pools and I can use kmalloc() to
allocated memory from .kheap and plain malloc() to allocate mempory
from .heap.
This layout allows us to switch guest context with simple banking:
+----------+
| .reset |
+----------+
| .text |
+----------+
| .ro |
+----------+
| .kdata |
+----------+
| .kbss |
+----------+
| .kheap |
+----------+
============ ============ ============
==Guest 1=== ==Guest 2=== ==Guest 3===
============ ============ ============
| .data | | .data | | .data |
+----------+ +----------+ +----------+
| .bss | | .bss | | .bss |
+----------+ +----------+ +----------+
| .heap | | .heap | | .heap |
+----------+ +----------+ +----------+
| TA SPACE | | TA SPACE | | TA SPACE |
+----------+ +----------+ +----------+
If guest suddenly dies, we can't cleanup resources (consider mutex that
will be never unlocked). Instead we can just drop whole guest context
and forged about it. But we will need special cleanup code for kernel
state, though. This is a reason to keep kernel data footprint as
small as possible.
I think, it is clear now, why I want to talk about virtual memory
management :)
Right now (in absence of pager) OP-TEE is mostly mapped 1:1, all CPUs
use the same mappings. Also there is a separate address space for a
dynamic shared memory mappings. Pager actually does two things:
it breaks 1:1 mapping and also actually does paging.
My first intention was to reuse pager and to make it manage mappings
for a different guests. But ever now it have an overhead, because of
page encryption/hashing. Also, for virtualization it is crucial
to have different mappings on different CPUs. Plus, for efficient
guest context switching it is good to use TTBR1. All this means
that pager should be severely rewritten. Also, use of TTBR1 imposes
restrictions on guest context location in virtual address space.
So, I think it is a good occasion to fully overhaul VM in OP-TEE.
What I propose:
1. Let OP-TEE to live in own address space, not bound to platform
configuration (i.e. as linux does). For example most of the OP-TEE
will be mapped at 0x2000000, when TEE contexts will be mapped at
0x8000000.
2. Add page allocator. Currently tee_mm acts both as a page allocator
and as a address space allocator.
3. Promote pgt_cache to full-scale address space manager.
4. Split pager into two parts: paging mechanism and backend. Backend
can encrypt pages, hash them, or just use some platform-specific
mechanism to protect paged-out pages
5. Rename things. pgt_cache is no more just a cache. tee_mm does
two different things at once.
Jens, I am sure, you have your own vision how VM management should
like. Would you share your thoughts, please? Maybe there is a way, how
I can implement TEE context banking with less effort. I will be very
happy in this case :-) My biggest concern that if I'll take straight
approach to context banking, this will complicate things a lot.
So, I'm ready to improve VM part of OP-TEE for everyone's benefit, if it
will ease up integration of virtualization support.
I also CC'ed Julien Grall from ARM (and, now, from Linaro). He is one of
ARM arch maintainers in XEN project. I think, he can share some valuable
ideas about virtualization as a whole.
--
WBR Volodymyr Babchuk aka lorc [+380976646013]
mailto: vlad.babchuk(a)gmail.com
From: Volodymyr Babchuk <vlad.babchuk(a)gmail.com>
This patch series enables dynamic shared memory support in the TEE
subsystem as a whole and in OP-TEE in particular.
Global Platform TEE specification [1] allows client applications
to register part of own memory as a shared buffer between
application and TEE. This allows fast zero-copy communication between
TEE and REE. But current implementation of TEE in Linux does not support
this feature.
Also, current implementation of OP-TEE transport uses fixed size
pre-shared buffer for all communications with OP-TEE OS. This is okay
in the most use cases. But this prevents use of OP-TEE in virtualized
environments, because:
a) We can't share the same buffer between different virtual machines
b) Physically contiguous memory as seen by VM can be non-contiguous
in reality (and as seen by OP-TEE OS) due to second stage of
MMU translation.
c) Size of this pre-shared buffer is limited.
So, first part of this patch series adds generic register/unregister
interface to tee subsystem. Next patches add necessary features
into OP-TEE driver, so it can use not only static pre-shared buffer,
but whole RAM to communicate with OP-TEE OS.
[1] https://www.globalplatform.org/specificationsdevice.asp
Jens Wiklander (2):
tee: flexible shared memory pool creation
tee: add register user memory
Volodymyr Babchuk (12):
tee: shm: add accessors for buffer size and page offset
tee: shm: add page accessor functions
tee: optee: Update protocol definitions
tee: optee: add page list manipulation functions
tee: optee: add shared buffer registration functions
tee: optee: add registered shared parameters handling
tee: optee: add registered buffers handling into RPC calls
tee: optee: store OP-TEE capabilities in private data
tee: optee: add optee-specific shared pool implementation
tee: optee: enable dynamic SHM support
tee: use reference counting for tee_context
tee: shm: inline tee_shm getter functions
drivers/tee/optee/Makefile | 1 +
drivers/tee/optee/call.c | 131 +++++++++++++++++++++-
drivers/tee/optee/core.c | 160 +++++++++++++++++++++------
drivers/tee/optee/optee_msg.h | 38 ++++++-
drivers/tee/optee/optee_private.h | 26 ++++-
drivers/tee/optee/optee_smc.h | 7 ++
drivers/tee/optee/rpc.c | 72 ++++++++++--
drivers/tee/optee/shm_pool.c | 75 +++++++++++++
drivers/tee/optee/shm_pool.h | 23 ++++
drivers/tee/tee_core.c | 81 ++++++++++++--
drivers/tee/tee_private.h | 60 +---------
drivers/tee/tee_shm.c | 226 +++++++++++++++++++++++++++++++-------
drivers/tee/tee_shm_pool.c | 165 +++++++++++++++++-----------
include/linux/tee_drv.h | 184 ++++++++++++++++++++++++++++++-
include/uapi/linux/tee.h | 30 +++++
15 files changed, 1058 insertions(+), 221 deletions(-)
create mode 100644 drivers/tee/optee/shm_pool.c
create mode 100644 drivers/tee/optee/shm_pool.h
--
2.7.4
There is no storage controller driver in OP-TEE, as pointed out in the RPMB doc:
There is no eMMC controller driver in OP-TEE. The device operations all have
to go through the normal world. They are handled by the tee-supplicant process
which further relies on the kernel's ioctl() interface to access the device.
Is doing this a roadmap (or potential roadmap) item for OP-TEE? I'm wondering
what discussions might have happened in the past, and if the idea has been
rejected for some reason. Or, is it a potential future to do item?
The use case would be if OP-TEE provided a secure key store, and access was
need to that key store prior to normal world being available...for example,
to store keys that encrypted the disk to be used by Linux.
Thanks,
Stuart
Hello,
I wanted to play wit pager on my RCAR board. Just to see if I can fit
it to my virtualization PoC.
But, I can't start OP-TEE with it. I have found this check:
#ifdef ARM64
#ifdef CFG_WITH_PAGER
#error "Pager not supported for ARM64"
#endif
#endif /*ARM64*/
in multiple platform_config.h files. But it bothers my, that this
check is being done in platform code, not in some common place.
I tried to remove it from plat-rcar/platform_config.h (along with
adding TZSRAM definition). All builds fine, but, predictably, does not
work :-). I added KEEP_PAGER() there and here in now at least I can
see some debug output. Right now it fails there:
ERROR: [0x0] TEE-CORE: assertion '!((va | end) & SMALL_PAGE_MASK)'
failed at core/arch/arm/mm/core_mmu.c:851 <init_mem_map>
So, now I'm wondering: is it really that ARMv8 is not supported at
all? Why there is no check in common code then?
Or is it problem of my platform configuration?
--
WBR Volodymyr Babchuk aka lorc [+380976646013]
mailto: vlad.babchuk(a)gmail.com
The first node supplied to of_find_matching_node() has its reference
counter decreased as part of call to that function. In optee_driver_init()
after calling of_find_matching_node() it's invalid to call of_node_put() on
the supplied node again.
So remove the invalid call to of_node_put().
Signed-off-by: Jens Wiklander <jens.wiklander(a)linaro.org>
---
drivers/tee/optee/core.c | 1 -
1 file changed, 1 deletion(-)
diff --git a/drivers/tee/optee/core.c b/drivers/tee/optee/core.c
index 58169e519422..18c8c0a50d37 100644
--- a/drivers/tee/optee/core.c
+++ b/drivers/tee/optee/core.c
@@ -589,7 +589,6 @@ static int __init optee_driver_init(void)
return -ENODEV;
np = of_find_matching_node(fw_np, optee_match);
- of_node_put(fw_np);
if (!np)
return -ENODEV;
--
2.7.4
Hi,
Currently all tee supplicant communication is synchronous. This isn't very
limiting if the supplicant only is accessing system local resources like
storage. With network access via the supplicant it becomes a larger
problem.
This patch set enables asynchronous communication with the supplicant by
introducing meta parameters in the user space API. The meta parameters can
be used to tag requests with an id that can be matched against an
asynchronous response as is done here in the OP-TEE driver.
Asynchronous supplicant communication is needed by OP-TEE to implement
GlobalPlatforms TEE Sockets API Specification v1.0.1. The specification is
available at https://www.globalplatform.org/specificationsdevice.asp.
This change is backwards compatible allowing older supplicants to work with
newer kernels and vice versa.
Thanks,
Jens
Jens Wiklander (3):
tee: add tee_param_is_memref() for driver use
tee: add TEE_IOCTL_PARAM_ATTR_META
optee: support asynchronous supplicant requests
drivers/tee/optee/core.c | 11 +-
drivers/tee/optee/optee_private.h | 43 ++---
drivers/tee/optee/rpc.c | 4 +-
drivers/tee/optee/supp.c | 375 ++++++++++++++++++++++++--------------
drivers/tee/tee_core.c | 32 ++--
include/linux/tee_drv.h | 12 ++
include/uapi/linux/tee.h | 7 +
7 files changed, 295 insertions(+), 189 deletions(-)
--
2.7.4
All,
I am facing an issue I need to debug where after running some number of TAs, the OP-TEE kernel is no longer able to malloc() memory and can no longer load a TA. So, there seems to be a leak of some kind I need to debug. I'm using a crypto accelerator, and so there is most likely a bug in my crypto driver.
Is there any debug mechanism in OP-TEE I could use to get data or statistics about how much space is left on the heap? I've poked around some and don't see anything, but thought I would ask.
Thanks,
Stuart
Dear OP-TEE contributors and maintainers,
We're getting close to releasing OP-TEE 2.6.0.
I am pretty excited about this release, because it supports quite a few new
platforms and introduces cool features. A big one, in my opinion, is
dynamic shared memory [1] by Volodymyr Babchuk. In addition to being quite
helpful technically, this contribution is remarkable because it was
developed largely outside Linaro. I certainly hope we get more and more
involvement from the community in the future.
I have created release candidate tag 1 (2.6.0-rc1). Can you please help
with the following?
1. Check the CHANGELOG, see pull request #1881 [2]
2. Test 2.6.0-rc1 on your favorite platform(s).
Please use the change log pull request to report success (Tested-by:) or
issues.
To upgrade to 2.6.0-rc1 you need to checkout this tag in projects optee_os,
optee_client and optee_test. Please note our linux kernel branch has been
updated [3], it is now based on upstream 4.12. If your platform uses
OP-TEE's Secure Data Path feature (CFG_SECURE_DATA_PATH=y), make sure you
upgrade because ION has changed and xtest depends on this [4].
[1] https://github.com/OP-TEE/optee_os/commit/55d6853cb468 and
https://github.com/OP-TEE/optee_os/commit/b05cd886e06d
[2] https://github.com/OP-TEE/optee_os/pull/1881
[3] https://github.com/linaro-swg/linux/tree/optee
[4] https://github.com/OP-TEE/optee_test/commit/8bc3142b3b2b
Thanks for your help and support,
--
Jerome
OP-TEE Maintainer