.. _ivshmem_kvmfr: IVSHMEM with the KVMFR module (Recommended) ########################################### The kernel module exposes IVSHMEM to Looking Glass and can export its frame buffers for direct GPU import. .. _ivshmem_kvmfr_prereq: Prerequisites ------------- The Linux kernel headers for your kernel version are required for building along with `dkms` to manage the module when you upgrade your kernel. .. code:: bash apt-get install linux-headers-$(uname -r) dkms Then switch to the ``module/`` directory .. code:: bash cd module/ .. _ivshmem_kvmfr_dkms: Installing ---------- To install the module into DKMS, run .. code:: bash dkms install "." .. _ivshmem_kvmfr_loading: Loading ------- Using the IVSHMEM size from :ref:`Determining Memory `, simply use ``modprobe`` with the parameter ``static_size_mb``, for example: .. code:: bash modprobe kvmfr static_size_mb=64 Alternatively you can make this setting permanent by creating the file ``/etc/modprobe.d/kvmfr.conf`` with the following content. .. code:: text options kvmfr static_size_mb=64 After this has been done, simply running ``modprobe kvmfr`` is all that is required. .. note:: Don't forget to adjust ``static_size_mb`` to your needs. .. _ivshmem_kvmfr_systemd: systemd-modules-load ~~~~~~~~~~~~~~~~~~~~ You can use the ``systemd-modules-load.service(8)`` service to load KVMFR when you start your computer. Create the file ``/etc/modules-load.d/kvmfr.conf`` with the following contents:: # KVMFR Looking Glass module kvmfr This will now run the next time you start your machine. .. _ivshmem_kvmfr_verification: Verification ------------ If everything has been done correctly you should see the following output in dmesg: .. code:: text kvmfr: creating 1 static devices You should now also have the character device ``/dev/kvmfr0`` .. code:: bash $ ls -l /dev/kvmfr0 crw------- 1 root root 242, 0 Mar 5 05:53 /dev/kvmfr0 .. warning:: If you start the VM prior to loading the module, QEMU will create the file ``/dev/kvmfr0`` as a regular file rather than as a character device. You can see if this has happened by running ``ls -l /dev/kvmfr0`` and checking if the file size is greater than zero, or the permissions do not start with ``c``. If this has occurred: 1. stop the VM 2. delete ``/dev/kvmfr0`` 3. load the KVMFR module 4. confirm that ``/dev/kvmfr0`` is character device 5. start the VM again .. _ivhsmem_kvmfr_permissions: Permissions ----------- The module will create the ``/dev/kvmfr0`` node, which represents the KVMFR interface. To use the interface, you need permission to access it by either creating a udev rule to ensure your user can read and write to it, or simply change its ownership manually, i.e.: .. code:: bash sudo chown user:kvm /dev/kvmfr0 (replace ``user`` with your username) As an example, you can create a new file in ``/etc/udev/rules.d/70-kvmfr.rules`` with the following contents:: SUBSYSTEM=="kvmfr", GROUP="kvm", MODE="0660", TAG+="uaccess" .. note:: Make sure the udev rule file name ordinal value is below (lexically sorts before) ``73-seat-late.rules`` to allow the uaccess tag to be processed properly. .. _ivshmem_kvmfr_libvirt: libvirt ------- Using the module in libvirt requires adding a ```` block to your libvirt XML configuration. That block, in turn, requires modifying the XML domain namespace. To modify the namespace edit the ```` tag at the top of your XML config to: .. code:: xml .. note:: Make sure to add both the block and the domain namespace change in a single editing session prior to saving it. Failure to do so will cause libvirt to reject the changes. then the ```` block below to your domain XML: .. code:: xml .. note:: - The ``'size'`` tag represents the size of the shared memory device in bytes. Once you determine the proper size of the device as per :ref:`Determining Memory `, use the figure you got to calculate the size in bytes: ``size_in_MB x 1024 x 1024 = size_in_bytes`` Running libvirt this way violates AppArmor and cgroups policies, which will block the VM from running. These policies must be amended to allow the VM to start. .. tip:: If you are not sure, you likely have cgroups also as this is usually deployed and configured by default by most distributions when you install libvirt. AppArmor ~~~~~~~~ Create ``/etc/apparmor.d/local/abstractions/libvirt-qemu`` if it doesn't exist and add the following: .. code:: text # Looking Glass /dev/kvmfr0 rw, cgroups ~~~~~~~ Edit the file ``/etc/libvirt/qemu.conf`` and uncomment the ``cgroup_device_acl`` block, adding ``/dev/kvmfr0`` to the list. Restart ``libvirtd`` to apply it: .. code:: bash sudo systemctl restart libvirtd.service .. _ivshmem_kvmfr_qemu: QEMU ---- If you are using QEMU directly without libvirt, add the following arguments to your ``qemu`` command line:: -device ivshmem-plain,id=shmem0,memdev=looking-glass -object memory-backend-file,id=looking-glass,mem-path=/dev/kvmfr0,size=64M,share=yes .. note:: The ``size`` argument must be the same size you passed to the ``static_size_mb`` argument when loading the kernel module.