aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorKonstantin Belousov <kib@FreeBSD.org>2026-01-19 11:55:36 +0000
committerKonstantin Belousov <kib@FreeBSD.org>2026-01-19 16:20:37 +0000
commit709a53c8b20b5770f7e2f117d4799b5617479976 (patch)
tree1a5f892c394a4c46f0ec8fc1f5d2d67cf4c41197
parentad5e3cb950344f9822dbbd90f5ac7c256f97fa4c (diff)
x86/local_apic.c: Properly calculate the number of LVT entries
First, the CMCI entry index is APIC_LVT_MAX, so it was excluded unconditionall [1]. Second, the number of entries is reported by the version register, and we must not access past the last reported entry. Reported by: olivier [1] Fixes: 11f954b021a1aadde1d03d40ed5d6b529e14da98 Reviewed by: markj Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D54773
-rw-r--r--sys/x86/include/apicreg.h7
-rw-r--r--sys/x86/x86/local_apic.c7
2 files changed, 11 insertions, 3 deletions
diff --git a/sys/x86/include/apicreg.h b/sys/x86/include/apicreg.h
index 1252647fbab3..4cc9cabdad9e 100644
--- a/sys/x86/include/apicreg.h
+++ b/sys/x86/include/apicreg.h
@@ -439,7 +439,12 @@ typedef struct IOAPIC ioapic_t;
#define APIC_EXTF_SEIO_CAP 0x00000002
#define APIC_EXTF_IER_CAP 0x00000001
-/* LVT table indices */
+/*
+ * LVT table indices.
+ * Must be ordered following the appearance of the LVT entries in
+ * series the LAPIC versions, which is reported by LAPIC_VERSION
+ * MAXLVT field.
+ */
#define APIC_LVT_LINT0 0
#define APIC_LVT_LINT1 1
#define APIC_LVT_TIMER 2
diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 68f42c9eed0b..b444142d5481 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -819,9 +819,12 @@ lapic_early_mask_vec(const struct lvt *l)
static void
lapic_early_mask_vecs(void)
{
- int elvt_count, i;
+ int elvt_count, lvts_count, i;
+ uint32_t version;
- for (i = 0; i < APIC_LVT_MAX; i++)
+ version = lapic_read32(LAPIC_VERSION);
+ lvts_count = min(nitems(lvts), lapic_maxlvt(version) + 1);
+ for (i = 0; i < lvts_count; i++)
lapic_early_mask_vec(&lvts[i]);
elvt_count = amd_read_elvt_count();