CentOS 7 KVM 搭建并设置PCI穿透/直通 Nvidia 显卡

标签: none

KVM(Kernel-based Virtual Machine, 即内核级虚拟机) 是一个开源的系统虚拟化模块。它使用Linux自身的调度器进行管理,所以相对于Xen,其核心
源码很少。目前KVM已成为学术界的主流VMM之一,它包含一个为处理器提供底层虚拟化 可加载的核心模块kvm.ko(kvm-intel.ko 或 kvm-amd.ko)。kvm
还需要一个经过修改的QEMU 软件(qemu-kvm),作为虚拟机上层控制和界面。KVM的虚拟化需要硬件支持(如 Intel VT技术或者AMD V技术)。是基于硬件的
完全虚拟化。 KVM可以运行多个其本身运行未改动的镜像的虚拟机,例如Windows,Mac OS X ,每个虚拟机都有各自的虚拟硬件,比如网卡、硬盘核图形适配
器等。

KVM和QEMU的关系
QEMU是个独立的虚拟化解决方案,从这个角度它并不依赖KVM。而KVM是另一套虚拟化解决方案,不过因为这个方案实际上只实现了内核中对处理器(Intel VT)
, AMD SVM)虚拟化特性的支持,换言之,它缺乏设备虚拟化以及相应的用户空间管理虚拟机的工具,所以它借用了QEMU的代码并加以精简,连同KVM一起构成了
另一个独立的虚拟化解决方案:KVM+QEMU。

我一直希望使用CentOS 7 作为主要的操作系统,但是想使用Nvidia 显卡玩游戏就需要一个Windows系统。所以我需要一个win 10系统作为游戏机.
我发现可以用VFIO,KVM和QEMU这些开源技术,直通GPU的虚拟机它可以实现接近原生性能的显卡。

准备工作

硬件

1.CPU Intel i7-8700K 需要支持 VT-d (Intel Virtualization Technology for Directed I/O) 以及VT-x
2.内存 40G RAM (目前是8G + 48G)
3.显卡 RTX2080Ti 虚拟机 (显卡需要UEFI 支持) 新显卡都支持,可以在这里查询
4.主板 ASUS Strix Z370-F

软件

1.CentOS 7.6
2.KVM 套件
3.qemu-kvm 需要2.9.0 以上版本
4.Win 10 1809 版本 RTX 需要最新的win 10

软件配置

1.从内核中禁用nouveau驱动
2.PCI直通 (VFIO/IOMMU)
3.KVM 网桥
4.qemu-kvm: could not open disk image ' ': Permission denied 权限问题
5.虚拟机 CPU分配 (虚拟物理核心和虚拟线程的设置)
6.下载VFIO驱动程序
7.虚拟机中N卡驱动 43 错误代码 (N卡检测到在虚拟机中运行会出现这个错误)
8.添加物理磁盘到虚拟机

配置流程

1.检查硬件是否满足要求
2.准备系统环境 安装KVM 套件
3.检查是否正确加载kvm模块
4.禁用nouveau 驱动
5.开启IOMMU 支持
6.设置 vfio-pci 设备 (IOMMU)
7.设置网桥
8.更新qemu-kvm 到2.9.0以上版本
9.分配虚拟机磁盘
10.配置qemu-kvm 权限
11.安装虚拟机
12.设置虚拟机CPU 核心
13.分配鼠标键盘给虚拟机
14.虚拟机win VFIO驱动程序安装
15.给虚拟机添加显卡
16.解决显卡 43错误代码
17.给虚拟机添加物理磁盘

1.检查硬件是否满足要求

1.验证CPU是否支持KVM;如果结果中有vmx(Intel VT虚拟化技术)或svm (SVM安全虚拟化技术的AMD处理器,也可以叫AMD-V )字样,就说明CPU的支持的。如果没有配置可以在BIOS中进行配置。如果没有任何的输出,说明你的cpu不支持,将无法使用KVM虚拟机。

egrep '(vmx|svm)' /proc/cpuinfo

flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt
flags       : fpu vme de pse tsc msr pae mce cx8 apic sep mtrr pge mca cmov pat pse36 clflush dts acpi mmx fxsr sse sse2 ss ht tm pbe syscall nx pdpe1gb rdtscp lm constant_tsc arch_perfmon pebs bts rep_good nopl xtopology nonstop_tsc aperfmperf eagerfpu pni pclmulqdq dtes64 monitor ds_cpl vmx smx est tm2 ssse3 cx16 xtpr pdcm pcid dca sse4_1 sse4_2 x2apic popcnt tsc_deadline_timer aes xsave avx f16c rdrand lahf_lm arat epb pln pts dtherm tpr_shadow vnmi flexpriority ept vpid fsgsbase smep erms xsaveopt

