Problema
En entornos de virtualización con Proxmox, es frecuente intentar pasar una GPU dedicada a una VM Windows (XP, 7 o versiones más recientes) usando PCI passthrough. Cuando la máquina virtual se basa en el modelo de máquina i440fx, algunos usuarios se encuentran con un bucle de reinicio que termina en el STOP: 0x000000A5 (ACPI_BIOS_ERROR). El síntoma típico es un bootloop continuo, sin que la VM llegue a cargar el sistema operativo. Aunque el error parece estar relacionado con la BIOS del invitado, la causa raíz a menudo está en la configuración de la VM y no en la propia GPU.
Causa
Proxmox genera automáticamente dos dispositivos pci‑bridge (pci.1 y pci.2) para cada VM basada en i440fx. Estos puentes son simplemente reservas de espacio de direcciones; no se usan cuando la VM solo necesita dispositivos pasados directamente (hostpci0‑hostpci3, vga, balloon, etc.). Sin embargo, el firmware ACPI de Windows XP/7 verifica la topología PCI y, al encontrar un puente que no está completamente mapeado, devuelve el código 0xA5 con el subcódigo ACPI_ROOT_PCI_RESOURCE_FAILURE.
Las causas más habituales son:
- Presencia incondicional de los puentes – Proxmox no ofrece una opción de configuración para desactivarlos.
- Compatibilidad de la BIOS del host – En hardware antiguo o con BIOS no totalmente ACPI‑compliant, la presencia de los puentes desencadena la falla.
- Uso del modelo de máquina i440fx – El modelo q35 no crea estos puentes, pero para Windows XP el i440fx es obligatorio porque el controlador IDE de q35 (ICH9 AHCI) no es compatible con SeaBIOS/CSMWrap.
- Configuraciones de dispositivos adicionales – Añadir dispositivos detrás de los puentes (por ejemplo, virtio‑rng‑pci o xHCI) no soluciona el problema porque el propio puente sigue existiendo.
En la práctica, el error desaparece cuando los puentes son eliminados del comando de arranque de QEMU. Como Proxmox no permite su supresión mediante la UI, la solución pasa por intervenir en el binario kvm que Proxmox invoca.
Solución
La estrategia general consiste en interceptar la llamada a kvm y remover los argumentos -device pci-bridge,... antes de que QEMU los reciba. El proceso se puede resumir en tres pasos:
- Crear un wrapper que reescriba la línea de comandos, filtre los puentes y delegue al binario real (
kvm.distrib). - Divertir el binario original usando
dpkg-divert(o el gestor de paquetes equivalente) para que/usr/bin/kvmapunte al wrapper sin sobrescribir el paquete oficial. - Mantener una lista de allow‑list con los IDs de VM que pueden ejecutarse sin puentes. El wrapper aborta el arranque si una VM no está en la lista y todavía referencia
pci.1opci.2, evitando bucles silenciosos.
Implementación paso a paso
-
Instalar el wrapper
curl -sSL https://gitlab.com/zubrjan/2am-idea/raw/master/pve-kvm-nobridge-setup.sh -o /usr/local/sbin/pve-kvm-nobridge-setup.sh chmod +x /usr/local/sbin/pve-kvm-nobridge-setup.sh /usr/local/sbin/pve-kvm-nobridge-setup.sh --installEl script realiza tres auto‑tests contra una VM real, crea la diversión y genera el archivo de configuración
/etc/pve-kvm-nobridge.conf. -
Agregar la VM a la allow‑list (suponiendo VMID 301)
/usr/local/sbin/pve-kvm-nobridge-setup.sh --add-vm 301 -
Revisar el log para confirmar que el wrapper se está usando:
tail -f /var/log/pve-kvm-nobridge/301.cmd -
Iniciar la VM normalmente con
qm start 301. Si el wrapper detecta referencias apci.1opci.2en la configuración, abortará y mostrará un mensaje claro.
El wrapper también protege contra actualizaciones del paquete pve-qemu-kvm. Después de cada actualización, verifica que la diversión siga activa (dpkg-divert --list /usr/bin/kvm). Si desaparece, reinstale el wrapper.
Cuándo aplicar esta solución
- Entornos con GPU passthrough donde la VM usa el modelo de máquina i440fx (por ejemplo, Windows XP SP3 o Windows 7 32‑bit) y necesita ACPI activo.
- Errores de arranque que terminan en
STOP: 0x000000A5con subcódigo0x2(ACPI_ROOT_PCI_RESOURCE_FAILURE). - Configuraciones que no requieren dispositivos detrás de los puentes (solo hostpci, vga, balloon, IDE).
- No aplicar si la VM usa el modelo q35, ya que los puentes no se crean y la solución no es necesaria.
- No aplicar a entornos donde se dependen de dispositivos virtio‑rng‑pci, xHCI u otros que se asignan detrás de los puentes, a menos que se migren a
pci.0.
Código
# Wrapper installation script (simplificado)
#!/usr/bin/env bash
REAL="/usr/bin/kvm.distrib"
CONF="/etc/pve-kvm-nobridge.conf"
VMID="$1"
if [[ "$1" == "--install" ]]; then
dpkg-divert --divert /usr/bin/kvm.distrib --rename /usr/bin/kvm
cat <<'EOF' > /usr/local/sbin/pve-kvm-nobridge
#!/usr/bin/env bash
REAL="/usr/bin/kvm.distrib"
ARGS=()
ALLOWLIST=$(cat /etc/pve-kvm-nobridge.conf)
while [[ $# -gt 0 ]]; do
case "$1" in
-id)
VMID="$2"
shift 2
;;
-device)
if [[ "$2" =~ ^pci-bridge ]]; then
shift 2
continue
fi
;;
*)
ARGS+=("$1")
shift
;;
esac
done
if grep -q "^$VMID$" "$ALLOWLIST"; then
exec -a "$0" "$REAL" "${ARGS[@]}"
else
echo "VM $VMID no está en la allow‑list. Abortando."
exit 1
fi
EOF
chmod +x /usr/local/sbin/pve-kvm-nobridge
ln -sf /usr/local/sbin/pve-kvm-nobridge /usr/bin/kvm
echo "# Lista de VM permitidas" > "$CONF"
echo "301" >> "$CONF"
echo "Instalación completada."
exit 0
fi
Verificación
-
Comprobar que el wrapper está activo
which kvm # debe devolver /usr/bin/kvm (enlace al wrapper) kvm --version # debe mostrar la versión de QEMU sin errores -
Iniciar la VM y observar el log
qm start 301 grep -i "pci-bridge" /var/log/pve-kvm-nobridge/301.cmdNo debe aparecer ninguna línea con
pci-bridge. -
Confirmar que Windows arranca y que el
STOP: 0xA5no se produce. En caso de fallo, revisa que la VM sigue usandomachine: pc-i440fx-5.0y que no hay dispositivos ocultos detrás depci.1/2. -
Después de una actualización de Proxmox, repite
dpkg-divert --list /usr/bin/kvm. Si el wrapper desaparece, ejecuta nuevamente el script--install.
Notas adicionales
- No desactivar ACPI en la VM. Quitar ACPI evita el error 0xA5 pero degrada gravemente el rendimiento de Windows XP, que pasa a usar el temporizador PIT y consume un vCPU completo.
- Mantener la máquina i440fx para XP. Cambiar a q35 obliga a usar controladores AHCI que SeaBIOS/CSMWrap no soporta en modo legado.
- Evitar
--usb0 host=...en VMs envueltas, ya que Proxmox coloca el controlador xHCI detrás del puente eliminado. En su lugar, pasa el controlador USB completo mediantehostpci<n>. - Clonar VMs: la afinidad NUMA y la allow‑list no se copian automáticamente. Añade el nuevo VMID a
/etc/pve-kvm-nobridge.confantes de arrancar. - Depuración rápida:
qm monitor <vmid>yinfo pcimuestra cuántos puentes están presentes en tiempo de ejecución. Un recuento de0confirma la eliminación exitosa.
Con este enfoque, los entornos de GPU passthrough en Proxmox dejan de tropezar con el error ACPI_BIOS_ERROR 0xA5 y pueden ejecutar Windows XP/7 de forma estable, sin sacrificar ACPI ni rendimiento.