Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Table of Contents
minLevel1
maxLevel7
excludeTable of Contents

Taxonomy

Xen: the Xen Project hypervisor

VM: Virtual Machine

OS: Operating System

Dom0: privileged VM, booted directly from Xen

DomU: regular unprivileged VM, started from Dom0 using the “xl” tool

Dom0less DomU: regular unprivilehed VM started from Xen at boot (in parallel with Dom0)

Introduction

A simple, yet effective, way to setup VM-to-VM communication between Xen guests is plain shared memory and notifications. Shared memory can be used to setup a ring buffer and exchange data, while notifications can be used to avoid having to poll for updates on the ring.

...

Xen events are delivered as GUEST_EVTCHN_PPI, statically defined as interrupt 31. Firstly, register a handler in your OS for PPI 31.

...

Information about event channels is provided on a memory page called “sharedshared_info” info because it is shared between the VM and Xen. In order to access the shared_info page it is necessary to register it:

...

Allocating and Binding Event Channels

The previous chapter section described how to receive event channels in general. This chapter describes how to allocate and bind one event channel so that it can be used for notifications between domains.

...

  1. The receiver domain allocates a new unbound event channel by calling EVTCHNOP_alloc_unbound.

    Code Block
    languagec
            struct evtchn_alloc_unbound alloc;
            alloc.dom = DOMID_SELF;
            alloc.remote_dom = remote_domid;
            alloc.port = 0;
            ret = xen_hypercall(EVTCHNOP_alloc_unbound, (unsigned long)&alloc,
                                0, 0, HYPERVISOR_event_channel_op);

  2. The sender domain needs to know the remote event channel number, typically refer to as “port” port, to bind to it. As the remote port number is dynamically allocated by the EVTCHNOP_alloc_unbound hypercall, it is best if the port number is passed over shared memory from the receiver to the sender.

    Code Block
    languagec
            /* wait for readiness signal */
            while (1) {
                if (strcmp(shared_mem, "go") == 0)
                    break;
                mb();
            }
            mb();
            /* read port number of the other domain */
            memcpy(&remote_port, shared_mem + 4, sizeof(remote_port));

  3. The sender domain issues an EVTCHNOP_bind_interdomain call to bind to the remote port.

    Code Block
    languagec
            struct evtchn_bind_interdomain bind;
            bind.remote_dom = remote_domid;
            bind.remote_port = remote_port;
            bind.local_port = 0;
            ret = xen_hypercall(EVTCHNOP_bind_interdomain, (unsigned long)&bind,
                                0, 0, HYPERVISOR_event_channel_op);

  4. The sender domain can start sending notifications to the receiver domain by issuing EVTCHNOP_send hypercalls

    Code Block
    languagec
            struct evtchn_send send;
            send.port = bind.local_port;
            xen_hypercall(EVTCHNOP_send, (unsigned long)&send,
                          0, 0, HYPERVISOR_event_channel_op);

...