diff --git a/LICENSE b/LICENSE old mode 100644 new mode 100755 diff --git a/README.md b/README.md old mode 100644 new mode 100755 index b1ab62b..2d38a00 --- a/README.md +++ b/README.md @@ -4,15 +4,17 @@ VFIO scripts, notes, and configs for the Lenovo Legion 7 (2021). The `notes` directory mainly contains command outputs and other useful pieces of information such as IOMMU groups on various kernels. +The `resources` directory contains the necessary files for creating the VM. + The `scripts` directory contains: - `iommu.sh` which can be used to see your system's IOMMU groups - `kvm.conf` which contains necessary environment variables -- multiple QEMU hook scripts +- Multiple QEMU hook scripts -The `xml` directory contains the final XML files for two Windows 10 virtual machines. +The `xml` directory contains the final XML files for two Windows 10 virtual machines: -- `Win10-nopass.xml` is a virtual machine without any passthrough -- `Win10.xml` is a virtual machine with GPU, Audio, Network Card, Keyboard, Touchpad, and USB Mouse passthrough +- `win10.xml` is a virtual machine without any passthrough +- `win10-igpu.xml` is a virtual machine with GPU passthrough for when the laptop is in hybrid graphics mode Full guide on how to create a Windows 10 gaming virtual machine available on my [blog](https://blog.karaolidis.com/vfio/). diff --git a/notes/iommu-groups-linux-vfio.txt b/notes/iommu-groups-linux-vfio.txt old mode 100644 new mode 100755 diff --git a/notes/iommu-groups-linux.txt b/notes/iommu-groups-linux.txt old mode 100644 new mode 100755 diff --git a/resources/SSDT1.dat b/resources/SSDT1.dat new file mode 100644 index 0000000..49334e7 Binary files /dev/null and b/resources/SSDT1.dat differ diff --git a/scripts/hooks/kvm.conf b/scripts/hooks/kvm.conf new file mode 100644 index 0000000..96f34c5 --- /dev/null +++ b/scripts/hooks/kvm.conf @@ -0,0 +1,5 @@ +## Virsh devices +VIRSH_GPU_VIDEO=pci_0000_01_00_0 +VIRSH_GPU_AUDIO=pci_0000_01_00_1 +MEMORY=20480 +WIN=/dev/nvme1n1p3 \ No newline at end of file diff --git a/scripts/hooks/win10-igpu/prepare/begin/start.sh b/scripts/hooks/win10-igpu/prepare/begin/start.sh new file mode 100644 index 0000000..4c5073f --- /dev/null +++ b/scripts/hooks/win10-igpu/prepare/begin/start.sh @@ -0,0 +1,65 @@ +#!/bin/bash + +set -x + +# Load Variables +source "/etc/libvirt/hooks/kvm.conf" + +# Unmount the Windows drive +umount $WIN || /bin/true + +# Stop LightDM +systemctl stop lightdm.service +sleep 2 + +# Calculate number of hugepages to allocate from memory (in MB) +HUGEPAGES="$(($MEMORY/$(($(grep Hugepagesize /proc/meminfo | awk '{print $2}')/1024))))" + +echo "Allocating hugepages..." +echo $HUGEPAGES > /proc/sys/vm/nr_hugepages +ALLOC_PAGES=$(cat /proc/sys/vm/nr_hugepages) + +TRIES=0 +while (( $ALLOC_PAGES != $HUGEPAGES && $TRIES < 1000 )) +do + echo 1 > /proc/sys/vm/compact_memory ## defrag ram + echo $HUGEPAGES > /proc/sys/vm/nr_hugepages + ALLOC_PAGES=$(cat /proc/sys/vm/nr_hugepages) + echo "Succesfully allocated $ALLOC_PAGES / $HUGEPAGES" + let TRIES+=1 +done + +if [ "$ALLOC_PAGES" -ne "$HUGEPAGES" ] +then + echo "Not able to allocate all hugepages. Reverting..." + echo 0 > /proc/sys/vm/nr_hugepages + exit 1 +fi + +# Unload all Nvidia drivers +modprobe -r nvidia_drm +modprobe -r nvidia_modeset +modprobe -r nvidia_uvm +modprobe -r nvidia + +# Unbind the GPU from display driver +virsh nodedev-detach $VIRSH_GPU_VIDEO +virsh nodedev-detach $VIRSH_GPU_AUDIO + +# Load VFIO kernel module +modprobe vfio +modprobe vfio_pci +modprobe vfio_iommu_type1 + +# Create looking glass shm +systemd-tmpfiles --create /etc/tmpfiles.d/10-looking-glass.conf + +# Enable CPU governor performance mode +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "performance" > $file; done +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Isolate host +systemctl set-property --runtime -- user.slice AllowedCPUs=12,13,14,15 +systemctl set-property --runtime -- system.slice AllowedCPUs=12,13,14,15 +systemctl set-property --runtime -- init.scope AllowedCPUs=12,13,14,15 diff --git a/scripts/hooks/win10-igpu/release/end/revert.sh b/scripts/hooks/win10-igpu/release/end/revert.sh new file mode 100644 index 0000000..a84bd63 --- /dev/null +++ b/scripts/hooks/win10-igpu/release/end/revert.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +set -x + +# Load Variables +source "/etc/libvirt/hooks/kvm.conf" + +# Unload VFIO kernel module +modprobe -r vfio_pci +modprobe -r vfio_iommu_type1 +modprobe -r vfio + +# Rebind the GPU to display driver +virsh nodedev-reattach $VIRSH_GPU_VIDEO +virsh nodedev-reattach $VIRSH_GPU_AUDIO + +# Read our nvidia configuration when before starting our graphics +nvidia-xconfig --query-gpu-info > /dev/null 2>&1 + +# Load all Nvidia drivers +modprobe nvidia_drm +modprobe nvidia_modeset +modprobe nvidia_uvm +modprobe nvidia + +# Dealloc hugepages +echo 0 > /proc/sys/vm/nr_hugepages + +## Enable CPU governor schedutil mode +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "schedutil" > $file; done +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Deisolate host +systemctl set-property --runtime -- user.slice AllowedCPUs=0-15 +systemctl set-property --runtime -- system.slice AllowedCPUs=0-15 +systemctl set-property --runtime -- init.scope AllowedCPUs=0-15 + +# Delete looking glass shm +rm /dev/shm/looking-glass + +# Mount the Windows drive +mount -a || /bin/true diff --git a/scripts/hooks/win10-igpu/started/begin/lightdm.sh b/scripts/hooks/win10-igpu/started/begin/lightdm.sh new file mode 100644 index 0000000..0fe3fc5 --- /dev/null +++ b/scripts/hooks/win10-igpu/started/begin/lightdm.sh @@ -0,0 +1,17 @@ +#!/bin/bash + +# Uncomment autologin lines in /etc/lightdm/lightdm.conf +sed -i 's/^#autologin-user=/autologin-user=/' /etc/lightdm/lightdm.conf +sed -i 's/^#autologin-user-timeout=/autologin-user-timeout=/' /etc/lightdm/lightdm.conf +sed -i 's/^#autologin-session=/autologin-session=/' /etc/lightdm/lightdm.conf + +# Restart lightdm +systemctl restart lightdm.service + +# Sleep 10 seconds +sleep 10 + +# Comment out autologin lines in /etc/lightdm/lightdm.conf +sed -i 's/^autologin-user=/#autologin-user=/' /etc/lightdm/lightdm.conf +sed -i 's/^autologin-user-timeout=/#autologin-user-timeout=/' /etc/lightdm/lightdm.conf +sed -i 's/^autologin-session=/#autologin-session=/' /etc/lightdm/lightdm.conf diff --git a/scripts/prepare/begin/alloc_hugepages.sh b/scripts/hooks/win10/prepare/begin/start.sh similarity index 56% rename from scripts/prepare/begin/alloc_hugepages.sh rename to scripts/hooks/win10/prepare/begin/start.sh index ca9af58..16f2581 100644 --- a/scripts/prepare/begin/alloc_hugepages.sh +++ b/scripts/hooks/win10/prepare/begin/start.sh @@ -1,9 +1,11 @@ #!/bin/bash -## Load the config file +set -x + +# Load Variables source "/etc/libvirt/hooks/kvm.conf" -## Calculate number of hugepages to allocate from memory (in MB) +# Calculate number of hugepages to allocate from memory (in MB) HUGEPAGES="$(($MEMORY/$(($(grep Hugepagesize /proc/meminfo | awk '{print $2}')/1024))))" echo "Allocating hugepages..." @@ -26,3 +28,13 @@ then echo 0 > /proc/sys/vm/nr_hugepages exit 1 fi + +# Enable CPU governor performance mode +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "performance" > $file; done +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Isolate host +systemctl set-property --runtime -- user.slice AllowedCPUs=14,15 +systemctl set-property --runtime -- system.slice AllowedCPUs=14,15 +systemctl set-property --runtime -- init.scope AllowedCPUs=14,15 diff --git a/scripts/hooks/win10/release/end/revert.sh b/scripts/hooks/win10/release/end/revert.sh new file mode 100644 index 0000000..ff43ace --- /dev/null +++ b/scripts/hooks/win10/release/end/revert.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -x + +# Enable CPU governor schedutil mode +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor +for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "schedutil" > $file; done +cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor + +# Deisolate host +systemctl set-property --runtime -- user.slice AllowedCPUs=0-15 +systemctl set-property --runtime -- system.slice AllowedCPUs=0-15 +systemctl set-property --runtime -- init.scope AllowedCPUs=0-15 + +# Dealloc hugepages +echo 0 > /proc/sys/vm/nr_hugepages diff --git a/scripts/iommu.sh b/scripts/iommu.sh old mode 100644 new mode 100755 diff --git a/scripts/prepare/begin/cpu_mode_performance.sh b/scripts/prepare/begin/cpu_mode_performance.sh deleted file mode 100644 index 7a1c821..0000000 --- a/scripts/prepare/begin/cpu_mode_performance.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -## Enable CPU governor performance mode -cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor -for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "performance" > $file; done -cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor diff --git a/scripts/prepare/begin/start.sh b/scripts/prepare/begin/start.sh deleted file mode 100644 index 0917147..0000000 --- a/scripts/prepare/begin/start.sh +++ /dev/null @@ -1,36 +0,0 @@ -#!/bin/bash - -set -x - -# Load Variables -source "/etc/libvirt/hooks/kvm.conf" - -# Stop LightDM -systemctl stop lightdm.service -sleep 2 - -# Unbind VTconsoles -echo 0 > /sys/class/vtconsole/vtcon0/bind -echo 0 > /sys/class/vtconsole/vtcon1/bind - -# Unbind EFI-Framebuffer -echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind - -# Avoid a race condition by waiting a couple of seconds. This can be calibrated to be shorter or longer if required for your system -sleep 2 - -# Unload all Nvidia drivers -modprobe -r nvidia_drm -modprobe -r nvidia_modeset -modprobe -r drm_kms_helper -modprobe -r nvidia -modprobe -r drm - -# Unbind the GPU from display driver -virsh nodedev-detach $VIRSH_GPU_VIDEO -virsh nodedev-detach $VIRSH_GPU_AUDIO - -# Load VFIO kernel module -modprobe vfio -modprobe vfio_pci -modprobe vfio_iommu_type1 diff --git a/scripts/release/end/cpu_mode_schedutil.sh b/scripts/release/end/cpu_mode_schedutil.sh deleted file mode 100644 index 5e471f0..0000000 --- a/scripts/release/end/cpu_mode_schedutil.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -## Enable CPU governor on-demand mode -cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor -for file in /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor; do echo "schedutil" > $file; done -cat /sys/devices/system/cpu/cpu*/cpufreq/scaling_governor diff --git a/scripts/release/end/dealloc_hugepages.sh b/scripts/release/end/dealloc_hugepages.sh deleted file mode 100644 index 2e35d1c..0000000 --- a/scripts/release/end/dealloc_hugepages.sh +++ /dev/null @@ -1,6 +0,0 @@ -#!/bin/bash - -## Load the config file -source "/etc/libvirt/hooks/kvm.conf" - -echo 0 > /proc/sys/vm/nr_hugepages diff --git a/scripts/release/end/revert.sh b/scripts/release/end/revert.sh deleted file mode 100644 index 3748ec0..0000000 --- a/scripts/release/end/revert.sh +++ /dev/null @@ -1,34 +0,0 @@ -#!/bin/bash -set -x - -# Load the config file with our environmental variables -source "/etc/libvirt/hooks/kvm.conf" - -# Unload VFIO-PCI Kernel Driver -modprobe -r vfio_pci -modprobe -r vfio_iommu_type1 -modprobe -r vfio - -# Re-Bind GPU to our display drivers -virsh nodedev-reattach $VIRSH_GPU_VIDEO -virsh nodedev-reattach $VIRSH_GPU_AUDIO - -# Rebind VT consoles -echo 1 > /sys/class/vtconsole/vtcon0/bind -echo 1 > /sys/class/vtconsole/vtcon1/bind - -# Read our nvidia configuration when before starting our graphics -nvidia-xconfig --query-gpu-info > /dev/null 2>&1 - -# Re-Bind EFI-Framebuffer -echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind - -# Load nvidia drivers -modprobe nvidia_drm -modprobe nvidia_modeset -modprobe drm_kms_helper -modprobe nvidia -modprobe drm - -# Restart Display Manager -systemctl start lightdm.service diff --git a/xml/Win10-nopass.xml b/xml/win10-igpu.xml similarity index 69% rename from xml/Win10-nopass.xml rename to xml/win10-igpu.xml index d50cb67..21af61c 100644 --- a/xml/Win10-nopass.xml +++ b/xml/win10-igpu.xml @@ -1,52 +1,50 @@ - - Win10-nopass - 550b0a1a-a823-467f-9632-a100834cb900 - Windows 10 - No Passthrough + + win10-igpu + fcac9afe-ee92-4803-a744-62b940e23e18 + Windows 10 - Passthrough (Hybrid Mode) - 25165824 - 25165824 + 20971520 + 20971520 12 - 2 - - - - - - - - - - - - - - - + + + + + + + + + + + + - hvm + hvm /usr/share/edk2-ovmf/x64/OVMF_CODE.fd - /var/lib/libvirt/qemu/nvram/Win10-nopass_VARS.fd + /var/lib/libvirt/qemu/nvram/win10-igpu_VARS.fd + + - + @@ -54,13 +52,13 @@ or other application using the libvirt API. + - @@ -82,26 +80,22 @@ or other application using the libvirt API. /usr/bin/qemu-system-x86_64 - - - + + + -
- - + + -
+
- -
- @@ -140,63 +134,56 @@ or other application using the libvirt API. - -
+ +
- -
+ +
- -
+ +
- -
+ +
- -
+ +
- -
+ +
- -
+ +
- -
+ +
- - - -
- - - - -
- - + -
+
+ + +
- +
@@ -206,36 +193,54 @@ or other application using the libvirt API.
-
+
-
+
- + + +