# vendor-reset: an out of tree module for hardware resets the kernel cannot do

> vendor-reset is a Linux kernel module that resets specific GPUs and other devices into a re-initialisable state, including for VFIO passthrough, using ftrace to hook the kernel's own reset path so no kernel patching is needed. It suits a user passing an AMD GPU to a virtual machine, and it must be loaded early because the default reset breaks the hardware.

**gnif/vendor-reset** — Linux kernel vendor specific hardware reset module for sequences that are too complex/complicated to land in pci_quirks.c

- Repository: https://github.com/gnif/vendor-reset
- Stars: 975 · Forks: 150
- Language: C
- License: GPL-2.0
- Published: 2026-10-20 · Updated: 2026-10-20 · Language: en
- Canonical page: https://hysenlabs.com/projects/gnif-vendor-reset

## Why a reset procedure is too complex for a PCI quirk

The goal of the project is to provide a kernel module that is capable of resetting hardware devices into a state where they can be re-initialised or passed through into a virtual machine using VFIO. The README makes the reason it cannot live in the kernel explicit: while it would be great to have these as PCI quirks, some of the reset procedures are very complex and would never be accepted as a quirk, with the example given being the AMD Vega 10.

That is a specific and recognisable complaint. Kernel quirks are reviewed for good reason, and a quirk that encodes a long vendor-specific dance of register writes across a firmware handshake is exactly the kind of thing that will not be merged into a file shared by every distribution and every vendor's hardware.

The out of tree arrangement solves two problems at once. By providing this as an out of tree kernel module, vendors will be able to easily create pull requests to add functionality to the module, and users will be able to easily update the module without requiring a complete kernel rebuild.

So the module is a staging area for reset code that is too bespoke for upstream, and the update story is the point. A kernel rebuild for a graphics card reset is a big ask, and an out of tree module turns the same fix into a package update.

The project is GPL-2.0 licensed, the primary language is C, and the only tagged release is v0.1.0 from January 2021, described as an initial semi-stable release. The last push to the master branch was on 2026-06-29.

## ftrace instead of patching, which is the clever part

The patching section is headed with a TL;DR that reads no patching required, and the mechanism is the most interesting thing in the repository.

The module has been written to use ftrace to hook pci_dev_specific_reset, allowing it to handle device resets directly without patching the running kernel. Simply modprobing the module is enough to enable the reset routines for all supported hardware.

That is the design decision that makes the whole project work without a kernel rebuild. A conventional out of tree module that changes the behaviour of a core kernel path would need to either replace the function, which means symbol surgery and a fragile build, or duplicate the reset logic in userspace, which is a lot of register poking from an unprivileged context. ftrace gives a supported hook point instead, so the module attaches to the function the kernel already calls and takes over the work for the devices it knows about.

The requirement list is what that mechanism needs from the kernel, and it is a specific set of options:

```
CONFIG_FTRACE=y
CONFIG_KPROBES=y
CONFIG_PCI_QUIRKS=y
CONFIG_KALLSYMS=y
CONFIG_KALLSYMS_ALL=y
CONFIG_FUNCTION_TRACER=y
```

The kprobes and function tracer entries are the hooking machinery, the symbol tables are needed to resolve the target function, and the PCI quirks option is because the module is taking over a path that lives in the quirks code.

If you are building a kernel for this, those options are the checklist, and a distribution kernel without them cannot use the module at all.

## Installing through dkms, and loading it early

The module can be installed either using the standard make, make install pattern, or through dkms, which the README recommends:

```
dkms install .
```

DKMS is the right choice here because it rebuilds the module automatically when the kernel changes, which is the whole reason the project exists in this shape. The Makefile supports the manual path too, with KVER taken from uname -r and KDIR pointing at /lib/modules/$(KVER)/build, and the build, install and clean targets all delegate to the kernel build system with M set to the current directory.

The Makefile also has a load target, which is convenient during development. It removes the module if it is already loaded, by grepping /proc/modules for vendor_reset and running rmmod, and then loads the freshly built one with insmod, passing install_hook=no when the NOHOOK variable is set.

That last detail matters for understanding the design. The module can be built with the hook disabled, which is the escape hatch for the case where you want the module present but not intercepting the kernel's reset path.