2.准备系统环境 安装KVM 套件

1.安装基础工具
2.安装epel-release 源
3.安装 KVM 套件
4.添加virtio-win 源并安装 virtio-win

yum install net-tools vim wget kernel-devel
yum update
yum install epel-release htop 
yum install virt-manager qemu-img qemu-kvm qemu-kvm-tools libvirt virt-install bridge-utils
wget https://fedorapeople.org/groups/virt/virtio-win/virtio-win.repo -O /etc/yum.repos.d/virtio-win.repo
yum install virtio-win

kvm相关安装包及其作用

qemu-kvm          主要的KVM程序包
python-virtinst   创建虚拟机所需要的命令行工具和程序库
virt-manager      GUI虚拟机管理工具
virt-top          虚拟机统计命令
virt-viewer       GUI连接程序,连接到已配置好的虚拟机
libvirt           C语言工具包,提供libvirt服务
libvirt-client    虚拟客户机提供的C语言工具包
virt-install      基于libvirt服务的虚拟机创建命令
bridge-utils      创建和管理桥接设备的工具

3.检查是否正确加载kvm模块

一共会输出三条,三条都必须满足.

[root@corehadoop31 ~]# lsmod |grep kvm
kvm_intel             170181  3
kvm                   554609  1 kvm_intel
irqbypass              13503  1 kvm

4.禁用nouveau 驱动

1.在配置文件中禁用nouveau
CentOS 7 文件路径在 /usr/lib/modprobe.d/dist-blacklist.conf /lib/modprobe.d/dist-blacklist.conf 是同一个文件,修改其中一个即可.

其他路径我没找到的,但是这个路径多次出现在其他教程里面 /etc/modprobe.d/blacklist.conf

echo "blacklist radeon" >> /etc/modprobe.d/blacklist.conf 
echo "blacklist nouveau" >> /etc/modprobe.d/blacklist.conf 
echo "blacklist nvidia" >> /etc/modprobe.d/blacklist.conf 

本段文章教程 两篇文章结合使用
centos 7禁用nouveau及安装NVIDIA显卡驱动
CentOS中禁用nouveau驱动

vim /usr/lib/modprobe.d/dist-blacklist.conf

#在文件最后加上
blacklist nouveau
options nouveau modeset=0 

#备份镜像
mv /boot/initramfs-$(uname -r).img /boot/initramfs-$(uname -r).img.bak
#重建镜像
dracut -v /boot/initramfs-$(uname -r).img $(uname -r)

reboot
#重启之后检查是否禁用成功,应该返回空
lsmod | grep nouveau

扩展阅读
禁用Nvidia的libGL
Using integrated graphics card for display and Nvidia card for GPU
注释掉 /etc/ld.so.conf.d/nvidia.conf 文件里面的内容

# /etc/ld.so.conf.d/nvidia.conf provided by http://elrepo.org
/usr/lib64/nvidia
/usr/lib64/vdpau
/usr/lib/nvidia
/usr/lib/vdpau

5.开启IOMMU 支持

本段文章教程
CentOS7 minimal kvm iommu 辅助虚拟化 vt-x (用于pci透传)
Intel CPU: intel_iommu=on
AMD CPU: amd_iommu=on

方法一 (我用方法一失败了,很多文章都是方法一)

1.配置

vim /etc/default/grub

GRUB_CMDLINE_LINUX_DEFAULT="... intel_iommu=on ..."
或
GRUB_CMDLINE_LINUX="... intel_iommu=on ..."

2.更新

grub2-mkconfig -o /boot/grub2/grub.cfg

3.重启

reboot

4.验证

cat /proc/cmdline |grep intel_iommu=on

Snipaste_2019-03-19_09-44-07.png
5.验证

dmesg | grep -E "DMAR|IOMMU"

Snipaste_2019-03-19_09-46-51.png
注:如果方法一 失败,应该是启动的时候并没有使用 /boot/grub2/grub.cfg, 可以用方法二

方法二

1.查找

find / -name "grub.cfg"

Snipaste_2019-03-19_09-55-23.png
发现还有 /boot/efi/EFI/centos/grub.cfg

