Intel GVT (iGVT, Intel® Graphics Virtualization Technology) é uma solução desenvolvida pela Intel para permitir que parte ou toda a capacidade das GPU (Graphics Processing Unit) Intel seja cedida para convidados KVM ou Xen, suas implementações chamadas KVMGT e XenGT, respectivamente. Há três formas diferentes de se aplicar a tecnologia iGVT:
- Aceleração gráfica virtual dedicada (iGVT-d): um convidado por GPU;
- Aceleração gráfica virtual compartilhada (iGVT-s): múltiplos convidados por GPU;
- GPU virtual: (iGVT-g): múltiplos convidados por GPU. Nesse artigo, será dado foco nessa implementação.
Intel GVT-g (ou iGVT-g, Intel® Graphics Virtualization Technology-g) é uma tecnologia que permite criar GPU virtuais que podem ser utilizadas por convidados KVM ou Xen. Dependendo da quantidade de memória RAM disponível e da fatia de memória dada a cada convidado, é possível ter até sete convidados utilizando a mesma GPU Intel.
Através dela, é possível criar máquinas virtuais capazes de utilizar as capacidades de codificação e decodificação de vídeo da Intel (Intel QSV e/ou VAAPI), é possível utilizar a aceleração 3D para o uso de programas de CAD (Computer Aided Design) e jogos. Tudo isso dentro do convidado e ainda permitindo ao hospedeiro utilizar a GPU.
Requisitos para o hospedeiro
Para utilizar a tecnologia iGVT-g, é necessário ter um processador Intel, ao menos, da 5ª Geração com GPU Intel Graphics, com a virtualização ativada (VT-d e VT-x) e uma placa-mãe compatível. A quantidade de memória disponível para ceder aos convidados e a quantidade de convidados simultâneos dependem de quanta memória RAM o sistema hospedeiro possui instalada.
Nesse caso, será utilizado o QEMU/KVM para criar os convidados. A necessidade ou não de construir o QEMU dependerá de qual alternativa será escolhida a respeito da tela do convidado (isso será explicado adiante).
O hospedeiro utilizado no exemplo é o Xubuntu 18.04. O Ubuntu 18.04 vem com o kernel
Linux na versão 4.15 (no momento em que escrevo, 4.15.0-23). Essa versão possui as configurações necessárias para o funcionamento do Intel GVT-g com KVM. A partir da versão 4.16 uma opção essencial para permitir a estabilidade de convidados Windows passou a funcionar. Portanto, recomenda-se usar o kernel Linux com a versão ao menos 4.16.
Caso seja necessário construir um kernel porque o que determinada distribuição provê não possui as configurações necessárias, é preciso garantir que as seguintes configurações estejam presentes e configuradas: CONFIG_DRM_I915_GVT, CONFIG_DRM_I915_GVT_KVMGT, CONFIG_VFIO_MDEV e CONFIG_VFIO_MDEV_DEVICE
Um exemplo, baseando-se nas configurações do kernel do Ubuntu 18.04:
CONFIG_DRM_I915_GVT=y
CONFIG_DRM_I915_GVT_KVMGT=m
CONFIG_VFIO_MDEV=m
CONFIG_VFIO_MDEV_DEVICE=m
Tenha certeza de que as opções acima estão no arquivo .config ANTES de construir o kernel. Para construir o kernel (o foco não é ensinar a construir o kernel, mas ainda assim há essa pequena explicação):
git clone git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
$ make oldconfig
Antes do comando abaixo, veja se as opções CONFIG_* acima estão configuradas corretamente no arquivo .config:
make -j `nproc` bindeb-pkg
Recomenda-se grandemente ler a ajuda do makefile do kernel Linux (make help), há opções que criam pacotes DEB (como a do exemplo) e pacotes RPM prontos para serem instalados em distribuições que utilizam tais pacotes.
Uma vez com o kernel construído e instalado com as configurações necessárias, é preciso adicionar alguns módulos no initramfs. No caso do Xubuntu 18.04, é necessário adicionar no arquivo
/etc/initramfs-tools/modules as seguintes três linhas:
kvmgt
vfio-iommu-type1
vfio-mdev
E atualizar o initramfs com:
sudo update-initramfs -u -k all
Caso haja muitas versões do kernel Linux instaladas, isso pode demorar. -u significa update (atualizar), -k define a versão do kernel. Com "all", todas as versões são atualizadas.
Com o kernel configurado e instalado e o initramfs atualizado, é preciso adicionar algumas opções na linha de comando da inicialização do sistema. No caso do GRUB2 no Xubuntu 18.04, o arquivo é o
/etc/default/grub, para editá-lo, pode-se usar o seguinte comando:
sudo nano /etc/default/grub
Na linha que contém:
GRUB_CMDLINE_LINUX_DEFAULT=
Algumas opções precisam ser adicionadas entre as aspas. Por padrão, há apenas "quiet splash". É NECESSÁRIO ADICIONAR:
intel_iommu=on i915.enable_gvt=1
A linha de comando fica semelhante a:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on i915.enable_gvt=1"
Outras opções são recomendadas. kvm.ignore_msrs=1 é importante caso os convidados sejam Windows, sem ela o sistema se torna instável pois o convidado pode tentar ler registros de forma direta onde o KVM não definiu valores. kvm.halt_poll_ns=0 e kvm.halt_poll_ns_grow=0 são opções relevantes para o som, sem elas configuradas os convidados tornam-se cada vez mais lentos conformes sons são reproduzidos neles, especialmente convidados Windows. A linha de comando ficaria algo como:
GRUB_CMDLINE_LINUX_DEFAULT="quiet splash intel_iommu=on i915.enable_gvt=1 kvm.ignore_msrs=1 kvm.halt_poll_ns=0 kvm.halt_poll_ns_grow=0"
Então um:
sudo update-grub
Atualiza o GRUB2 para que as opções estejam presentes ao iniciar o sistema. Ao reiniciá-lo, o sistema irá iniciar com essas opções adicionais.
Caso tudo tenha ocorrido corretamente, deve ser possível ver quais são os modos disponíveis em que se pode criar as GPUs virtuais. Para isso, há um diretório no sysfs onde as opções podem ser vistas. Nesse exemplo, o Intel HD Graphics é o dispositivo PCI 00:02.0, o endereço PCI pode ser diferente, logo pode ser necessário adaptar o caminho do diretório, isso pode ser visto com o comando:
lspci
Com o endereço PCI sendo 00:02.0, o diretório é:
/sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
Dentro desse diretório devem haver outros, cada um representando um modo. No exemplo, tem-se:
i915-GVTg_V5_4
i915-GVTg_V5_8
E, dentro de cada um desses diretórios, há três arquivos com informações. O arquivo available_instances mostra quantas GPUs virtuais podem ser criadas com aquela configuração, o arquivo device_api mostra a API utilizada, nesse caso, vfio-pci, e o arquivo description tem detalhes do modo:
low_gm_size: 128MB
high_gm_size: 512MB
fence: 4
resolution: 1920x1200
weight: 4
O diretório devices tem ligações simbólicas para as GPUs virtuais criadas. O arquivo create é utilizado para criar as GPUs virtuais, seu uso será explicado nas configurações do convidado.
Enquanto com o que foi feito até agora já seria possível inicializar o QEMU, na experiência utilizando iGVT-g sem configurar o driver de vídeo do hospedeiro em um Lenovo Ideapad 310-14ISK com um Intel Core i3-6100U e uma Intel HD Graphics 520, podem ocorrer piscadas na tela por um motivo ainda desconhecido.
Para corrigir é preciso alterar o driver de vídeo que é utilizado de "modesetting" para "intel". Inicialmente é preciso instalar o driver Intel caso não esteja instalado. No caso do Ubuntu 18.04, para instalar o pacote necessário se utiliza:
sudo apt install xserver-xorg-video-intel
Então deve-se editar ou criar o arquivo
/etc/X11/xorg.conf usando:
sudo nano /etc/X11/xorg.conf
Deixando-o com o seguinte conteúdo:
Section "Device"
Identifier "Intel Graphics"
Driver "intel"
Option "DRI" "3"
EndSection
E então se pode reiniciar a sessão do X com, por exemplo:
sudo systemctl restart lightdm.service
Ou reiniciar o sistema para aplicar a nova configuração do driver de vídeo.
Além disso, é recomendável utilizar UEFI para os convidados. Usando iGVT-g muitas das capacidades de vídeo estão disponíveis, mas os modos VGA não estão, devido a sua complexidade. Isso significa que a tela inicial do GRUB2, ou a tela inicial do ISOLINUX não aparecem no modo BIOS, o que compromete o funcionamento dos convidados. Enquanto o GRUB2 consegue lidar com o fato de não poder ser exibido, o ISOLINUX faz com que o convidado trave.
Como alternativa, há um framebuffer básico que funciona apenas em UEFI. Ele é capaz de prover a tela inicial do GRUB2 de forma limitada, mas suficiente para escolher e editar opções do GRUB2.
Para usar convidados com UEFI, o hospedeiro precisa do OVMF. Há o pacote ovmf no Ubuntu 18.04:
sudo apt install ovmf
Ou há a possibilidade de construir o OVMF do Git
https://github.com/tianocore/edk2, mas o processo não é tão trivial, leia a documentação disponível primeiro.