Versions Compared

Key

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

...

Code Block
    reserved-memory {
        #address-cells = <0x2>;
        #size-cells = <0x2>;
        ranges;


        xen-shmem@70000000 {
            compatible = "xen,shared-memory-v1";
            reg = <0x0 0x70000000 0x0 0x1000>;
        };
    };

...

This feature allows sharing one or more pages in memory across VMs, simply by adding one config option to the VM config file. Memory can be shared as cacheable memory. Here is an example:

Code Block
# Add following to the config file of VM1:

...

 
static_shm = ["id=ID1, begin=0x40000000, size=0x1000, role=owner"]

...



# Add following to the config file of VM2:

...

 
static_shm = ["id=ID1, begin=0x48000000, size=0x1000, role=borrower"]

In this example we are sharing one page owned by VM1 with VM2. The owner of the page is the "owner" VM (VM1), while the other VM is called "borrower" (VM2). The memory of Xen VMs always starts at 0x40000000 (guest physical address), so in this example we are sharing the first page of VM1 with VM2. Make sure to choose a valid allocated address of the owner VM.

...

The shared page is advertised as "reserved-memory" in the guest device tree. This is a sample device tree node of a guest with a static_shm configuration:

Code Block

...

reserved-memory {

...


                #address-cells = <0x2>;

...


                #size-cells = <0x2>;

...


                ranges;

...



                xen-shmem@40000000 {

...


                        compatible = "xen,shared-memory-v1";

...


                        id = "ID1";

...


                        reg = <0x0 0x40000000 0x0 0x1000>;

...


                };

The guest is free to use the reserved-memory region as it wishes. For instance, in the case of the Linux kernel, it is possible to export the memory as cacheable memory to userspace with a dmabuf driver. See this proof of concept of Linux driver and userspace program:

https://git.kernel.org/pub/scm/linux/kernel/git/sstabellini/xen.git xen-dmabuf

https://github.com/sstabellini/dmabuf-user xen-dmabufuser-space program:

Xen-dmabuf Linux driver

xen-dmabuf user space program

Dom0-less Shared Memory

  1. Carve out a range of memory to be used for sharing
    You can do that by editing the host device tree, reducing the amount of RAM in the memory node, and adding a separate new "mmio-sram" node as follows:

    Code Block
    --- mpsoc.dts.1 2019-10-31 16:00:35.574817353 -0700
    +++ mpsoc.dts.2 2019-10-31 16:00:24.850379706 -0700
    @@ -1738,6 +1738,11 @@
      
        memory {
            device_type = "memory";
    -       reg = <0x0 0x0 0x0 0x80000000 0x8 0x0 0x0 0x80000000>;
    +       reg = <0x0 0x0 0x0 0x7f000000 0x8 0x0 0x0 0x80000000>;
    +   };
    +
    +   sram@7f000000 {
    +       compatible = "mmio-sram";
    +       reg = <0x0 0x7f000000 0x0 0x1000000>;
        };
     };


    In this example the range 0x7f000000 - 0x80000000 was removed from the memory node and exposed as a special mmio-sram region to be assigned.

    If you don’t want dom0 to get access automatically to the range, add xen,passthrough; under the sram@7f000000 node.

  2. Share the sram region with dom0-less domUs
    Dom0 will get access to the sram region automatically (unless xen,passthrough; was specified). You can map the region to one or more dom0-less domUs by adding an sram node to the dom0-less DomU partial device tree. For instance:

    Code Block
    /dts-v1/;
     
    / {
        #address-cells = <0x2>;
        #size-cells = <0x1>;
     
        gic: gic {
            #interrupt-cells = <0x3>;
            interrupt-controller;
        };
     
        passthrough {
            compatible = "simple-bus";
            ranges;
            #address-cells = <0x2>;
            #size-cells = <0x1>;
     
            sram@7f000000 {
                compatible = "mmio-sram";
                reg = <0x0 0x7f000000 0x0 0x1000000>;
                xen,reg = <0x0 0x7f000000 0x1000000 0x0 0x7f000000>;
                xen,force-assign-without-iommu = <0x1>;
            };
        };
    };


    Note that the xen,reg property is key because it triggers the remapping of the memory range at the same location into the DomU. If you want to map the memory as cacheable is possible to use xen,reg-cacheable instead of xen,reg.

  3. Use the sram region
    When you boot the system, Dom0 and the DomUs will get a mapping of the sram region (0x7f000000 - 0x80000000) automatically. You can use the shared memory by calling `ioremap' in your kernel.