x86: Properly align interrupt vectors for MSI

MSI (not MSI-X) interrupt vectors must be allocated in groups that are
powers of 2, and the block of IDT vectors must be aligned to the size
of the request.

The code in native_apic_alloc_vectors() does an alignment check in the loop:

    if ((vector & (align - 1)) != 0)
        continue;
    first = vector;

But 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:

As a result, a request for 32 vectors (the max supported by MSI), was
not always aligned.  To fix, check the alignment of
'vector + APIC_IO_INTS' in the loop.

PR:		274074
Reviewed by:	jhb
This commit is contained in:
John Hay 2023-09-28 14:08:08 -07:00 committed by John Baldwin
parent b45ab4b000
commit d33a4ae8ba

View file

@ -1582,7 +1582,7 @@ apic_alloc_vectors(u_int apic_id, u_int *irqs, u_int count, u_int align)
/* 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;
}