Sei sulla pagina 1di 9

Cmo virtualizar con KVM+QEMU + VGA Passthrough y no morir en

el intento.
(en construccin)
No me hago cargo del dao que hagis a vuestras mquinas, vuestra mente
o vuestro gato.

INDICE
1-Escogiendo hard / Escogiendo host y Guests
2-Instalando paquetera y tocando mdulos al arranque
3- Arrebandonos el hardware para nuestros guests
3.1 Opcional, usar la VGA primaria para passthrough
4- Scripteando con qemu
5-Briconsejo

1-Escogiendo hard / Escogiendo host y Guests


Trabajarermos con:
Asrock 970A pro3 R2
AMD FX 8320
8GB DDR3 1866 @ 1600
GPUPCIex16 -> MSI Radeon 7950 Twin Frozr
GPUPCIex16x(4x)->Radeon Asus Hd5450
GPUPCIex1x+serruchomod -> EVGA Nvidia GT210
HDD1 WD1000GB no se usar porque tengo un windows 8.1 nativo
instalado
HDD2 ST500 aqu ir todo el batiburrillo
Lo ideal si vais a tener varias VMs es que no compartan bus sata para no
compartir bus para lectura/escritura de HDD pero bueno es lo que hay.
Usaremos Ubuntu 14.04 Desktop 64 bits porque no tena ganas de partirme
el pecho en compilar paquetera (acepto aluviones de hostias xD por noob).
Como guests Windows escojo Windows 8.1 64bits porque el 7 se eterniza
expandiendo archivos pero tambin instalara sin hacer nada raro.
Habilitad en BIOS/UEFI IOMMU y otras tecnologas de virtualizacin, en mi
placa aparece en el apartado northbridge. Es posible que el fabricante no de
soporte ni deje habilitarlo pero este chipset tiene la capacidad por lo que si
no podis habilitarlo, yo mandara a tomar por culo para siempre a esa
marca de placas por vagos.

2-Instalando paquetera y tocando mdulos al arranque


Pongmonos serios ya. Instalamos el host CON SWAP por favor no
hagamos el mongolo y se nos cuelguen las mquinas por habernos pasado
con la RAM a repartir.
Una vez logueados en Ubuntu:
sudo apt-get update
sudo apt-get upgrade
sudo apt-get install openssh-server qemu-kvm virt-manager vim
Yo instalo a parte de la paquetera de virtualizacin y sus dependencias, un
server ssh because the flies y un editor de texto.
Ahora vamos a habilitar IOMMU en el kernel
sudo vim /etc/default/grub
Y en esta lnea GRUB_CMDLINE_LINUX_DEFAULT
Aadiremos entre las comillas iommu=on iommu=1.
Aqu se pueden agregar varias opciones y podis probar otras
combinaciones como por ejemplo iommu=pt sustituyendo a iommu=on
pero empezaremos poniendo solo esto. Si vfio no pilla las grficas al iniciar
la VM u os da problemas aadid esta opcin tambin:
vfio_iommu_type1.allow_unsafe_interrupts=1
Guardamos y salimos. Ahora editamos:
sudo vim /etc/modules
Y aadimos:
pci_stub
vfio
vfio_iommu_type1
vfio_pci
kvm
kvm_amd

Guardamos y salimos
sudo update-grub
Esperamos y reiniciamos. Al arranque comprobaremos que tenemos todo
OK.
dmesg | grep AMD-Vi
Deberamos obtener varias lneas una de ellas con esto AMD-Vi:
Initialized for Passthrough Mode

Si no se habilita, revisad las opciones de placa y del grub. Asimismo podis


tener un kernel que no est compilado con soporte IOMMU (ya me
extraara si estis usando el Ubuntu antedicho) si es as ya sabis, a
recompilar os toca aadiendo este soporte adems de VFIO VFIO PCI (que
no lo tendris tampoco) y no estara mal aadir el parche ACS Override. Pero
esto no me toca a mi explicarlo porque tengo poca idea.

3- Arrebandonos el hardware para nuestros guests


Mucho cuidadn, ahora tenemos que pensar qu gpus vamos a pasar pero
tranquilos que quedarse sin la principal (si es como la ma) en Ubuntu 14.04
es misin casi imposible y lo veris en el apartado 3.1. Lo que reservemos
en pci-stub, en teora no ser usable para los mdulos de nuestro host, pero
como digo es solo teora ya que depende mucho del hardware an as
conviene tener acceso por terminal ssh no sea que la manguemos.
lspci nn | grep VGA //nos devolver n lneas por n vgas pinchadas
Un ejemplo de lnea con datos inventados:
01:00.0 VGA compatible controller [0300]: AMD RADEON Tahiti PRO/XT [MSI RADEON
7950/7970] [1002:68f9]

A nosotros nos interesa lo que marco en rojo. Lo primero es un BusID PCI y


lo segundo un ID de dispositivo. Lo siguiente es identificar los HDMI
tambin:
L

