3

I'm trying to pass a function pointer from EL1 (Android Kernel) to EL2(Hypervisor) using a SMC Call and trapping the SMC call in the hypervisor. I understand that just passing the pointer the the Hypervisor won't work because its a VA and it means nothing to the Hypervisor.

Any comments on how to do it? I would want to invoke the function from EL2 basically and not from EL1.

My guesses are that I might need to use ion memory or might need to convert the VA -> IPA/PA

Any help or pointers is appreciated, thanks!

kimi
  • 315
  • 3
  • 11

1 Answers1

0

Generally, you don't wish to keep a pointer that is passed this way. It is better to pass a buffer index and copy it in the monitor portion. If the normal OS resumes, the pointed to memory may change and this can result in various overflows and condition checks being avoided.

For this reason, it is often better to pass information by value if possible. If you must pass buffers, it is best to use some lock free structures in memory shared between the normal and secure world. The buffer is fixed and indexed. The SMC call is done to make the secure world aware of the state change. It copies the buffers and updates the structure in shared memory to say it is free. The buffer is then validated in the private copy and acted on.

Generally, acting on a normal world address is not a good idea. This is very error prone and should be avoided. This is why micro-kernels use message passing which copies buffers all the time.

artless noise
  • 21,212
  • 6
  • 68
  • 105
  • Thanks @artless_noise I completely understand the concern of passing pointers between secure and non-secure worlds. But what I'm trying here is to see if I can invoke a function present in the kernel module driver at EL1 to be invoked from a higher privilege level EL2 (Hypervisor) Does this seem possible according to you? I understand that it has a lot of security concerns but I'm trying to do this just for kicks! :) Thanks and I really appreciate your time. – kimi Nov 25 '13 at 19:22
  • You can add a physical address to your SMC API and map that in the secure world. I don't think you have access to the virtual addresses. The EL1 and EL2 naming seem to be AAarch64 specific. If you want an answer to that, then you should update your question. Note: A Hypervisor is different than [tag:Trust-Zone]; they are similar, but different. See [hypervisor vs trustzone](http://stackoverflow.com/questions/17485367/trustzone-versus-hypervisor) – artless noise Nov 25 '13 at 20:17
  • What do you mean by "map that in the secure world" ? Sorry, but I'm new to this linux world and still on a learning phase. I've a system with the TZ and Hyp programmed already and working as they should. Aim is to trap a SMC call in the Hyp and invoke a function in the kernel driver – kimi Nov 25 '13 at 20:30
  • The Linux virtual address will have no meaning to the hyper-visor. You should pass a physical address. You can use the general macro `virt_to_phys()` with `kmalloc()` pointers. Pass this to the SMC interface. In the secure world, if you have the MMU enabled, you need to *map* this physical address to a virtual address (via the secure MMU). If the secure world has no MMU, then you just use the physical address. I assume that Linux is the normal world. – artless noise Nov 25 '13 at 20:57