Hi,
this is a follow-up question to an earlier thread [0] on this mailinglist regarding the injection of software interrupts from Genode into the normal world VM.
The basic mechanism works fine, but we need to transfer some meta information with the interrupt to the normal world.
One possible approach would be to write something to a certain location in the non-secure memory before triggering the interrupt and reading that location from Linux. Of course, a cross-world synchronization mechanism is required here to maintain the consistency of the reserved memory range.
Another approach could use Linux's shared interrupts: Additional information can be transferred via the dev_id pointer passed to an interrupt handler.
Are both approaches possible in general, which one would you recommend?
David
[0] http://sourceforge.net/p/genode/mailman/message/34244066/
Hi David,
On 06.11.2015 15:39, David Goltzsche wrote:
The basic mechanism works fine, but we need to transfer some meta information with the interrupt to the normal world.
One possible approach would be to write something to a certain location in the non-secure memory before triggering the interrupt and reading that location from Linux. Of course, a cross-world synchronization mechanism is required here to maintain the consistency of the reserved memory range.
Another approach could use Linux's shared interrupts: Additional information can be transferred via the dev_id pointer passed to an interrupt handler.
Are both approaches possible in general, which one would you recommend?
I am not knowledgeable with the second approach. But passing additional information along with the interrupt delivery sounds not natural to me. The natural and time-tested approach would be to pass the information in a (virtual) device register, like a real device would do it. This is essentially your first approach.
Cheers Norman
Hi David,
Am 06.11.2015 um 15:39 schrieb David Goltzsche:
One possible approach would be to write something to a certain location in the non-secure memory before triggering the interrupt and reading that location from Linux. Of course, a cross-world synchronization mechanism is required here to maintain the consistency of the reserved memory range.
I would recommend this approach. An example how to implement this, is the paravirtualized block-driver for the Linux-VM on my working branches 1497_usb_armory_demo [1] and [2]. The secure back-end of the driver is implemented in [3] whereas the unsecure front-end can be found in [4]. Initially, genode_blk_init (Linux) installs a piece of unsecured RAM as communication buffer by requesting Vmm::Block::_buffer (Genode). The latter checks that the buffer is completely in the VMs RAM and determines its local base. Now, as soon as the device signals the completion of a block request to the VMM, Callback::entry (Genode) injects an IRQ into the VM. Then, event_interrupt (Linux) requests Vmm::Block::_collect_reply (Genode) which writes the result of the block request into the communictaion buffer. For proper communication, it is important that the buffer is mapped uncached on both secure and unsecure side. On the unsecure side, this is achieved via dma_alloc_coherent wich unfortunately requires a device object as input. As we have no real device, we create a dummy device object for that purpose at the beginning of genode_blk_init. On the secure side, the whole VM RAM is mapped as "IO-MEM", which is uncached by default (see _ram and _ram_iomem in [5]).
Another approach could use Linux's shared interrupts: Additional information can be transferred via the dev_id pointer passed to an interrupt handler.
Admittedly, I have don't know whether this approach is feasible and, in case it is, how much effort it would be to implement it. But I assume that communicating via shared RAM means less effort and higher flexibility.
Cheers, Martin
[1] https://github.com/m-stein/genode/tree/1497_usb_armory_demo [2] https://github.com/m-stein/linux/tree/1497_usb_armory_demo [3] <GENODE>/repos/os/src/server/tz_vmm/block.cc [4] <LINUX>/drivers/block/genode.c [5] <GENODE>/repos/os/src/server/tz_vmm/include/vm_base.h