From b0e1b1069d655f12ab69cf3a1dc1904dd35ad1da Mon Sep 17 00:00:00 2001 From: Colin Percival Date: Mon, 16 Mar 2026 23:45:32 +0000 Subject: [PATCH] io_apic: Support APIC Extended Destination IDs If APIC Extended Destination ID support is enabled, use it in APIC RTEs by allowing APIC IDs up to 2^15 - 1 and encoding the high bits into Intel "reserved" bits per the standard. Reviewed by: kib MFC after: 3 weeks Sponsored by: Amazon Differential Revision: https://reviews.freebsd.org/D55889 --- sys/x86/include/apicvar.h | 1 + sys/x86/x86/io_apic.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/sys/x86/include/apicvar.h b/sys/x86/include/apicvar.h index c2f4414ec8d..2dda3103f93 100644 --- a/sys/x86/include/apicvar.h +++ b/sys/x86/include/apicvar.h @@ -84,6 +84,7 @@ * to use that ID. */ #define IOAPIC_MAX_ID 0xff +#define IOAPIC_MAX_EXT_ID 0x7fff /* I/O Interrupts are used for external devices such as ISA, PCI, etc. */ #define APIC_IO_INTS (IDT_IO_INTS + 16) diff --git a/sys/x86/x86/io_apic.c b/sys/x86/x86/io_apic.c index 5d28b7e8c61..28841cfc0e2 100644 --- a/sys/x86/x86/io_apic.c +++ b/sys/x86/x86/io_apic.c @@ -371,6 +371,13 @@ ioapic_program_intpin(struct ioapic_intsrc *intpin) low = IOART_DESTPHY; high = intpin->io_cpu << APIC_ID_SHIFT; intpin->io_valid = 1; + } else if (intpin->io_cpu <= IOAPIC_MAX_EXT_ID && + apic_ext_dest_id == 1) { + low = IOART_DESTPHY; + high = intpin->io_cpu << APIC_ID_SHIFT & APIC_ID_MASK; + high |= (intpin->io_cpu >> 8) << APIC_EXT_ID_SHIFT + & APIC_EXT_ID_MASK; + intpin->io_valid = 1; } else { printf("%s: unsupported destination APIC ID %u for pin %u\n", __func__, intpin->io_cpu, intpin->io_intpin);