How to configure a Linux Host with GPU Passthrough for Windows Mixed Reality

This is my report on researching and testing the possibility of using a Linux host, with a Windows virtual machine in KVM, with GPU passthrough and a Windows Mixed Reality(WMR) headset. My findings have been that it is indeed possible, with near native performance, but hardware and software setup is complex. It requires an understanding of the Linux operating system, virtual machines and KVM, hardware schematics, and ability to build/modify a computer tower. It is possible with a smaller budget (like I had) to do this, but that might mean searching for pre-owned parts to reduce the cost of the upgrade.

Virtual reality is growing in popularity every year, and similarly, frustrations with Windows operating systems are driving more people to Linux. In the virtual reality world, there is an increase in immersion, as your movements are mimicked by the headset tracking. But Microsoft has recently announced that they are removing support for the WMR headset in Windows 11. This is incredibly frustrating to the people who purchased a WMR headset, especially since Windows is not releasing the source code for the platform. On the other hand, Linux developers have been experimenting with creating compatibility layers of software to allow for the headsets to work natively in Linux. While this is great for open source users and developers, there are still compatibility problems with playing games designed for Windows. Specifically, the headset is still not fully functional in its alpha state.

Linux

Linux distributions generally have a stronger focus in security, privacy, and openness to customize the operating system. As Windows continues to add to the growing list of performance problems and intrusive tracking software, many people are looking for a way to continue using older devices that are not compatible with the latest Windows operating systems. In my case, I wanted the ability to make more decisions about what and how my computer runs, and the safety of using open source software has actually increased the capabilities of my system with no added tracking or telemetry.

Virtual Machine

The current way to run native Linux but have Windows for gaming available is through using a kernel-based virtual machine (KVM), a Linux native hypervisor that allows for more capabilities than other hypervisors, like VirtualBox. It uses QEMU as its emulator and Libvirt for Virtual Machine(VM) management. This is controllable with a graphical application called Virtual Machine Manager, used as a Graphical User Interface(GUI) to function without needing to use a terminal. KVM, when properly set up, provides near-native performance and the ability to dedicate PCIe devices (like graphics cards) to the virtual machine of your choice. This allows your devices to function completely separate from the Linux desktop, and can be operated independently from each other (i.e. you can play games on Windows while working or playing videos on your Linux desktop) if you have multiple monitors or separate video inputs on your current monitor.

IOMMU

The way this is achieved is through enabling virtualization tools in the BIOS, and sending Input/Output Memory Management Unit (IOMMU) PCIe groupings to the virtual machine. Modern laptops and desktops have virtualization abilities that you can enable within the BIOS, with some features for better VM performance. IOMMU groupings are the way motherboards dedicate certain pipelines of data to and from their location in the motherboard. Nearly everything, including the CPU and its components, has its own groupings, but some are grouped together in a way that would conflict with virtualization passthrough.

The Virtual Function I/O(VFIO) is responsible for allowing hardware devices to be controlled directly with an application. In other words, it is possible to pass control to an application, like KVM, for direct hardware access. The IOMMU groupings dictate what devices you can share, while giving them a hardware address that an application can recognize. Tricky part is you have to pass the entire grouping for it to function in the virtual machine. In my case, my motherboard grouped some PCIe slots I wanted to use with the CPU. I needed a solution.

PCIe

I was able to pass my Nvidia graphics card to the VM, after blocking any Nvidia drivers in the kernel from loading, but I could not pass the USB-C included on my motherboard I/O because it was tied to CPU functions. I wanted to do this so I could use my WMR headset, which requires a DisplayPort and USB-C actively connected to function. I purchased a few USB PCIe cards to use in one of my unused slots, but it only supported an x1 connection. This essentially means it can only fit very small expansion cards, and isn’t capable of transferring as much data than larger slots (4x, 8x, 16x etc.) Even with a supported x1 USB card, it was not able to be passed to my virtual machine, because the slot was shared with some CPU functions on my motherboard.

