*至少两个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
(若用qemu内置的seabios,则跳过此步)
代码: 全选
git clone git://git.seabios.org/seabios.git seabios
cd seabios
make
本文使用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
e3 1230 v2 为 8线程,故-j 8
代码: 全选
make -j 8 && make -j 8 modules && make -j 8 modules_install && make install
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)
代码: 全选
!/bin/bash
modprobe pci-stub
#显卡设备id 10de 11c0
#声卡设备id 10de 0e0b
set +x
chmod 755 /sys/bus/pci/drivers/pci-stub[code]
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"
************************************************************************************
测试
测试将使用两个显示屏,如果没有两个,可以将显示屏连上要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
*host=xxxxx 此处为lspci获得的总线
*x-vga 将选定的vfio-pci 设备用于图形显示
*vga none 禁用qemu内置的图形设备
若passthrough卡连接的显示屏上会显示字符,则成功
************************************************************************************
第二种方法
************************************************************************************
准备
0)apt-get安装qemu或源码编译qemu
代码: 全选
sudo apt install qemu-kvm
在此处下载 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
(该步骤与第一种方法相同)
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
*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
代码: 全选
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
×××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
推荐:性能增强
如下为性能优化
(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
代码: 全选
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
具体参考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 \
*cache=none aio=native 大幅提升性能,已测试
半虚拟化网卡
建立桥接br0
代码: 全选
sudo apt install bridge-utils
代码: 全选
!/bin/bash
brctl addbr br0
brctl addif br0 enp4s0
brctl stp br0 on
dhclient br0
route
代码: 全选
#!/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
脚本 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
代码: 全选
-mem-path /dev/hugepages \
-mem-prealloc \
-balloon none \
代码: 全选
taskset -c 0,1,2,3,4,5 \
qemu-system-x86_64 -enable...
××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××××
补充
1.关于nvidia gtx600 系列的efi问题
nvidia gtx600系列部分不支持efi,但有官方的工具可以通过刷bios来支持uefi启动,不过该工具支持的主板很少
另外一个工具是微星的,据说支持所有品牌,在华硕gtx660上测试成功,但不保证其他型号
工具: (注意:这可能会摧毁你的显卡!!!!!!!!!!!!)
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