[分享]kvm gpu passthrough 建立你的1cpu多gpu平台

Kvm、VMware、Virtualbox、Xen、Qemu 等
回复
justvirtual
帖子: 3
注册时间: 2016-02-10 11:53
系统: lubuntu

[分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#1

帖子 justvirtual » 2016-02-10 15:34

如图是虚拟机的检测结果:
gpz.gif
cpuz.png
前提:
*至少两个gpu,现代cpu一般集成显卡,若是服务器cpu,可以花20在某宝买个二手集显(最好与要pass的显卡品牌不同)
*cpu必须支持虚拟化 intel vt-d 或 amd vt

实现此有两种方法:
1.seabios 传统bios
2.ovmf efi(显卡bios须支持uefi)

首先描述第一种方法:

************************************************************************************
准备:

0)apt-get安装qemu或源码编译qemu

代码: 全选

sudo apt install qemu-kvm 
1)编译seabios 或 直接下载目标文件(可选)
(若用qemu内置的seabios,则跳过此步)

代码: 全选

git clone git://git.seabios.org/seabios.git seabios
cd seabios
make
2)编译内核(可选)
本文使用4.4.0 内核

代码: 全选

wget https://www.kernel.org/pub/linux/kernel/v4.x/linux-4.4.tar.xz
tar xf linux-4.4.tar.xz
于以下地址下载内核补丁
https://aur.archlinux.org/cgit/aur.git/ ... fio.tar.gz
打补丁

代码: 全选