My system was originally using a Ryzen 7 5800x with 32GB of DDR4 ram, with my Asus B550-F motherboard, and an RTX 2070 + RX 550x for graphics. The Asus motherboard only had one or two PCI 4.0 slots(the latest and highest rated), the rest were 3.0 with IOMMU groupings that could not be used in passthrough.

It was powerful enough for my needs, but I wanted to push my computer to be as upgraded as possible for the AM4 generation of CPUs, since it is already considered outdated hardware. Initially, I had set up a Windows virtual machine with my Nvidia RTX 2070 graphics card passed to the VM. Along with an AMD RX 550x low profile RX 580 graphics card to be used with Fedora Linux, my host OS. I also have a separate USB microphone and USB audio output device that I similarly pass control of to the VM. It worked, but I did not have enough slots to Install any other cards (like a PCIe USB expansion card). I did not have any other option for getting my virtual reality headset, an HP Reverb G2, working correctly. So I started looking into a motherboard that could support this.

Motherboard

After some research, I realized I would need to buy a high end AM4 motherboard. I initially looked at Asus, but I read they had very mixed reviews on its IOMMU groupings, so Asus didn’t seem to have the groupings I needed. So, I looked into other motherboards, and I eventually settled on a used Gigabyte X570 Aorus Master, which was purchased for about $170, about half the price of original retail value. User accounting said that the gigabyte had better separation in its IOMMU groupings, and this seemed to match what I found in my research.

I got the new motherboard installed, and everything seemed to function properly. The BIOS was different from my Asus motherboard, but a search for the manual told me everything I needed to do (always RTFM). I also upgraded my CPU to a Ryzen 5950x, so that way I could give both my Windows machine and my Linux host machine 8 dedicated cores and 16 threads to work with. This was unnecessary, but at the time the market prices were cheaper, and it gets more expensive the longer production has stopped and the hardware becomes rarer to find. This was with upgrading my machine to 64 gigabytes (16GB x 4) of RAM, but initial tests indicated it would not be enough resources to make this work. So I ended up settling on 128 gigabytes (32GB x 4) of ram to ensure future proofing and long term stability.

PCIe USB Expansion Card

The motherboard had three x16 PCIe slots that had satisfactory IOMMU separation, so I purchased what seemed like the best USB expansion card. It has two USB-C ports and three USB type A ports. Reviews indicated other cards that have USB-A slots facing vertically are not ideal, and often led to problems because the case made the ports difficult to access, since the ports were wider than my case slots. I finally decided on a dual combined USB-A and USB-C expansion card that had the slots facing horizontally, for a total of 3 USB-A and 2 USB-C ports on a PCIe x4 card.

Windows Mixed Reality

Once I got the USB card successfully passed through to the VM, I plugged in my VR headset into the DisplayPort slot and the USB-C slot. At first, I had to configure Windows to cheat the minimum hardware standards test for Windows mixed reality because it false-reported that I didn’t have enough system resources to run the VR application. This was corrected with a careful registry change, and I was then able to then get it to accept the hardware. I plugged in my headset, downloaded all the VR games and Software that I needed to run the VR. I turned it on, and it worked! Side note: leaving the headset plugged in before turning on the VM ended up crashing the VM every time, so I disconnect power to the headset until I am logged in.

Gaming Performance

I had interestingly better results with the performance of the VR. I suspect this is because I had only one monitor plugged into the GPU, instead of all 3 of the monitors I use. The framerate and response time were more consistent, and while testing Half Life: Alyx I was no longer getting the VRAM warning messages I had before.

Resource Allocation

I initially had my Windows VM set up as a virtual disk partition in the KVM software. But then I decided I wanted two separate M.2 SSDs for maximum space and performance. So I purchased the exact same 2TB Inland SSDs. I passed one of those SSDs, through the isolated IOMMU group, directly to Windows with minimal performance loss. The virtual machine was assigned 40 gigabytes of dedicated RAM solely for Windows. This may sound excessive, but I have plenty of resources are available to spare for increased stability. My Windows VM now runs games and VR as if it’s on a completely separate computer, though it does generate more heat.

