The branch main has been updated by kib:

URL: 
https://cgit.FreeBSD.org/src/commit/?id=709a53c8b20b5770f7e2f117d4799b5617479976

commit 709a53c8b20b5770f7e2f117d4799b5617479976
Author:     Konstantin Belousov <[email protected]>
AuthorDate: 2026-01-19 11:55:36 +0000
Commit:     Konstantin Belousov <[email protected]>
CommitDate: 2026-01-19 16:20:37 +0000

    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
---
 sys/x86/include/apicreg.h | 7 ++++++-
 sys/x86/x86/local_apic.c  | 7 +++++--
 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();

Reply via email to