git: 060ecf296664 - main - x86/local_apic.c: Factor out version read and max LVT slot computation

From: Olivier Certner <olce_at_FreeBSD.org>
Date: Fri, 10 Jul 2026 15:30:38 UTC
The branch main has been updated by olce:

URL: https://cgit.FreeBSD.org/src/commit/?id=060ecf296664fd150328ac6dcdc24764a427bc3a

commit 060ecf296664fd150328ac6dcdc24764a427bc3a
Author:     Olivier Certner <olce@FreeBSD.org>
AuthorDate: 2026-07-08 12:59:28 +0000
Commit:     Olivier Certner <olce@FreeBSD.org>
CommitDate: 2026-07-10 15:29:44 +0000

    x86/local_apic.c: Factor out version read and max LVT slot computation
    
    This makes the code slightly more compact and easier to read.
    
    No functional change intended.
    
    Reviewed by:    bnovkov
    MFC after:      2 weeks
    Sponsored by:   The FreeBSD Foundation
    Differential Revision:  https://reviews.freebsd.org/D58110
---
 sys/x86/x86/local_apic.c | 72 ++++++++++++++++++++++++------------------------
 1 file changed, 36 insertions(+), 36 deletions(-)

diff --git a/sys/x86/x86/local_apic.c b/sys/x86/x86/local_apic.c
index 9e1c1d70aea7..73ddf9115e4c 100644
--- a/sys/x86/x86/local_apic.c
+++ b/sys/x86/x86/local_apic.c
@@ -333,16 +333,6 @@ SYSCTL_INT(_hw_apic, OID_AUTO, ds_idle_timeout, CTLFLAG_RWTUN,
 
 static void lapic_calibrate_initcount(struct lapic *la);
 
-/*
- * Calculate the max index of the present LVT entry from the value of
- * the LAPIC version register.
- */
-static int
-lapic_maxlvt(uint32_t version)
-{
-	return ((version & APIC_VER_MAXLVT) >> MAXLVTSHIFT);
-}
-
 /*
  * Use __nosanitizethread to exempt the LAPIC I/O accessors from KCSan
  * instrumentation.  Otherwise, if x2APIC is not available, use of the global
@@ -390,6 +380,28 @@ lapic_write32_nofence(enum LAPIC_REGISTERS reg, uint32_t val)
 	}
 }
 
+static inline uint32_t __pure2
+lapic_version(void)
+{
+	return (lapic_read32(LAPIC_VERSION));
+}
+
+/*
+ * Calculate the max index of the present LVT entry from the value of
+ * the LAPIC version register.
+ */
+static inline int __pure2
+lapic_version_maxlvt(uint32_t version)
+{
+	return ((version & APIC_VER_MAXLVT) >> MAXLVTSHIFT);
+}
+
+static inline int __pure2
+lapic_maxlvt(void)
+{
+	return (lapic_version_maxlvt(lapic_version()));
+}
+
 #ifdef SMP
 static uint64_t
 lapic_read_icr_lo(void)
@@ -648,7 +660,7 @@ lapic_init(vm_paddr_t addr)
 	 * It seems that at least some KVM versions report
 	 * EOI_SUPPRESSION bit, but auto-EOI does not work.
 	 */
-	ver = lapic_read32(LAPIC_VERSION);
+	ver = lapic_version();
 	if ((ver & APIC_VER_EOI_SUPPRESSION) != 0) {
 		lapic_eoi_suppression = 1;
 		if (vm_guest == VM_GUEST_KVM) {
@@ -755,7 +767,7 @@ amd_read_ext_features(void)
 	if (cpu_vendor_id != CPU_VENDOR_AMD &&
 	    cpu_vendor_id != CPU_VENDOR_HYGON)
 		return (0);
-	version = lapic_read32(LAPIC_VERSION);
+	version = lapic_version();
 	if ((version & APIC_VER_AMD_EXT_SPACE) != 0)
 		return (lapic_read32(LAPIC_EXT_FEATURES));
 	else
@@ -780,14 +792,12 @@ amd_read_elvt_count(void)
 void
 lapic_dump(const char* str)
 {
-	uint32_t version;
-	uint32_t maxlvt;
+	const uint32_t version = lapic_version();
+	const int maxlvt = lapic_version_maxlvt(version);
 	uint32_t extf;
 	int elvt_count;
 	int i;
 
-	version = lapic_read32(LAPIC_VERSION);
-	maxlvt = lapic_maxlvt(version);
 	printf("cpu%d %s:\n", PCPU_GET(cpuid), str);
 	printf("     ID: 0x%08x   VER: 0x%08x LDR: 0x%08x DFR: 0x%08x",
 	    lapic_read32(LAPIC_ID), version,
@@ -844,10 +854,8 @@ static void
 lapic_early_mask_vecs(void)
 {
 	int elvt_count, lvts_count, i;
-	uint32_t version;
 
-	version = lapic_read32(LAPIC_VERSION);
-	lvts_count = min(nitems(lvts), lapic_maxlvt(version) + 1);
+	lvts_count = min(nitems(lvts), lapic_maxlvt() + 1);
 	for (i = 0; i < lvts_count; i++)
 		lapic_early_mask_vec(&lvts[i]);
 
@@ -859,9 +867,9 @@ lapic_early_mask_vecs(void)
 void
 lapic_setup(int boot)
 {
+	const uint32_t version = lapic_version();
+	const uint32_t maxlvt = lapic_version_maxlvt(version);
 	struct lapic *la;
-	uint32_t version;
-	uint32_t maxlvt;
 	register_t saveintr;
 	int elvt_count;
 	int i;
@@ -870,8 +878,6 @@ lapic_setup(int boot)
 
 	la = &lapics[lapic_id()];
 	KASSERT(la->la_present, ("missing APIC structure"));
-	version = lapic_read32(LAPIC_VERSION);
-	maxlvt = lapic_maxlvt(version);
 
 	/* Initialize the TPR to allow all interrupts. */
 	lapic_set_tpr(0);
@@ -1032,8 +1038,6 @@ lapic_calibrate_timer(void)
 int
 lapic_enable_pcint(void)
 {
-	u_int32_t maxlvt;
-
 #ifdef DEV_ATPIC
 	/* Fail if the local APIC is not present. */
 	if (!x2apic_mode && lapic_map == NULL)
@@ -1041,8 +1045,7 @@ lapic_enable_pcint(void)
 #endif
 
 	/* Fail if the PMC LVT is not present. */
-	maxlvt = lapic_maxlvt(lapic_read32(LAPIC_VERSION));
-	if (maxlvt < APIC_LVT_PMC)
+	if (lapic_maxlvt() < APIC_LVT_PMC)
 		return (0);
 	if (refcount_acquire(&pcint_refcnt) > 0)
 		return (1);
@@ -1059,8 +1062,6 @@ lapic_enable_pcint(void)
 void
 lapic_disable_pcint(void)
 {
-	u_int32_t maxlvt;
-
 #ifdef DEV_ATPIC
 	/* Fail if the local APIC is not present. */
 	if (!x2apic_mode && lapic_map == NULL)
@@ -1068,8 +1069,7 @@ lapic_disable_pcint(void)
 #endif
 
 	/* Fail if the PMC LVT is not present. */
-	maxlvt = lapic_maxlvt(lapic_read32(LAPIC_VERSION));
-	if (maxlvt < APIC_LVT_PMC)
+	if (lapic_maxlvt() < APIC_LVT_PMC)
 		return;
 	if (!refcount_release(&pcint_refcnt))
 		return;
@@ -1987,19 +1987,19 @@ DB_SHOW_COMMAND_FLAGS(lapic, db_show_lapic, DB_CMD_MEMSAFE)
 {
 	const struct lvt *l;
 	int elvt_count, lvts_count, i;
-	uint32_t v, vr;
+	const uint32_t v = lapic_version();
+	const int maxlvt = lapic_version_maxlvt(v);
+	const uint32_t vr = lapic_read32(LAPIC_SVR);
 
 	db_printf("lapic ID = %d\n", lapic_id());
-	v = lapic_read32(LAPIC_VERSION);
 	db_printf("version  = %d.%d (%#x) \n", (v & APIC_VER_VERSION) >> 4,
 	    v & 0xf, v);
-	db_printf("max LVT  = %d\n", lapic_maxlvt(v));
-	vr = lapic_read32(LAPIC_SVR);
+	db_printf("max LVT  = %d\n", maxlvt);
 	db_printf("SVR      = %02x (%s)\n", vr & APIC_SVR_VECTOR,
 	    vr & APIC_SVR_ENABLE ? "enabled" : "disabled");
 	db_printf("TPR      = %02x\n", lapic_read32(LAPIC_TPR));
 
-	lvts_count = min(nitems(lvts), lapic_maxlvt(v) + 1);
+	lvts_count = min(nitems(lvts), maxlvt + 1);
 	for (i = 0; i < lvts_count; i++) {
 		l = &lvts[i];
 		db_printf("LVT%d  (reg %#x %-5s) = %#010x\n", i, l->lvt_reg,