This Week in Spectrum

Alyssa Ross
2020-04-19T22:25:49Z

[-- Attachment #1: Type: text/plain, Size: 8312 bytes --]

Wow, a week isn't very long at all. But still, there's definitely
enough to write about, even if I spent most of the week just reading
mailing list threads. More on that in a bit.

Spectrum Live + nixpkgs
-----------------------

I did another stream. This time, we looked at updating the Chromium OS
packages in Spectrum. The script I used to update them had broken -- it
was stuck on an old version, so first we had to fix the script, and then
fix the package builds. A lot of the Chromium OS packages aren't
actually necessary at the moment, but I made them a while ago when it
looked like they would be. I couldn't get one particular such package,
libchrome, to build any more at all after spending quite a few hours on
it, so I ended up just dropping it, along with libbrillo, which depended
on it. Some other package updates had some complexity, but we managed
to work through them all on the stream.

This stream was much more focused on what I was working on than the last
one. The last one was more about people asking general questions and me
answering them and demonstrating things. This time I stayed on the
package updates for the whole stream. I figure people asked all their
questions last time. But there were lots of questions about specific
issues in the package updates, etc. It was nice to know that I had
explained things sufficiently well that people could follow along with
what I was doing. Viewer numbers were up too, which was nice. We were
on 15 for most of the stream.

The packaging work I mostly did on the stream, and then finished up
afterwards is here:

https://spectrum-os.org/git/nixpkgs/log/?h=2bd191e91f097ff2146099fae8b7c8bd90817808

And a couple of small upstream Nixpkgs PRs:

https://github.com/NixOS/nixpkgs/pull/85549
https://github.com/NixOS/nixpkgs/pull/85551

crosvm still needs to be updated in upstream Nixpkgs. If you want to
help out, this might be a good thing to pick up! You'd need to copy the
update.py change I made in Spectrum's Nixpkgs to the crosvm update.py in
upstream Nixpkgs, and then copy the changes in Spectrum nixpkgs' crosvm
to upstream Nixpkgs's crosvm.

If not, I'll probably get to it in a few days.

crosvm
------

Last week, I said that we might me able to use Virtio Wayland as a
transport for crosvm device <-> crosvm communication across a VM
boundary, but that I'd just had the idea and I might decide it couldn't
work.

Having researched it extensively this week, reading over the code for
the virtio_wl kernel driver with puck and consuming a huge number of
messages on assorted kernel-adjacent mailing lists, I think we can make
it work, and it's our best path forward, but I'm still not sure how
exactly. The main problem is that Virtio Wayland can only send shared
memory from host to guest, not the other way around. So when a Wayland
compositor in a guest hands the Wayland crosvm device, it's not going to
be able to pass it over the VM boundary to the crosvm instance running a
Wayland client.

Sharing a guest memory buffer with the host, or another guest, turns out
not to be a solved problem in general. As an example, here is a very
long mailing list thread about how a generic way to do this could work,
from November/December, which reached no firm conclusions:

https://lore.kernel.org/linux-media/20191105105456.7xbhtistnbp272lj@sirius.home.kraxel.org/t/#u

I expect that for most devices, e.g. the network driver, this won't be a
problem. But we're definitely going to need this for Wayland. One
option would be to modify a Wayland compositor to make it ask the host
for some shared memory, rather than allocating its own shared memory
buffer. That would work, but it's the last resort, because it would
have to be a modification made to any Wayland compositor we might want
to use.

At a high level, what we want to do is have a crosvm device running
inside a device VM tell crosvm that a certain address in guest memory
is some shared memory, and have it handle that as it would shared memory
it had allocated itself.

crosvm does support sending dmabufs from guest to host, because of
virtio-gpu. There's a relatively new kernel API called udmabuf that
converts a memfd into a dmabuf, which sounds like it should solve
exactly this problem. It has no documentation in the kernel, but I did
manage to find a small amount of documentation in a patch that was for
some reason never applied[1]. I then managed to write a small test
program that at least called all the ioctls properly and ended up with a
dmabuf. Actually testing this any further will involve a VM, and
testing this sort of thing in a VM at the moment is a real pain, and I
want to make a small tooling improvement around that before I proceed
any further with testing udmabuf. There are also good reasons to
suspect that the udmabuf idea won't work anyway. puck thinks that the
only dmabufs Virtio Wayland will be able to transfer are those allocated
by virtio-gpu. So, not dmabufs that we just made out of a memfd given
to us by a Wayland compositor.

If udmabuf ends up not working, I'll want to see whether we can use
virtio-gpu to allocate dmabufs. The problem with this is that I don't
know how we'll bridge compositor shared memory to virtio-gpu dmabufs.
It'll presumably involve writing kernel code, which I've been pleased to
avoid so far. I can at least probably use the udmabuf implementation as
a starting point.

The third least bad option would be to modify the virtio_wl kernel
driver so it supports shared memory originating from the guest. This
would be very nice to use from userspace, but I just don't think there's
any way I'll be able to write the required kernel code.

And the fourth least bad option (the worst one) would be to modify the
compositor as mentioned above.

spectrum-vm
-----------

The current way of running a Spectrum test VM is to build and run a file
called start-vm.nix that lives in the root of a non-default branch of
Spectrum's nixpkgs called crosvm-demo. Any time you want to try a
custom kernel, rootfs, or crosvm, you need to modify this file. This is
extremely annoying. Also, as time goes on, start-vm.nix is getting
longer and longer, and more and more difficult to understand. So I
think it's finally time to do something better. The something better is
that we introduce derivations for a Spectrum rootfs, guest kernel, and
crosvm, and then provide a program, spectrum-vm, that by default runs a
VM with those three components. It would also have options for
overriding those components, so if you built a custom kernel you could
just drop that one in instead of the default one, for example. And
finally, it would allow changing the flags passed to crosvm.

I started working on this this morning, and I'm quite excited about it.
It's not going to take very long at all to do, but it's going to be such
a big improvement. It will also mean I no longer have a separate
crosvm-demo branch, to merge Spectrum nixpkgs master into every time I
update it. So I'm going to spend the next couple of days on this, and
then get back into investigating udmabuf with a nice new tool.

So, that's what happened this week. I feel like I just spent most of
the week reading mailing lists and not making much progress, but I've
managed to write quite a lot (again) so I suppose I've accomplished
something!

Now, I've been extremely immersed in this stuff all week, and I suspect
that some of this update, especially the crosvm stuff, will not be clear
to somebody who has not been similarly immersed. And, it's getting
dangerously close to midnight UTC, my self-imposed This Week in Spectrum
deadline. So I'm going to send this as is, even though it's probably
confusing. But! I do want you to understand what's going on. So
please feel free to reply and point out anything I didn't explain very
well and ask me for a better explanation. Just be prepared for me not
to know the answer, since I'm still trying to figure out a lot of this
stuff! As a nice side effect, maybe we'll get a mailing list discussion
going. :)

[1]: https://lore.kernel.org/lkml/20180911134216.9760-14-kraxel@redhat.com/

[-- Attachment #2: signature.asc --]
[-- Type: application/pgp-signature, Size: 832 bytes --]