2.编辑
vim /boot/efi/EFI/centos/grub.cfg
对照 /boot/grub2/grub.cfgintel_iommu=on 添加到 /boot/efi/EFI/centos/grub.cfg 相应位置

3次
添加到 linuxefi ... intel_iommu=on ...
Snipaste_2019-03-19_09-58-59.png

3.重启验证

6.设置 vfio-pci 设备 (IOMMU)

1.给VFIO-PCI 添加内核模块.

lspci -nn | grep -i nvidia
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f7] (rev a1)
01:00.2 USB controller [0c03]: NVIDIA Corporation Device [10de:1ad6] (rev a1)
01:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device [10de:1ad7] (rev a1)

vim /etc/modprobe.d/vfio.conf
# create new: for [ids=***], specify [vendor-ID:device-ID] 没有ACS的需要把整组都放入
options vfio-pci ids=10de:1e07,10de:10f7,10de:1ad6,10de:1ad7

echo 'vfio-pci' > /etc/modules-load.d/vfio-pci.conf
reboot

2.验证

dmesg | grep -i vfio
   >># dmesg | grep -i vfio
[    1.423654] VFIO - User Level meta-driver version: 0.3
[    1.435816] vfio_pci: add [10de:1e07[ffff:ffff]] class 0x000000/00000000
[    1.447858] vfio_pci: add [10de:10f7[ffff:ffff]] class 0x000000/00000000

扩展阅读!!! 注意事项!!!

验证IOMMU隔离

本段文章教程
Pci passthrough #Verify IOMMU isolation
要让pci passthrough正常工作,需要为你的pci设备提供专用的iommu组
你应该有类似的东西

# find /sys/kernel/iommu_groups/ -type l
/sys/kernel/iommu_groups/0/devices/0000:00:00.0
/sys/kernel/iommu_groups/1/devices/0000:00:01.0
/sys/kernel/iommu_groups/1/devices/0000:01:00.0
/sys/kernel/iommu_groups/1/devices/0000:01:00.1
/sys/kernel/iommu_groups/2/devices/0000:00:02.0
/sys/kernel/iommu_groups/3/devices/0000:00:16.0
/sys/kernel/iommu_groups/4/devices/0000:00:1a.0
/sys/kernel/iommu_groups/5/devices/0000:00:1b.0
/sys/kernel/iommu_groups/6/devices/0000:00:1c.0
/sys/kernel/iommu_groups/7/devices/0000:00:1c.5
/sys/kernel/iommu_groups/8/devices/0000:00:1c.6
/sys/kernel/iommu_groups/9/devices/0000:00:1c.7
/sys/kernel/iommu_groups/9/devices/0000:05:00.0
/sys/kernel/iommu_groups/10/devices/0000:00:1d.0
/sys/kernel/iommu_groups/11/devices/0000:00:1f.0
/sys/kernel/iommu_groups/11/devices/0000:00:1f.2
/sys/kernel/iommu_groups/11/devices/0000:00:1f.3
/sys/kernel/iommu_groups/12/devices/0000:02:00.0
/sys/kernel/iommu_groups/12/devices/0000:02:00.1
/sys/kernel/iommu_groups/13/devices/0000:03:00.0
/sys/kernel/iommu_groups/14/devices/0000:04:00.0

要拥有单独的iommu,您的处理器需要支持称为ACS(访问控制服务)的功能。
所有Xeon处理器都支持它们(E3,E5),不包括Xeon E3-1200
对于intel Core,它是不同的,只有一些处理器支持ACS

Haswell-E (LGA2011-v3)
i7-5960X (8-core, 3/3.5GHz)
i7-5930K (6-core, 3.2/3.8GHz)
i7-5820K (6-core, 3.3/3.6GHz)

Ivy Bridge-E (LGA2011)
i7-4960X (6-core, 3.6/4GHz)
i7-4930K (6-core, 3.4/3.6GHz)
i7-4820K (4-core, 3.7/3.9GHz)

Sandy Bridge-E (LGA2011)
i7-3960X (6-core, 3.3/3.9GHz)
i7-3970X (6-core, 3.5/4GHz)
i7-3930K (6-core, 3.2/3.8GHz)
i7-3820 (4-core, 3.6/3.8GHz)

7.设置网桥

本段文章
配置宿主机网络

Bridge模式配置

