Вопрос или проблема
У меня установлена Windows на виртуальной машине, использующей libvirt/kvm. Я настроил свою дискретную видеокарту (nvidia) для сквозного доступа к GPU, однако мой курсор мыши не может переместиться на подключенный монитор и застрял на виртуальном мониторе (который не использует драйвер nvidia, а вместо этого использует драйвер Microsoft Basic Display Adapter
). Но это не происходит, когда я отключаю spice guest, установленный в гостевой Windows как служба Windows. Однако я не хочу отключать/останавливать программу spice, которая работает на гостевой системе, потому что мне нужна функциональность общего буфера обмена.
Я не уверен, что делать, так как не знаю, что вызывает такое поведение, и буду признателен за любые указания 🙂
Вот XML-домен для запуска Windows с использованием virt-manager:
<domain type="kvm">
<name>win11-only-spice</name>
<uuid>5d0ed6d6-28e8-4f5a-ae82-aca6454f5b9c</uuid>
<metadata>
<libosinfo:libosinfo xmlns:libosinfo="http://libosinfo.org/xmlns/libvirt/domain/1.0">
<libosinfo:os id="http://microsoft.com/win/11"/>
</libosinfo:libosinfo>
</metadata>
<memory unit="KiB">15728640</memory>
<currentMemory unit="KiB">15728640</currentMemory>
<vcpu placement="static">12</vcpu>
<os firmware="efi">
<type arch="x86_64" machine="pc-q35-9.0">hvm</type>
<firmware>
<feature enabled="no" name="enrolled-keys"/>
<feature enabled="yes" name="secure-boot"/>
</firmware>
<loader readonly="yes" secure="yes" type="pflash" format="raw">/usr/share/edk2/x64/OVMF_CODE.secboot.4m.fd</loader>
<nvram template="/usr/share/edk2/x64/OVMF_VARS.4m.fd" templateFormat="raw" format="raw">/var/lib/libvirt/qemu/nvram/win11-only-spice_VARS.fd</nvram>
<boot dev="hd"/>
<bootmenu enable="yes"/>
</os>
<features>
<acpi/>
<apic/>
<hyperv mode="custom">
<relaxed state="on"/>
<vapic state="on"/>
<spinlocks state="on" retries="8191"/>
</hyperv>
<kvm>
<hidden state="on"/>
</kvm>
<vmport state="off"/>
<smm state="on"/>
</features>
<cpu mode="host-passthrough" check="none" migratable="on">
<topology sockets="1" dies="1" clusters="1" cores="6" threads="2"/>
<feature policy="require" name="topoext"/>
</cpu>
<clock offset="localtime">
<timer name="rtc" tickpolicy="catchup"/>
<timer name="pit" tickpolicy="delay"/>
<timer name="hpet" present="no"/>
<timer name="hypervclock" present="yes"/>
</clock>
<on_poweroff>destroy</on_poweroff>
<on_reboot>restart</on_reboot>
<on_crash>destroy</on_crash>
<pm>
<suspend-to-mem enabled="no"/>
<suspend-to-disk enabled="no"/>
</pm>
<devices>
<emulator>/usr/bin/qemu-system-x86_64</emulator>
<disk type="file" device="disk">
<driver name="qemu" type="qcow2" discard="unmap"/>
<source file="/var/lib/libvirt/images/win11.qcow2"/>
<target dev="sda" bus="sata"/>
<address type="drive" controller="0" bus="0" target="0" unit="0"/>
</disk>
<controller type="usb" index="0" model="qemu-xhci" ports="15">
<address type="pci" domain="0x0000" bus="0x02" slot="0x00" function="0x0"/>
</controller>
<controller type="pci" index="0" model="pcie-root"/>
<controller type="pci" index="1" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="1" port="0x10"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="2" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="2" port="0x11"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x1"/>
</controller>
<controller type="pci" index="3" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="3" port="0x12"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x2"/>
</controller>
<controller type="pci" index="4" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="4" port="0x13"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x3"/>
</controller>
<controller type="pci" index="5" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="5" port="0x14"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x4"/>
</controller>
<controller type="pci" index="6" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="6" port="0x15"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x5"/>
</controller>
<controller type="pci" index="7" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="7" port="0x16"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x6"/>
</controller>
<controller type="pci" index="8" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="8" port="0x17"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x02" function="0x7"/>
</controller>
<controller type="pci" index="9" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="9" port="0x18"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x0" multifunction="on"/>
</controller>
<controller type="pci" index="10" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="10" port="0x19"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x1"/>
</controller>
<controller type="pci" index="11" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="11" port="0x1a"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x2"/>
</controller>
<controller type="pci" index="12" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="12" port="0x1b"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x3"/>
</controller>
<controller type="pci" index="13" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="13" port="0x1c"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x4"/>
</controller>
<controller type="pci" index="14" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="14" port="0x1d"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x5"/>
</controller>
<controller type="pci" index="15" model="pcie-root-port">
<model name="pcie-root-port"/>
<target chassis="15" port="0x1e"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x03" function="0x6"/>
</controller>
<controller type="pci" index="16" model="pcie-to-pci-bridge">
<model name="pcie-pci-bridge"/>
<address type="pci" domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</controller>
<controller type="sata" index="0">
<address type="pci" domain="0x0000" bus="0x00" slot="0x1f" function="0x2"/>
</controller>
<controller type="virtio-serial" index="0">
<address type="pci" domain="0x0000" bus="0x03" slot="0x00" function="0x0"/>
</controller>
<serial type="pty">
<target type="isa-serial" port="0">
<model name="isa-serial"/>
</target>
</serial>
<console type="pty">
<target type="serial" port="0"/>
</console>
<channel type="spicevmc">
<target type="virtio" name="com.redhat.spice.0"/>
<address type="virtio-serial" controller="0" bus="0" port="1"/>
</channel>
<input type="mouse" bus="virtio">
<address type="pci" domain="0x0000" bus="0x05" slot="0x00" function="0x0"/>
</input>
<input type="keyboard" bus="virtio">
<address type="pci" domain="0x0000" bus="0x04" slot="0x00" function="0x0"/>
</input>
<input type="mouse" bus="ps2"/>
<input type="keyboard" bus="ps2"/>
<tpm model="tpm-crb">
<backend type="emulator" version="2.0">
<profile name="default-v1"/>
</backend>
</tpm>
<graphics type="spice" autoport="yes">
<listen type="address"/>
<image compression="off"/>
</graphics>
<sound model="ich9">
<audio id="1"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x1b" function="0x0"/>
</sound>
<audio id="1" type="spice"/>
<video>
<model type="vga" vram="16384" heads="1" primary="yes"/>
<address type="pci" domain="0x0000" bus="0x00" slot="0x01" function="0x0"/>
</video>
<hostdev mode="subsystem" type="pci" managed="yes">
<source>
<address domain="0x0000" bus="0x01" slot="0x00" function="0x0"/>
</source>
<address type="pci" domain="0x0000" bus="0x06" slot="0x00" function="0x0"/>
</hostdev>
<watchdog model="itco" action="reset"/>
<memballoon model="none"/>
</devices>
</domain>
.
Ответ или решение
Проблема, с которой вы столкнулись при использовании виртуальной машины (VM) с Windows на основе libvirt/kvm с GPU-пассингом, заключается в том, что указатель мыши застревает на виртуальном мониторе, который не использует драйвер NVIDIA, в то время как физический монитор подключен через GPU-пассинг. Вашей целью является сохранение функциональности общего буфера обмена, предоставляемой Spice, без отключения его сервиса. Давайте разберемся с этой ситуацией в деталях, чтобы предложить наиболее эффективное и практичное решение.
Теория
Основной элемент вашего вопроса связан с использованием графического адаптера в VM и поддержкой нескольких мониторов. Виртуализация с GPU-пассингом позволяет приложению на гостевой виртуальной машине использовать физическую графическую карту хоста. Однако, это может привести к конфликтам между различными драйверами виртуальной видео-графики и физической графики. В вашем случае интересы сталкиваются между Spice-каналом, который предоставляет графическое подключение и общий буфер обмена, и физическим GPU, подключенным через passthrough.
Spice в основном используется для передачи данных, таких как изображение на дисплее, аудио и общий буфер обмена, но его графический драйвер может конфликтовать с назначенными драйверами GPU. Поэтому пользователь обнаруживает невозможность перемещения курсора между виртуальным и физическим дисплеями, если установлена служба Spice-инструментов в Windows-госте.
Пример
Чтобы проиллюстрировать, представим, что у вас есть двойное графическое подключение: одно от интегрированной графики, соответствующее "Microsoft Basic Display Adapter" в гостевой Windows, и другое от выделенного GPU-пассинга, использующего драйверы Nvidia. Когда вы отключаете Spice, конфликта нет, курсор перемещается без проблем. Однако при включении Spice, который становится "основной" графической системой, курсор перехватывается.
Применение
Вот несколько шагов, которые помогут решить вашу проблему:
-
Проверка конфигурации VM:
- Убедитесь, что конфигурация виртуальной машины поддерживает ваше оборудование GPU-passthrough. Рассмотрите возможность изменения в XML-домене вашей VM параметров видео. Например, попробуйте изменить тип модели видео с
vga
наqxl
,virtio
, или другие совместимые опции, которые могут улучшить интеграцию с Spice.
- Убедитесь, что конфигурация виртуальной машины поддерживает ваше оборудование GPU-passthrough. Рассмотрите возможность изменения в XML-домене вашей VM параметров видео. Например, попробуйте изменить тип модели видео с
-
Настройка драйвера Spice:
- Обновление установленных драйверов Spice до последней версии может помочь в решении проблемы с курсором. Убедитесь, что версия Spice-агента, установленного на гостевой системе, совместима с вашим текущим сетапом.
-
Установка дополнительных дисплейных драйверов:
- Поддержка дополнительного дисплея возможно улучшится, если вы установите дисплейные драйверы, которые могут поддерживать мульти-дисплейные конфигурации (например, драйверы QXL или VirtIO).
-
Редактирование параметров гостевой ОС:
- В Windows попробуйте изменить порядок дисплеев через настройки "Параметры экрана", назначив два дисплея и корректно выбрав основной. Убедитесь, что виртуальная дисплейная среда не конфигурируется выше, чем физическое подключение.
-
Специальные настройки для Windows:
- Рассмотрите возможность отключения ограничения окна при помощи
Spice VM Tools
или поиска решающих проблем в Спайс-коммунити или форумах,оной модификации реестра Windows для дальнейшей поддержки коннекций через дисплей.
- Рассмотрите возможность отключения ограничения окна при помощи
-
Использование разных VNC-протоколов:
- Вы можете рассмотреть временное использование другого подключения, например VNC, чтобы полностью изолировать проблему с Spice и проверить, происходит ли аналогичный конфликт без использования Spice.
Профессионалы часто сталкиваются с проблемами конфигурации GPU-passthrough в виртуализированных средах; ключ к решению часто лежит в детальной проработке конфигурации и настройке драйверов. Надеюсь, эти шаги помогут решить проблему с курсором, сохраняя преимущества использования Spice.