Hi Genode team & list,
in my master's thesis I built a framework, which enables cross-world-communication between the normal and secure world. This was based on your tz_vmm demo. If this sounds familiar: I already posted a few questions on this list related to my thesis ;)
My framework relied on periodic world switches triggered by Genode's scheduler (The normal world is running within a Genode thread, so the scheduler prevents both worlds from starving). Of course, simply waiting for world switches leads to high latencies and a low throughput.
To speed things up, we already improved the communication from normal to secure world: The normal world instantly hands over control to the secure world utilizing the smc instruction, when a message is available. We extended the hypercall handler in the Vmm class to notify the receiver via a semaphore.
Unfortunately, forcing a world switch from secure to normal world does not seem to be that easy: Genode's monitor mode implementation cannot handle entries from the secure world. Hence, usage of the smc instruction is not possible.
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Any hints?
Thanks in advance David
Hi David,
On 06/26/2015 03:57 PM, David Goltzsche wrote:
Hi Genode team & list,
in my master's thesis I built a framework, which enables cross-world-communication between the normal and secure world. This was based on your tz_vmm demo. If this sounds familiar: I already posted a few questions on this list related to my thesis ;)
My framework relied on periodic world switches triggered by Genode's scheduler (The normal world is running within a Genode thread, so the scheduler prevents both worlds from starving). Of course, simply waiting for world switches leads to high latencies and a low throughput.
To speed things up, we already improved the communication from normal to secure world: The normal world instantly hands over control to the secure world utilizing the smc instruction, when a message is available. We extended the hypercall handler in the Vmm class to notify the receiver via a semaphore.
Unfortunately, forcing a world switch from secure to normal world does not seem to be that easy: Genode's monitor mode implementation cannot handle entries from the secure world. Hence, usage of the smc instruction is not possible.
Giving control from the VMM to the normal world is pretty simple by calling "run" on the VM session interface. Of course, it doesn't guarantee that the kernel's scheduler immediately switches to the normal world, depending on the current workload of the machine. Anyway, I think what you are trying to bypass is the guest OS' scheduler, and forcing to deliver your signal directly to your corresponding kernel module. This can be achieved relatively simple, as you as VMM developer have full control regarding the normal world's machine state.
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Indeed, this seems to be the most promising approach triggering a software interrupt on the secure side, and handle it in the normal world. Everything that needs to be done is marking a designated SPI (ARM terminology for software-triggered IRQ) as a non-secure interrupt, and delegate that interrupt to your kernel module within the guest OS. Moreover, you will need to extend the VM session interface with the ability to trigger that designated "TrustZone interrupt", as the user-level VMM is not able to access the interrupt controller directly, which has to be done by the kernel itself.
I do not really understood your sentences regarding the supervisor call.
Best Regards Stefan
Any hints?
Thanks in advance David
Hi David,
On 06/26/2015 03:57 PM, David Goltzsche wrote:
Hi Genode team & list,
in my master's thesis I built a framework, which enables cross-world-communication between the normal and secure world. This was based on your tz_vmm demo. If this sounds familiar: I already posted a few questions on this list related to my thesis ;)
My framework relied on periodic world switches triggered by Genode's scheduler (The normal world is running within a Genode thread, so the scheduler prevents both worlds from starving). Of course, simply waiting for world switches leads to high latencies and a low throughput.
To speed things up, we already improved the communication from normal to secure world: The normal world instantly hands over control to the secure world utilizing the smc instruction, when a message is available. We extended the hypercall handler in the Vmm class to notify the receiver via a semaphore.
Unfortunately, forcing a world switch from secure to normal world does not seem to be that easy: Genode's monitor mode implementation cannot handle entries from the secure world. Hence, usage of the smc instruction is not possible.
Giving control from the VMM to the normal world is pretty simple by calling "run" on the VM session interface. Of course, it doesn't guarantee that the kernel's scheduler immediately switches to the normal world, depending on the current workload of the machine. Anyway, I think what you are trying to bypass is the guest OS' scheduler, and forcing to deliver your signal directly to your corresponding kernel module. This can be achieved relatively simple, as you as VMM developer have full control regarding the normal world's machine state.
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Indeed, this seems to be the most promising approach triggering a software interrupt on the secure side, and handle it in the normal world. Everything that needs to be done is marking a designated SPI (ARM terminology for software-triggered IRQ) as a non-secure interrupt, and delegate that interrupt to your kernel module within the guest OS. Moreover, you will need to extend the VM session interface with the ability to trigger that designated "TrustZone interrupt", as the user-level VMM is not able to access the interrupt controller directly, which has to be done by the kernel itself.
I do not really understood your sentences regarding the supervisor call.
Best Regards Stefan
Any hints?
Thanks in advance David
Hi David,
On 29.06.2015 09:20, Stefan Kalkowski wrote:
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Indeed, this seems to be the most promising approach triggering a software interrupt on the secure side, and handle it in the normal world. Everything that needs to be done is marking a designated SPI (ARM terminology for software-triggered IRQ) as a non-secure interrupt, and delegate that interrupt to your kernel module within the guest OS. Moreover, you will need to extend the VM session interface with the ability to trigger that designated "TrustZone interrupt", as the user-level VMM is not able to access the interrupt controller directly, which has to be done by the kernel itself.
On my working branches [1] I've implemented IRQ injection to provide a pseudo block device in a non-secure linux guest. Maybe this code gives you some good hints. Especially the linux commits [2] and the Genode commits [3] should be interesting. Please be aware that this code is still in progress and should not be considered as final solution.
Don't hesitate to ask if you have further questions ;)
Cheers, Martin
[1] https://github.com/m-stein/genode/tree/1497_usb_armory_demo https://github.com/m-stein/linux/tree/1497_usb_armory_demo
[2] 0fa1c63 .handle multiple replies and end interrupt 9ca75d0 .injected IRQ reaches the stub-block handler in linux
[3] 08a3b09 .prototype of inject_vm_irq kernel call 2927f04 .Vm_session::inject_irq(unsigned irq) 42865c4 .injected IRQ reaches the stub-block handler in linux
Hi Martin,
based on the commits you mentioned, I implemented a minimal kernel module, which should receive the interrupts injected by genode.
Overall it works: My Handler gets called when I trigger a software interrupt in genode.
However, the handler is called endlessly for a single interrupt. I assume, i have to clear the interrupt somehow. I called tzic_end_sw_irq(..) before returning from the handler.
Here is my code: http://pastebin.com/NDBV6qYf
Any Hints?
David
On 06/29/2015 12:05 PM, Martin Stein wrote:
Hi David,
On 29.06.2015 09:20, Stefan Kalkowski wrote:
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Indeed, this seems to be the most promising approach triggering a software interrupt on the secure side, and handle it in the normal world. Everything that needs to be done is marking a designated SPI (ARM terminology for software-triggered IRQ) as a non-secure interrupt, and delegate that interrupt to your kernel module within the guest OS. Moreover, you will need to extend the VM session interface with the ability to trigger that designated "TrustZone interrupt", as the user-level VMM is not able to access the interrupt controller directly, which has to be done by the kernel itself.
On my working branches [1] I've implemented IRQ injection to provide a pseudo block device in a non-secure linux guest. Maybe this code gives you some good hints. Especially the linux commits [2] and the Genode commits [3] should be interesting. Please be aware that this code is still in progress and should not be considered as final solution.
Don't hesitate to ask if you have further questions ;)
Cheers, Martin
[1] https://github.com/m-stein/genode/tree/1497_usb_armory_demo https://github.com/m-stein/linux/tree/1497_usb_armory_demo
[2] 0fa1c63 .handle multiple replies and end interrupt 9ca75d0 .injected IRQ reaches the stub-block handler in linux
[3] 08a3b09 .prototype of inject_vm_irq kernel call 2927f04 .Vm_session::inject_irq(unsigned irq) 42865c4 .injected IRQ reaches the stub-block handler in linux
Monitor 25 network devices or servers for free with OpManager! OpManager is web-based network management software that monitors network devices and physical & virtual servers, alerts via email & sms for fault. Monitor 25 devices for free with no restriction. Download now http://ad.doubleclick.net/ddm/clk/292181274;119417398;o _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi David,
Yes, you're right. I had the same problem when I received my first IRQ. This is what Linux commit [1] is for. It calls tzic_end_sw_irq at the end of event_interrupt in file [2]. Note that you have to call it with the physical IRQ number (in my case defined through the Genode config and read via SMC genode_block_irq) and not the virtual IRQ number, which is normally used in Linux (e.g. on request_irq).
[1] 0fa1c63 .handle multiple replies and end interrupt
[2] <LINUX>/drivers/block/genode_block.c
On 28.07.2015 15:03, David Goltzsche wrote:
Hi Martin,
based on the commits you mentioned, I implemented a minimal kernel module, which should receive the interrupts injected by genode.
Overall it works: My Handler gets called when I trigger a software interrupt in genode.
However, the handler is called endlessly for a single interrupt. I assume, i have to clear the interrupt somehow. I called tzic_end_sw_irq(..) before returning from the handler.
Here is my code: http://pastebin.com/NDBV6qYf
Any Hints?
David
On 06/29/2015 12:05 PM, Martin Stein wrote:
Hi David,
On 29.06.2015 09:20, Stefan Kalkowski wrote:
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Indeed, this seems to be the most promising approach triggering a software interrupt on the secure side, and handle it in the normal world. Everything that needs to be done is marking a designated SPI (ARM terminology for software-triggered IRQ) as a non-secure interrupt, and delegate that interrupt to your kernel module within the guest OS. Moreover, you will need to extend the VM session interface with the ability to trigger that designated "TrustZone interrupt", as the user-level VMM is not able to access the interrupt controller directly, which has to be done by the kernel itself.
On my working branches [1] I've implemented IRQ injection to provide a pseudo block device in a non-secure linux guest. Maybe this code gives you some good hints. Especially the linux commits [2] and the Genode commits [3] should be interesting. Please be aware that this code is still in progress and should not be considered as final solution.
Don't hesitate to ask if you have further questions ;)
Cheers, Martin
[1] https://github.com/m-stein/genode/tree/1497_usb_armory_demo https://github.com/m-stein/linux/tree/1497_usb_armory_demo
[2] 0fa1c63 .handle multiple replies and end interrupt 9ca75d0 .injected IRQ reaches the stub-block handler in linux
[3] 08a3b09 .prototype of inject_vm_irq kernel call 2927f04 .Vm_session::inject_irq(unsigned irq) 42865c4 .injected IRQ reaches the stub-block handler in linux
Monitor 25 network devices or servers for free with OpManager! OpManager is web-based network management software that monitors network devices and physical & virtual servers, alerts via email & sms for fault. Monitor 25 devices for free with no restriction. Download now http://ad.doubleclick.net/ddm/clk/292181274;119417398;o _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hi Martin,
thanks for the help. When passing the physical IRQ number, it works!
David
On 08/03/2015 03:49 PM, Martin Stein wrote:
Hi David,
Yes, you're right. I had the same problem when I received my first IRQ. This is what Linux commit [1] is for. It calls tzic_end_sw_irq at the end of event_interrupt in file [2]. Note that you have to call it with the physical IRQ number (in my case defined through the Genode config and read via SMC genode_block_irq) and not the virtual IRQ number, which is normally used in Linux (e.g. on request_irq).
[1] 0fa1c63 .handle multiple replies and end interrupt
[2] <LINUX>/drivers/block/genode_block.c
On 28.07.2015 15:03, David Goltzsche wrote:
Hi Martin,
based on the commits you mentioned, I implemented a minimal kernel module, which should receive the interrupts injected by genode.
Overall it works: My Handler gets called when I trigger a software interrupt in genode.
However, the handler is called endlessly for a single interrupt. I assume, i have to clear the interrupt somehow. I called tzic_end_sw_irq(..) before returning from the handler.
Here is my code: http://pastebin.com/NDBV6qYf
Any Hints?
David
On 06/29/2015 12:05 PM, Martin Stein wrote:
Hi David,
On 29.06.2015 09:20, Stefan Kalkowski wrote:
So, my approach would be using software interrupts which sould be routed to the normal world. I played around with the svc (supervisor call) instruction, but I don't know how to route this to the secure world.
Indeed, this seems to be the most promising approach triggering a software interrupt on the secure side, and handle it in the normal world. Everything that needs to be done is marking a designated SPI (ARM terminology for software-triggered IRQ) as a non-secure interrupt, and delegate that interrupt to your kernel module within the guest OS. Moreover, you will need to extend the VM session interface with the ability to trigger that designated "TrustZone interrupt", as the user-level VMM is not able to access the interrupt controller directly, which has to be done by the kernel itself.
On my working branches [1] I've implemented IRQ injection to provide a pseudo block device in a non-secure linux guest. Maybe this code gives you some good hints. Especially the linux commits [2] and the Genode commits [3] should be interesting. Please be aware that this code is still in progress and should not be considered as final solution.
Don't hesitate to ask if you have further questions ;)
Cheers, Martin
[1] https://github.com/m-stein/genode/tree/1497_usb_armory_demo https://github.com/m-stein/linux/tree/1497_usb_armory_demo
[2] 0fa1c63 .handle multiple replies and end interrupt 9ca75d0 .injected IRQ reaches the stub-block handler in linux
[3] 08a3b09 .prototype of inject_vm_irq kernel call 2927f04 .Vm_session::inject_irq(unsigned irq) 42865c4 .injected IRQ reaches the stub-block handler in linux
Monitor 25 network devices or servers for free with OpManager! OpManager is web-based network management software that monitors network devices and physical & virtual servers, alerts via email & sms for fault. Monitor 25 devices for free with no restriction. Download now http://ad.doubleclick.net/ddm/clk/292181274;119417398;o _______________________________________________ genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
genode-main mailing list genode-main@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/genode-main
Hey David
On 04.08.2015 14:28, David Goltzsche wrote:
thanks for the help. When passing the physical IRQ number, it works!
Maybe one more hint, by the way, although I assume that you're already aware of it. Choose carefully which IRQ numbers to use for cross-world communication. Logically, you don't want to use any IRQ number that is used for device-software communication at the same time or that is not unmasked in your Linux guest.
As you can see in [1], I have made good experience with IRQ 92 (TV encoder IRQ) on the USB armory.
Cheers, Martin
[1] <GENODE>/repos/os/run/tz_vmm.run