Occasionally, the virtual machine will not work properly with Evdev, which is a function that can be added to the VM configuration to pass keyboard and mouse controls to the VM with minimal input lag. I can switch desktops by hitting both my left and my right control keys, but occasionally the keyboard shortcut stops working (mouse stays with one desktop and keyboard starts malfunctioning in the VM). Power cycling the VM can fix the issue.

UPDATE: I have not had this problem since the latest Fedora 42 update, so I can still use my primary keyboard and mouse in the VM without anything breaking!

Networking

At first, I struggled to figure out the networking side of the VM, as it did not have a visible IP on my network that I could interact with. I found a solution that shares the network in bridged mode that allows both the Linux host and the Windows VM to share the connection while having separate IP addresses visible to my local network. And I can still use my Linux host machine that performs with no difference to if the VM is being used or not. While I’m sure my system draws more power now, it costs less and draws less power than if I were to build a second dedicated gaming machine, and it is much easier to tweak and interact with Windows through the virtualization controls.

Inspiration

This was just a fun hobby project that I really wanted to test out. I was encouraged by many sources, such as Mutahar AKA SomeOrdinaryGamers who has discussed his desktop setup in many of his videos, my friends, and Linux memes I’ve encountered discussing the idea. I had to add a few extra steps to get my WMR headset functioning, but it was truly worth every bit of effort!

Update 12/2025

So I’ve made some recent adjustments and changes to my setup. Because of how premium the Aurora Master is, I have 2 separate Ethernet connections for my machine, and I can directly pass one of them to my virtual machine without issue. I wanted to highlight this because it changes the way I use it now. No more network bridging, just two separate direct connections with individual IP addresses. This will vary from motherboard to motherboard, so always check your motherboards iommu groupings to ensure compatibility.

I also swapped out my AMD card with the larger RX 580, so unfortunately I had to sacrifice my SATA expansion card to make room for the new card. Thankfully I have just enough ports on the motherboard so not a big deal, but I thought I would mention this.

FAQ: Using a Linux Host with a Windows VM for WMR Headset and GPU Passthrough

Can I use a Windows Mixed Reality (WMR) headset with a Linux host and a Windows virtual machine (VM)?

Yes, it’s possible with a Linux host running a Windows VM using KVM with GPU passthrough. However, the setup is complex, requiring knowledge of Linux, KVM, hardware schematics, and PC building. The WMR headset can work, but compatibility is limited due to its alpha-state support on Linux.

What hardware is needed for this setup?

You’ll need a motherboard with good IOMMU groupings for PCIe passthrough (e.g., Gigabyte X570 Aorus Master), a compatible GPU (e.g., Nvidia RTX 2070), a CPU with virtualization support (e.g., Ryzen 5950x), ample RAM (64GB or more recommended), and a PCIe USB expansion card for WMR headset connectivity.

Why use a Linux host instead of Windows for VR gaming?

Linux offers better security, privacy, and customization. With Windows dropping WMR support in Windows 11 and adding performance issues, a Linux host with a Windows VM allows you to use open-source software while running Windows games and VR applications with near-native performance.

What are the challenges with this setup?

Challenges include complex hardware and software configuration, ensuring proper IOMMU groupings, and managing compatibility issues with WMR headsets. You may need to tweak BIOS settings, block conflicting drivers, and handle occasional VM issues like input lag or crashes.

How does GPU passthrough work with KVM?

GPU passthrough uses KVM and VFIO to dedicate a GPU to the Windows VM, providing near-native performance. This requires enabling virtualization in the BIOS, configuring IOMMU groupings, and passing PCIe devices (like the GPU and USB card) to the VM.

Are there any tips for setting up a WMR headset?

Ensure the USB-C and DisplayPort connections are passed through correctly via a PCIe USB card. Disconnect the headset before starting the VM to avoid crashes, and you may need to adjust Windows registry settings to bypass WMR’s hardware check.

Questions?

If you have any questions or comments feel free to leave them below.

Affiliate

This page contains affiliate links. If you make a purchase through these links, we may earn a small commission at no extra cost to you.

Related Resources

View our How to Mount an SMB (Samba) Share in Linux with cifs-utils guide.