Then there is the usage note, and it is the most important operational statement in the README. This module must be loaded EARLY, because the default reset the kernel will try to perform completely breaks the GPU which this module cannot recover from. The advice is to consult the distribution's documentation, and for most it is as simple as adding vendor-reset to /etc/modules and updating the initrd.

That last part is the detail people miss. Adding the module to /etc/modules without rebuilding the initrd means the module loads after the kernel has already tried to reset the card, and by then the damage is done. The order is not optional.

## Which devices are covered, and what the vendor is asked to check first

The supported devices table is a list of AMD families, and the pattern in it is that the coverage is by GPU generation rather than by retail model.

For Polaris 10 there are the RX 470, 480, 570, 580 and 590. Polaris 11 covers the RX 460 and 560, and Polaris 12 the RX 540 and 550. Vega 10 covers the Vega 56, 64 and FE, and Vega 20 covers the Radeon VII and the Instinct MI100. Navi 10 covers the 5600XT, 5700, 5700XT and the 680M Rembrandt, and Navi 12 the Pro 5600M. Navi 14 covers the Pro 5300, RX 5300 and 5500XT.

Notice that every entry is AMD, which fits the use case. These are the cards people want to pass into a virtual machine for GPU acceleration, and they are also the cards whose reset sequences do not fit the kernel's simple model.

The developing section asks vendors to consider two things before adding a device. First, can you fix your hardware or firmware to reset correctly using FLR or a BUS reset? Second, is the reset simple enough that it should really be a kernel PCI quirk, with the reference to kernel/drivers/pci/quirk.c? And the answer is that if you answer yes to either of these questions, this project is not for you.

That is a well-drawn boundary for an out of tree module, and it is the reason the project is small. The module exists for the residue that upstream will not take, and the contributing guidance tries to keep that residue from growing into a general purpose driver collection.

## Conclusion

Adopt vendor-reset if you need to reset a GPU that the kernel's own reset path cannot recover, most often because you are passing the card to a virtual machine with VFIO, since the module exists for exactly the reset sequences too complex to be accepted as a PCI quirk. Do not adopt it if a simple FLR or bus reset would do, because the contributing guidance asks vendors to check that first. Before you load it, read the early loading requirement, since the default reset the kernel performs breaks the GPU irrecoverably, so add vendor-reset to the module list and rebuild the initrd.

## FAQ

### What is the vendor-reset kernel module for?

It resets hardware devices into a state where they can be re-initialised or passed through into a virtual machine using VFIO. It exists because some vendor reset procedures are too complex to be accepted upstream as PCI quirks, with the AMD Vega 10 given as the example, and an out of tree module lets vendors contribute and users update without a kernel rebuild.

### Does vendor-reset require patching the kernel?

No. The README says no patching required, because the module uses ftrace to hook pci_dev_specific_reset and handle device resets directly. Modprobing the module is enough to enable the reset routines for all supported hardware, and the kernel must be built with CONFIG_FTRACE, CONFIG_KPROBES, CONFIG_PCI_QUIRKS, CONFIG_KALLSYMS, CONFIG_KALLSYMS_ALL and CONFIG_FUNCTION_TRACER enabled.

### How do I install and load vendor-reset?

Use `dkms install .`, which the README recommends over the standard make and make install pattern, then load the module with modprobe vendor-reset or add it to /etc/modules on Debian. The module must be loaded early, because the default reset the kernel performs breaks the GPU irrecoverably, so in most cases you add vendor-reset to the module list and update the initrd.

### Which devices does vendor-reset support?

AMD families, listed by the common retail names: Polaris 10 for the RX 470, 480, 570, 580 and 590, Polaris 11 for the RX 460 and 560, Polaris 12 for the RX 540 and 550, Vega 10 for the Vega 56, 64 and FE, Vega 20 for the Radeon VII and Instinct MI100, and Navi 10, 12 and 14 for the listed 5000 and 6000 series parts.

## Sources

- [gnif/vendor-reset on GitHub](https://github.com/gnif/vendor-reset)
- [Issues](https://github.com/gnif/vendor-reset/issues)
- [License: GPL-2.0](https://github.com/gnif/vendor-reset/blob/master/LICENSE)
- [README](https://github.com/gnif/vendor-reset/blob/master/README.md)
- [Releases](https://github.com/gnif/vendor-reset/releases)

---

Hysen Labs editorial analysis, written from the project's own repository and release notes. Cite the canonical page: https://hysenlabs.com/projects/gnif-vendor-reset
