├── LICENSE
├── README-cn.md
├── README.md
├── VFIO
├── Configure Libvirt cn.md
├── Configure Libvirt.md
├── Debugging and other features.md
├── Libvirt Hooks cn.md
├── Libvirt Hooks.md
├── Setting up Passthrough cn.md
├── Setting up Passthrough.md
├── Setting up a basic KVM cn.md
├── Setting up a basic KVM.md
└── libvirt_hooks_nvidia-cn.md
├── libvirt-hooks
├── qemu
├── vfio-startup.sh
└── vfio-teardown.sh
├── libvirt-nvidia-hooks
├── qemu
├── vfio-startup.sh
└── vfio-teardown.sh
└── resources
├── iommuamd.sh
└── wechatpay.jpg
/LICENSE:
--------------------------------------------------------------------------------
1 | Copyright (C) 2021 liucreator.
2 | Permission is granted to copy, distribute and/or modify this document
3 | under the terms of the GNU Free Documentation License, Version 1.3
4 | or any later version published by the Free Software Foundation;
5 | with no Invariant Sections, no Front-Cover Texts, and no Back-Cover Texts.
6 | A copy of the license is included in the section entitled "GNU
7 | Free Documentation License".
--------------------------------------------------------------------------------
/README-cn.md:
--------------------------------------------------------------------------------
1 | # ledis的单显卡直通教程
2 | [英文版本](README.md)
3 |
4 | 这是我的单显卡直通配置过程;我在多个不同配置的电脑上都试过,这个方法都成功了。
5 | 如果有问题可以去B站上找我, 视频教程链接:*还没做完*https://space.bilibili.com/589560036
6 |
7 | - [](https://space.bilibili.com/589560036/channel/seriesdetail?sid=2031728)
8 | - [](https://www.youtube.com/channel/UCKXFTVfYRA8Ho71bAT5tfVA?sub_confirmation=1)
9 |
10 |
11 | 我这里讲的是AMD处理器(英特尔的也差不多,个别参数会不一样); 系统是Arch, 如果是其它发行版一些软件名和文件位置可能会不太一样。
12 |
13 | ---
14 | 更新日期:2021年12月26日
15 | 添加了更适合英伟达显卡直通的脚本
16 | ---
17 |
18 | **我的电脑配置**
19 | - 处理器: AMD 锐龙 3900x 12核
20 | - 显卡: 微星 Radeon RX 560 4GT LP 超频
21 | - 主版:玩家国度 ROG Strix B550-A GAMING 吹雪
22 | - 内存: 32GB 3200Mhz 双通道
23 | - 系统: Arch Linux 5.11
24 | - 桌面环境: KDE Plasma 5.21 X11
25 |
26 | * * *
27 | **步骤**
28 | 1. [配置一个简单的KVM(非直通)](VFIO/Setting%20up%20a%20basic%20KVM%20cn.md)
29 | 2. [Libvirt 钩子](VFIO/Libvirt%20Hooks%20cn.md)
30 | 3. [QEMU和Libvirt的配置](VFIO/Configure%20Libvirt%20cn.md)
31 | 4. [显卡直通](VFIO/Setting%20up%20Passthrough%20cn.md)
32 | 5. [some other things](VFIO/Debugging%20and%20other%20features.md)
33 |
34 | ---
35 |
36 | 还在编辑中,请考虑帮我更新添加更多内容!
37 |
38 | 本人是一名半工半读的学生,如果你觉得我的视频和这些教程有用,请支持我!
39 |
40 | 可以通过Paypal捐赠:
41 |
42 | [](https://www.paypal.com/donate/?hosted_button_id=HVU7NRQMZGMNN)
43 |
44 | 或者可以选择在在微信上给我打赏(标注VFIO),非常感谢!
45 |
46 | 
47 |
48 | ---
49 |
50 | **其它资源**
51 | - Arch Wiki [PCI passthrough](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF)
52 | - GitLab [RisingPrismTV's script](https://gitlab.com/risingprismtv/single-gpu-passthrough)
53 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Single GPU Passthrough on Ryzen CPU
2 |
3 | https://liucreator.gitlab.io/zh/posts/0x0b-single-gpu-passthrough/main/
4 |
5 | [中文版本](README-cn.md)
6 | These are my steps to set up QEMU/KVM with GPU passthrough as of 2021 March,
7 | it works for me as I tried many times on different systems.
8 |
9 | You might need to change a few things, and feel free to ask me if you have any questions!
10 |
11 | My current setup is on Ryzen CPU with Radeon GPU, and sorry my English is not the best.
12 |
13 | - [](https://space.bilibili.com/589560036/channel/seriesdetail?sid=2031728)
14 | - [](https://www.youtube.com/channel/UCKXFTVfYRA8Ho71bAT5tfVA?sub_confirmation=1)
15 |
16 | **My Specs:**
17 | - CPU: AMD Ryzen 3900x 12 cores
18 | - GPU: MSI Radeon RX 560 4GT LP OC
19 | - RAM: 32GB 3200Mhz dual channels
20 | - OS: Arch Linux 5.11
21 | - DE: KDE Plasma 5.21
22 |
23 |
24 | * * *
25 | **Procedure:**
26 | 1. [Setting up an basic KVM on linux without VFIO](/VFIO/Setting%20up%20a%20basic%20KVM.md)
27 | 2. [Libvirt Hooks and Scripts](/VFIO/Libvirt%20Hooks.md)
28 | 3. [QEMU+Libvirt Configuration](/VFIO/Configure%20Libvirt.md)
29 | 4. [GPU passthrough](/VFIO/Setting%20up%20Passthrough.md)
30 | 5. [some other things](/VFIO/Debugging%20and%20other%20features.md)
31 |
32 | * * *
33 |
34 | ---
35 |
36 | Please considering of supporting me if you find my guides or videos helpful!
37 |
38 | [](https://www.paypal.com/donate/?hosted_button_id=A47HPSXTPD5HE)
39 |
40 | ---
41 |
42 | **Credits:**
43 | - Arch Wiki [PCI passthrough](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF)
44 | - GitLab [RisingPrismTV's script](https://gitlab.com/risingprismtv/single-gpu-passthrough)
45 | - SubReddit [r/VFIO](https://www.reddit.com/r/VFIO/)
46 |
--------------------------------------------------------------------------------
/VFIO/Configure Libvirt cn.md:
--------------------------------------------------------------------------------
1 | # 配置Libvirt
2 |
3 | **编辑libvirt.conf**
4 | `sudo nano /etc/libvirt/libvirtd.conf`
5 |
6 | 找到这两行,把前面的`#`删掉:
7 | ```
8 | unix_sock_group = "libvirt"
9 | unix_sock_rw_perms = "0770"
10 | ```
11 | 可以选择把这两行添加到文件的最后面(日志文件):
12 | ```
13 | log_filters="1:qemu"
14 | log_outputs="1:file:/var/log/libvirt/libvirtd.log"
15 | ```
16 | * * *
17 | **编辑qemu.conf**
18 | `sudo nano /etc/libvirt/qemu.conf`
19 |
20 | 把 `#user = "root"` 改成 `user = "yourusername"`,
21 | `#group = "root"` 改成 `group = "libvirt"`
22 |
23 | 把自己添加到libvirt组里面:
24 | `sudo usermod -a -G libvirt 用户名`
25 | * * *
26 |
27 | **重启电脑或者重启libvirt**
28 | ```
29 | sudo systemctl restart libvirtd.service
30 | sudo systemctl restart virtlogd.socket
31 | ```
32 |
33 | [教程主页](../README-cn.md)
--------------------------------------------------------------------------------
/VFIO/Configure Libvirt.md:
--------------------------------------------------------------------------------
1 | # Configuring Libvirt
2 |
3 | edit libvirt.conf:
4 | `sudo nano /etc/libvirt/libvirtd.conf`
5 |
6 | uncomment these two lines by removing the `#` in front of them:
7 | ```
8 | unix_sock_group = "libvirt"
9 | unix_sock_rw_perms = "0770"
10 | ```
11 |
12 | add these two lines to the end of the file for logs:
13 | ```
14 | log_filters="1:qemu"
15 | log_outputs="1:file:/var/log/libvirt/libvirtd.log"
16 | ```
17 | * * *
18 | edit qemu.conf:
19 |
20 | change `#user = "root"` to `user = "yourusername"`
21 | change `#group = "root"` to `group = "libvirt"`
22 |
23 | add yourself to the libvirt group:
24 | `sudo usermod -a -G libvirt yourusername`
25 | * * *
26 |
27 | **Restart computer or restart libvirt:**
28 | ```
29 | sudo systemctl restart libvirtd.service
30 | sudo systemctl restart virtlogd.socket
31 | ```
32 |
--------------------------------------------------------------------------------
/VFIO/Debugging and other features.md:
--------------------------------------------------------------------------------
1 | **You can find Logs at:**
2 | **win10.log** in /var/log/libvirt/qemu
3 | **custom_hooks.log** in/var/log/libvirt
4 | **libvirtd.log** in /var/log/libvirt/
5 | also check `journalctl` and `dmesg` if necessary
6 |
7 | * * *
8 | **to do:**
9 | - [ ] CPU performance tweak
10 | - [ ] virtio drivers
11 | - [ ] sound passsthrough
12 | - [ ] physical drive passthrough
13 | - [ ] game controller passthrough
14 | - [ ] nested VM in guest
15 |
16 | * * *
17 | **Bugs and fixes**
18 | you can sent me any issues you have, if we have a solution I can post them here.
19 |
20 |
21 | - [ ]
--------------------------------------------------------------------------------
/VFIO/Libvirt Hooks cn.md:
--------------------------------------------------------------------------------
1 | # 配置Libvirt脚本
2 | [英伟达显卡请看这里](libvirt_hooks_nvidia-cn.md)
3 |
4 | 在Libirt里面创建一个hooks文件夹
5 | `sudo mkdir /etc/libvirt/hooks`
6 |
7 | 把[这里](../libvirt-hooks)的三个文件放到hooks文件夹里面
8 |
9 | 都变成可执行的文件
10 | `sudo chmod +x /etc/libvirt/hooks/*`
11 |
12 | 把两个脚本软链接到根目录的bin文件夹
13 | ```
14 | sudo ln -s /etc/libvirt/hooks/vfio-startup.sh /bin/vfio-startup.sh
15 | sudo ln -s /etc/libvirt/hooks/vfio-teardown.sh /bin/vfio-teardown.sh
16 | ```
17 |
18 | * * *
19 | **防止Libvirt在运行时休眠**
20 | `sudo nano /etc/systemd/system/libvirt-nosleep@.service`
21 |
22 | 在libvirt-nosleep@.service里面添加:
23 | ```
24 | [Unit]
25 | Description=Preventing sleep while libvirt domain "%i" is running
26 |
27 | [Service]
28 | Type=simple
29 | ExecStart=/usr/bin/systemd-inhibit --what=sleep --why="Libvirt domain \"%i\" is running" --who=%U --mode=block sleep infinity
30 | ```
31 | 更改权限:
32 | `sudo chmod 644 -R /etc/systemd/system/libvirt-nosleep@.service`
33 |
34 | 变成系统文件
35 | `sudo chown root:root /etc/systemd/system/libvirt-nosleep@.service`
36 |
37 | [教程主页](../README-cn.md)
--------------------------------------------------------------------------------
/VFIO/Libvirt Hooks.md:
--------------------------------------------------------------------------------
1 | # Setup libvirt hooks
2 | ```
3 | sudo mkdir /etc/libvirt/hooks
4 | sudo nano /etc/libvirt/hooks/qemu
5 | ```
6 |
7 | in qemu:
8 | ```
9 | #!/bin/bash
10 |
11 | OBJECT="$1"
12 | OPERATION="$2"
13 |
14 | if [[ $OBJECT == "win10" ]]; then
15 | case "$OPERATION" in
16 | "prepare")
17 | systemctl start libvirt-nosleep@"$OBJECT" 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
18 | /bin/vfio-startup.sh 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
19 | ;;
20 |
21 | "release")
22 | systemctl stop libvirt-nosleep@"$OBJECT" 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
23 | /bin/vfio-teardown.sh 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
24 | ;;
25 | esac
26 | fi
27 | ```
28 | then make it executable:
29 | `sudo chmod +x /etc/libvirt/hooks/qemu`
30 |
31 | * * *
32 | **edit start up script:**
33 | `sudo nano /etc/libvirt/hooks/vfio-startup.sh`
34 |
35 | in vfio-startup.sh:
36 | ```
37 | #!/bin/bash
38 | # Helpful to read output when debugging
39 | set -x
40 |
41 | long_delay=10
42 | medium_delay=5
43 | short_delay=1
44 | echo "Beginning of startup!"
45 |
46 | function stop_display_manager_if_running {
47 | # Stop dm using systemd
48 | if command -v systemctl; then
49 | if systemctl is-active --quiet "$1.service" ; then
50 | echo $1 >> /tmp/vfio-store-display-manager
51 | systemctl stop "$1.service"
52 | fi
53 |
54 | while systemctl is-active --quiet "$1.service" ; do
55 | sleep "${medium_delay}"
56 | done
57 |
58 | return
59 | fi
60 |
61 | # Stop dm using runit
62 | if command -v sv; then
63 | if sv status $1 ; then
64 | echo $1 >> /tmp/vfio-store-display-manager
65 | sv stop $1
66 | fi
67 | fi
68 | }
69 |
70 |
71 | # Stop currently running display manager
72 | if test -e "/tmp/vfio-store-display-manager" ; then
73 | rm -f /tmp/vfio-store-display-manager
74 | fi
75 |
76 | stop_display_manager_if_running sddm
77 | stop_display_manager_if_running gdm
78 | stop_display_manager_if_running lightdm
79 | stop_display_manager_if_running lxdm
80 | stop_display_manager_if_running xdm
81 | stop_display_manager_if_running mdm
82 | stop_display_manager_if_running display-manager
83 |
84 | sleep "${medium_delay}"
85 |
86 | # Unbind VTconsoles if currently bound (adapted from https://www.kernel.org/doc/Documentation/fb/fbcon.txt)
87 | if test -e "/tmp/vfio-bound-consoles" ; then
88 | rm -f /tmp/vfio-bound-consoles
89 | fi
90 | for (( i = 0; i < 16; i++))
91 | do
92 | if test -x /sys/class/vtconsole/vtcon${i}; then
93 | if [ `cat /sys/class/vtconsole/vtcon${i}/name | grep -c "frame buffer"` \
94 | = 1 ]; then
95 | echo 0 > /sys/class/vtconsole/vtcon${i}/bind
96 | echo "Unbinding console ${i}"
97 | echo $i >> /tmp/vfio-bound-consoles
98 | fi
99 | fi
100 | done
101 |
102 | # Unbind EFI-Framebuffer
103 | if test -e "/tmp/vfio-is-nvidia" ; then
104 | rm -f /tmp/vfio-is-nvidia
105 | fi
106 |
107 | if lsmod | grep "nvidia" &> /dev/null ; then
108 | echo "true" >> /tmp/vfio-is-nvidia
109 | echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind
110 | fi
111 |
112 | echo "End of startup!"
113 | ```
114 | make it executable:
115 | ```sudo chmod +x /etc/libvirt/hooks/vfio-startup.sh```
116 |
117 | soft link it to /bin:
118 | `sudo ln -s /etc/libvirt/hooks/vfio-startup.sh /bin/vfio-startup.sh`
119 |
120 | * * *
121 | **edit tear down script:**
122 | `sudo nano /etc/libvirt/hooks/vfio-teardown.sh`
123 |
124 | in vfio-teardown.sh:
125 | ```
126 | #!/bin/bash
127 | set -x
128 |
129 | echo "Beginning of teardown!"
130 |
131 | sleep 10
132 |
133 | # Restart Display Manager
134 | input="/tmp/vfio-store-display-manager"
135 | while read displayManager; do
136 | if command -v systemctl; then
137 | systemctl start "$displayManager.service"
138 | else
139 | if command -v sv; then
140 | sv start $displayManager
141 | fi
142 | fi
143 | done < "$input"
144 |
145 | # Rebind VT consoles (adapted from https://www.kernel.org/doc/Documentation/fb/fbcon.txt)
146 | input="/tmp/vfio-bound-consoles"
147 | while read consoleNumber; do
148 | if test -x /sys/class/vtconsole/vtcon${consoleNumber}; then
149 | if [ `cat /sys/class/vtconsole/vtcon${consoleNumber}/name | grep -c "frame buffer"` \
150 | = 1 ]; then
151 | echo "Rebinding console ${consoleNumber}"
152 | echo 1 > /sys/class/vtconsole/vtcon${consoleNumber}/bind
153 | fi
154 | fi
155 | done < "$input"
156 |
157 | # Rebind framebuffer for nvidia
158 | if test -e "/tmp/vfio-is-nvidia" ; then
159 | echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind
160 | fi
161 |
162 | echo "End of teardown!"
163 | ```
164 | make it executable:
165 | `sudo chmod +x /etc/libvirt/hooks/vfio-teardown.sh`
166 |
167 | soft link it to /bin:
168 | `sudo ln -s /etc/libvirt/hooks/vfio-teardown.sh /bin/vfio-teardown.sh`
169 |
170 | * * *
171 | **edit libvirt no sleep service**
172 | `sudo nano /etc/systemd/system/libvirt-nosleep@.service`
173 |
174 | in libvirt-nosleep@.service:
175 | ```
176 | [Unit]
177 | Description=Preventing sleep while libvirt domain "%i" is running
178 |
179 | [Service]
180 | Type=simple
181 | ExecStart=/usr/bin/systemd-inhibit --what=sleep --why="Libvirt domain \"%i\" is running" --who=%U --mode=block sleep infinity
182 | ```
183 | change permission:
184 | `sudo chmod 644 -R /etc/systemd/system/libvirt-nosleep@.service`
185 |
186 | change ownership:
187 | `sudo chown root:root /etc/systemd/system/libvirt-nosleep@.service`
188 |
--------------------------------------------------------------------------------
/VFIO/Setting up Passthrough cn.md:
--------------------------------------------------------------------------------
1 | # 直通显卡
2 |
3 | **导出你的显卡的VGA BIOS**
4 | - 最简单的办法: 如果电脑是Windows双系统,可以用[GPU-Z](https://www.techpowerup.com/gpuz/)
5 | - 去[Tech Power Up](https://www.techpowerup.com/vgabios/)下载一个
6 | - 在Linux上使用[NVIDIA](https://www.techpowerup.com/download/nvidia-nvflash/) or [AMD](https://www.techpowerup.com/download/ati-atiflash/)
7 | - 其它命令行方法[Arch Wiki](https://wiki.archlinux.org/index.php/PCI_passthrough_via_OVMF#UEFI_(OVMF)_compatibility_in_VBIOS)
8 |
9 | **VBIOS补丁- 只有英伟达显卡需要**
10 | 1. 用十六进制编辑器打开导出的rom(我个人喜欢Bless)
11 | 2. 查找字符"VIDEO"
12 | 把`VIDEO`前面第一个大写`U.`(十六进制是55)之前的所有的headers都删掉.
13 | 4. 保存到某个地方
14 | *我在Arch上保存到个人主目录文件夹是没问题的*
15 | Arch、Fedora可以保存到`/var/lib/libvirt/vbios`里面,
16 | Ubuntu/OpenSUSE/Mint(用AppArmour的发行版)可以保存到`/usr/share/vgabios`里面。
17 | 5. 修改权限:
18 | `sudo chmod -R 660 vbios文件.rom`
19 | 6. 更改拥有者
20 | `sudo chown 你的用户名:users vbios文件.rom`
21 |
22 | * * *
23 |
24 | **配置qemu虚拟机**
25 | 1. 打开虚拟机管理器,把显卡的所有pci部分都添加到虚拟机里面。
26 | 2. 启用XML编辑, 在显卡的所有pci设备里面, 在``之后添加:
27 | ``
28 | 3. 把信道,usb转接,显卡qxl,触摸板那些东西删掉
29 | 4. 添加你的USB设备,比如鼠标、键盘和USB耳机。
30 |
31 | **绕过英伟达Geforce显卡防虚拟化检测(恶名昭著的错误43)**
32 | *2021四月之后好像不需要了*
33 | 编辑XML:
34 | - 在``之前添加(value应该等于8-12个字母):
35 | ``
36 | AMD显卡可以用"`AuthenticAMD`"作为id但不需要,因为AMD不会拦着你显卡虚拟化。
37 |
38 | - 在`` 和 `` 之间添加:
39 | ```
40 |
41 |
42 |
43 | ```
44 | 那么现在试试你的虚拟机吧!第一次开机可能会有点慢,因为要装显卡驱动,不过等等就可以了。
45 |
46 | [教程主页](../README-cn.md)
--------------------------------------------------------------------------------
/VFIO/Setting up Passthrough.md:
--------------------------------------------------------------------------------
1 | # Setting up passthrough
2 |
3 | **dump GPU VBIOS:**
4 | - easiest way: use GPU-Z on a temporary windows 10
5 | - or download it from [tech power up vga bios collection](https://www.techpowerup.com/vgabios/)
6 | - dump in linux using [NVIDIA](https://www.techpowerup.com/download/nvidia-nvflash/) or [AMD](https://www.techpowerup.com/download/ati-atiflash/)
7 | - or by command line
8 |
9 | **patch VBIOS - NVIDIA only**
10 | 1. open the rom with a hex editor (I use Okteta or Bless)
11 | 2. look for CHAR "video"
12 | Remove everything before `U.`(55 in hex).
13 | 4. save it somewhere
14 | *home directory works for Arch Linux*
15 | Arch/Fedora: `sudo mkdir /var/lib/libvirt/vbios`
16 | Ubuntu/OpenSUSE/Mint(Distros with AppArmour): `sudo mkdir /usr/share/vgabios`
17 |
18 | 5. add read and execute permission
19 | `sudo chmod -R 660 patched.rom`
20 | 6. own it
21 | `sudo chown yourusername:users patched.rom`
22 |
23 | **configure VM**
24 | 1. go to virt-manager and add all pcie part of the graphic card to vm
25 | 2. enable XML editing, in pci device, after `` add:
26 | ``
27 | 3. remove things like channel spice, tablet, usb redirection, video QXL etc.
28 | 4. add usb devices like mouse, keyboard, usb headsets
29 |
30 | **Bypass Nvidia VM detection(not required anymore as of April 2021?)**
31 | Edit XML:
32 | - add the following before ``, value should be 8 to 12 characters:
33 | ``
34 | AMD gpu can use id "`AuthenticAMD`".
35 |
36 | - inside of `` and `` add:
37 | ```
38 |
39 |
40 |
41 | ```
42 |
--------------------------------------------------------------------------------
/VFIO/Setting up a basic KVM cn.md:
--------------------------------------------------------------------------------
1 | # 配置一个简单的KVM
2 |
3 | **启用IOMMU**
4 | 比如Systemd启动器:
5 | `nano /boot/loader/entries/arch.conf`
6 | 把 `amd_iommu=on iommu=pt` 添加到options后面
7 | 保存,重启系统
8 |
9 | **检查IOMMU是否已启用**
10 | `sudo dmesg | grep -e DMAR -e IOMMU`
11 | 找找有没有amd_IOMMU:Detected"
12 |
13 | **检查IOMMU组是否有效**
14 | [iommuamd.sh](../resources/iommuamd.sh)
15 | 运行这个脚本,看看显卡是不是在自己的一个组里面。
16 | ```
17 | IOMMU group 16
18 | 0a:00.0 VGA compatible controller \[0300\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin \[Radeon RX 550 640SP / RX 560/560X\] \[1002:67ff\] (rev cf)
19 | Driver: amdgpu
20 | 0a:00.1 Audio device \[0403\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin HDMI/DP Audio \[Radeon RX 550 640SP / RX 560/560X\] \[1002:aae0\]
21 | Driver: snd\_hda\_intel
22 |
23 | ```
24 | 复制一下,先保存下来。
25 |
26 | **添加VFIO到内核模块**
27 | `sudo nano /etc/modprobe.d/vfio.conf`
28 | 在vfio.conf里面添加
29 | ```
30 | options vfio-pci ids=1002:67ff,1002:aae0
31 | options vfio-pci disable_idle_d3=1
32 | options vfio-pci disable_vga=1
33 | ```
34 | *ids=后面应该是刚才查看的显卡的那些id,每个值之间用`,`隔开*
35 |
36 |
37 | **安装需要的软件
38 | `sudo pacman -S qemu libvirt edk2-ovmf virt-manager dnsmasq ebtables iptables bridge-utils`
39 |
40 | **开机启用服务**
41 | ```
42 | sudo systemctl enable libvirtd
43 | sudo systemctl enable virtlogd.socket
44 | ```
45 |
46 | **开始Libvirt**
47 | ```
48 | "sudo systemctl start libvirtd"
49 | `sudo systemctl start virtlogd.socket
50 | ```
51 |
52 | **启用虚拟网络**
53 | ```
54 | sudo virsh net-start default
55 | sudo virsh net-autostart default
56 | ```
57 |
58 | **先打开Virt-Manager安装一个没有直通的虚拟机,然后去下一步**
59 |
60 | [教程主页](../README-cn.md)
--------------------------------------------------------------------------------
/VFIO/Setting up a basic KVM.md:
--------------------------------------------------------------------------------
1 | # Setting up a Basic KVM
2 |
3 | **Enable IOMMU in Bootloader**
4 | `nano /boot/loader/entries/arch.conf`
5 | add `amd_iommu=on iommu=pt` to the end of the options
6 | Save and Reboot
7 |
8 | **check IOMMU**
9 | `sudo dmesg | grep -e DMAR -e IOMMU`
10 | look for amd_IOMMU:Detected"
11 |
12 | **check PCI iommu groups**
13 | [iommuamd.sh](../_resources/5276daf6236346479e15f96ce0afe812.sh)
14 | run this script, look for your GPU, make sure they are in their own group
15 | ```
16 | IOMMU group 16
17 | 0a:00.0 VGA compatible controller \[0300\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin \[Radeon RX 550 640SP / RX 560/560X\] \[1002:67ff\] (rev cf)
18 | Driver: amdgpu
19 | 0a:00.1 Audio device \[0403\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin HDMI/DP Audio \[Radeon RX 550 640SP / RX 560/560X\] \[1002:aae0\]
20 | Driver: snd\_hda\_intel
21 |
22 | ```
23 | copy it and save it somewhere.
24 |
25 | **add modprobe module:**
26 | `sudo nano /etc/modprobe.d/vfio.conf`
27 | in vfio.conf add:
28 | ```
29 | options vfio-pci ids=1002:67ff,1002:aae0
30 | options vfio-pci disable_idle_d3=1
31 | options vfio-pci disable_vga=1
32 | ```
33 | *ids should be your pci parts ids with `,` in between*
34 |
35 |
36 | **Install required packages**
37 | `sudo pacman -S qemu libvirt edk2-ovmf virt-manager dnsmasq ebtables iptables bridge-utils`
38 |
39 | **Enable them in init system**
40 | ```
41 | sudo systemctl enable libvirtd
42 | sudo systemctl enable virtlogd.socket
43 | ```
44 |
45 | **Start services**
46 | ```
47 | "sudo systemctl start libvirtd"
48 | `sudo systemctl start virtlogd.socket
49 | ```
50 |
51 | **enable virtual network**
52 | ```
53 | sudo virsh net-start default
54 | sudo virsh net-autostart default
55 | ```
56 |
57 | **open virt-manager and setting up an basic virtual machine without passthrough**
58 |
--------------------------------------------------------------------------------
/VFIO/libvirt_hooks_nvidia-cn.md:
--------------------------------------------------------------------------------
1 | # 配置Libvirt脚本(针对宿主机在使用闭源驱动的英伟达显卡)
2 | [AMD显卡请看这里](Libvirt%20Hooks%20cn.md)
3 |
4 | 在Libirt里面创建一个hooks文件夹
5 | `sudo mkdir /etc/libvirt/hooks`
6 |
7 | 把[这里](../libvirt-nvidia-hooks)的三个文件放到hooks文件夹里面
8 |
9 | 记得之前保存的这个吗?(我这拿AMD显卡举例子)
10 | ```
11 | IOMMU group 16
12 | 0a:00.0 VGA compatible controller \[0300\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin \[Radeon RX 550 640SP / RX 560/560X\] \[1002:67ff\] (rev cf)
13 | Driver: amdgpu
14 | 0a:00.1 Audio device \[0403\]: Advanced Micro Devices, Inc. \[AMD/ATI\] Baffin HDMI/DP Audio \[Radeon RX 550 640SP / RX 560/560X\] \[1002:aae0\]
15 | Driver: snd\_hda\_intel
16 |
17 | ```
18 |
19 | 看到前面的`0a:00.0`和`0a:00.1`吗?把它看成`AB:CD.E`.
20 | 打开**vfio-startup.sh**和**vfio-teardown.sh**,
21 | 把里面的`pci_0000_AB_CD_E`按字母替换了,你的显卡有几个部分,就需要几行。
22 |
23 | 然后要根据你的显示管理器,把`your-display-manager` 改成你的显示管理器的服务,我用的是SDDM
24 | 不知道的可以尝试用`file /etc/systemd/system/display-manager.service` 命令查看。
25 |
26 | 比如这是我的**vfio-startup.sh**,从:
27 | ```
28 | ...
29 | systemctl stop your-display-manager
30 | ...
31 | virsh nodedev-detach pci_0000_AB_CD_E
32 | ...
33 | ```
34 |
35 | 改成了:
36 | ```
37 | ...
38 | systemctl stop sddm
39 | ...
40 | virsh nodedev-detach pci_0000_0a_00_0
41 | virsh nodedev-detach pci_0000_0a_00_1
42 | ...
43 | ```
44 |
45 |
46 | 别忘了也要改**vfio-teardown.sh**!
47 |
48 | ---
49 |
50 | 都变成可执行的文件
51 | `sudo chmod +x /etc/libvirt/hooks/*`
52 |
53 | 把两个脚本软链接到根目录的bin文件夹
54 | ```
55 | sudo ln -s /etc/libvirt/hooks/vfio-startup.sh /bin/vfio-startup.sh
56 | sudo ln -s /etc/libvirt/hooks/vfio-teardown.sh /bin/vfio-teardown.sh
57 | ```
58 |
59 | * * *
60 | **防止Libvirt在运行时休眠**
61 | `sudo nano /etc/systemd/system/libvirt-nosleep@.service`
62 |
63 | 在libvirt-nosleep@.service里面添加:
64 | ```
65 | [Unit]
66 | Description=Preventing sleep while libvirt domain "%i" is running
67 |
68 | [Service]
69 | Type=simple
70 | ExecStart=/usr/bin/systemd-inhibit --what=sleep --why="Libvirt domain \"%i\" is running" --who=%U --mode=block sleep infinity
71 | ```
72 | 更改权限:
73 | `sudo chmod 644 -R /etc/systemd/system/libvirt-nosleep@.service`
74 |
75 | 变成系统文件
76 | `sudo chown root:root /etc/systemd/system/libvirt-nosleep@.service`
77 |
78 | [教程主页](../README-cn.md)
--------------------------------------------------------------------------------
/libvirt-hooks/qemu:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | OBJECT="$1"
4 | OPERATION="$2"
5 |
6 | if [[ $OBJECT == "win10" ]]; then
7 | case "$OPERATION" in
8 | "prepare")
9 | systemctl start libvirt-nosleep@"$OBJECT" 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
10 | /bin/vfio-startup.sh 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
11 | ;;
12 |
13 | "release")
14 | systemctl stop libvirt-nosleep@"$OBJECT" 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
15 | /bin/vfio-teardown.sh 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
16 | ;;
17 | esac
18 | fi
--------------------------------------------------------------------------------
/libvirt-hooks/vfio-startup.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | # Helpful to read output when debugging
3 | set -x
4 |
5 | long_delay=10
6 | medium_delay=5
7 | short_delay=1
8 | echo "Beginning of startup!"
9 |
10 | function stop_display_manager_if_running {
11 | # Stop dm using systemd
12 | if command -v systemctl; then
13 | if systemctl is-active --quiet "$1.service" ; then
14 | echo $1 >> /tmp/vfio-store-display-manager
15 | systemctl stop "$1.service"
16 | fi
17 |
18 | while systemctl is-active --quiet "$1.service" ; do
19 | sleep "${medium_delay}"
20 | done
21 |
22 | return
23 | fi
24 |
25 | # Stop dm using runit
26 | if command -v sv; then
27 | if sv status $1 ; then
28 | echo $1 >> /tmp/vfio-store-display-manager
29 | sv stop $1
30 | fi
31 | fi
32 | }
33 |
34 |
35 | # Stop currently running display manager
36 | if test -e "/tmp/vfio-store-display-manager" ; then
37 | rm -f /tmp/vfio-store-display-manager
38 | fi
39 |
40 | stop_display_manager_if_running sddm
41 | stop_display_manager_if_running gdm
42 | stop_display_manager_if_running lightdm
43 | stop_display_manager_if_running lxdm
44 | stop_display_manager_if_running xdm
45 | stop_display_manager_if_running mdm
46 | stop_display_manager_if_running display-manager
47 |
48 | sleep "${medium_delay}"
49 |
50 | # Unbind VTconsoles if currently bound (adapted from https://www.kernel.org/doc/Documentation/fb/fbcon.txt)
51 | if test -e "/tmp/vfio-bound-consoles" ; then
52 | rm -f /tmp/vfio-bound-consoles
53 | fi
54 | for (( i = 0; i < 16; i++))
55 | do
56 | if test -x /sys/class/vtconsole/vtcon${i}; then
57 | if [ `cat /sys/class/vtconsole/vtcon${i}/name | grep -c "frame buffer"` \
58 | = 1 ]; then
59 | echo 0 > /sys/class/vtconsole/vtcon${i}/bind
60 | echo "Unbinding console ${i}"
61 | echo $i >> /tmp/vfio-bound-consoles
62 | fi
63 | fi
64 | done
65 |
66 | # Unbind EFI-Framebuffer
67 | if test -e "/tmp/vfio-is-nvidia" ; then
68 | rm -f /tmp/vfio-is-nvidia
69 | fi
70 |
71 | if lsmod | grep "nvidia" &> /dev/null ; then
72 | echo "true" >> /tmp/vfio-is-nvidia
73 | echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind
74 | fi
75 |
76 | echo "End of startup!"
--------------------------------------------------------------------------------
/libvirt-hooks/vfio-teardown.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 | set -x
3 |
4 | echo "Beginning of teardown!"
5 |
6 | sleep 10
7 |
8 | # Restart Display Manager
9 | input="/tmp/vfio-store-display-manager"
10 | while read displayManager; do
11 | if command -v systemctl; then
12 | systemctl start "$displayManager.service"
13 | else
14 | if command -v sv; then
15 | sv start $displayManager
16 | fi
17 | fi
18 | done < "$input"
19 |
20 | # Rebind VT consoles (adapted from https://www.kernel.org/doc/Documentation/fb/fbcon.txt)
21 | input="/tmp/vfio-bound-consoles"
22 | while read consoleNumber; do
23 | if test -x /sys/class/vtconsole/vtcon${consoleNumber}; then
24 | if [ `cat /sys/class/vtconsole/vtcon${consoleNumber}/name | grep -c "frame buffer"` \
25 | = 1 ]; then
26 | echo "Rebinding console ${consoleNumber}"
27 | echo 1 > /sys/class/vtconsole/vtcon${consoleNumber}/bind
28 | fi
29 | fi
30 | done < "$input"
31 |
32 | # Rebind framebuffer for nvidia
33 | if test -e "/tmp/vfio-is-nvidia" ; then
34 | echo "efi-framebuffer.0" > /sys/bus/platform/drivers/efi-framebuffer/bind
35 | fi
36 |
37 | echo "End of teardown!"
--------------------------------------------------------------------------------
/libvirt-nvidia-hooks/qemu:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | OBJECT="$1"
4 | OPERATION="$2"
5 |
6 | if [[ $OBJECT == "win10" ]]; then
7 | case "$OPERATION" in
8 | "prepare")
9 | systemctl start libvirt-nosleep@"$OBJECT" 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
10 | /bin/vfio-startup.sh 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
11 | ;;
12 |
13 | "release")
14 | systemctl stop libvirt-nosleep@"$OBJECT" 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
15 | /bin/vfio-teardown.sh 2>&1 | tee -a /var/log/libvirt/custom_hooks.log
16 | ;;
17 | esac
18 | fi
--------------------------------------------------------------------------------
/libvirt-nvidia-hooks/vfio-startup.sh:
--------------------------------------------------------------------------------
1 | set -x
2 |
3 | systemctl stop your-display-manager
4 |
5 | echo 0 > /etc/class/vtconsole/vtcon0/bind
6 | echo 0 > /etc/class/vtconsole/vtcon1/bind
7 |
8 | echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/unbind
9 |
10 | sleep 15
11 |
12 | modprobe -r nvidia_drm
13 | modprobe -r nvidia_uvm
14 | modprobe -r nvidia_modeset
15 | modprobe -r drm_kms_helper
16 | modprobe -r nvidia
17 | modprobe -r i2c_nvidia_gpu
18 | modprobe -r drm
19 |
20 | virsh nodedev-detach pci_0000_AB_CD_E
21 |
22 | modprobe vfio_pci
23 | modprobe vfio
24 | modprobe vfio_iommu_type1
25 | modprobe vfio_virqfd
--------------------------------------------------------------------------------
/libvirt-nvidia-hooks/vfio-teardown.sh:
--------------------------------------------------------------------------------
1 | set -x
2 |
3 | sleep 10
4 |
5 | modprobe -r vfio_pci
6 | modprobe -r vfio
7 | modprobe -r vfio_iommu_type1
8 | modprobe -r vfio_virqfd
9 |
10 | virsh nodedev-reattach pci_0000_AB_CD_E
11 |
12 | echo 1 > /etc/class/vtconsole/vtcon0/bind
13 | echo 1 > /etc/class/vtconsole/vtcon1/bind
14 |
15 | echo efi-framebuffer.0 > /sys/bus/platform/drivers/efi-framebuffer/bind
16 |
17 | modprobe nvidia
18 | modprobe nvidia_modeset
19 | modprobe nvidia_uvm
20 | modprobe nvidia_drm
21 | modprobe drm_kms_helper
22 | modprobe i2c_nvidia_gpu
23 | modprobe drm
24 |
25 | sleep 10
26 |
27 | systemctl start your-display-manager
--------------------------------------------------------------------------------
/resources/iommuamd.sh:
--------------------------------------------------------------------------------
1 | #!/bin/bash
2 |
3 | useColors=true
4 | usePager=true
5 |
6 | usage() {
7 | echo "\
8 | Usage: $(basename $0) [OPTIONS]
9 | Shows information about IOMMU groups relevant for working with PCI-passthrough
10 |
11 | -c -C enables/disables colored output, respectively
12 | -p -P enables/disables pager (less), respectively
13 |
14 | -h display this help message"
15 | }
16 |
17 | color() {
18 | if ! $useColors; then
19 | cat
20 | return
21 | fi
22 |
23 | rset=$'\E[0m'
24 | case "$1" in
25 | black) colr=$'\E[22;30m' ;;
26 | red) colr=$'\E[22;31m' ;;
27 | green) colr=$'\E[22;32m' ;;
28 | yellow) colr=$'\E[22;33m' ;;
29 | blue) colr=$'\E[22;34m' ;;
30 | magenta) colr=$'\E[22;35m' ;;
31 | cyan) colr=$'\E[22;36m' ;;
32 | white) colr=$'\E[22;37m' ;;
33 | intenseBlack) colr=$'\E[01;30m' ;;
34 | intenseRed) colr=$'\E[01;31m' ;;
35 | intenseGreen) colr=$'\E[01;32m' ;;
36 | intenseYellow) colr=$'\E[01;33m' ;;
37 | intenseBlue) colr=$'\E[01;34m' ;;
38 | intenseMagenta) colr=$'\E[01;35m' ;;
39 | intenseCyan) colr=$'\E[01;36m' ;;
40 | intenseWhite) colr=$'\E[01;37m' ;;
41 | esac
42 |
43 | sed "s/^/$colr/;s/\$/$rset/"
44 | }
45 |
46 | indent() {
47 | sed 's/^/\t/'
48 | }
49 |
50 | pager() {
51 | if $usePager; then
52 | less -SR
53 | else
54 | cat
55 | fi
56 | }
57 |
58 | while getopts cCpPh opt; do
59 | case $opt in
60 | c)
61 | useColors=true
62 | ;;
63 | C)
64 | useColors=false
65 | ;;
66 | p)
67 | usePager=true
68 | ;;
69 | P)
70 | usePager=false
71 | ;;
72 | h)
73 | usage
74 | exit
75 | ;;
76 | esac
77 | done
78 |
79 | iommuGroups=$(find '/sys/kernel/iommu_groups/' -maxdepth 1 -mindepth 1 -type d)
80 |
81 | if [ -z "$iommuGroups" ]; then
82 | echo "No IOMMU groups found. Are you sure IOMMU is enabled?"
83 | exit
84 | fi
85 |
86 | for iommuGroup in $iommuGroups; do
87 | echo "IOMMU group $(basename "$iommuGroup")" | color red
88 |
89 | for device in $(ls -1 "$iommuGroup/devices/"); do
90 | devicePath="$iommuGroup/devices/$device/"
91 |
92 | # Print pci device
93 | lspci -nns "$device" | color blue
94 |
95 | # Print drivers
96 | driverPath=$(readlink "$devicePath/driver")
97 | if [ -z "$driverPath" ]; then
98 | echo "Driver: none"
99 | else
100 | echo "Driver: $(basename $driverPath)"
101 | fi | indent | color cyan
102 |
103 | # Print usb devices
104 | usbBuses=$(find $devicePath -maxdepth 2 -path '*usb*/busnum')
105 | for usb in $usbBuses; do
106 | echo 'Usb bus:' | color cyan
107 | lsusb -s $(cat "$usb"): | indent | color green
108 | done | indent
109 |
110 | # Print block devices
111 | blockDevices=$(find $devicePath -mindepth 5 -maxdepth 5 -name 'block')
112 | for blockDevice in $blockDevices; do
113 | echo 'Block device:' | color cyan
114 | echo "Model: $(cat "$blockDevice/../model")" | indent | color green
115 | lsblk -no NAME,SIZE,MOUNTPOINT "/dev/$(ls -1 $blockDevice)" | indent | color green
116 | done | indent
117 | done | indent
118 | done | pager
119 |
--------------------------------------------------------------------------------
/resources/wechatpay.jpg:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/ledisthebest/LEDs-single-gpu-passthrough/1b7df961107d83231b7b4cd2eb6eaf3f3521ff65/resources/wechatpay.jpg
--------------------------------------------------------------------------------