spci nn | grep HDMI

nos devolver n lneas por n HDMI disponible excepto nvidias que


devuelven el mismo HDMI.
Vamos creando las configs vfios que es facilito (un fichero necesario por
cada mquina virtual:
sudo vim /etc/vfioconfig1
Aqu aadimos el/los BusID con salto de lnea entre cada uno empezando
por 0000 (no se por qu es as, imagino que ser porque cada PCIroot use
un prefijo):
0000:01:00.0
0000:01:00.1
Uno es la VGA y el otro el HDMI, vosotros ponis el vuestro, si no es la
principal probablemente vuestro BusID no ser 01:00:0 sino 02 o 03:00.0.
Guardamos y salimos
Ahora hacemos que pci-stub se agarrapie el/los device ID.
sudo vim /etc/initramfs-tools/modules

Aadimos los ids separados por ,


pci_stub ids=1002:67f9,1002:aaa0

Guardamos y salimos. Adicionalmente es altamente recomendable meter en


blacklist los mdulos que puedan hacer uso de nuestro hardware.
sudo vim /etc/modprobe.d/blacklist.conf
Metemos con un salto de lnea entre cada mdulo:
blacklist radeon
blacklist fglrx
etc, guardamos y salimos.
sudo update-initramfs u
Reiniciamos y si todo ha ido bien, al arrancar ejecutamos:
dmesg |grep pci-stub
Y observamos cmo se ha reservado las GPU: pci-stub 0000:01:00.0:
claimed by stub
Si estis haciendo todo esto con VGA secundarias pasad del punto 3.1.
3.1 Opcional, usar la VGA primaria para passthrough
Esto para valientes que no tienen remedio (like me xD). Qu es lo que
ocurre si queremos pasar la VGA con el bus ms gordo para jugar que es el
primario siempre?Debemos relegar nuestra grfica de 250 pavos a un bus
4x? o peor an y si tienes un Windows nativo con el que jugabas,
cambiamos de PCIex a uno de menos bus la gpu que quieres pasar? Nada
chicos desinstalad todo y empezad con XEN que es super bonito super chuli
y nos deja hacer todo esto mientras KVM es una mierda y dicen los
entendidos que no funciona Es coa, es coa xD tambin quiero aclarar
que este comportamiento random es aplicable a hardware igual al mo igual
a vosotros os deja pasar la primaria sin problemas.
En mi caso mi maravillosa UEFI de las 3 GPU solo me dejaba poner como
principal o una GPU PCI32 o la GPU pinchada en PCIExpress 16x pasando de
la otra GPU 4x y de la 1x ni te cuento.
Si habis seguido el tutorial con vuestra GPU principal y es una Radeon os
habris dado cuenta de que no habis perdido el video, ni siquiera el
xserver se cae XD. Menos mal que el pci-stub lo pillaba porque si no
Lo primero es reconfigurar el servidor X para que use la GPU que vosotros
queris, no la que a l le de la gana.
lspci nn | grep VGA
En mi caso yo quiero usar la que est en el bus: 05:00.0 Nvidia GT210.
Editamos nuestras X si sabemos:

sudo vim /etc/X11/xorg.conf


U os aconsejo aqu que ejecutis mejor: X configure y copiis el fichero
generado a la ruta anterior y empecis a borrar cosas, debemos tener
definido Display0 Scrren0 Device0 para que salga de nuestra GPU BusID
05:00.0. Os pego un ejemplo de Section Device para usar solo una GPU y
un solo monitor para el host.
Section "Device"

### Available Driver options are:-

### Values: <i>: integer, <f>: float, <bool>: "True"/"False",

### <string>: "String", <freq>: "<f> Hz/kHz/MHz",

### <percent>: "<f>%"

### [arg]: arg optional

#Option

"SWcursor"

# [<bool>]

#Option

"HWcursor"

# [<bool>]

#Option

"NoAccel"

# [<bool>]

#Option

"ShadowFB"

# [<bool>]

#Option

"VideoKey"

# <i>

#Option

"WrappedFB"

# [<bool>]

#Option

"GLXVBlank"

# [<bool>]

#Option

"ZaphodHeads"

# <str>

#Option

"PageFlip"

# [<bool>]

#Option

"SwapLimit"

# <i>

#Option

"AsyncUTSDFS"

# [<bool>]

Identifier "Card0"

Driver

BusID

"nouveau"

"PCI:5:0:0"

EndSection

Una vez hecho esto, probad a reiniciar, veris que el splash no se muestra
en la gpu principal, pero inmediatamente tendris el xserver levantado
desde la GPU deseada si lo habis hecho bien. Pues bien si segus el tutorial
e intentis levantar la VM sin seguir leyendo en este punto tendris una
bonita ristra de errores relacionada con esto
VFIO 0000:01:00.0 BAR 0 mmap unsupported.

Y diris puto Dani me ha estado troleando durante 30 minutos


Me cost una semana dar con el problema y se llama grub (o una
coimbinacin de grub + placa con bios de mierda) que inicializa la GPU que
la bios marca como principal. Si trabajis con Debian todo esto os lo
ahorris creo recordar porque la libera bien. Editad esto:

sudo vim /boot/grub/grub.cfg


Buscis la opcin de carga default de vuestro Ubuntu y dentro de las
opciones eliminad 2 lneas:
load_video
gfxmode $linux_gfx_mode

No tengis miedo a esto porque el grub seguir mostrando sus opciones.


Guardad y reiniciad.
Con esto y de una vez por todas se olvidar de la GPU principal y podris
iniciar tranquilamente, incluso si tenis problemas podris iniciar en
recovery puesto que la opcin la hemos cambiado para el arranque default.
No se qu consecuencias trae esto, posiblemente me quede sin el resto de
terminales multiusuario pero me preocupa poco cuando puedo acceder por
ssh y tengo un magnifico xserver levantado en mi querida GT210.

4- Scripteando con qemu


Preparmonos nuestra iso de instalacin y nuestras bios de GPU ubicadas
en nuestro $HOME y vamos a crear discos duros virtuales de 80GB que yo
alojo en /var.
sudo dd if=/dev/zero of=/var/windows81.img bs=1M seek=80000 count=0

Usad este script:


#!/bin/bash
configfile=/etc/vfioconfig1
vfiobind() {
dev="$1"
vendor=$(cat /sys/bus/pci/devices/$dev/vendor)
device=$(cat /sys/bus/pci/devices/$dev/device)
if [ -e /sys/bus/pci/devices/$dev/driver ]; then
echo $dev > /sys/bus/pci/devices/$dev/driver/unbind
fi
echo $vendor $device > /sys/bus/pci/drivers/vfio-pci/new_id
}
modprobe vfio-pci
cat $configfile | while read line;do
echo $line | grep ^# >/dev/null 2>&1 && continue
vfiobind $line
done
sudo qemu-system-x86_64 -enable-kvm -M q35 -m 4096 -cpu host \

-smp 4,sockets=1,cores=4,threads=1 \
-bios /usr/share/qemu/bios.bin -vga none \
-device ioh3420,bus=pcie.0,addr=1c.0,multifunction=on,port=1,chassis=1,id=root.1 \
-device vfio-pci,host=01:00.0,bus=root.1,addr=00.0,multifunction=on,x-vga=on \
-device vfio-pci,host=01:00.1,bus=root.1,addr=00.1 \
-drive file=/var/windows81.img,id=disk,format=raw -device ide-hd,bus=ide.0,drive=disk
\
-drive file=/home/dani/Windows81.iso,id=isocd -device ide-cd,bus=ide.1,drive=isocd \
-boot menu=on
exit 0

Adecuad vuestros datos a lo marcado en rojo. Lo guardis como maquina.sh


+ permisos de ejecucin y a testear:
sudo sh maquina.sh
Veremos como por la salida de nuestra querida VGA que queramos pasar
sale el video tan deseado. Si no lo logramos pasamos tambin su bios
previamente extrada modificando la lnea:
-device vfio-pci,host=01:00.0,bus=root.1,addr=00.0,multifunction=on,x-vga=on,
romfile=/home/dani/Tahiti.bin \

Vamos con usb:


lsusb
Aqu tenemos una ristra de dispositivos usb en sus respectivos buses.
Bus
Bus
Bus
Bus
Bus
Bus

002
002
002
002
002
002

Device
Device
Device
Device
Device
Device

017:
016:
015:
013:
014:
011:

ID
ID
ID
ID
ID
ID

045e:00cb Microsoft Corp. Basic Optical Mouse v2.0


045e:00cb Microsoft Corp. Basic Optical Mouse v2.0
045e:00cb Microsoft Corp. Basic Optical Mouse v2.0
045e:07f8 Microsoft Corp.
045e:07f8 Microsoft Corp.
045e:07f8 Microsoft Corp.

En teora se podra pasar controladoras completes USB pero a mi no me


funcion. Olvidaos de pasar USB3.0 completa o Hubs porque no va.
Aadimos en el script debajo de los drive files los device ID usb que
queramos pasar.
-usb -usbdevice host:045e:00cb -usbdevice host:045e:07f8 \
Guardamos salimos y rearrancamos la mquina, a veces tarda un poco en
pasar los USB tened algo de paciencia, a m me funciona incluso el hotplug,
es decir con la vm arrancada pincho el teclado despus y se lo come sin
problema.
Vamos con la red:
<< en contruccin>>

5-Briconsejo
Leed, leed mucho y no os desesperis. A veces es una chorrada lo que no os
funciona.
Links de obligatoria lectura:
https://bbs.archlinux.org/viewtopic.php?id=162768
http://www.pugetsystems.com/labs/articles/Multiheaded-NVIDIA-Gamingusing-Ubuntu-14-04-KVM-585/

Potrebbero piacerti anche