Bridge方式即虚拟网桥的网络连接方式,是客户机和子网里面的机器能够互相通信。可以使虚拟机成为网络中具有独立IP的主机。桥接网络(也叫 物理设备共享)被用作把一个物理设备复制到一台虚拟机。网桥多用作高级设置,特别是主机多个网络接口的情况。
修改前一定要备份!!!

┌─────────────────────────┐      ┌─────────────────┐
│          HOST           │      │Virtual Machine 1│
│ ┌──────┐      ┌───────┐ │      │    ┌──────┐     │
│ │ br0  │──┬───│ vnet0 │─│─ ─ ─ │    │ br0  │     │
│ └──────┘  │   └───────┘ │      │    └──────┘     │
│     │     │             │      └─────────────────┘
│     │     │   ┌───────┐ │      ┌─────────────────┐
│ ┌──────┐  └───│ vnet1 │─│─     │Virtual Machine 2│
│ │ eno0 │      └───────┘ │ │    │    ┌──────┐     │
│ └──────┘                │  ─ ─ │    │ br0  │     │
│ ┌──────┐                │      │    └──────┘     │
│ │ eno1 │                │      └─────────────────┘
│ └──────┘                │
└─────────────────────────┘

可以看到上面eno1是有获取到ip地址的,相对应的文件在/etc/sysconfig/network-scripts/目录中,ifcfg-eno1 宿主机的物理网卡配置文件

# cat ifcfg-eno1
TYPE="Ethernet"
PROXY_METHOD="none"
BROWSER_ONLY="no"
BOOTPROTO="dhcp"
DEFROUTE="yes"
IPV4_FAILURE_FATAL="no"
IPV6INIT="yes"
IPV6_AUTOCONF="yes"
IPV6_DEFROUTE="yes"
IPV6_FAILURE_FATAL="no"
IPV6_ADDR_GEN_MODE="stable-privacy"
NAME="eno1"
UUID="242b3d4d-37a5-4f46-b072-55554c185ecf"
DEVICE="eno1"
ONBOOT="yes"
ZONE=nas

BRIDGE="br0" # 指定桥接网卡的名称

ifcfg-br0 桥接网卡配置在同一个目录中 修改成主机IP 和路由器的网关

# cat ifcfg-br0
BOOTPROTO=static
DEFROUTE=yes
PEERDNS=yes
PEERROUTES=yes
IPV4_FAILURE_FATAL=no
IPV6INIT=yes
IPV6_AUTOCONF=yes
IPV6_DEFROUTE=yes
IPV6_PEERDNS=yes
IPV6_PEERROUTES=yes
IPV6_FAILURE_FATAL=no
NAME=br0
UUID=242b3d4d-37a5-4f46-b072-55554c185ecf
DEVICE=br0
ONBOOT=yes
IPV6_PRIVACY=rfc3041
TYPE=bridge  # 将制定为桥接类型
IPADDR=192.168.188.133  # 设置IP地址
PREFIX=24               # 设置子网掩码
GATEWAY=192.168.188.1   # 设置网关

配置好之后,通过systemctl 命令重启网卡。

ifup eno1 # 激活网卡
ifup br0 # 激活桥接网卡
# 两种重启网络的方法
systemctl restart network.service
service network restart

# 校验桥接接口
brctl show

bridge name bridge id   STP enabled interfaces
br0   8000.3863bb44cf6c no    eno1
              vnet0
virbr0    8000.525400193f0f yes   virbr0-nic

8.更新qemu-kvm 到2.9.0以上版本

本段文章
CentOS 7 : KVM : GPU Passthrough : Server World Update QEMU

[root@dlp ~]# /usr/libexec/qemu-kvm -version 
QEMU emulator version 1.5.3 (qemu-kvm-1.5.3-141.el7_4.6), Copyright (c) 2003-2008 Fabrice Bellard

[root@dlp ~]# yum -y install centos-release-qemu-ev

# disable usually
[root@dlp ~]# sed -i -e "s/enabled=1/enabled=0/g" /etc/yum.repos.d/CentOS-QEMU-EV.repo

# for this installing, [qemu-kvm] package is replaced to [qemu-kvm-ev] package
[root@dlp ~]# yum --enablerepo=centos-qemu-ev -y install qemu-kvm-ev

[root@dlp ~]# systemctl restart libvirtd

[root@dlp ~]# /usr/libexec/qemu-kvm -version 
QEMU emulator version 2.9.0(qemu-kvm-ev-2.9.0-16.el7_4.13.1)
Copyright (c) 2003-2017 Fabrice Bellard and the QEMU Project developers

