From 358db6d8825b38296a205206ac3d25b2084aa5f4 Mon Sep 17 00:00:00 2001 From: John Hay Date: Thu, 28 Sep 2023 14:08:08 -0700 Subject: 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 (cherry picked from commit d33a4ae8ba5343f555842e6e32321f9cd64dfd09) --- sys/x86/x86/local_apic.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'sys') diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c index 64358a53afcf..68468110e522 100644 --- a/sys/x86/x86/local_apic.c +++ b/sys/x86/x86/local_apic.c @@ -1655,7 +1655,7 @@ native_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; } -- cgit v1.2.3