I recently switched to a Ryzen 5 5500GT based system for my Proxmox server. I plan on using the onboard GPU for hardware transcoding in Plex.

However, AMD GPUs suffer from a reset bug in Proxmox. The bug causes the GPU to become unusable if the VM is restarted i.e. it works exactly once before requiring a reboot of the host machine.

Workaround

The core bug lies in power state handling, linux is unable to change its state from cold to hot. The workaround is to disable cold state using the following command in proxmox.

echo "0" | tee /sys/bus/pci/devices/0000\:07\:00.0/d3cold_allowed

Replace 0000:07:00.0 with the bus id of your AMD GPU. Use lspci to find this out.

In the VM config, keep both PCI-Express and Primary GPU unchecked.

Automate the fix

d3cold_allowed will be restored every time you reboot the host. Add a pre-start hookscript to the VM in order to set it to 0 on start.

#!/usr/bin/perl

# Hookscript to automate disabling of d3cold state for AMD GPU
# Usage:
# Example hook script for PVE guests (hookscript config option)
# You can set this via pct/qm with
# pct set <vmid> -hookscript <volume-id>
# qm set <vmid> -hookscript <volume-id>
# where <volume-id> has to be an executable file in the snippets folder
# of any storage with directories e.g.:
# qm set 100 -hookscript local:snippets/hookscript.pl

use strict;
use warnings;

# First argument is the vmid
my $vmid = shift;

# Second argument is the phase
my $phase = shift;

if ($phase eq 'pre-start') {

    # First phase 'pre-start' will be executed before the guest
    # is started. Exiting with a code != 0 will abort the start

    print "$vmid is starting, disabling d3cold for selected PCI device.\n";

    # Run the command to disable d3cold for the specified PCI device
    my $pci_device = '/sys/bus/pci/devices/0000:07:00.0/d3cold_allowed';
    my $cmd = "echo '0' | tee $pci_device";

    if (system($cmd) != 0) {
        print "Failed to execute command: $cmd\n";
        exit(1);
    }

}

exit(0);

Save this script in the snippets folder of any snippet capable storage on your proxmox server. The path looks something like this: /mnt/pve/yourstoragedevice/snippets

Add it to the desired VM using:

qm set 100 -hookscript local:snippets/hookscript.pl

Replace 100 with your VM id and hookscript.pl with the name of the script you save.