Learn How to Install Ubuntu Server 22.04 [Step by Step].

Check out How to Setup OpenSSH with Keys on Ubuntu 22.04.

View our How to Create a Mapped Network Drive in Windows 10 tutorial.

Learn How to Install and Configure Grafana on Ubuntu 22.04.

View all of our available online tools and converters at Formatswap.com.

How to Setup an SFTP Server on Ubuntu 22.04 using OpenSSH

sftp splash

In this article you will learn how to enable and connect to the SFTP server in OpenSSH. With SFTP (Secure File Transfer Protocol) you can easily transfer files over the internet using SSH. We will be using Ubuntu 22.04 for our server, however any version of Linux should work.

This guide will use password authentication with IP firewall restriction. This will prevent anyone besides those who you want accessing the box via SSH or SFTP. If you want the highest level of security possible you will want to enable keys in OpenSSH before following this guide. Learn how to enable keys with our How to Setup OpenSSH with Keys on Ubuntu 22.04 tutorial.

SFTP vs FTP

It is important to mention that SFTP is not the same as FTP. One of the main differences is while they both transfer files, only SFTP encrypts the data during transit. Another difference is FTP is unable to benefit from public key files for authentication. Using public keys with SFTP increases security by encrypting the transfer data stream. If your aim is security then it is highly recommended you use SFTP versus FTP. Now that I have described the differences lets move on to configuring and connecting to an SFTP server in OpenSSH.

Update and Upgrade Ubuntu

update and upgrade ubuntu

The first thing you need to do is update and upgrade your Ubuntu installation. Open a terminal and type the following command. Afterwards press “Y” to confirm.

sudo apt update && sudo apt upgrade

Install OpenSSH

install open-ssh

After your system has finished updating you will need to install the OpenSSH server software. OpenSSH provides encrypted file transfer for file transfers and remote logins. Install the software using the apt command.

sudo apt install openssh-server

View SSH Status

view ssh status

Next you need to verify that OpenSSH is installed on your system and actively running. Use the below command and confirm that you see “active (running)” on the third line.

sudo systemctl status ssh

If SSH does not show as active and running it may be disabled. Run the following command to enable and start the OpenSSH server.

sudo systemctl enable ssh && sudo systemctl start ssh

Create New User

create a new user

Now you will need to create a new user for logging into the SFTP server. Run the adduser command then type a password. You can skip the other fields if you wish. Finally press “Y” to confirm.

sudo adduser sftpuser

Create New Group

create a new group

Afterwards we will create a new group for our sftpuser. We will configure SSH to give SFTP access to any user in this group. Run the addgroup command to proceed.

sudo addgroup sftpusers

Add User to Group

add user to group

Next we need to add the user to the new group. Run the usermod command to add the sftpuser to the sftpusers group.

sudo usermod -a -G sftpusers sftpuser

Change User’s Home Permissions

change users home permissions

Then we will set new permissions on the sftpuser’s home directory. This will allow the SFTP server to access these files. First execute the chown command followed by the chmod command. The sftpuser’s home will be the folder you access when you connect to the SFTP server.

sudo chown root: /home/sftpuser
sudo chmod 777 /home/sftpuser

Edit the SSH Config File

Next we need to edit the sshd_config file and edit a few lines. Open the configuration file using the nano text editor as shown below.

sudo nano /etc/ssh/sshd_config

Locate the Subsytem Line

locate subsystem line

After you open the file scroll down and look for the Subsystem line. Once you locate the line comment it out using the “#” symbol as shown below.

#Subsystem      sftp    /usr/lib/openssh/sftp-server

Add New Lines

Now that you have commented out the Subsystem line you need to add a few additional lines. Paste the following underneath the line you commented out. Your sshd_config file should match the screenshot above. After the lines have been added save and close the file using “Ctrl+X”.

Subsystem sftp internal-sftp

Match Group sftpgroup
     ChrootDirectory %h
     X11Forwarding no
     AllowTCPForwarding no

Restart SSH

restart ssh

To apply our changes we will restart ssh. Use the following service command.

sudo service ssh restart

Configure the Firewall

