git: e79e4c7031a4 - stable/14 - arm64: Add cpu_feat_disabled for disabled features

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Thu, 15 Jan 2026 14:51:03 UTC
The branch stable/14 has been updated by andrew:

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

commit e79e4c7031a444ac4d8466bc9834d2f4c3d31132
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2025-09-19 10:05:46 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2026-01-14 21:14:13 +0000

    arm64: Add cpu_feat_disabled for disabled features
    
    When a feature is disabled we may need to run a cleanup handler, e.g.
    to remove a feature from the sanitized ID registers. Add support for
    this with a new feat_disabled handler.
    
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D52577
    
    (cherry picked from commit 055229eda697445880edd0050d0230a3f1bc85b3)
---
 sys/arm64/arm64/cpu_feat.c   | 10 +++++++---
 sys/arm64/include/cpu_feat.h |  5 ++++-
 2 files changed, 11 insertions(+), 4 deletions(-)

diff --git a/sys/arm64/arm64/cpu_feat.c b/sys/arm64/arm64/cpu_feat.c
index 6aec0fdf8a78..11d42d5f3561 100644
--- a/sys/arm64/arm64/cpu_feat.c
+++ b/sys/arm64/arm64/cpu_feat.c
@@ -70,18 +70,18 @@ enable_cpu_feat(uint32_t stage)
 		}
 		/* Ignore features that are not present */
 		if (check_status == FEAT_ALWAYS_DISABLE)
-			continue;
+			goto next;
 
 		snprintf(tunable, sizeof(tunable), "hw.feat.%s",
 		    feat->feat_name);
 		if (TUNABLE_BOOL_FETCH(tunable, &val)) {
 			/* Is the feature disabled by the tunable? */
 			if (!val)
-				continue;
+				goto next;
 			/* If enabled by the tunable then enable it */
 		} else if (check_status == FEAT_DEFAULT_DISABLE) {
 			/* No tunable set and disabled by default */
-			continue;
+			goto next;
 		}
 
 		/*
@@ -123,6 +123,10 @@ enable_cpu_feat(uint32_t stage)
 		if (feat->feat_enable(feat, errata_status, errata_list,
 		    errata_count))
 			feat->feat_enabled = true;
+
+next:
+		if (!feat->feat_enabled && feat->feat_disabled != NULL)
+			feat->feat_disabled(feat);
 	}
 }
 
diff --git a/sys/arm64/include/cpu_feat.h b/sys/arm64/include/cpu_feat.h
index 6a554b6baedf..20c743a7e507 100644
--- a/sys/arm64/include/cpu_feat.h
+++ b/sys/arm64/include/cpu_feat.h
@@ -80,12 +80,14 @@ typedef bool (cpu_feat_has_errata)(const struct cpu_feat *, u_int,
     u_int **, u_int *);
 typedef bool (cpu_feat_enable)(const struct cpu_feat *, cpu_feat_errata,
     u_int *, u_int);
+typedef void (cpu_feat_disabled)(const struct cpu_feat *);
 
 struct cpu_feat {
 	const char		*feat_name;
 	cpu_feat_check		*feat_check;
 	cpu_feat_has_errata	*feat_has_errata;
 	cpu_feat_enable		*feat_enable;
+	cpu_feat_disabled	*feat_disabled;
 	uint32_t		 feat_flags;
 	bool			 feat_enabled;
 };
@@ -93,12 +95,13 @@ SET_DECLARE(cpu_feat_set, struct cpu_feat);
 
 SYSCTL_DECL(_hw_feat);
 
-#define	CPU_FEAT(name, descr, check, has_errata, enable, flags)	\
+#define	CPU_FEAT(name, descr, check, has_errata, enable, disabled, flags) \
 static struct cpu_feat name = {						\
 	.feat_name		= #name,				\
 	.feat_check		= check,				\
 	.feat_has_errata	= has_errata,				\
 	.feat_enable		= enable,				\
+	.feat_disabled		= disabled,				\
 	.feat_flags		= flags,				\
 	.feat_enabled		= false,				\
 };									\