[Bug 274074] native_apic_alloc_vectors() does not properly align vectors when 32 are requested
Date: Mon, 25 Sep 2023 07:42:02 UTC
https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=274074 Bug ID: 274074 Summary: native_apic_alloc_vectors() does not properly align vectors when 32 are requested Product: Base System Version: Unspecified Hardware: amd64 OS: Any Status: New Severity: Affects Only Me Priority: --- Component: kern Assignee: bugs@FreeBSD.org Reporter: john@sanren.ac.za Created attachment 245210 --> https://bugs.freebsd.org/bugzilla/attachment.cgi?id=245210&action=edit Fix to align the msi vector properly MSI interrupt vectors needs to be aligned to the size of the request and have to be in powers of 2. The code in native_apic_alloc_vectors() does an alignment check in the loop: if ((vector & (align - 1)) != 0) continue; first = vector; But when it adds APIC_IO_INTS to the value it returns: return (first + APIC_IO_INTS); The problem is that APIC_IO_INTS is not a multiple of 32. It is 48: #define NRSVIDT 32 #define IDT_IO_INTS NRSVIDT #define APIC_IO_INTS (IDT_IO_INTS + 16) My fix is to include it during the alignment check: --- /sys/x86/x86/local_apic.c.org 2023-04-07 02:34:45.000000000 +0200 +++ /sys/x86/x86/local_apic.c 2023-09-24 21:10:04.785720000 +0200 @@ -1657,7 +1657,7 @@ /* Start a new run if run == 0 and vector is aligned. */ if (run == 0) { - if ((vector & (align - 1)) != 0) + if (((vector + APIC_IO_INTS) & (align - 1)) != 0) continue; first = vector; } The patch is against 13.2, but the code in current looks the same. Without the patch, pci_alloc_msi() with a count of 32 would return without an error and allocate 32 vectors, but in my case with a base vector of 0x50 and that was configured on the card. But the card would then ignore the bottom 5 bits and generate interrupt vectors from 0x40 to 0x5f. -- You are receiving this mail because: You are the assignee for the bug.