Convidados Windows não são muito difíceis de serem configurados, mas falhar em configurá-los de forma apropriada causa muitos problemas, podendo tornar o sistema hospedeiro inoperante. A versão a ser utilizada no sistema convidado é o Windows 10 Single Language (pt-BR) Pro x86_64. A recomendação é usar o kernel
Linux ao menos na versão 4.16 no hospedeiro.
Inicialmente, tenha certeza de que na linha de comando da inicialização do hospedeiro Linux as seguintes opções estejam configuradas:
kvm.ignore_msrs=1 kvm.halt_poll_ns=0 kvm.halt_poll_ns_grow=0 intel_iommu=on i915.enable_gvt=1
As opções intel_iommu=on e i915.enable_gvt=1 são requeridas para usar o iGVT-g.
A opção kvm.ignore_msrs=1 é essencial para a estabilidade dos sistemas hospedeiro e convidado, pois sem ela o Windows pode tentar acessar endereços da memória não definidos ou não acessíveis pelo KVM, causando telas azuis e/ou corrupção.
Veja as consequência de ignorar a opção do parágrafo acima:
A corrupção chegou ao sistema hospedeiro, tornando-o inoperante.
As opções kvm.halt_poll_ns=0 e kvm.halt_poll_ns_grow=0 diminuem a degradação de desempenho que a emulação de som causa (após algumas horas ligado, o convidado fica lento sem elas mesmo sem uma saída de áudio).
Tendo certeza de que o hospedeiro está pronto, é possível começar as preparações para o convidado. A primeira observação: o convidado Windows precisa de bem mais espaço que o convidado Linux. Ao invés de criar imagens de 10 GB, é melhor criar images de, no mínimo, 32 GB. Mesmo assim, o convidado Windows tende a ficar sem espaço devido às atualizações do sistema, então é necessário cuidado com o espaço em disco.
Inicialmente, deve-se criar a GPU virtual para o Windows. Use o comando uuid para criar um identificador para nomear a GPU virtual. Se não estiver instalado, instale usando:
sudo apt install uuid
Então:
uuid
185802b6-7405-11e8-9e14-6ff0319bd0dc
sudo sh -c 'echo 185802b6-7405-11e8-9e14-6ff0319bd0dc > /sys/bus/pci/devices/0000:00:02.0/mdev_supported_types/i915-GVTg_V5_4/create'
Várias opções que não eram relevantes em convidados Linux serão requeridas em convidados Windows, por isso a linha de comando do QEMU fica bastante grande:
sudo env PULSE_LATENCY_MSEC=0 QEMU_PA_SAMPLES=98875 QEMU_AUDIO_DAC_FIXED_FREQ=48000
qemu-system-x86_64
-hda win10.raw -enable-kvm -cpu host -smp cores=2,threads=2 -m 3G
-device vfio-pci,sysfsdev=/sys/bus/pci/devices/0000:00:02.0/185802b6-7405-11e8-9e14-6ff0319bd0dc,rombar=0,x-igd-opregion=on,display=off,x-vga=off
-usb -device usb-mouse -bios /usr/share/ovmf/OVMF.fd -monitor vc -serial stdio
-vga cirrus -display gtk -cdrom "Win10_1709_BrazilianPortuguese_x64.iso"
-netdev user,id=net0,hostfwd=::33890-:3389 -device e1000,netdev=net0,bus=pci.0,addr=0x8
Em primeiro lugar, há algumas variáveis de ambiente. A primeira (PULSE_LATENCY_MSEC=0) faz com que a latência do PulseAudio seja de 0 ms (isso não é perfeito e há aplicações que podem ter problemas, mas essa não teve). A segunda (QEMU_AUDIO_DRV=pa) escolhe o driver de áudio do QEMU, nesse caso PulseAudio. A terceira (QEMU_PA_SAMPLES=98875) define quantas amostras serão armazenadas no buffer do som. A quarta (QEMU_AUDIO_DAC_FIXED_FREQ=48000) é a taxa de amostragem utilizada pelo QEMU. Mesmo com todas essas opções, o som emulado ainda pode ter problemas, mas eles serão muito menores do que antes. Os valores foram iterados até chegar a uma experiência boa.
A respeito do comando do QEMU em si:
A imagem do HD é raw, KVM é habilitado, a CPU escolhida é a mesma do hospedeiro, foram alocados dois núcleos, cada um com duas threads e foram alocados 3 GB de memória RAM.
A GPU virtual é configurada, sem passar ROM para ela, com x-igd-opregion=on (com convidados Windows, é necessário pela estabilidade), o display e a VGA estão desativados, ou seja, sem dma-buf.
Foi definido que a máquina virtual tem dispositivos USB, um mouse USB foi definido (isso é importante), é utilizado o firmware UEFI do OVMF, o monitor (terminal do QEMU) está no console virtual (na mesma janela onde aparece a tela do convidado) e a porta serial está no stdio (no terminal de onde o comando foi executado, por exemplo).
A VGA virtual é Cirrus, o display (a interface) é GTK, o CD-ROM é a mídia de instalação do Windows 10, a rede foi escolhida em modo usuário e redireciona a porta 33890 do hospedeiro para a 3389 do convidado (para utilizar com o protocolo RDP). O endereço PCI do adaptador de rede foi selecionado bem alto para evitar conflitos com as GPUs (tanto a VGA virtual como a GPU Intel).
A instalação procede normalmente, mas atenção: para usar como convidado, não é possível usar o Windows 10 Home, é necessário ter uma licença, ao menos, do Windows 10 Pro.
Uma vez com o sistema instalado, será pedido sua conta da Microsoft (se houver) ou poderá criar um novo usuário e senha, e haverá a possibilidade de configurar quais informações são enviadas. Uma vez com tudo pronto, o sistema deve iniciar e quase que imediatamente avisar a respeito da ausência de um driver de vídeo, e ele está correto. No entanto, o que ele faz a seguir é ruim (mais sobre isso adiante), ele instala o driver genérico.
É preciso ativar o acesso remoto do convidado Windows. Para isso, abra o Meu Computador, vá em Propriedades -> Configurações remotas -> Remoto e escolha a opção "Permitir conexões remotas com este computador". Aplique e teste tentando conectar-se ao localhost:33890 com o vinagre ou outro programa. Se falhar, tente desmarcar a opção "Permitir conexões somente de computadores que estejam executando a Área de Trabalho Remota com Autenticação no Nível da Rede (recomendável)" e aplique. Só desative se a tentativa falhar.
Uma vez com o protocolo RDP funcionando, é preciso instalar o driver da Intel. Para isso, acesse o site da Intel pelo convidado e busque pelo driver adequado para sua GPU Intel (sim, é o mesmo driver que seria utilizado se o Windows 10 fosse o hospedeiro). Qual é a versão do driver depende da GPU, mas é necessário que seja baixado o arquivo ZIP, pois o arquivo EXE tende a falhar por não ser certificado (explicações a frente). A página onde se podem buscar os driver é https://downloadcenter.intel.com/ .
Pode haver mais de um driver disponível. Os certificados pela Intel são da versão 15.45, mas eles não têm DirectX12, têm desempenho pior e será uma luta constante para impedir que o Windows Update instale o driver genérico. A versão 15.45 do driver era mais estável com versões 4.15 do kernel Linux. A partir do kernel 4.16, a diferença de estabilidade diminuiu muito ou deixou de existir, mas a de desempenho ainda é gritante. Busque pelo modelo de sua GPU e baixe a versão ZIP do driver que desejar.
Os drivers mais antigos da Intel podem fazer o convidado nunca iniciar a tela, e podem fazer o seguinte erro surgir no dmesg:
[26948.391884] Detected your guest driver doesn't support GVT-g.
[26948.391888] Now vgpu 1 will enter failsafe mode.
Se as mensagens acima surgirem ao iniciar o convidado, a tela nunca será iniciada. Reinicie o convidado para tentar novamente.
Evite o driver genérico a todo o custo (é aquele com data 11/11/2016). O driver genérico causa erros 43 de forma consistente e impede que o driver Intel seja atualizado normalmente. Caso ele acabe instalado, é melhor removê-lo no Modo de Segurança e então, ao reiniciar e voltar ao modo normal, desativar a internet para poder instalar o driver da Intel sem o genérico reaparecer. Com as versões 24.xxx, o genérico não será mais oferecido.
Uma vez que os drivers corretos tenham sido devidamente instalados, abra o dxdiag. Se não der tela azul no momento ou alguns segundos depois, é sucesso. O Windows 10 convidado está estável.
O dxdiag deve mostrar algo semelhante a:
Nas configurações de energia, é melhor desabilitar a opção de apagar a tela devido a inatividade e desabilitar a suspensão do sistema (uma das poucas ocasiões em que telas azuis ainda ocorrem).
O convidado Windows 10 sem dma-buf está pronto para ser usado e a VGA virtual pode ser removida.
Para criar um convidado com dma-buf, os cuidados com o hospedeiro são os mesmos, mas o comando usado no QEMU é um pouco diferente:
sudo env PULSE_LATENCY_MSEC=0 QEMU_PA_SAMPLES=98875 QEMU_AUDIO_DAC_FIXED_FREQ=48000
qemu-system-x86_64
-hda win10.raw -enable-kvm -cpu host -smp cores=2,threads=2 -m 3G
-device vfio-pci,sysfsdev=/sys/bus/pci/devices/0000:00:02.0/185802b6-7405-11e8-9e14-6ff0319bd0dc,rombar=0,x-igd-opregion=on,display=on,x-vga=off
-usb -device usb-mouse -bios bios.bin -monitor vc -serial stdio
-vga cirrus -display gtk,gl=on -cdrom "Win10_1709_BrazilianPortuguese_x64.iso"
-netdev user,id=net0,hostfwd=::33890-:3389 -device e1000,netdev=net0,bus=pci.0,addr=0x8
Boa parte do comando é igual, mas a opção display=on foi configurada para ativar o dma-buf, a opção -bios foi trocada para a bios.bin, que é a SeaBIOS, construída junto com o QEMU 2.12 (ela pode ser localizada no diretório onde o QEMU 2.12 foi instalado, dentro do diretório share/qemu), pois o convidado Windows 10 não inicializa a tela em modo UEFI (só pode ser acessado remotamente). Na opção -display, adicionou-se o gtk,gl=on para que a janela GTK seja acelerada por OpenGL.
Os procedimentos para configurar o convidado Windows 10 com dma-buf são iguais aos do convidado Windows 10 sem dma-buf, incluindo o RDP, que precisa ser ativado no convidado com dma-buf também.
Quando usando o modo BIOS, o dxdiag deve mostrar algo como:
Preste atenção nos valores exibidos em BIOS: veja como o dxdiag não é capaz de apresentar os valores. Sem a opção kvm.ignore_msrs=1 na linha de comando do kernel Linux e sem a opção x-igd-opregion=on na linha de comando do QEMU, quando o Windows tenta ler os valores que deveriam preencher o local das variáveis, o convidado sofre uma pane e dá tela azul, podendo comprometer a funcionalidade do hospedeiro também.
Uma vez que o uso do convidado tenha terminado, pode-se remover a GPU virtual usando (vide exemplo):
sudo sh -c 'echo 1 > /sys/bus/pci/devices/0000:00:02.0/185802b6-7405-11e8-9e14-6ff0319bd0dc/remove'