aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Hay <jhay@FreeBSD.org>2023-09-28 21:08:08 +0000
committerJohn Baldwin <jhb@FreeBSD.org>2023-10-16 23:04:33 +0000
commit9851b24ed4fa571ae3b931f834d21b9f800db9e9 (patch)
tree7fa1bbd7640f9f00a08b7994d026865eb35c50cb
parent5c855665a04ea950bc98e92f3a78f2a4d9988a3d (diff)
downloadsrc-9851b24ed4fa571ae3b931f834d21b9f800db9e9.tar.gz
src-9851b24ed4fa571ae3b931f834d21b9f800db9e9.zip
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) (cherry picked from commit d73b4f06403af6c1a384c8c59ba9eb138c861ee1) Approved by: re (karels)
-rw-r--r--sys/x86/x86/local_apic.c2
1 files changed, 1 insertions, 1 deletions
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 17b0223f834b..b382368cc626 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -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;
}