How to Run (Not Only) Windows Virtual Machine on Linux

I guess you are running Linux on your physical computer. Have you ever needed to run some Windows-only software on your Linux machine? While there are some solutions like Wine, the most reliable way to run Windows programs is by running them on Windows itself. You don't want to install Windows on your computer, you say? You can install it in a virtual machine! Installation media for Windows 10 can be downloaded free of charge from the Microsoft website, and it even works without having a license (with some limitations, like an inability to change a wallpaper).

This method mentioned in this howto also works for installing other operating systems. In the case of Linux guests, it is even easier because Linux distros often already include virtio and QXL drivers, and there is no need to install any additional drivers.

Created
October 16, 2019
Updated
March 30, 2020

Virtualization Software on Linux

To be able to create virtual machines, software called hypervisor needs to be installed on the host machine. A host machine is the (usually physical) machine that runs the virtual machines. Virtual machines are then called guests.

Type-1 hypervisors run on bare metal. One of the examples is Hyper-V, which is available on non-home Windows versions. Installing Hyper-V turns the original Windows operating system itself into a virtual machine. Because of this, Hyper-V virtual machines do not show up in the Task Manager. An example of a Type-1 hypervisor on Linux is Xen.

Type-2 hypervisors run virtual machines as processes within the host operating system. Some examples are QEMU/KVM, VirtualBox, VMware Workstation.

These are some of the popular hypervisors (or virtual machine managers) that run on Linux and are free to use:

GNOME Boxes

This app often comes pre-installed with the GNOME desktop. It is installed by default on Fedora Workstation. The user interface is very simple and does not offer many advanced settings. It uses the QEMU/KVM hypervisor in the background. Because of this, advanced settings of virtual machines can be specified using some other software tools, such as virsh.

I use GNOME Boxes for quick testing of various operating systems.

Virtual Machine Manager (virt-manager)

This is a graphical user interface for various Linux virtualization hypervisors, including QEMU/KVM. It is usually included in repositories of the Linux distribution and is easy to install and get running.

Virtual Machine Manager with KVM is my go-to solution for running virtual machines on Linux. With virtio graphical driver, it supports 3D acceleration on Linux guests (but not on Windows guests).

VirtualBox

VirtualBox is a free and open-source hypervisor. It is cross-platform, meaning that it can be installed on various operating systems, including Linux, Windows, macOS, and Solaris. It may not be available in the Linux distro's repositories, but it can be installed from the official 3rd party repositories. However, it may cause problems with UEFI Secure Boot (if it is enabled on the host machine) because of unsigned kernel modules.

VirtualBox can be useful for creating portable virtual machines that can be run on various operating systems. Its performance can be a bit slower compared to other hypervisors.

VMware Workstation Player

This is a free version of VMware Workstation Pro. It is free for personal use only and comes with some limitations to the Pro version. It can be installed on Linux and Windows.

I don't have much experience with VMware Player. However, I've read that it (reliably) supports graphical 3D acceleration on Windows guests and that its virtual machines perform very well.

Install Virtual Machine Manager (virt-manager)

I use Virtual Machine Manager with QEMU/KVM hypervisor. On Fedora, it comes as a part of the Virtualization group. This group can be installed using the following command.

sudo dnf install @virtualization

On other Linux distributions, search for some official documentation regarding virtualization or just try searching for virt-manager package in the repositories.

Once the Virtual Machine Manager is installed, it should be accessible from the application menu:

A screenshot of an icon of Virtual Machine Manager in an app overview on GNOME desktop

It will need an administrator's password to be able to manage virtual machines. This should be possible to change by adding the user to some specific group and/or by settings some additional permissions. Writing my password doesn't bother me, so I never had a reason to investigate this more.

A screenshot of a GNOME polkit pasword prompt

Next, a window like the following should appear. It contains an overview of existing virtual machines on the system. The list will be empty if there are no virtual machines created.

A screenshot of the main Virtual Machine Manager window

Create a Virtual Machine and Install Guest Operating System

This is only a brief overview of the steps I do when creating a virtual machine in Virtual Machine Manager (virt-manager). A step-by-step guide showing how to accomplish these steps follows by clicking the button below.

