Como fazer o Intel GVT-g funcionar
Olá pessoal! A Intel ofereceu uma excelente solução para o eterno problema: "Eu tenho um laptop no Linux e preciso executar o Windows com aceleração de hardware, mas não tenho um laptop pesado com duas GPUs e refrigeração líquida". Usando a arquitetura da GPU ou qualquer outra coisa, eles conseguiram fazer com que você pudesse dividir a GPU Intel integrada em duas ou mais GPUs.
Infelizmente, isso está longe de ser simples ... A documentação está um pouco desatualizada e algumas coisas quebram inexplicavelmente sem motivo aparente. Portanto, neste post, mostrarei como configurar uma máquina virtual Windows acelerada por hardware com virtio legal e drivers rápidos Intel GVT-g.
Para fazer isso, você precisa de uma GPU mais ou menos moderna ( nota do tradutor : de acordo com a documentação oficial , o GVT-g suporta placas de vídeo integradas, começando com a quinta geração Intel Core e a quarta geração Xeon ).

Etapa 1: configurar o kernel
Verifique se você possui uma versão nova do kernel. Parece que as opções para o GVT-g foram incluídas antes da versão 4.8, mas definitivamente funcionaram pior, por isso recomendo o uso do kernel disponível mais recente. Se você é original o suficiente para construir seu kernel, ative essas opções . Desative também a remoção de ksyms não utilizados, pois esta opção causa um erro .
Agora você precisa corrigir os argumentos da linha de comando do kernel. As opções importantes são:
i915.enable_gvt=1 kvm.ignore_msrs=1 intel_iommu=on i915.enable_guc=0
Certifique-se de não substituir o enable_guc=0
por algo que permita o carregamento do GuC, pois isso causará uma queda deprimente do driver i915. Ao inicializar, entre no seu ambiente de trabalho e verifique o diretório /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/
. Se não existir, o GVT-g não funcionará. Verifique os toros e / ou chore no travesseiro.
Como solução para o problema, você pode adicionar esses módulos ao initramfs e remover o i915 de lá.
Para um registro mais detalhado, você pode definir a variável drm.debug
com algum valor, por exemplo, defini-la como 0x02 incluirá mensagens dos drivers.
Etapa 2: criar um amigo virtual
Dentro do mdev_supported_types
você encontra um conjunto inteiro de diretórios. Esse conjunto é determinado pela quantidade de memória gráfica, cada subdiretório corresponde a algum tipo de GPU virtual. O arquivo de description
contém informações sobre a memória e as resoluções suportadas por esta GPU virtual. Se a criação de uma GPU virtual com memória grande usando a saída UUID no arquivo /create
fornecer um erro incompreensível, você terá várias opções. Primeiro, vá ao BIOS e adicione memória de vídeo, se possível. Se isso não funcionar, você pode interromper o seu DM, alternar para o framebuffer, criar a vGPU desejada a partir daí e retornar ao x11. Infelizmente, esse método gera muitos bugs e não permite atingir 60 FPS no meu laptop. Uma alternativa é criar uma vGPU menor e usar um programa especial para aumentar a resolução (CRU). Dessa maneira, consegui atingir 60 FPS e havia muito menos bugs e congelamentos.
Você pode criar vGPU com este comando:
$ echo ${vGPU_UUID} | sudo tee /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/${vGPU_TYPE}/create
E excluir - isto:
$ echo 1 | sudo tee /sys/bus/mdev/devices/${vGPU_UUID}/remove
Nota do tradutor :
Você pode gerar um UUID para vGPU usando o comando uuidgen
sem argumentos. A variável $ {vGPU_TYPE} indica um dos tipos listados no diretório mdev_supported_types
. Também é importante notar que a vGPU deve ser recriada a cada reinicialização; elas não são salvas entre os lançamentos do SO.
Etapa 3: Cortana grita com você
O próximo passo é muito melhor suportado e muito mais lento e doloroso - instalação do Windows 10. Não use torrents ou downloads não oficiais, ou a versão antiga do Windows, o link correto está aqui . Também vale a pena fazer o download da imagem do disco com drivers virtio projetados especificamente para acelerar os convidados aqui . Instale libvirt
e virt-manager
e execute libvirtd
:
# systemctl start libvirtd
Execute o virt-manager
e verifique se você está conectado à sessão do sistema libvirt
, e não ao usuário:

