Exceptions, Non-Maskable Interrupts (NMIs), Inter-Processor Interrupts (IPIs), and device interrupts all use the same interrupt mechanism on x86 CPUs. The operating system provides an Interrupt Descriptor Table (IDT) to the CPU that contains an array of handlers. When an interrupt is asserted, the CPU determines the associated IDT index, or vector. It can do this by asking an external interrupt controller for the IDT vector. If the interrupt was triggered by a message, the message will contain the IDT vector. Exceptions and NMIs are assigned static IDT vectors. Once the CPU has the IDT vector, it uses that vector as an index into the IDT. It then triggers the handler for that IDT slot. Thus, for an operating system to handle a device interrupt on an x86 CPU, it must know which device driver handlers are associated with a given IDT vector.
Thus, at one end we have a PCI interrupt line being signaled by a PCI function that needs attention. At the other end we have a CPU receiving an IDT vector. In the middle is one of those ``and then a miracle occurs'' mysteries. In this case the mystery hardware in the middle is known collectively as interrupt controllers.