# verify q35 is included like follows
[root@dlp ~]# /usr/libexec/qemu-kvm -machine help 
Supported machines are:
pc                   RHEL 7.4.0 PC (i440FX + PIIX, 1996) (alias of pc-i440fx-rhel7.4.0)
pc-i440fx-rhel7.4.0  RHEL 7.4.0 PC (i440FX + PIIX, 1996) (default)
pc-i440fx-rhel7.3.0  RHEL 7.3.0 PC (i440FX + PIIX, 1996)
pc-i440fx-rhel7.2.0  RHEL 7.2.0 PC (i440FX + PIIX, 1996)
pc-i440fx-rhel7.1.0  RHEL 7.1.0 PC (i440FX + PIIX, 1996)
pc-i440fx-rhel7.0.0  RHEL 7.0.0 PC (i440FX + PIIX, 1996)
rhel6.6.0            RHEL 6.6.0 PC
rhel6.5.0            RHEL 6.5.0 PC
rhel6.4.0            RHEL 6.4.0 PC
rhel6.3.0            RHEL 6.3.0 PC
rhel6.2.0            RHEL 6.2.0 PC
rhel6.1.0            RHEL 6.1.0 PC
rhel6.0.0            RHEL 6.0.0 PC
q35                  RHEL-7.4.0 PC (Q35 + ICH9, 2009) (alias of pc-q35-rhel7.4.0)
pc-q35-rhel7.4.0     RHEL-7.4.0 PC (Q35 + ICH9, 2009)
pc-q35-rhel7.3.0     RHEL-7.3.0 PC (Q35 + ICH9, 2009)
none                 empty machine

9.分配虚拟机磁盘

qemu-img create -f raw /root/kvm/win10.raw 50G
# 注意类型为raw,50G容量其实没有意义

qemu-img info /root/kvm/win10.raw
image: /root/kvm/win10.raw
file format: raw
virtual size: 50G (53687091200 bytes)
disk size: 0

10.配置qemu-kvm 权限

遇到 qemu-kvm: could not open disk image ' ': Permission denied 这个问题的原因是libvirtd的权限管理很严格所以也需要给他设置权限.

方法一 我使用方法一,但不推荐

本段文章
qemu-kvm: could not open disk image ' ': Permission denied

修改 /etc/libvirt/qemu.conf
删除注释 user/group 设置为 root 用户
重启 libvirtd

# The user for QEMU processes run by the system instance. It can be
# specified as a user name or as a user id. The qemu driver will try to
# parse this value first as a name and then, if the name doesn't exist,
# as a user id.
#
# Since a sequence of digits is a valid user name, a leading plus sign
# can be used to ensure that a user id will not be interpreted as a user
# name.
#
# Some examples of valid values are:
#
#       user = "qemu"   # A user named "qemu"
#       user = "+0"     # Super user (uid=0)
#       user = "100"    # A user named "100" or a user with uid=100
#
user = "root"

# The group for QEMU processes run by the system instance. It can be
# specified in a similar way to user.
group = "root"

# Whether libvirt should dynamically change file ownership
# to match the configured user/group above. Defaults to 1.
# Set to 0 to disable file ownership changes.
#dynamic_ownership = 1

[root@dev1 ~]# service libvirtd restart
Stopping libvirtd daemon:                                  [  OK  ]
Starting libvirtd daemon:                                  [  OK  ]

方法二

配置ACL 权限

murlock@asus:~/kubernet $ sudo getfacl -e /home/murlock
getfacl: Removing leading '/' from absolute path names
# file: home/murlock
# owner: murlock
# group: murlock
user::rwx
user:libvirt-qemu:--x        #effective:---
group::---            #effective:---
mask::---
other::---
murlock@asus:~/kubernet $ sudo setfacl -m u:libvirt-qemu:rx /home/murlock
murlock@asus:~/kubernet $ sudo getfacl -e /home/murlock
getfacl: Removing leading '/' from absolute path names
# file: home/murlock
# owner: murlock
# group: murlock
user::rwx
user:libvirt-qemu:r-x        #effective:r-x
group::---            #effective:---
mask::r-x
other::---

11.安装虚拟机

虚拟机先创建一个可以使用的再为他添加PCI直通设备. 特别需要注意的参数 --machine q35 --features kvm_hidden=on

