{ "meta": { "title": "Añadir GPU a VM (Passthrough) | ProxMenux Documentation", "description": "Pasa una GPU Intel, AMD o NVIDIA a una VM Proxmox con rendimiento cercano al nativo. ProxMenux gestiona la preparación del host (módulos VFIO, blacklist de drivers, cmdline del kernel), la configuración de la VM (hostpci, función de audio, hermanos del grupo IOMMU), workarounds específicos del fabricante (Code 43 de NVIDIA, reset bug de AMD, dump de ROM) y conflictos de switch-mode con LXCs." }, "header": { "title": "Añadir GPU a VM (Passthrough)", "description": "Dale una de tus GPUs a una máquina virtual con rendimiento cercano al nativo. ProxMenux detecta Intel / AMD / NVIDIA, valida IOMMU, analiza el grupo IOMMU de la GPU para pasar cada dispositivo hermano junto, configura VFIO en el host, escribe las líneas hostpci correctas en la config de la VM y aplica fixes específicos del fabricante cuando hace falta.", "section": "Hardware: GPUs y Coral-TPU" }, "intro": { "title": "Qué hace esto", "body": "Todo lo que la wiki oficial de Proxmox de PCI passthrough te explica paso a paso manualmente — habilitar IOMMU, módulos VFIO, blacklisting de drivers, descubrimiento de vendor ID, setup de hostpci, dump de ROM en AMD, ocultación de KVM en NVIDIA — hecho en una sola ejecución con comprobaciones de cordura en cada paso. El script también es consciente de las otras cosas en tu host: si la misma GPU ya está asignada a un LXC u otra VM, te ofrece migrar limpiamente en lugar de romper silenciosamente el setup existente." }, "who": { "heading": "¿Para quién es esto?", "body": "Tienes una GPU física en tu host Proxmox y quieres que una máquina virtual (Windows gaming, macOS, un nodo headless de cómputo en GPU, un media server en VM) la use directamente. Pasar una GPU a una VM no es lo mismo que pasarla a un LXC — las VMs necesitan que el kernel trate la GPU como dispositivo VFIO (en esencia \"el host no la tocará\"), lo que significa que el host no puede usar esa GPU para nada más mientras la VM esté en ejecución. Para transcoding / cómputo en LXC, usa Añadir GPU a LXC — comparte la GPU y no necesita VFIO." }, "prereqs": { "title": "Antes de empezar", "gpu": "Una GPU soportada instalada físicamente. El script detecta Intel, AMD y NVIDIA vía lspci.", "gpuCheck": "lspci | grep -iE 'VGA|3D|Display'", "iommu": "Virtualización IOMMU disponible en BIOS/UEFI (Intel VT-d o AMD-Vi). Si está apagada a nivel de firmware, ninguna config de Linux lo arregla — tienes que habilitarla primero en la BIOS. El script detecta esto y se ofrece a habilitarlo en el lado del SO.", "q35": "La VM destino usa machine type q35. El antiguo i440fx no soporta de forma fiable el passthrough PCIe y el script se negará a continuar.", "q35Check": "qm config '<'vmid'>' | grep machine", "moreGpus": "Preferiblemente más de una GPU en el host, o acceso por consola en otra salida (IPMI, KVM-over-IP, serie). Una vez pases la única GPU a una VM, la consola del host se queda a oscuras. Con dos GPUs NVIDIA puedes pasar una a una VM y mantener la otra en el host — el script gestiona esto por BDF (ver NVIDIA en las notas del fabricante más abajo).", "nvidiaInstalled": "Si estás en un Proxmox que ya instaló el driver de NVIDIA vía NVIDIA Drivers en el host: la GPU que pases a la VM se desvincula del driver nvidia del host y se vincula a vfio-pci. El módulo nvidia sigue cargado, así que cualquier otra GPU NVIDIA que tengas en el host sigue funcionando con nvidia-smi." }, "pickOne": { "title": "Passthrough a VM vs compartición con LXC — elige uno por GPU", "body": "Una GPU vinculada a vfio-pci para passthrough a VM no puede usarla simultáneamente el host ni un LXC. Si tienes dos GPUs, puedes dedicar una a cada ruta. Si solo tienes una, elige:", "vmItem": "Ruta VM (esta página): acceso completo al hardware, pero exclusivo para la VM dueña de la GPU mientras esté en ejecución.", "lxcItem": "Ruta LXC (Añadir GPU a LXC): compartida con el host y otros contenedores, ideal para transcoding, sin magia VFIO." }, "running": { "heading": "Ejecutar el instalador", "body": "Abre ProxMenux en el host, ve a Hardware: GPUs and Coral-TPU → Add GPU to VM.", "imageAlt": "Entrada del menú 'Add GPU to VM' dentro de Hardware: GPUs and Coral-TPU" }, "howRuns": { "heading": "Cómo se ejecuta el script", "body": "El flujo tiene tres fases con separación clara entre \"recopilar información y decisiones\" y \"aplicar cambios realmente\". Hasta la confirmación final, no se ha tocado nada en tu host ni en la VM." }, "walkthrough": { "heading": "Recorriendo el flujo", "detect": { "title": "Detectar GPUs y comprobar IOMMU", "body": "El script lista cada GPU que encuentra. Si IOMMU no está ya habilitado en la cmdline del kernel en ejecución, recibirás un prompt sí/no para añadir intel_iommu=on (o amd_iommu=on) + iommu=pt al archivo de arranque correcto — /etc/kernel/cmdline en ZFS (systemd-boot) o /etc/default/grub en LVM/ext4. Si aceptas y la cmdline del kernel cambia, el script marca que el prompt de reinicio al final será obligatorio.", "tipTitle": "¿Ya ejecutaste post-instalación?", "tipBody": "Si habilitaste anteriormente soporte VFIO IOMMU desde los scripts post-instalación, IOMMU ya está activo y este paso pasa silenciosamente. Bien.", "imageAlt": "Lista de GPUs detectadas con fabricante y dirección PCI" }, "preflight": { "title": "Elegir una GPU y ejecutar las comprobaciones previas", "intro": "Una vez eliges la GPU, el script ejecuta una serie de comprobaciones que pueden bloquear el progreso:", "items": [ "No en SR-IOV. Si el dispositivo es una Virtual Function o una Physical Function con VFs activas, el passthrough chocaría con el uso de SR-IOV. Bloqueado.", "Aviso de GPU única. Si esta es la única GPU del host, recibirás un diálogo de aviso recordándote que después del reinicio la consola se queda a oscuras — asegúrate de tener acceso SSH o por la UI web desde otra máquina.", "Método de reset AMD. Las GPUs AMD tienen un largo historial de no resetear limpiamente entre paradas y arranques de VM. El script comprueba /sys/bus/pci/devices/<pci>/reset_method: si la tarjeta es una APU sin FLR bloquea (prácticamente inutilizable); una tarjeta AMD dedicada sin FLR también se bloquea; cualquier cosa con un modo de reset desconocido avisa pero te deja continuar con override explícito.", "No en D3cold. Algunas tarjetas AMD reportan estado de energía D3cold en reposo, lo que las hace invisibles durante el arranque de la VM. Bloqueado hasta que despiertes la GPU.", "Análisis del grupo IOMMU. Lee /sys/kernel/iommu_groups/ para encontrar cada dispositivo no-bridge del grupo de la GPU. Todos ellos se pasarán a la VM juntos — si tu placa base agrupa la GPU con una tarjeta de red, la tarjeta de red va también." ], "audioIntro": "Audio compañero. Dos rutas, según dónde viva el audio:", "audioDgpu": "GPU discreta (NVIDIA / AMD): el audio HDMI está en la misma tarjeta como función .1 del slot PCI de la GPU. Incluido automáticamente. Este dispositivo de audio nunca lo usó el host, así que nadie pierde nada.", "audioIgpu": "iGPU Intel (o cualquier GPU sin hermano .1): el audio HDMI / analógico vive en el chipset en un slot distinto (00:1f.3 normalmente). El script escanea el host, lista cada controlador de audio PCI con su driver actual (snd_hda_intel, etc.) y te pregunta cuál(es) pasar. Por defecto ninguno — tienes que aceptarlo explícitamente." }, "pickVm": { "title": "Elegir la VM destino", "body": "Se te muestra la lista de VMs del host y eliges una. El script comprueba que la VM es q35 — los machine types BIOS/i440fx se rechazan porque el passthrough PCIe en ellos no es fiable. Si tienes una VM q35 con la GPU ya asignada (parcial o completamente), la entrada existente se reutiliza en lugar de duplicarse.", "imageAlt": "Lista de VMs con nombre, ID y estado mostrada como selector" }, "switchMode": { "title": "Switch mode — gestionar que la GPU ya esté en otro sitio", "intro": "El script escanea cada config de VM y cada config de LXC en el host buscando la GPU que elegiste. Tres resultados posibles:", "items": [ "La GPU está libre. Nada que hacer, continúa.", "La GPU está en otra VM. Se te ofrece quitarla de esa otra VM antes de asignarla aquí. Si rechazas, el script aborta — dos VMs no pueden compartir una asignación VFIO exclusiva.", "La GPU está en un LXC (modo compartido). Se te ofrece quitar la configuración de passthrough del LXC (líneas lxc.cgroup2.devices.allow + lxc.mount.entry). El LXC dejará de ver la GPU, pero la VM la verá — esta es la mecánica de \"switch mode\" que le da a esta entrada de menú su etiqueta secundaria." ], "imageAlt": "Diálogo que ofrece quitar la GPU de un LXC antes de asignarla a la VM", "smartTitle": "Los hermanos de audio también se limpian con inteligencia", "smartBody": "Si la VM origen tenía dispositivos de audio extra adjuntos junto a la GPU, el script quita solo los que ahora son huérfanos — es decir, entradas de audio cuyo hermano de display también se está quitando. El audio vinculado a otra GPU que se queda en la VM se deja intacto. Esto importa cuando desadjuntas una iGPU Intel (que comparte el audio del chipset) de una VM que también tiene una tarjeta dedicada NVIDIA / AMD aún pasada: el audio HDMI de la dGPU (02:00.1) se queda, el audio del chipset (00:1f.3) se va." }, "audioPick": { "title": "(Si no hay hermano .1) Elegir qué controladores de audio incluir", "body": "Solo ocurre para iGPUs Intel y setups similares con audio separado. Una checklist muestra cada controlador de audio PCI del host (excluyendo cualquiera ya en el grupo IOMMU de la GPU), etiquetado con su driver actual. Selecciona los que quieras — o ninguno, si la VM no necesita audio del hardware del host.", "imageAlt": "Diálogo checklist con cada controlador de audio PCI del host (BDF + driver) cuando la GPU no tiene audio hermano .1", "warnTitle": "No marques audio del que depende el host", "warnBody": "Si el host usa actualmente un controlador de audio para algo — por ejemplo, el beep del shell de Proxmox o una VM a la que ya lo has pasado — marcarlo aquí significa que el host (y cualquier otra VM que lo comparta) pierde acceso después del reinicio. Ante la duda, déjalo vacío y siempre puedes volver a ejecutar el script más tarde para añadir audio si hace falta." }, "summary": { "title": "Revisar el resumen de confirmación", "body": "Un diálogo final muestra exactamente qué está a punto de cambiar en el host y en la VM. Esta es la última salida — si algo se ve mal (un dispositivo extra en el grupo IOMMU que no esperabas, la GPU equivocada, la VM equivocada), cancela aquí y aún no se ha tocado nada.", "imageAlt": "Diálogo de resumen listando los cambios del host (archivos VFIO/blacklist) y los cambios de config de la VM (líneas hostpci) antes de aplicar" }, "hostApply": { "title": "Se aplican los cambios del host", "intro": "La Fase 2 se ejecuta de forma no interactiva. En el lado del host el script puede tocar:", "items": [ "/etc/modules — añade vfio, vfio_iommu_type1, vfio_pci (más vfio_virqfd en kernels < 6.2).", "/etc/modprobe.d/vfio.conf — para AMD / Intel, define options vfio-pci ids=<vendor:device,...> disable_vga=1 para que VFIO reclame la GPU pronto en el arranque. Para NVIDIA el archivo solo añade softdep nvidia pre: vfio-pci (más _drm/_modeset/_uvm) — el binding real es por BDF vía la regla udev de abajo. En AMD, también añade líneas softdep forzando que vfio-pci cargue antes de radeon / amdgpu.", "/etc/modprobe.d/iommu_unsafe_interrupts.conf y kvm.conf — workarounds sensatos que la mayoría de VMs Windows / macOS necesitan (allow_unsafe_interrupts=1, ignore_msrs=1).", "/etc/modprobe.d/blacklist.conf — pone en blacklist los drivers open-source compañeros (nouveau, amdgpu, radeon, i915) que si no agarrarían la GPU antes que VFIO. El módulo propietario nvidia nunca se pone en blacklist — sigue disponible para cualquier OTRA GPU NVIDIA que mantengas en el host.", "/etc/udev/rules.d/10-proxmenux-vfio-bind.rules + /etc/proxmenux/vfio-bind.bdfssolo NVIDIA. Estado de binding por BDF. La regla udev aplica ATTR'{'driver_override'}'=\"vfio-pci\" en el evento PCI ADD para cada Bus:Device.Function rastreado, así que solo las GPUs que has pasado explícitamente van a VFIO. Esto es lo que hace que NVIDIA multi-GPU funcione — tus otras tarjetas NVIDIA mantienen su driver nvidia y siguen siendo usables en el host.", "Solo AMD. Vuelca la ROM de la GPU desde sysfs (/sys/bus/pci/.../rom) o la tabla ACPI VFCT a /usr/share/kvm/vbios_<card>.bin. La VM la referencia vía romfile= para que las tarjetas que mal-reportan su propia VBIOS aún inicialicen correctamente.", "Solo NVIDIA. Para y deshabilita los servicios NVIDIA del host que podrían sondear / bloquear la GPU en el arranque (nvidia-persistenced, nvidia-powerd, nvidia-fabricmanager). El propio módulo nvidia se deja cargado para que otras GPUs NVIDIA del host sigan funcionando con nvidia-smi.", "update-initramfs -u -k all — solo se ejecuta si algo de lo de arriba ha cambiado realmente." ] }, "vmApply": { "title": "La config de la VM se aplica vía qm set", "body": "La config de la VM en /etc/pve/qemu-server/<vmid>.conf se actualiza vía qm set (nunca por sed directo):", "after1": "Se añade un flag x-vga=1 para cada fabricante excepto iGPU Intel — las GPUs integradas Intel no tienen VRAM dedicada para una consola pre-arranque, así que ese flag causa hangs.", "after2": "Se añaden líneas hostpciN adicionales si el grupo IOMMU de la GPU contiene otros dispositivos que necesitas pasar juntos." }, "reboot": { "title": "Reiniciar si se tocó la config del host", "body": "Si la Fase 2 cambió algo a nivel de módulo de kernel / cmdline / blacklist, se te pedirá reiniciar. El reinicio es obligatorio antes de arrancar la VM — si no la GPU sigue retenida por el driver del host y VFIO no puede reclamarla.", "imageAlt": "Pantalla de resumen mostrando qué se cambió, seguida de un prompt de reinicio" } }, "vendors": { "heading": "Notas específicas del fabricante", "nvidiaHeading": "NVIDIA", "nvidiaBody": "Los drivers de consumo de NVIDIA detectan que están corriendo en una VM y se niegan a inicializar con el infame error \"Code 43\". El workaround de ProxMenux: ocultar KVM al guest (hidden=1), poner un hypervisor vendor ID falseado NV43FIX en la línea args y pasar kvm=off. Esto ha funcionado de forma fiable en drivers GeForce durante años. En tarjetas datacenter / Tesla / Quadro esto no hace falta — esos drivers están licenciados para virtualización.", "nvidiaMultiHeading": "Soporte NVIDIA multi-GPU", "nvidiaMultiBody": "Los hosts con dos o más GPUs NVIDIA son de primera clase. Puedes pasar una tarjeta a una VM y mantener la(s) otra(s) en el host para nvidia-smi, compartición de GPU con LXC o cualquier carga del lado del host. ProxMenux vincula VFIO por BDF (Bus:Device.Function) vía una regla udev en lugar de poner en blacklist globalmente el módulo nvidia — así el destino de cada tarjeta es independiente de las otras, incluso cuando ambas GPUs son del mismo modelo y comparten el mismo ID vendor:device. El driver nvidia del host sigue cargado; solo los BDFs específicos que selecciones se redirigen a vfio-pci.", "amdHeading": "AMD", "amdBody": "El \"AMD reset bug\" significa que algunas tarjetas crashean cuando la VM para y no pueden re-inicializarse sin un reinicio del host. ProxMenux pre-criba para esto leyendo el método de reset PCI, pero no puede arreglarlo después. Si lo encuentras, el fix de la comunidad es el módulo de kernel vendor-reset. El script no lo instala automáticamente — el módulo es una build DKMS que añades tú si ves fallos de reset. También en guests Windows, el servicio RadeonResetBugFix es el workaround común a nivel userspace.", "intelHeading": "iGPU Intel", "intelBody": "El passthrough de iGPU Intel es inestable pero posible en generaciones UHD 630+ con i915-sriov-dkms para SR-IOV. Para un caso simple de \"darle la iGPU a una VM\", el script la vincula exactamente como una GPU dedicada, pero se salta x-vga=1 (las iGPUs no llevan una VBIOS pre-arranque). Perderás la salida de consola del host — planifícalo en consecuencia." }, "verification": { "heading": "Verificación" }, "troubleshoot": { "heading": "Solución de problemas", "code43Title": "Code 43 en Windows (NVIDIA)", "code43Body": "Los args de ocultación de KVM no se aplicaron. Comprueba qm config <vmid> | grep -E \"cpu|args\" — deberías ver hidden=1 y hv_vendor_id=NV43FIX. Si faltan, vuelve a ejecutar el script y reselecciona la misma VM.", "amdResetTitle": "La GPU AMD funciona una vez, falla al reiniciar la VM", "amdResetBody": "El AMD reset bug. Soluciones (en orden): (1) reiniciar el host — la GPU será usable de nuevo para un ciclo más de VM; (2) instalar el módulo DKMS vendor-reset y añadir softdep amdgpu pre: vendor-reset; (3) dentro de Windows, instalar el servicio RadeonResetBugFix.", "stuckBootTitle": "VM colgada arrancando / GPU no detectada", "stuckBootBody": "Confirma que VFIO realmente retiene la GPU al arrancar: lspci -nnk -d vendor:device debe mostrar Kernel driver in use: vfio-pci. Si aún muestra el driver del fabricante, el blacklist no surtió efecto — revisa /etc/modprobe.d/blacklist.conf y dmesg | grep vfio, y regenera initramfs: update-initramfs -u -k all y luego reinicia.", "darkTitle": "La consola del host se queda a oscuras tras reiniciar y no puedo entrar por SSH", "darkBody": "Pasaste la GPU primaria sin tener acceso alternativo. Arranca en un recovery shell (ISO de rescate, IPMI), quita las líneas de la config de la VM (/etc/pve/qemu-server/<vmid>.conf) y quita las opciones vfio:", "logTitle": "Revisa el log de instalación", "logBody": "Cada ejecución escribe en /tmp/add_gpu_vm.log. Adjúntalo cuando pidas ayuda en GitHub." }, "revert": { "heading": "Revertir manualmente", "intro": "Hoy no hay un atajo dedicado de \"quitar GPU de la VM\" en ProxMenux. Para desadjuntar limpiamente:" }, "related": { "heading": "Relacionado", "items": [ { "label": "Instalar drivers NVIDIA (Host)", "href": "/docs/hardware/nvidia-host", "tail": " — instala los drivers en el host primero si también quieres la GPU usable desde ahí." }, { "label": "Añadir GPU a LXC", "href": "/docs/hardware/igpu-acceleration-lxc", "tail": " — modelo alternativo: comparte la GPU con varios contenedores en lugar de dedicarla a una VM." }, { "label": "Switch GPU Mode (VM ↔ LXC)", "href": "/docs/hardware/switch-gpu-mode", "tail": " — cambia la misma GPU entre modos sin rehacer todo el cableado." }, { "label": "Comandos de GPU Passthrough", "href": "/docs/help-info/gpu-commands", "tail": " — referencia de lspci, verificación de IOMMU, qm set hostpci." } ] } }