tar xf linux-vfio.tar.gz
for file in $(ls xlinux-vfio/*);do patch -p1 < $file;done
linux-vfio patch包里的config 可能会编译不成功 ,附上已测试的config
config.txt
(183.7 KiB) 已下载 275 次
切换root用户
e3 1230 v2 为 8线程,故-j 8

代码: 全选

make -j 8 && make  -j 8 modules && make -j 8 modules_install && make install
3)禁用显卡驱动
nivida显卡: nouveau 或 nvidia
amd显卡: radeon 或 fglrx

代码: 全选

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

4)编辑grub内核启动参数

编辑文件为 /etc/default/grub

加入启动参数 i915.enable_hd_vgaarb=1
注意
1.该选项会禁用DirectRenderInterface(DRI) !!!!
2.如果是amd的cpu,或者是intel的服务器cpu(无intel集显),则不需要


取得要passthrough的设备id,用pci-stub来隐藏

代码: 全选

lspci #查看显卡及其声卡的总线,gtx660为0000:01:00.0 0000:01:00.1
lspci -n #对应总线得到设备id 01:00.0 0300:[color=#FF0000] 10de:11c0[/color] (rev a1) 01:00.1 0403: [color=#FF0000]10de:0e0b[/color] (rev a1)
若已将pci-stub编译进内核,则pci-stub.ids=xxxx:xxxx (例如: pci-stub.ids=10de:11c0,10de:0e0b #gtx660的两个设备id),否则使用脚本

代码: 全选

!/bin/bash

modprobe pci-stub

#显卡设备id 10de 11c0
#声卡设备id 10de 0e0b

set +x
chmod 755 /sys/bus/pci/drivers/pci-stub[code]
chmod 755 /sys/bus/pci/devices
echo "10de 11c0" > /sys/bus/pci/drivers/pci-stub/new_id
echo "0000:01:00.0" > /sys/bus/pci/devices/0000:01:00.0/driver/unbind
echo "0000:01:00.0" > /sys/bus/pci/drivers/pci-stub/bind
echo "10de 0e0b" > /sys/bus/pci/drivers/pci-stub/new_id
echo "0000:01:00.1" > /sys/bus/pci/devices/0000:01:00.1/driver/unbind
echo "0000:01:00.1" > /sys/bus/pci/drivers/pci-stub/bind

exit 0

[/code]

保存为pci-stub

代码: 全选

chomd 755 pci-stub
./pci-stub
以下内核参数可选
*此选项在出现vfio_iommu_type1_attach_group: No interrupt remapping support. Use the module param "allow_unsafe_interrupts" to enable VFIO IOMMU support on this platform时需要
若已编译入内核,则
内核参数加上 vfio_iommu_type1.allow_unsafe_interrupts=1
否则 运行

代码: 全选

echo "options vfio_iommu_type1 allow_unsafe_interrupts=1" > /etc/modprobe.d/vfio_iommu_type1.conf
*这些选项在需要使用虚拟机嵌套以及一些跑分软件时需要
已编译入内核
kvm.ignore_msrs=1 kvm-intel.nested=1 kvm_intel.ept=1

代码: 全选

echo 1 > /sys/module/kvm/parameters/ignore_msrs
echo 1 > /sys/module/kvm_intel/parameters/ept
echo 1 >  /sys/module/kvm_intel/parameters/nested
或 未编译入内核 模块形式

代码: 全选

modprobe kvm ignore_msrs=y
modprobe kvm_intel nested=y ept=y
例子:

代码: 全选

GRUB_DEFAULT=0
GRUB_TIMEOUT=5
GRUB_DISTRIBUTOR=`lsb_release -i -s 2> /dev/null || echo Debian`
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash pci-stub.ids=10de:11c0,10de:0e0b intel_iommu=on kvm.ignore_msrs=1 kvm-intel.nested=1"
GRUB_CMDLINE_LINUX="locale=zh_CN"
如果使用本文附带的config可以直接采用此例子,附带的config已将所有需要的模块编译入内核中

************************************************************************************
测试

测试将使用两个显示屏,如果没有两个,可以将显示屏连上要pass的显卡,用ssh访问主机

代码: 全选

qemu-system-x86_64 -enable-kvm -m 6144 -cpu host,kvm=off \
-smp 6,sockets=1,cores=3,threads=2 \
-device vfio-pci,host=01:00.0,x-vga=on \
-device vfio-pci,host=01:00.1 \
-vga none
*kvm=off 关闭kvm的签名,因为nvidia的驱动会检测kvm签名并拒绝初始化显卡,除非是专业图形卡
*host=xxxxx 此处为lspci获得的总线
*x-vga 将选定的vfio-pci 设备用于图形显示
*vga none 禁用qemu内置的图形设备

若passthrough卡连接的显示屏上会显示字符,则成功

************************************************************************************
第二种方法

************************************************************************************

准备
0)apt-get安装qemu或源码编译qemu

代码: 全选

sudo apt install qemu-kvm 
1)下载ovmf包
在此处下载 edk2.git-ovmf-x64-0为前缀的rpm包
https://www.kraxel.org/repos/jenkins/edk2/

转换rpm到deb并安装
(用具体包名替换例子包名)

代码: 全选

sudo apt-get install alien
sudo alien edk2.git-ovmf-x64-0-xxxx.rpm
sudo dpkg -i edk2.git-ovmf-x64_0-xxxx.deb
检查

代码: 全选

ls /usr/share/edk2.git/ovmf-x64
2)编译内核(可选)
(该步骤与第一种方法相同)

3)禁用显卡驱动
(该步骤与第一种方法相同)


4)编辑grub内核启动参数
不需要加入启动参数 i915.enable_hd_vgaarb=1 (这是ovmf的优点所在,但是显卡必须支持uefi,查看支持情况可以使用gpuz)
其余与第一种方法相同



************************************************************************************
测试

测试将使用两个显示屏,如果没有两个,可以将显示屏连上要pass的显卡,用ssh访问主机

代码: 全选

qemu-system-x86_64 -enable-kvm -m 6144 -cpu host,kvm=off  \
-smp 6,sockets=1,cores=3,threads=2 \
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd \
-drive if=pflash,format=raw,file=/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd \
-device vfio-pci,host=01:00.0 \
-device vfio-pci,host=01:00.1 \
-vga none
*kvm=off 关闭kvm的签名,因为nvidia的驱动会检测kvm签名并拒绝初始化显卡,除非是专业图形卡
*host=xxxxx 此处为lspci获得的总线
*x-vga 将选定的vfio-pci 设备用于图形显示
*vga none 禁用qemu内置的图形设备
*-drive if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd 加入efi固件
-drive if=pflash,format=raw,file=/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd 加入efi配置保存处,可以自行复制一份以适应多虚拟机

************************************************************************************


以上就是基础方法,现在可以创建虚拟机了。
创建虚拟机有两种方法 qemu的命令行 或是 libvirt的virsh的xml风格和virt-manager的图形界面
本文采用qemu的命令行

例子

(1)传统的seabios引导
创建硬盘

代码: 全选

dd if=/dev/zero of=windowsleacy.img bs=1G seek=40 count=0
启动虚拟机,使用windows.iso镜像

代码: 全选

qemu-system-x86_64 -enable-kvm -m 6G -cpu host,kvm=off  \
-smp 6,sockets=1,cores=3,threads=2 \
-bios ./bios.bin \
-vga none \
-no-hpet \
-localtime \
-device vfio-pci,host=01:00.0,x-vga=on \
-device vfio-pci,host=01:00.1 \
-hda ./windowsleacy.img \
-cdrom ./windows.iso \
-net nic,vlan=1 -net user,vlan=1

(2)ovmf uefi 引导

代码: 全选

qemu-system-x86_64 -enable-kvm -m 6144 -cpu host,kvm=off  \
-smp 6,sockets=1,cores=3,threads=2 \
-drive if=pflash,format=raw,readonly,file=/usr/share/edk2.git/ovmf-x64/OVMF_CODE-pure-efi.fd \
-drive if=pflash,format=raw,file=/usr/share/edk2.git/ovmf-x64/OVMF_VARS-pure-efi.fd \
-device vfio-pci,host=01:00.0 \
-device vfio-pci,host=01:00.1 \
-vga none \
-no-hpet \
-localtime \
-hda ./windowsleacy.img \
-cdrom ./windows.iso \
-net nic,vlan=1 -net user,vlan=1
*-localtime 为同步主机与客户机的时钟

×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
推荐:性能增强

如下为性能优化

(1)使用virtio 半虚拟化
(注意:该项需要半虚拟化模块或驱动支持
linux :

代码: 全选

CONFIG_VIRTIO_PCI=y 
CONFIG_VIRTIO_BALLOON=y 
CONFIG_VIRTIO_BLK=y 
CONFIG_VIRTIO_NET=y 
CONFIG_VIRTIO=y
CONFIG_VIRTIO_RING=y 
windows :

代码: 全选

wget https://fedorapeople.org/groups/virt/virtio-win/direct-downloads/stable-virtio/virtio-win.iso
加入参数

代码: 全选

-drive file=./virtio-win.iso,id=cd1,if=none -device ide-cd,bus=ide.1,drive=cd1
使用virtio-hd安装windows时,要注意在windows安装界面加载vitio驱动
具体参考http://www.ilanni.com/?p=5877

半虚拟化硬盘

代码: 全选

-object iothread,id=io1 \
-device virtio-scsi-pci,id=scsi,iothread=io1 \
-drive file=./vm1.img,id=disk,format=raw,if=none,cache=none,aio=native -device scsi-hd,drive=disk \
*-object iothread,id=io1 ...,,iothread=io1 开启dataplane
*cache=none aio=native 大幅提升性能,已测试

半虚拟化网卡
建立桥接br0

代码: 全选

sudo apt install bridge-utils  
脚本set-br0

代码: 全选

!/bin/bash
brctl addbr br0
brctl addif br0 enp4s0
brctl stp br0 on
dhclient br0
route
脚本 /etc/qemuif-up

代码: 全选

#!/bin/bash
switch=br0
if [ -n “$1” ]; then
	#create a TAP interface; qemu will handle it automatically.
	#tunctl -u $(whoami) -t $1
	#start up the TAP interface
	ip link set $1 up
	sleep 1
	#add TAP interface to the bridge
	brctl addif ${switch} $1
	exit 0
else
	echo “Error: no interface specified”
	exit 1
fi
参数

代码: 全选

-netdev type=tap,id=net0,script=/etc/qemuif-up,vhost=on -device virtio-net-pci,netdev=net0
(2)启用巨页内存
脚本 confhugepage

代码: 全选

#!/bin/bash
HUGE_SIZE_MB=6144 #此处为虚拟机需要的内存
HUGE_PAGE_SIZE_KB=`grep Hugepagesize /proc/meminfo | awk '{print $2}'` 
HUGE_PAGE_SIZE_MB=$((HUGE_PAGE_SIZE_KB/1024))
HUGE_PAGES_NEEDED=$(((HUGE_SIZE_MB+HUGE_PAGE_SIZE_MB-1)/HUGE_PAGE_SIZE_MB))
echo $HUGE_PAGES_NEEDED >/proc/sys/vm/nr_hugepages 
HUGE_PAGES_ALLOCATED=`cat /proc/sys/vm/nr_hugepages`
SHMMAX_NEEDED=$((HUGE_PAGES_ALLOCATED*HUGE_PAGE_SIZE_KB*1024)) 
echo $SHMMAX_NEEDED > /proc/sys/kernel/shmmax
PAGE_SIZE=`getconf PAGE_SIZE` 
SHMALL_NEEDED=$((SHMMAX_NEEDED/PAGE_SIZE)) 
echo $SHMALL_NEEDED > /proc/sys/kernel/shmall

if [ ! -d /dev/hugepages ]; then
	mkdir -p /dev/hugepages
fi
	mount -t hugetlbfs hugetlbfs /dev/hugepages
qemu启动参数

代码: 全选

-mem-path /dev/hugepages \
-mem-prealloc \
-balloon none \
(3)分配特定的cpu线程

代码: 全选

taskset -c 0,1,2,3,4,5 \
qemu-system-x86_64 -enable...
分配0,1,2,3,4,5线程到对应客户机

××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××

补充
1.关于nvidia gtx600 系列的efi问题
nvidia gtx600系列部分不支持efi,但有官方的工具可以通过刷bios来支持uefi启动,不过该工具支持的主板很少
另外一个工具是微星的,据说支持所有品牌,在华硕gtx660上测试成功,但不保证其他型号
工具:
vgabiosuefi.zip
(393.12 KiB) 已下载 202 次
(注意:这可能会摧毁你的显卡!!!!!!!!!!!!)
2.如果是仅有一个pciex16借口的主板,可以考虑pciex1转接或是pci显卡
3.ovmf与virtio在部分机器上可能有兼容问题


转载请注明出处,谢谢!
http://forum.ubuntu.com.cn/viewtopic.php?f=65&t=475190


参考
https://bbs.archlinux.org/viewtopic.php?id=162768
http://www.linux-kvm.org/page/Networking
附件
config.txt
(183.7 KiB) 已下载 199 次
头像
Hello World!
帖子: 3051
注册时间: 2008-06-23 15:19
系统: ���������
来自: 北欧某国
联系:

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#2

帖子 Hello World! » 2016-02-23 7:02

好深奥,我一时半会儿是看不懂了。

请问,必须要卸载驱动吗?
使用 sudo aticonfig --px-dgpu / sudo aticonfig --px-igpu 切换显卡可以吗?
使用 echo DIGD > /sys/kernel/debug/vgaswitcheroo/switch / echo OFF > /sys/kernel/debug/vgaswitcheroo/switch 切换显卡可以吗?

我也只是随便问问。我打算下半年显卡降价之后,再仔细研究这个问题。
http://noie.name 网站改版中。
justvirtual
帖子: 3
注册时间: 2016-02-10 11:53
系统: lubuntu

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#4

帖子 justvirtual » 2016-02-27 14:26

Hello World! 写了:好深奥,我一时半会儿是看不懂了。

请问,必须要卸载驱动吗?
使用 sudo aticonfig --px-dgpu / sudo aticonfig --px-igpu 切换显卡可以吗?
使用 echo DIGD > /sys/kernel/debug/vgaswitcheroo/switch / echo OFF > /sys/kernel/debug/vgaswitcheroo/switch 切换显卡可以吗?

我也只是随便问问。我打算下半年显卡降价之后,再仔细研究这个问题。
用pci-stub 禁用掉就可以,不同品牌显卡最好加入blacklist
justvirtual
帖子: 3
注册时间: 2016-02-10 11:53
系统: lubuntu

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#5

帖子 justvirtual » 2016-02-27 14:28

photor 写了:可以做GPU计算吗?
只要显卡支持就可以,因为是直通,cuda 可以正常使用
kvmkvm
帖子: 3
注册时间: 2016-09-10 20:53
系统: linux

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#6

帖子 kvmkvm » 2016-09-10 21:02

楼主,那个内核编译一定要做吗,我编译不了,研究KVM直通一个多星期了,每日每夜的搞,求指导一下
kvmkvm
帖子: 3
注册时间: 2016-09-10 20:53
系统: linux

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#7

帖子 kvmkvm » 2016-09-10 21:16

justvirtual, 楼主,请回复我,能否把具体的资料文献贴出来,我实在没法了,试了好多方法
manami5
帖子: 116
注册时间: 2016-06-21 13:16

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#8

帖子 manami5 » 2016-09-11 14:15

NVIDIA显卡的驱动会直接拒绝物理机的XEN内核,导致在XEN内核下根本无法启动X11。该如何解决?
hirako
帖子: 1
注册时间: 2017-05-10 10:05
系统: Centos

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#9

帖子 hirako » 2017-05-10 10:07

您好,请问直通后还能通过spice连接吗?
hope100
帖子: 1
注册时间: 2017-07-06 17:29

Re: [分享]kvm gpu passthrough 建立你的1cpu多gpu平台

#10

帖子 hope100 » 2017-07-06 17:32

【求指导】pci-stub运行不成功,提示:无法找到对应的路径,我用的是Ubuntu17.08
回复