Nota do tradutor :
Para que o virt-manager possa conectar-se à sessão do sistema, você pode executá-lo como root, mas é melhor configurar a autorização, por exemplo, conforme sugerido no Arch Wiki .
Depois de fazer isso, você pode começar a criar uma máquina virtual. Na caixa de diálogo de configurações, selecione o download da iso-imagem local e localize a imagem baixada. Se o virt-manager
não o reconhecer como uma imagem do Windows 10, selecione-o manualmente, pois isso acelerará o Windows, pois o virt-manager
nesse caso fornece algumas interfaces de virtualização da Microsoft. Crie uma imagem de disco ou partição LVM e configure conforme necessário. A interface de instalação antes da instalação é muito limitada, por isso geralmente inicio a instalação e a paro imediatamente para configurar tudo. Aqui estão algumas configurações:


Nota do tradutor :
Apesar do fato de a publicação sobre a configuração de uma máquina virtual em um laptop, por algum motivo, a pergunta sobre a distribuição da rede usando um adaptador sem fio é omitida. O fato é que as configurações de rede padrão no virt-manager não são adequadas para uma rede sem fio. Nessa situação, a resposta a essa pergunta e seus comentários podem ajudar. O autor também sugere o uso do BIOS em vez do UEFI, provavelmente devido ao fato de o UEFI exigir configuração adicional. Além disso, parece que o tianocore ainda não está funcionando com o GVT-g, veja o bug 935 . No meu caso, no entanto, a VM foi iniciada, mas o Windows não reconheceu o monitor ao qual a placa de vídeo integrada estava conectada.
Se você precisar de acesso rápido ao disco ou até a capacidade da máquina virtual de compactar a imagem do disco ao excluir arquivos da máquina virtual (encaminhamento TRIM, para isso, você precisará criar a imagem com qemu-img create -f qcow2 -o preallocation=metadata,lazy_refcounts
, instruções completas aqui ), configure a unidade principal para usar SCSI. Você precisará de drivers para a máquina virtual para Windows para entender esse formato; portanto, conecte o disco do driver virtio baixado anteriormente para o Windows 10. Por padrão, eles usam um IDE, mas você pode acelerar a instalação várias vezes e usar menos código legado, se usar para DVDs SCSI. O Windows suporta isso imediatamente. Você também pode:
- Forçar o USB a usar o USB 3.0
- Adicione canais spice, spice-webdav e qemu-ga para copiar e colar e compartilhar arquivos entre a VM e o host
- Remover hardware virtual não utilizado
- Troque a placa de vídeo emulada para QXL e mude a exibição para SPICE, NÃO ouvindo a rede (mesmo loopback) ( Nota do tradutor: caso contrário, a VM simplesmente trava ).
- Mude o tipo de chip para Q35, definindo próximo às configurações do BIOS.
- Alimente o cachorro
Você também pode se acostumar com o seu novo amigo virsh edit
. Se você executá-lo usando o sudo -E
, suas variáveis de ambiente, em particular EDITOR, serão usadas para edição e você usará a sessão do sistema libvirt, não a do usuário. Neste arquivo, por exemplo, você pode atribuir uma correspondência entre processadores físicos e virtuais, devido a quais caches de processador são mais consistentes e o planejador se comporta de maneira menos estranha. Aqui está um exemplo de XML que você pode colocar lá:
<vcpu placement='static'>6</vcpu> <cputune> <vcpupin vcpu='0' cpuset='1'/> <vcpupin vcpu='1' cpuset='2'/> <vcpupin vcpu='2' cpuset='3'/> <vcpupin vcpu='3' cpuset='5'/> <vcpupin vcpu='4' cpuset='6'/> <vcpupin vcpu='5' cpuset='7'/> </cputune> <features> <hyperv> <relaxed state='on'/> <vapic state='on'/> <spinlocks state='on' retries='8191'/> <runtime state='on'/> <synic state='on'/> <stimer state='on'/> </hyperv> </features> <cpu mode='host-passthrough' check='none'> <topology sockets='1' cores='3' threads='2'/> </cpu>
Neste snippet, eu configuro a VM para que ela veja um processador com três núcleos físicos, cada um com dois hyperthreads. Além disso, cada processador / hiper-thread é anexado ao seu próprio hiper-thread e essa correspondência não muda. O Windows Scheduler conhece os hyperthreads e pode usá-los corretamente, sem contar como processadores separados. Também habilito algumas interfaces do Hyper-V que estão desativadas por padrão e podem não ter efeito. Se você usa o SPICE, pode adicionar as seguintes linhas para desativar a compactação, pois a rede externa ainda não é usada para acessar a VM.
<graphics type='spice'> <listen type='none'/> <image compression='off'/> <jpeg compression='never'/> <zlib compression='never'/> <playback compression='off'/> <streaming mode='off'/> </graphics>
Agora você pode configurar a ordem de inicialização e iniciar a instalação do Windows. Se você usar uma unidade virtio
ou SCSI, o Windows não a encontrará. Você precisará instalar o driver SCSI a partir da unidade que você conectou, eles estão localizados no diretório virtscsi/amd64
. Tudo deve correr bem, e o Windows deve inicializar em um modo lento e miserável, não acelerado. A Cortana começará a gritar com você e sua rede não funcionará. Atravesse tudo na área de trabalho. Lá, inicie o gerenciador de dispositivos, encontre todos os dispositivos não identificados e atualize os drivers para eles a partir do disco que você conectou. Você obterá um Windows um pouco mais rápido.
Etapa 4: a parte divertida
Há três maneiras de obter a exibição acelerada da VM virtual do Windows na tela da sua máquina.
- VNC ou algum outro protocolo de acesso remoto (geralmente essa é uma solução muito ruim). Nesta opção, você só precisa conectar o vGPU e desativar todos os outros monitores e placas de vídeo. Defina também a configuração
display='off'
. Você não precisa da opção igd-opregion
mostrada mais tarde. - SPICE (não consegui atingir 30 FPS ou mais, mas a transferência geral de arquivos e de transferência entre a VM e o host funciona).
- Interface QEMU incorporada no GTK + (a área de transferência e transferência de arquivos compartilhadas não funcionam, mas é possível obter 60 FPS com um patch).
Tudo o que você pretende usar, você ainda precisa usar a segunda opção para instalar os drivers da GPU. Os drivers internos da Microsoft não funcionam muito bem com o GVT-g no momento da redação e geralmente quebram. Antes de conectar o vGPU à VM, é recomendável baixar o driver mais recente da Intel (aparentemente, a Intel está mudando sua abordagem de distribuição de drivers , portanto, no futuro, essa etapa poderá ser diferente ou não ser necessária). Agora, verifique se você criou o vGPU. Abra o virt-manager
e substitua o bom QXL rápido por um Cirrus lento para evitar conflitos. Para conectar o vGPU à VM, é necessário abrir a virsh edit
e adicionar o seguinte fragmento em algum lugar:
<domain type='kvm' xmlns:qemu='http://libvirt.org/schemas/domain/qemu/1.0'> <hostdev mode='subsystem' type='mdev' managed='no' model='vfio-pci' display='on'>
<address uuid='fff6f017-3417-4ad3-b05e-17ae3e1a4615'/>
<address type='pci' domain='0x0000' bus='0x00' slot='0x09' function='0x0'/> <rom enabled='no'/> </hostdev> <graphics type='spice'> <listen type='none'/> <image compression='off'/> <jpeg compression='never'/> <zlib compression='never'/> <playback compression='off'/> <streaming mode='off'/> <gl enable='yes' rendernode='/dev/dri/by-path/pci-0000:00:02.0-render'/> <!-- , virt-manager , GL. , , auto. --> </graphics> <qemu:commandline> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.x-igd-opregion=on'/> <!-- libvirt , --> </qemu:commandline> </domain>
Nota: Quando forneço um snippet XML como este, você deve adicioná-lo ao atual, se possível, sem substituir nada.
Verifique se você criou UUIDs exclusivos para todas as vGPUs que você está usando e se os números de slot não conflitam com nenhum dos outros dispositivos PCI. Se o número do slot for posterior à Cirrus GPU, a máquina virtual falhará. Agora você pode iniciar a máquina virtual. Você precisa instalar o virt-viewer
para ver os dois monitores! Você pode se conectar a uma VM usando o comando
$ sudo -E virt-viewer --attach
Uma das telas ficará em branco ou não inicializada; a segunda é uma tela familiar, pequena e não acelerada. Expanda-o e, após entrar, instale o driver da GPU. Se você tiver sorte, tudo funcionará imediatamente. Caso contrário, você deve desligar e reiniciar a VM (não reinicie) usando a tela de trabalho. Agora é hora de abrir um terminal e executar dmesg -w
dentro. Este comando fornecerá algumas informações úteis sobre problemas e progresso geral usando a vGPU. Por exemplo, no momento da inicialização, o KVM reclamará sobre MSRs bloqueados, e você receberá algumas mensagens de acesso incorretas quando o vGPU for inicializado. Se houver muitos, algo está errado.
Se o sistema inicializar, você poderá abrir as configurações de exibição e desativar a tela não acelerada. Uma tela em branco pode ser oculta através do menu Exibir no virt-viewer
. Em princípio, as VMs já podem ser usadas, mas há algumas coisas que podem ser feitas para obter maior resolução e velocidade.
O utilitário CRU é muito útil. Você pode brincar com ele, e mesmo se você se deparar com alguns artefatos gráficos ou até uma tela quase preta, como se viu para mim, poderá executar o arquivo Restart64.exe
que acompanha o programa para reiniciar o subsistema de gráficos do Windows. Pessoalmente, eu uso esse utilitário para usar maior resolução em uma vGPU mais modesta.
Para alcançar 60 FPS excelentes, você precisa mudar para o monitor QEMU embutido no GTK + sem suportar uma área de transferência compartilhada com o host e os pães semelhantes, além de alterar uma linha e reconstruir o QEMU. Você também precisará adicionar vários argumentos desagradáveis de linha de comando ao seu XML. Remova a tela SPICE e a placa gráfica Cirrus e defina o atributo display
da sua vGPU como off
(libvirt não suporta a tela no GTK + e não permitirá a inicialização de display='on'
sem tela).
<qemu:commandline> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.x-igd-opregion=on'/> <qemu:arg value='-set'/> <qemu:arg value='device.hostdev0.display=on'/> <qemu:arg value='-display'/> <qemu:arg value='gtk,gl=on'/> <qemu:env name='DISPLAY' value=':1'/> <qemu:env name='GDK_SCALE' value='1.0'/> </qemu:commandline>
O dimensionamento para HiDPI no monitor QEMU funciona muito mal, portanto, vamos desativá-lo. Além disso, você precisará definir a variável DISPLAY
para o número de exibição que você está usando. Para dar ao usuário que está executando o qemu acesso ao servidor X, use o comando:
# xhost si:localuser:nobody
Se isso não funcionar, tente xhost +
, mas verifique se você está usando um firewall. Caso contrário, tente um método mais seguro.
Com esses truques, você ainda não ficará acima de 30 FPS por causa desse bug estúpido no QEMU, se você não o corrigir alterando a linha, conforme indicado no link do comentário. Certifique-se de criar apenas QEMU para x86-64, a menos que você pretenda usá-lo em outra plataforma. Anexei meu PKGBUILD, que não altera a linha, mas apenas coleta o QEMU para x86_64 sem suporte de armazenamento em rede aqui .
Se você se perder em algum lugar ao longo do caminho, poderá ver meu XML atual para libvirt .
Links úteis
Guia oficial de ajuste da GVT-g
Dma-buf Guia do Usuário
Artigo de instalação do Intel GVT-g no NixOS Wiki
Artigo do Arch Wiki sobre libvirt
Configuração de rede no KVM na interface sem fio
Site da Intel GVT-g
PS: Agradecemos àNNMON pela ajuda na revisão do texto da tradução e na correção de erros.