Hi,
I used "*dma_alloc_coherent( )"* as described in this thread ( https://sourceforge.net/p/genode/mailman/message/34685275/) to allocate shared memory between the trustzone worlds in the tz_vmm example on i.mx53 qsb. It works well. But my questions is how do we prevent the normal world from modifying this shared buffer while it is being used by the secure world. Thanks in advance for answers.
Kind regards, Joseph
Hi Joseph,
On 04/04/2016 07:17 PM, Joseph Lee wrote:
Hi,
I used "*dma_alloc_coherent( )"* as described in this thread ( https://sourceforge.net/p/genode/mailman/message/34685275/) to allocate shared memory between the trustzone worlds in the tz_vmm example on i.mx53 qsb. It works well. But my questions is how do we prevent the normal world from modifying this shared buffer while it is being used by the secure world. Thanks in advance for answers.
this might be an issue in multi-processor environments only, where more than one core is used by the non-secure world. In the uni-processor case (the only one we experimented with TrustZone yet: CortexA8) either the secure world is running, or the normal world. As long as you do not schedule the non-secure Linux it won't run, and this is in the hands of the VMM, which handles traps and calls from the VM, and also makes it runnable again.
But even in the multi-processor case I would question whether this is a problem. In the normal case the guest OS should not touch the shared buffer after it send a request to the secure world. The VMM then copies the message out of the shared buffer and parses it. If the guest OS maliciously changes the shared buffer during the copy process that would result in a broken message. But the guest OS could place such a malicious message already in the first place. The parsing routine of the VMM must be robust against any kind of content it gets anyway, similar to all kind of input-data handlers from unsecure sources (e.g.: web formular interpreter ...).
regards Stefan
Kind regards, Joseph
genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Stefan,
Thanks a lot for your response.
I have another questions. I have tried to measure the time for the context switch between the worlds. I make an *SMC* call in the normal world (Linux) and modified the VMM to return to the normal world without doing any operation. I take time t1 before calling the SMC instruction and time t2 after the secure world switches back to the normal world. Then the difference (t2 - t1) is the time for the context switch. i am getting around *0.05* milliseconds. Is that the right way to measure the time for the context switch? FYI, i use *getrusage( )* function in Linux to measure t1 and t2.
How do we measure time for a process in Genode. Is there a method to get time in Genode? Thanks again for you help and time.
Kind regards, Joseph
On Tue, Apr 5, 2016 at 10:01 AM, Stefan Kalkowski < stefan.kalkowski@...1...> wrote:
Hi Joseph,
On 04/04/2016 07:17 PM, Joseph Lee wrote:
Hi,
I used "*dma_alloc_coherent( )"* as described in this thread ( https://sourceforge.net/p/genode/mailman/message/34685275/) to allocate shared memory between the trustzone worlds in the tz_vmm example on
i.mx53
qsb. It works well. But my questions is how do we prevent the normal
world
from modifying this shared buffer while it is being used by the secure world. Thanks in advance for answers.
this might be an issue in multi-processor environments only, where more than one core is used by the non-secure world. In the uni-processor case (the only one we experimented with TrustZone yet: CortexA8) either the secure world is running, or the normal world. As long as you do not schedule the non-secure Linux it won't run, and this is in the hands of the VMM, which handles traps and calls from the VM, and also makes it runnable again.
But even in the multi-processor case I would question whether this is a problem. In the normal case the guest OS should not touch the shared buffer after it send a request to the secure world. The VMM then copies the message out of the shared buffer and parses it. If the guest OS maliciously changes the shared buffer during the copy process that would result in a broken message. But the guest OS could place such a malicious message already in the first place. The parsing routine of the VMM must be robust against any kind of content it gets anyway, similar to all kind of input-data handlers from unsecure sources (e.g.: web formular interpreter ...).
regards Stefan
Kind regards, Joseph
genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
-- Stefan Kalkowski Genode Labs
http://www.genode-labs.com/ · http://genode.org/
genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Joseph,
Am 05.04.2016 um 11:19 schrieb Joseph Lee:
Hi Stefan,
Thanks a lot for your response.
I have another questions. I have tried to measure the time for the context switch between the worlds. I make an /SMC/ call in the normal world (Linux) and modified the VMM to return to the normal world without doing any operation. I take time t1 before calling the SMC instruction and time t2 after the secure world switches back to the normal world. Then the difference (t2 - t1) is the time for the context switch. i am getting around /0.05/ milliseconds. Is that the right way to measure the time for the context switch? FYI, i use /getrusage( )/ function in Linux to measure t1 and t2.
How do we measure time for a process in Genode. Is there a method to get time in Genode? Thanks again for you help and time.
In general, your set-up looks reasonable to me. It is not granted that the scheduling order in your test case is exactly 'guest os -> vmm -> guest os'. You have to ensure that the secure world kernel doesn't mix in other subjects.
Personally, I also would directly use a hardware timer instead of 'getrusage' to measure such small intervals. You could sample the timer via assembly instructions located directly before and after the SMC call, so no other instructions interfere. Make sure to prevent instruction re-ordering here also. The hardware as well as the compiler may under given circumstances re-order.
You may already know, but if you like to do more detailed measurements, a timer that is configured non-secure allows you to sample from both worlds.
Cheers, Martin
Hi Martin,
Thank you so much.
On Tue, Apr 5, 2016 at 12:53 PM, Martin Stein <martin.stein@...1...> wrote:
Hi Joseph,
Am 05.04.2016 um 11:19 schrieb Joseph Lee:
Hi Stefan,
Thanks a lot for your response.
I have another questions. I have tried to measure the time for the context switch between the worlds. I make an /SMC/ call in the normal world (Linux) and modified the VMM to return to the normal world without doing any operation. I take time t1 before calling the SMC instruction and time t2 after the secure world switches back to the normal world. Then the difference (t2 - t1) is the time for the context switch. i am getting around /0.05/ milliseconds. Is that the right way to measure the time for the context switch? FYI, i use /getrusage( )/ function in Linux to measure t1 and t2.
How do we measure time for a process in Genode. Is there a method to get time in Genode? Thanks again for you help and time.
In general, your set-up looks reasonable to me. It is not granted that the scheduling order in your test case is exactly 'guest os -> vmm -> guest os'. You have to ensure that the secure world kernel doesn't mix in other subjects.
I just only commented out line 118 (i.e.,* if (_handle_vm())*) in https://github.com/genodelabs/genode/blob/15.11/repos/os/src/server/tz_vmm/s... so that the TZ VMM switches to the normal world immediately by invoking the run function of the VM session interface. I don't know how to do with instruction re-ordering in secure world kernel. Can you please give me some hint?
Personally, I also would directly use a hardware timer instead of 'getrusage' to measure such small intervals. You could sample the timer via assembly instructions located directly before and after the SMC call, so no other instructions interfere. Make sure to prevent instruction re-ordering here also. The hardware as well as the compiler may under given circumstances re-order.
I wonder if you could tell me assembly instructions to measure small intervals? i have tried the following but i got 0 value.
* asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(t1));*
* // smc call* * asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(t2));*
* interval = t2 - t1;*
You may already know, but if you like to do more detailed measurements, a timer that is configured non-secure allows you to sample from both worlds.
how do we measure the time taken to execute some instructions in the
secure world?
Cheers, Martin
Thanks,
genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Joseph,
Am 14.04.2016 um 02:44 schrieb Joseph Lee:
I just only commented out line 118 (i.e.,/if (_handle_vm())/) in https://github.com/genodelabs/genode/blob/15.11/repos/os/src/server/tz_vmm/s... so that the TZ VMM switches to the normal world immediately by invoking the run function of the VM session interface. I don't know how to do with instruction re-ordering in secure world kernel. Can you please give me some hint?
Maybe there is a misconception about the VM session run function. It does not directly switch to the VM but rather marks it as executable again. A mere hint for the scheduler. It is up to the Scheduler when to schedule the VM according to the active subjects and their priorities / quotas. Assuming that you use the vanilla 'tz_vmm' scenario, there are additional subjects like the timer or the SD card driver that may be scheduled in between VMM and VM. And the same applies for the switch from VM to VMM. You can solve the latter by adding priorities:
<config verbose="yes" prio_levels="1"> ... <start name="tz_vmm" priority="0"> <resource name="CPU" quantum="40"/> ... </start> ... </config>
The easiest way to improve the former (VMM to VM) temporarily is by hacking the priority/quota of VMs in [1] like:
#include <cpu_session/cpu_session.h>
size_t percentage_to_quota(size_t const quota_percentage) { using Genode::Cpu_session; using Genode::sizet_arithm_t; size_t const tics = cpu_pool()-> timer()->ms_to_tics(Kernel::cpu_quota_ms);
size_t quota_user = Cpu_session:: quota_lim_upscale(quota_percentage, 100);
return Cpu_session:: quota_lim_downscale<sizet_arithm_t>(quota_user, tics); }
Kernel::Vm::Vm(void * const state, Kernel::Signal_context * const context, void * const table) : Cpu_job(Cpu_priority::MAX-1, percentage_to_quota(40)), ...
Leaving 20% CPU quota unused ensures that the other subjects don't starve.
I wonder if you could tell me assembly instructions to measure small intervals? i have tried the following but i got 0 value.
/ asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(t1)); / / // smc call // asm volatile ("MRC p15, 0, %0, c9, c13, 0\t\n": "=r"(t2)); / / interval = t2 - t1; /
As far as I understand, the performance counter you're accessing here wont help you. It counts processor cycles whereas you like to measure time. For an MMIO timer, you can do something like:
/* Initialize timer */ unsigned v1 = 0; unsigned v2 = TIMER_VALUE_REG_BASE; asm volatile ( "dsb\n" "ldr %1, [%2]\n" "dsb\n" "smc #0\n" "dsb\n" "ldr %2, [%2]\n" "dsb\n" : "=r" (v1), "+r" (v2) : ); unsigned interval = v2 - v1
You may use the FLEXCAN Free Running Timer or the General Purpose Timer (GPT). You don't want to use the EPIT timers as they are needed by the secure world for the scheduler and the userland timer that is needed by the SDHC driver.
The DSB instructions avoid re-ordering. I'm not sure if you need that many DSBs but as soon as the first DSB is through, the other DSBs shouldn't cause big overhead.
how do we measure the time taken to execute some instructions in the secure world?
Cheers, Martin
[1] base-hw/src/core/spec/arm_v7/trustzone/kernel/vm.cc