virt-install \
--name Win10 \
--memory 16384 \
--cpu host \
--vcpus 8 \
--disk path=/root/kvm/win10.raw \
--network bridge=br0,model='e1000' \
--cdrom=/root/kvm/win10.iso \
--boot cdrom \
--virt-type kvm \
--vnc \
--vncport=5902 \
--vnclisten=0.0.0.0 \
--os-type=windows \
--features kvm_hidden=on \
--machine q35

#临时开放端口 5902
firewall-cmd --add-port=5902/tcp

创建好之后,使用vnc 连接并安装win 10

virsh 基础命令

virsh list --all           # 查看所有运行和没有运行的虚拟机
virsh list                 # 查看在运行的虚拟机
virsh dumpxml vm-name      # 查看kvm虚拟机配置文件
virsh start vm-name        # 启动kvm虚拟机
virsh shutdown vm-name     # 正常关机

virsh destroy vm-name      # 非正常关机,强制关闭虚拟机(相当于物理机直接拔掉电源)
virsh undefine vm-name     # 删除vm的配置文件

ls /etc/libvirt/qemu
# 查看删除结果,Centos-6.6的配置文件被删除,但磁盘文件不会被删除

virsh define file-name.xml # 根据配置文件定义虚拟机
virsh suspend vm-name      # 挂起,终止
virsh resumed vm-name      # 恢复被挂起的虚拟机
virsh autostart vm-name    # 开机自启动vm
virsh console <虚拟机名称>   # 连接虚拟机

virsh start centos72     # 虚拟机开启(启动):
virsh reboot centos72    # 虚拟机重新启动
virsh shutdown centos72  # 虚拟机关机
virsh destroy centos72   # 强制关机(强制断电)
virsh suspend centos72   # 暂停(挂起)KVM 虚拟机
virsh resume centos72    # 恢复被挂起的 KVM 虚拟机
virsh undefine centos72  # 该方法只删除配置文件,磁盘文件未删除
virsh autostart centos72 # 随物理机启动而启动(开机启动)
virsh autostart --disable centos72 # 取消标记为自动开始(取消开机启动)

12.设置虚拟机CPU 核心

本段文章
Why does my Windows 7 VM running under Linux' KVM not use all the virtual processors?
默认设置的vcpus 作为单核单线程 分配给了虚拟机, 普通使用的版本最多支持2个插槽 他将使用两个处理器.
服务器版本的支持多个处理核心.

普通版本需要修改CPU 拓扑结构, 设置为单个8核心处理器,这样可以解决问题。
在libvirt 0.8.3以上,如果输入:
虚拟机XML 文件在 /etc/libvirt/qemu/

virsh capabilities | grep topology

它将列出主机的拓扑:

<topology sockets='1' cores='8' threads='1'/>

这些数字指的是套接字,每个套接字的核心数和每个核心的线程数。将此行添加到xml文件中的cpu条目,以允许窗口使用所有4个核心,例如:

<vcpu placement='static'>8</vcpu>
<cpu mode='host-model' check='partial'>
    <model fallback='allow'/>
    <topology sockets='1' cores='4' threads='2'/>
</cpu>

直通模式

<cpu mode='host-passthrough'>
  <topology sockets='1' cores='4' threads='2' />
  <feature policy='disable' name='hypervisor'/>
</cpu>

修改完需要重新定义虚拟机

virsh define Win10.xml

13.分配鼠标键盘给虚拟机

本段文章
Adding USB Device Pass-through

添加USB设备直通

限制
1.USB协议<= 2.0
首先找到usb供应商ID和产品ID:

$ lsusb
Bus 001 Device 001: ID 1d6b:0002 Linux Foundation 2.0 root hub
Bus 005 Device 012: ID 0a5c:2110 Broadcom Corp. Bluetooth Controller
Bus 005 Device 003: ID 0483:2016 SGS Thomson Microelectronics Fingerprint Reader
Bus 005 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 004 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 003 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub
Bus 002 Device 001: ID 1d6b:0001 Linux Foundation 1.1 root hub

如果想要选择Broadcom公司的蓝牙控制器,则供应商ID(Vendor ID)和产品ID(Product ID)分别为0a5c 2110。
Hot Add
新建一个只包含设备的xml 文件

<hostdev mode='subsystem' type='usb' managed='yes'>
    <source>
        <vendor id='0x0a5c'/>
        <product id='0x2110'/>
    </source>
</hostdev>

然后可以通过以下方式附加/分离:

