Re: [PATCH/RFC 7/9] Virtual network guest device driver

Anthony Liguori
2007-05-21T18:45:37Z

Arnd Bergmann wrote:
> On Monday 21 May 2007, Christian Borntraeger wrote:
>
>>> This is quite easy with KVM. I like the approach that vmchannel has
>>> taken. A simple PCI device. That gives you a discovery mechanism for
>>> shared memory and an interrupt and then you can just implement a ring
>>> queue using those mechanisms (along with a PIO port for signaling from
>>> the guest to the host). So given that underlying mechanism, the
>>> question is how to expose that within the guest kernel/userspace and
>>> within the host.
>>>
>> Sorry for answering late, but I dont like PCI as a device bus for all
>> platforms. s390 has no PCI and s390 has no PIO.

Right, I'm not interested in the lowest level implementation (PCI device
+ PIO). I'm more interested in the higher level interface. The goal is
to allow drivers to be able to be written to the higher level interface
so that they work on any platform that implements the lower level
interface. On x86, that would be PCI/PIO. On s390, that could be
hypercall based.

>> I would prefer a new
>> simple hypercall based virtual bus. I dont know much about windows
>> driver programming, but I guess it it is not that hard to add a new bus.
>>
>
> We've had the same discussion about PCI as virtual device abstraction
> recently when hpa made the suggestions to get a set of PCI device
> numbers registered for Linux.
>
> IIRC, the conclusion to which we came was that it is indeed helpful
> for most architecture to have a PCI device as one way to probe for
> the functionality, but not to rely on it. s390 is the obvious
> example where you can't have PCI, but you may also want to build
> a guest kernel without PCI support because of space constraints
> in a many-guests machine.
>
> What I think would be ideal is to have a new bus type in Linux
> that does not have any dependency on PCI itself, but can be
> easily implemented as a child of a PCI device.
>
> If we only need the stuff mentioned by Anthony, the interface could
> look like
>
> struct vmchannel_device {
> struct resource virt_mem;
> struct vm_device_id id;
> int irq;
> int (*signal)(struct vmchannel_device *);
> int (*irq_ack)(struct vmchannel_device *);
> struct device dev;
> };
>
> Such a device can easily be provided as a child of a PCI device,
> or as something that is purely virtual based on an hcall interface.
>

Yes, this is close to what I was thinking. I'm not sure that this
particular interface can encompass the variety of memory sharing
mechanisms though.

When I mentioned shared memory via the PCI device, I was referring to
the memory needed for boot strapping the device. You still need a
mechanism to transfer memory for things like zero-copy disk IO and
network devices. This may involve passing memory addresses directly,
copying data, or page flipping.

This leads me to think that a higher level interface that provided a
data passing interface would be more useful. Something like:

struct vmchannel_device {
struct vm_device_id id;
int (*open)(struct vmchannel_device *, const char *name, const char
*service)
int (*release)(struct vmchannel_device *);
ssize_t (*sendmsg)(struct vmchannel_device *, const void *, size_t);
ssize_t (*recvmsg)(struct vmchannel_device *, void *, size_t);
struct device dev;
};

The consuming interface of this would be a socket (PF_VIRTLINK). The
sockaddr would contain a name identifying a VM and a service description.

This doesn't address the memory issues I raised above but I think it
would be easier to special case the drivers where it mattered. For
instance, on x86 KVM, a PV disk driver front end would consist of
connecting to a virtlink socket, and then transferring struct bio's.
QEMU instances would listen on the virtlink socket in the host, and
service them directly (QEMU can access all of the guests memory directly
in userspace).

A PV graphics device could just be a VNC server that listened on a
virtlink socket.

Regards,

Anthony Liguori

> Arnd <><