One problem that affects many many GPU passthrough users is the need to permanently bind the host to an iGPU. This can be problematic if you have many games that run on Linux natively. It forces you to boot to a VM to play any graphically demanding games at full speed. With Witko‘s nvidia-xrun utility, you can switch a GPU between the host and guest without a reboot.

Read also: Binding a GPU to vfio-pci in Debian

The script’s intended purpose is to allow NVIDIA Optimus laptops higher graphical performance. Many GPU passthrough users have a similar use case to Optimus laptop users. Both want the Intel GPU to be the primary GPU – in the case of laptops, it is to cut power draw. In the case of passthrough, it is to bind the NVIDIA card to the vfio-pci module for KVM to use. In both cases, the GPU must also be ready to use on demand.

As such, Witko’s script can create a nifty passthrough setup. A reboot is not needed to switch Linux back to using the dedicated NVIDIA card. Unfortunately, you will need to restart the Xorg server.

Unbinding the card from the vfio-pci module

Let’s get started. First, you will need to remove any early-boot bindings to the vfio-pci driver for your NVIDIA graphics card. For Arch:

nano -w /etc/mkinitcpio.conf

Remove any modules containing “vfio.” Then regenerate the initramfs using:

mkinitcpio -p linux

There are many ways to add the vfio-pci module to your initramfs in Gentoo. As such, it is difficult to cover all the methods to revert it. Revert the method you used. For Debian and Ubuntu, you can simply

nano -w /etc/initramfs-tools/modules

and remove the line beginning with “vfio-pci.” Next, regenerate your initramfs using

update-initramfs -u -k all

Reboot after this step. Now that the vfio-pci module is unbound, you will need to install nvidia-xrun itself. On Arch Linux, install the nvidia-xrun AUR package:

pacaur -S nvidia-xrun

Note that this package depends on the nvidia driver package. On Gentoo, add the vampire overlay and emerge nvidia-xrun. Note that you will need to accept the ** keyword for x11-misc/nvidia-xrun to allow it to install. To do this, add the following to your /etc/portage/package.accept_keywords:

x11-misc/nvidia-xrun **

On Debian/Ubuntu based systems, there is currently no preconfigured package available. As such, you will have to manually install it from the git repository. The following commands will guide you through this process:

cd
apt install git
git clone https://github.com/Witko/nvidia-xrun.git
cd nvidia-xrun
cp nvidia-xorg.conf /etc/X11/
cp nvidia-xinitrc /etc/X11/xinit/
cp nvidia-xrun /usr/bin/
chmod +x /usr/bin/nvidia-xrun

Before testing nvidia-xrun, you will need to install the NVIDIA drivers for your distribution. This is fairly straightforward. On Arch, install the nvidia package, on Debian install the nvidia-driver package, and on Gentoo install x11-drivers/nvidia-drivers. Also reboot after this step.

Creating an Intel xorg.conf

Because your host system now has the NVIDIA graphics drivers installed, the main X session might attempt to run on the NVIDIA graphics card. This is problematic – if it does, it will prevent you from running your virtual machine at all. We must create an xorg.conf for the default X session in order to ensure that this does not happen. Add this to your /etc/X11/xorg.conf:

Section "Device"
    Identifier "Intel Graphics"
    Driver "modesetting"
EndSection

Testing nvidia-xrun

You are ready to test it now. Log out of your X session and switch to a free tty. Log in and stop your display manager. Using systemd, this is pretty straightforward:

systemctl stop {gdm,sddm,lightdm,slim,lxdm,mdm}

Replace the last bit with the display manager you use. This should stop all running instances of X on your system.

Depending on what desktop environment you use, you will need to modify this step. For MATE, use mate-session, for i3, use i3, for GNOME 3, use gnome-session, and so on:

echo i3 > ~/.nvidia-xinitrc

Now run the script to test it:

nvidia-xrun

Hopefully, you will be greeted with your familiar desktop, but run on your NVIDIA card! Fire up a Steam game to test it if you desire.

Usage

It is very inconvenient to constantly log out of your desktop, stop your display manager, and restart Xorg manually just to play a game. I suggest disabling your display manager with

systemctl disable {gdm,sddm,lightdm,slim,lxdm,mdm}
nvidia-xrun

Again, be sure to replace the last bit with only the display manager you use. This allows you to manually log in to a tty on boot and run startx. Before running startx for the first time, run:

cp ~/.nvidia-xinitrc ~/.xinitrc

This copies the xinitrc you created earlier to your Intel xinitrc. So, now, on boot, log in to the tty, run startx to start X on your Intel GPU. If you want the dedicated NVIDIA card’s power, log out of that session and run nvidia-xrun.

Troubleshooting

Try removing the “Files” section of xorg.conf

If you are using a Debian-based distribution and nvidia-xrun refuses to run, try commenting out the entire section that looks like this in /etc/X11/nvidia-xorg.conf:

#Section "Files"
# ModulePath "/usr/lib/nvidia"
# ModulePath "/usr/lib32/nvidia"
# ModulePath "/usr/lib32/nvidia/xorg/modules"
# ModulePath "/usr/lib32/xorg/modules"
# ModulePath "/usr/lib64/nvidia/xorg/modules"
# ModulePath "/usr/lib64/xorg/modules"
#EndSection

Ensure that there is indeed no other X server running

Simply run

ps aux | grep X

to get a list of all X servers running on the machine. If this shows an X server running in the background, find the tty it is running on and stop it. If it is a display manager, stop it with systemctl or service, depending on your init system.

How has your experience with nvidia-xrun been? Let us know in the comments below.

Join our Discord to chat with other readers and our writers!


Images courtesy PixaBay