$ virsh attach-device <guestname> <<our-device-xml-file>
# work with it in the guest
$ virsh detach-device <guestname> <<our-device-xml-file>

Static Add
可以将ID输入xml配置文件。这可以通过virsh编辑

<domain type='kvm'>
  <name>Win10</name>
  …
  <devices>
    …
     <hostdev mode='subsystem' type='usb' managed='yes'>
      <source>
        <vendor id='0x046d'/>
        <product id='0xc534'/>
      </source>
      <address type='usb' bus='0' port='2'/>
    </hostdev>
  </devices>
</domain>

修改完需要重新定义虚拟机 virsh define Win10.xml

14.虚拟机win VFIO驱动程序安装

在虚拟机里下载驱动程序并安装

https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso

之前用 yum install virtio-win 下载的文件在 /usr/share/virtio-win/

15.给虚拟机添加显卡

本段文章
Virtual Machine configuration
修改虚拟机 XML 文件.虚拟机XML 文件在 /etc/libvirt/qemu/

lspci -nn | grep -i nvidia
01:00.0 VGA compatible controller [0300]: NVIDIA Corporation TU102 [GeForce RTX 2080 Ti Rev. A] [10de:1e07] (rev a1)
01:00.1 Audio device [0403]: NVIDIA Corporation Device [10de:10f7] (rev a1)
01:00.2 USB controller [0c03]: NVIDIA Corporation Device [10de:1ad6] (rev a1)
01:00.3 Serial bus controller [0c80]: NVIDIA Corporation Device [10de:1ad7] (rev a1)

这里列出的PCI 设备序号 01:00.0 01:00.1 01:00.2 01:00.3
01:00.0 这里需要对应配置文件的 <source> 节点里面 <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
<hostdev> 里面是直通一个PCI 设备, 例如我这里有4个需要穿透到里面,就要有4个<hostdev>

    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </hostdev>

修改完需要重新定义虚拟机 virsh define Win10.xml

完整的XML配置文件

<domain type='kvm'>
  <name>Win10</name>
  …
  <devices>
    …
     <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x01' slot='0x00' function='0x0'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x01' slot='0x00' function='0x1'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x01' slot='0x00' function='0x2'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
    </hostdev>
    <hostdev mode='subsystem' type='pci' managed='yes'>
      <driver name='vfio'/>
      <source>
        <address domain='0x0000' bus='0x01' slot='0x00' function='0x3'/>
      </source>
      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
    </hostdev>
  </devices>
</domain>

16.解决显卡 43错误代码

本段文章
Fighting error 43 – how to use Nvidia GPU in a virtual machine.
Nvidia 显卡驱动安装完成之后,在设备管理器里面会显示 设备错误代码43
从337.88 版本开始 Windows上的Nvidia驱动程序检查虚拟机管理程序是否正在运行,如果检测到虚拟机管理程序,会导致Windows设备管理器出现错误43

找到第一行

<domain type='kvm'>

改为

<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'>

现在找到 <features> ,添加 如果存在按照这个修改:

<features>
    ...
  <kvm>
    <hidden state='on'/>
  </kvm>
</features>

找到</devices> 末尾, 按照这个修改:

  </devices>
  <qemu:commandline>
    <qemu:arg value='-cpu'/>
    <qemu:arg value='host,hv_time,kvm=off,hv_vendor_id=null'/>
  </qemu:commandline>
</domain>

