I followed this discussion with interest since I'm in the process of designing
an extension to the RISCV to allow for easier implementation of hypervisors.
On Tue, Jan 03, 2017 at 11:05:10PM -0800, Stefan O'Rear wrote:
On Mon, Jan 2, 2017 at 8:58 AM, ron minnich
Channel designs in general address the "one time transfer of data" case, but
not the "long-lived capabilities" case which primarily matters for
accelerators. If you want an attached program-executing accelerator to be
able to access memory with the precise authority of a single user process,
you need some kind of IOMMU which can walk CPU-format page tables. From the
documentation I've seen on the Intel-ish IOMMUs, I don't think they can be
significantly improved for the "accelerator trusted by some processes but
not system-wide" use case, although the number of hoops is ... high ... for
many simpler use cases.
Virtio also does not support grants of the form "read this block of physical
memory repeatedly until reconfigured", which are relevant for simple video
interfaces (without a device-side framebuffer).
In short, my current solution is a two step system with a memory segment
bitmap for each domain and a secondary page table that is queried on the
resulting physical address when a memory segmentator signals its not allowed
for the current domain to access that physical memory. This secondary page
table including the memory segmentation bitmap are exclusively maintained by a
hypervisor. It allows for each domain to have fully independent page mappings
that are prevented to access anything outside their allocated memory BUT for
the exceptions in the secondary page table and then only for read/write of
The protocol on these shared memory spaces is free to choose. A polling one
for say a framebuffer is fine but a queue of linked lists or virtio structures
is also OK. Just take note of the memory ordering semantics. As a tester I've
implemented a message based two way circular queue for memory/IO/config, a two
way console IO with circular queues and a (dumb) single issue block interface.
As extra instrumentation I've added a signaling function to notify for
processing. It now runs PV6 fine in an multi-CPU setup; writing `drivers' for
these was trivial and peanuts.