The next step is to configure the firewall using UFW to control access to our SFTP server. Start by denying all incoming traffic, and allowing all outgoing.

sudo ufw default deny incoming
sudo ufw default allow outgoing

Allow SSH (All IP’s)

allow ssh

You have two options when allowing SSH through the firewall. You can either allow any IP to access port 22 (not recommended). Or you can only allow specific IP(s) through the firewall. I recommend the section option as it offers higher security. If you want to allow any IP run the following command.

sudo ufw allow ssh

Allow SSH (Specific IP’s)

allow specfic ip

If you want to only allow specific IP’s to access the server run the following command for each IP you want to have access. You need to replace “IP-ADDRESS” with your own IP. This is highly recommended as it offers the highest level of security.

sudo ufw allow from IP-ADDRESS to any port ssh

Enable UFW

enable ufw

After you have allow the IP’s (or everyone) who you want to have access you will need to enable UFW. Run the following command.

sudo ufw enable

Check Firewall Status

check firerwall status

The last step is to check the firewall status and verify your configuration. Check it using the ufw status command. If you allowed access to only specific IP’s you will see them in the “From” column.

sudo ufw status

Connecting to the SFTP Server

Finally we can test our connection to the SFTP server. The first thing you will need is a FTP client. I recommend downloading FileZilla. This is the software we will use in this tutorial. You can install it using the following apt command.

sudo apt install filezilla

Edit Site List

edit filezilla site list

Open Filezilla and click on the site manager button in the upper left hand corner.

Add a New Site

add filezilla site

Type Connection Information

add filezilla connection information

Confirm Host Key Prompt

confirm filezilla hostkey

Verify Connection

verify filezilla connection

Questions?

If you have any questions or comments feel free to leave them below.

Related Resources

View our 5 Reasons to Switch from Windows 10 to Linux.

Learn How to Install Ubuntu Server 22.04 [Step by Step].

Check out How to Setup OpenSSH with Keys on Ubuntu 22.04.

View our How to Mount an SMB (Samba) Share in Linux with cifs-utils tutorial.

Learn How to Use the Alias Command in Linux.

View all of our available online tools and converters at Formatswap.com.

How to Mount an SMB (Samba) Share in Linux with cifs-utils

cifs-utils header image

In this tutorial you will learn how to use the CIFS-UTILS program to mount network shares. You will also learn how mount the file shares at boot. This allows you to avoid typing your credentials, as well as avoiding the use of the mount command when you turn on the system. With CIFS-UTILS you will be able to easily access files from a SMB share on your network. I will be using Ubuntu 22.04 LTS throughout this tutorial. However it is fine if you have a different version, as this guide will work on any Ubuntu based Linux distribution.

Update and Upgrade Ubuntu

update and upgrade ubuntu

The first thing you will need to do is update and upgrade your Ubuntu installation. Type in the following command and press Enter.

sudo apt update && sudo apt upgrade
install cifs utils

Now you will see a window asking you if you want to continue. Press “Y” and then Enter.

Install CIFS-UTILS

install cifs utils

Afterwards you will need to install cifs-utils. This is a program that allows you to easily mount different file shares on Linux. Type in the following command to install it.

sudo apt install cifs-utils

Create a Mount Directory

make share mount folder

Next you need to create a folder to mount the SMB share. You can create a folder in either /mnt/ or /media/.

sudo mkdir /media/Share
or
sudo mkdir /mnt/Share

Navigate to the Home Folder

cd to home folder

Now navigate to your home folder.

cd ~/

Create the Credentials File

create creds file

Once you are in the home folder you need to create a credentials file. A credentials file is vastly more secured versus providing the password and username in plain text.

nano .creds
enter user and pass cifs-utils

Now type your username and password in the format above. Once you have typed your credentials, press “Ctrl+X” then “Y” to save and quit the text editor.

Apply Permissions

apply permissions to creds file

Next we will apply the permissions to the credentials file. For security reasons you only want root to be able to read and write the file. Enter the command below to apply the changes.

sudo chown root: .creds && sudo chmod 600 .creds

Mount the SMB Share

mount smb share