这些设置对我有用.kira~('· w < ` )
修改完需要重新定义虚拟机 virsh define Win10.xml

17.给虚拟机添加物理磁盘

本段文章
2012/10/14: Adding a Physical Disk to a Guest with Libvirt / KVM
使用virt-manager无法做到这一点。据我所知,virt-manager适用于存储池。您可以将磁盘设置为存储池,但不能将现有磁盘直接添加到VM。

幸运的是:手动将磁盘添加到域的xml配置文件中。/etc/libvirt/qemu/<your-vm>.xml 在编辑器中打开并在<devices>部分添加 <disk>

<disk type='block' device='disk'>
  <driver name='qemu' type='raw'/>
  <source dev='/dev/md/storage'/>
  <target dev='vdb' bus='virtio'/>
  <address type='pci' domain='0x0000' bus='0x04' slot='0x00' function='0x0'/> #我的配置文件加入了这部分
</disk>

修改完需要重新定义虚拟机 virsh define Win10.xml

本文参考文献

KVM : GPU Passthrough ★★★★★
VGA Passthrough on virtual machines in CentOS 7 ★★★★★
centos 7禁用nouveau及安装NVIDIA显卡驱动 ★★★★★
CentOS7 minimal kvm iommu 辅助虚拟化 vt-x (用于pci透传) ★★★★★
配置宿主机网络 Bridge模式配置 ★★★★★
Why does my Windows 7 VM running under Linux' KVM not use all the virtual processors? ★★★★★
Fighting error 43 – how to use Nvidia GPU in a virtual machine. ★★★★★
Adding_USB_Device_Pass-through ★★★★★
Adding a Physical Disk to a Guest with Libvirt / KVM ★★★★★
Ubuntu 18.04 - KVM/QEMU Windows 10 GPU Passthrough ★★★★☆
CentOS7.2上用KVM安装虚拟机windows10踩过的坑 ★★★★☆
vga-passthrough/3_BASIC_SETUP.md ★★★☆☆
"Error 43: Driver failed to load" on Nvidia GPUs passed to Windows VMs ★★☆☆☆
Centos7.4安装kvm虚拟机(使用virt-manager管理) ★☆☆☆☆
未使用到的资料 SR-IOV 直通设置 万兆网卡
16.2. PCI DEVICE ASSIGNMENT WITH SR-IOV DEVICES
Frequently Asked Questions for SR-IOV on Intel® Ethernet Server Adapters
QEMU's new -nic command line option
10G NIC performance: VFIO vs virtio - KVM
libvirt: Domain XML format KVM xml 格式
CentOS 7でKVM + libvirt + Open vSwitchな仮想化環境のつくり方
KVM Virtualization 10gbe virtual ethernet


扫描二维码,在手机上阅读!

已有 15 条评论

  1. jerrrrrrrry jerrrrrrrry

    我想问一下,我透传都没问题,但是虚拟机工作一段时间后会花屏死机,请问遇到过这种情况吗,有什么解决方案

    1. 我从搭完之后一直都是稳定的没遇到过花屏.
      花屏问题还是检查一下显卡

  2. 麋鹿麋鹿迷了路 麋鹿麋鹿迷了路

    博主你好,我这是amd的集成显卡加上N卡GTX650的环境,系统是centos7
    按照您的文章里操作,到了添加pci设备这一步,我是在virt-manager里面添加的,添加完N卡了之后,启动虚拟机宿主机就卡死了,ssh也断了,但是宿主机cpu明显还在跑,宿主机bios我设置了多显示屏幕显示,宿主机连接集成显卡有没有显示了。
    我换了win10系统也还是一样的问题,请问大佬我这有什么解决办法么

    1. 麋鹿麋鹿迷了路 麋鹿麋鹿迷了路

      发现qeum没更新,现在开机成功了,目前在驱动43错误上挣扎~~~

  3. 刘

    你好kvm 直通之后,怎么虚拟机无法访问本宿主机网络

    1. 应该是没配置对吧, 直通的是显卡. 和网络无关. 建议重启

  4. iVampireSP.com iVampireSP.com

    博主博主,我能引用下你的文章中的内容到我的博客吗?可能有点多,但是我会保留来源的!谢谢~

    1. 莫问题, 这个是自己整理的笔记. 有地址可以去看看吗

      1. 嗯嗯,谢谢博主。地址就是我的昵称,只不过我还在整理中。

  5. dodo dodo

    大佬,找遍reddit和pve的论坛都没有找到rtx显卡的直通教程,都说要修改vbios,感谢。

    1. RTX 和 GTX 直通的区别不大

  6. QQ:243677979 QQ:243677979

    能否请教下 E3-1230v3能否这种方式显卡直通?我显卡是GTX1660 试过guest机是ubuntu 安装驱动后nvidia-smi可以正常显示内容 但是nvidia-settings无法打开(打开后一片空白)如果禁用虚拟显卡使用GTX1660直接卡在登陆界面(桌面无法正常显示)。 然后试了试guest机改为 win7 Nvidia Geforce Exprience安装后无法打开,硬件信息显示错误代码12 。 请问这是硬件不支持还是设置有问题? 有解决办法吗?

    1. 在win 7下找到的错误代码可以按照这个错误代码查询对应的问题
      像我遇到的43错误代码, 就是因为英伟达会检测是否是在虚拟机里面运行而报错

      1. 游客 游客

        我也是英伟达显卡在win10的虚机报43错误代码,这个要怎么解决呢?

        1. 按照文章内容就能解决,至少对我有效

添加新评论