View a step-by-step guide

Create a Virtual Machine

Before creating a virtual machine, decide whether to use a user or global session for QEMU/KVM. User session does not require administrator privileges but may not offer all features like some hardware passthrough or advanced networking.

Things I do when creating a virtual machine (not all are necessary):

  1. Use qcow2 disk format for snapshot ability or raw disk format for better performance.
  2. Set the Chipset to Q35 (it is selected by default on recent virt-manager versions).
  3. Change Firmware from BIOS to UEFI (OVMF_CODE.fd) or UEFI with Secure Boot (OVMF_CODE.secboot.fd).
  4. Add a Virtio SCSI controller which supports discard/TRIM:
    • Type: SCSI
    • Model: VirtIO SCSI
  5. Attach the hard drive to this controller. In the disk options, select SCSI and enable TRIM:
    • Disk bus: SCSI
    • Discard mode: unmap
  6. Maybe change CPU topology to one socket with multiple cores. It is also possible to specify the CPU architecture.

My trust in qcow2 format, and QEMU in general, has been negatively impacted by this bug which caused a corruption of data stored on qcow2 virtual disks: https://bugzilla.redhat.com/show_bug.cgi?id=1763519. The issue was quickly resolved and does not occur anymore.

Install

Once the virtual machine is created, a guest os (Windows in this case) can be installed. The steps are the same as if the installation was done on a physical computer.

Install Windows Guest Drivers

Windows does not always include all drivers by default. Most notably, it does not include a QXL driver for the virtual graphics card and a virtio SCSI driver for accessing virtio SCSI hard drives.

If OVMF_CODE.secboot.fd firmware is used by the virtual machine and Secure Boot is enabled, all drivers need to be signed by Microsoft (WHQL). Note that drivers provided by Fedora are not Microsoft-signed. As of March 28, 2020, they are signed only by Red Hat. The use of Fedora-provided virtio drivers for important system components, such as virtio-scsi driver, may prevent the virtual machine from booting, resulting in a BSOD or entering a Repair Mode instead. This can be solved either by disabling Secure Boot in the UEFI of the virtual machine or by using WHQL drivers provided by Red Hat with the RHEL.

As of March 28, 2020:

Drivers can be obtained from various sources:

  1. VirtIO drivers (not WHQL!!!) from a Fedora repository (recommended on linux-kvm.org),
  2. VirtIO drivers provided by virtio-win package in RHEL or CentOS (CentOS 8 repository),
  3. VirtIO drivers installed by Spice Windows Guest Tools (spice-guest-tools-latest.exe from https://www.spice-space.org/download.html).

Troubleshooting

These are some of the things I came across when using virtual machines in virt-manager.

Virtual Machine Crashes When a Debugging Software is Run on The Guest

Symptom: When I run OllyDbg version 2.01 debugger on a Windows virtual machine, the guest Windows freezes, shows a Blue Screen Of Death and reboots.

Solution: As per this Microsoft Answers thread, this is caused because the debugging software accesses some Model Specific Registers (MSR) that cannot be virtualized. QEMU hypervisor does not try to emulate these registers.

Accessing these registers can be ignored by running the following script (info about this feature).

#!/bin/bash
echo '(Must be run as root)'
# Debuggers in Windows can result in BSOD under KVM, this is the solution
echo 1 > /sys/module/kvm/parameters/ignore_msrs && \
echo Success.

Note that these registers can be accessed by other software than debuggers, including games. It may be possible to mitigate this problem by changing the virtual CPU architecture to Core 2 Duo. In this case, the app should fall back to not using these MSRs.

Host Operating System Uses Swap Space When RAM Is Not Full Yet

Symptom: There is still some free space in the RAM on the host, but it starts swapping to hard drive anyway.

Solution: Decrease swappiness value (but do not disable swap altogether):

sudo sysctl -w vm.swappiness=1

Virt-manager does not offer an unmap discard option

Solution: just change it manually using virsh:

sudo virsh edit virtual-debian

Change this line, add discard='unmap':

<driver name='qemu' type='qcow2' discard='unmap'/>