Finally you will mount the SMB network share. Enter the below cifs mount command replacing the credential directory, IP address, mount location, and share name with your own.

sudo mount -t cifs -o credentials=/home/USERNAME/.creds,dir_mode=0755,file_mode=0755 //IPADDRESS/ShareName /mnt/Share

After you run the command you can navigate to the mount folder to view the network share that you have added. You have now successfully mounted a SMB network share using cifs-utils.

Auto Mounting

If you only use the mount command, your network share will no longer be mounted when you reboot. We will edit the fstab file and add a few entries. This is the file that defines what file systems are mounted at boot. Continue reading below to make the share persistent.

Edit the fstab File

edit fstab file

First we need to open the fstab file. Type in the following command to edit it.

sudo nano /etc/fstab

Add fstab Entries

mount cifs share

Now you will want to add a new line for mounting your cifs share. Use the code below as an example of what to type, replacing the credentials, IP, and share name with your own.

//IPADDRESS/ShareName  /mnt/Share  cifs  credentials=/home/USERNAME/.creds,file_mode=0755,dir_mode=0755 0  0

Reboot PC

reboot pc

The last step will be to reboot your PC. After rebooting you will see the network share mounted at /mnt/ShareName or /media/ShareName depending on where you created the folder. Thank you for reading the tutorial. If you are interested in similar technology tutorials check out some of our articles below.

Questions?

If you have any questions or comments feel free to leave them below.

Related Resources

View our How to Permanently Disable Windows Defender article.

Learn How to Install Ubuntu Server 22.04 [Step by Step].

Click here to learn How to install and configure Nginx – Ubuntu 20.04.

View our Programming Articles and Tutorials.

Learn more cool things in Linux with our Linux Tutorials.

View all of our available online tools and converters at Formatswap.com.

How to Add a Network Location in Windows 10

add network location splash image

In this tutorial you will learn how to add a network location to Windows 10. This will allow you to access a file share remotely by connecting computers on the network. The main benefit to adding a network location is that it will be permanently saved in file explorer. This allows you to avoid typing the network address of the location each time. As well as easy management of multiple network shares. When you are finished you should have a new location added to the Windows Explorer Network Locations list.

Open File Explorer

file explorer window

You can open File Explorer by clicking on the folder icon in the taskbar or by pressing “Win+E” on your keyboard.

Navigate to This PC

open "This PC"

Now you will need to click on “This PC” (the computer icon on the left) in your File Explorer.

Open Add Network Location Dialog

add a network location

After navigating to the “This PC” window you have to right click then click on “Add a network location”.

Click Next

welcome to the add network location wizard

Now that the Add Network Location window is open press the “Next” button.

Set Network Location to Custom

set custom location

Afterwards click on “Choose a custom network location”. Then click “Next” to continue.

Enter Network Address

enter network address

Now you will need to enter the IP address and the name of the share, then press “Next”.

Confirm Credentials

windows credentials dialog

A window will open asking you to enter the shares credentials. Enter the credentials and press “Next” to continue.

Enter a Share Name

enter share location ip

You will then be asked to type a name for the network share. I will be using “My share”. Then you will click on the “Next” button.

Network Location Added

network location added

The Network Location has been successfully added. Click on the “Finish” button to open the share folder.

View in My PC

this pc file explorer

You can find the Network Share you just added by navigating to “This PC” in the left column of File Explorer. You will see the share listed under “Network locations”. You have now completed the tutorial. If you would like to learn how to create a network share continue reading below.

How to Create a Mapped Network Drive in Windows 10

If you want an in depth tutorial on creating mapped network shares in Windows 10 click the link below.

Map a Network Drive in Windows Tutorial

Questions?

If you have any questions or comments feel free to leave them below.

Related Resources

View our How to Create a Deepfake Video Using DeepFaceLab article.

Learn How to Install Ubuntu Server 22.04 [Step by Step].

Click here to learn How to install and configure Nginx – Ubuntu 20.04.

View our Programming Articles and Tutorials.

Learn more cool things in Linux with our Linux Tutorials.

View all of our available online tools and converters at Formatswap.com.