git: f03149940554 - main - arm64: Use a bit to hold userspace ID reg exports

From: Andrew Turner <andrew_at_FreeBSD.org>
Date: Mon, 21 Oct 2024 12:24:18 UTC
The branch main has been updated by andrew:

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

commit f031499405544933038e50ebd84a400218082b77
Author:     Andrew Turner <andrew@FreeBSD.org>
AuthorDate: 2024-10-18 09:16:31 +0000
Commit:     Andrew Turner <andrew@FreeBSD.org>
CommitDate: 2024-10-21 12:23:15 +0000

    arm64: Use a bit to hold userspace ID reg exports
    
    When exporting ID registers to userspace we should either adjust them
    the same way for FreeBSD and Linux binaries, or export the Linux
    field values to a safe value, e.g. when a needed syscall is missing.
    
    To allow for this, and to clean up ID register handling in the kernel
    move to using a bit per userspace ABI.
    
    Reviewed by:    imp
    Sponsored by:   Arm Ltd
    Differential Revision:  https://reviews.freebsd.org/D47121
---
 sys/arm64/arm64/identcpu.c | 438 ++++++++++++++++++++++++---------------------
 1 file changed, 232 insertions(+), 206 deletions(-)

diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
index c36428cfa1d6..83d934af345e 100644
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -290,8 +290,6 @@ const struct cpu_implementers cpu_implementers[] = {
 };
 
 #define	MRS_TYPE_MASK		0xf
-#define	MRS_TYPE_FBSD_SHIFT	0
-#define	MRS_TYPE_LNX_SHIFT	8
 #define	MRS_INVALID		0
 #define	MRS_EXACT		1
 #define	MRS_LOWER		2
@@ -299,6 +297,9 @@ const struct cpu_implementers cpu_implementers[] = {
 #define	MRS_SAFE_MASK		(0xfu << MRS_SAFE_SHIFT)
 #define	MRS_SAFE(x)		(((x) << MRS_SAFE_SHIFT) & MRS_SAFE_MASK)
 #define	MRS_SAFE_VAL(x)		(((x) & MRS_SAFE_MASK) >> MRS_SAFE_SHIFT)
+#define	MRS_FREEBSD		(1u << 8)
+#define	MRS_LINUX		(1u << 9)
+#define	MRS_USERSPACE		(MRS_FREEBSD | MRS_LINUX)
 
 struct mrs_field_value {
 	uint64_t	value;
@@ -361,13 +362,12 @@ struct mrs_field {
 	u_int		shift;
 };
 
-#define	MRS_FIELD_HWCAP_SPLIT(_register, _name, _sign, _fbsd_type,	\
-    _lnx_type, _values, _hwcap)						\
+#define	MRS_FIELD_HWCAP(_register, _name, _sign, _type, _visibility,	\
+    _values, _hwcap)							\
 	{								\
 		.name = #_name,						\
 		.sign = (_sign),					\
-		.type = ((_fbsd_type) << MRS_TYPE_FBSD_SHIFT) |		\
-		    ((_lnx_type) << MRS_TYPE_LNX_SHIFT),		\
+		.type = ((_type) | (_visibility)),			\
 		.width = _register ## _ ## _name ## _WIDTH,		\
 		.shift = _register ## _ ## _name ## _SHIFT,		\
 		.mask = _register ## _ ## _name ## _MASK,		\
@@ -375,15 +375,13 @@ struct mrs_field {
 		.hwcaps = (_hwcap),					\
 	}
 
-#define	MRS_FIELD_HWCAP(_register, _name, _sign, _type, _values, _hwcap) \
-	MRS_FIELD_HWCAP_SPLIT(_register, _name, _sign, _type, _type,	\
-	    _values, _hwcap)
-
-#define	MRS_FIELD(_register, _name, _sign, _type, _values)		\
-	MRS_FIELD_HWCAP(_register, _name, _sign, _type, _values, NULL)
+#define	MRS_FIELD(_register, _name, _sign, _type, _visibility, _values)	\
+	MRS_FIELD_HWCAP(_register, _name, _sign, _type, _visibility,	\
+	    _values, NULL)
 
 #define	MRS_FIELD_END	{ .type = MRS_INVALID, }
 
+
 /* ID_AA64AFR0_EL1 */
 static const struct mrs_field id_aa64afr0_fields[] = {
 	MRS_FIELD_END,
@@ -483,24 +481,26 @@ static const struct mrs_field_value id_aa64dfr0_debugver[] = {
 };
 
 static const struct mrs_field id_aa64dfr0_fields[] = {
-	MRS_FIELD(ID_AA64DFR0, HPMN0, false, MRS_EXACT, id_aa64dfr0_hpmn0),
-	MRS_FIELD(ID_AA64DFR0, BRBE, false, MRS_EXACT, id_aa64dfr0_brbe),
-	MRS_FIELD(ID_AA64DFR0, MTPMU, true, MRS_EXACT, id_aa64dfr0_mtpmu),
-	MRS_FIELD(ID_AA64DFR0, TraceBuffer, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64DFR0, HPMN0, false, MRS_LOWER, 0, id_aa64dfr0_hpmn0),
+	MRS_FIELD(ID_AA64DFR0, BRBE, false, MRS_LOWER, 0, id_aa64dfr0_brbe),
+	MRS_FIELD(ID_AA64DFR0, MTPMU, true, MRS_LOWER, 0, id_aa64dfr0_mtpmu),
+	MRS_FIELD(ID_AA64DFR0, TraceBuffer, false, MRS_LOWER, 0,
 	    id_aa64dfr0_tracebuffer),
-	MRS_FIELD(ID_AA64DFR0, TraceFilt, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64DFR0, TraceFilt, false, MRS_LOWER, 0,
 	    id_aa64dfr0_tracefilt),
-	MRS_FIELD(ID_AA64DFR0, DoubleLock, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64DFR0, DoubleLock, false, MRS_LOWER, 0,
 	    id_aa64dfr0_doublelock),
-	MRS_FIELD(ID_AA64DFR0, PMSVer, false, MRS_EXACT, id_aa64dfr0_pmsver),
-	MRS_FIELD(ID_AA64DFR0, CTX_CMPs, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64DFR0, PMSVer, false, MRS_LOWER, 0, id_aa64dfr0_pmsver),
+	MRS_FIELD(ID_AA64DFR0, CTX_CMPs, false, MRS_LOWER, 0,
 	    id_aa64dfr0_ctx_cmps),
-	MRS_FIELD(ID_AA64DFR0, WRPs, false, MRS_LOWER, id_aa64dfr0_wrps),
-	MRS_FIELD(ID_AA64DFR0, BRPs, false, MRS_LOWER, id_aa64dfr0_brps),
-	MRS_FIELD(ID_AA64DFR0, PMUVer, false, MRS_EXACT, id_aa64dfr0_pmuver),
-	MRS_FIELD(ID_AA64DFR0, TraceVer, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64DFR0, WRPs, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64dfr0_wrps),
+	MRS_FIELD(ID_AA64DFR0, BRPs, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64dfr0_brps),
+	MRS_FIELD(ID_AA64DFR0, PMUVer, false, MRS_LOWER, 0, id_aa64dfr0_pmuver),
+	MRS_FIELD(ID_AA64DFR0, TraceVer, false, MRS_LOWER, 0,
 	    id_aa64dfr0_tracever),
-	MRS_FIELD(ID_AA64DFR0, DebugVer, false, MRS_EXACT | MRS_SAFE(0x6),
+	MRS_FIELD(ID_AA64DFR0, DebugVer, false, MRS_LOWER | MRS_SAFE(0x6), 0,
 	    id_aa64dfr0_debugver),
 	MRS_FIELD_END,
 };
@@ -664,34 +664,34 @@ static const struct mrs_field_hwcap id_aa64isar0_aes_caps[] = {
 };
 
 static const struct mrs_field id_aa64isar0_fields[] = {
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, RNDR, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, RNDR, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar0_rndr, id_aa64isar0_rndr_caps),
-	MRS_FIELD(ID_AA64ISAR0, TLB, false, MRS_EXACT, id_aa64isar0_tlb),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, TS, false, MRS_LOWER, id_aa64isar0_ts,
-	    id_aa64isar0_ts_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, FHM, false, MRS_LOWER, id_aa64isar0_fhm,
-	    id_aa64isar0_fhm_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, DP, false, MRS_LOWER, id_aa64isar0_dp,
-	    id_aa64isar0_dp_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, SM4, false, MRS_LOWER, id_aa64isar0_sm4,
-	    id_aa64isar0_sm4_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, SM3, false, MRS_LOWER, id_aa64isar0_sm3,
-	    id_aa64isar0_sm3_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, SHA3, false, MRS_LOWER, id_aa64isar0_sha3,
-	    id_aa64isar0_sha3_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, RDM, false, MRS_LOWER, id_aa64isar0_rdm,
-	    id_aa64isar0_rdm_caps),
-	MRS_FIELD(ID_AA64ISAR0, TME, false, MRS_EXACT, id_aa64isar0_tme),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, Atomic, false, MRS_LOWER,
+	MRS_FIELD(ID_AA64ISAR0, TLB, false, MRS_LOWER, 0, id_aa64isar0_tlb),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, TS, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_ts, id_aa64isar0_ts_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, FHM, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_fhm, id_aa64isar0_fhm_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, DP, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_dp, id_aa64isar0_dp_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, SM4, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_sm4, id_aa64isar0_sm4_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, SM3, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_sm3, id_aa64isar0_sm3_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, SHA3, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_sha3, id_aa64isar0_sha3_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, RDM, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_rdm, id_aa64isar0_rdm_caps),
+	MRS_FIELD(ID_AA64ISAR0, TME, false, MRS_LOWER, 0, id_aa64isar0_tme),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, Atomic, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar0_atomic, id_aa64isar0_atomic_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, CRC32, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, CRC32, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar0_crc32, id_aa64isar0_crc32_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, SHA2, false, MRS_LOWER, id_aa64isar0_sha2,
-	    id_aa64isar0_sha2_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, SHA1, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, SHA2, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_sha2, id_aa64isar0_sha2_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, SHA1, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar0_sha1, id_aa64isar0_sha1_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR0, AES, false, MRS_LOWER, id_aa64isar0_aes,
-	    id_aa64isar0_aes_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR0, AES, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar0_aes, id_aa64isar0_aes_caps),
 	MRS_FIELD_END,
 };
 
@@ -865,36 +865,36 @@ static const struct mrs_field_hwcap id_aa64isar1_dpb_caps[] = {
 };
 
 static const struct mrs_field id_aa64isar1_fields[] = {
-	MRS_FIELD(ID_AA64ISAR1, LS64, false, MRS_EXACT, id_aa64isar1_ls64),
-	MRS_FIELD(ID_AA64ISAR1, XS, false, MRS_EXACT, id_aa64isar1_xs),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, I8MM, false, MRS_LOWER,
+	MRS_FIELD(ID_AA64ISAR1, LS64, false, MRS_LOWER, 0, id_aa64isar1_ls64),
+	MRS_FIELD(ID_AA64ISAR1, XS, false, MRS_LOWER, 0, id_aa64isar1_xs),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, I8MM, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar1_i8mm, id_aa64isar1_i8mm_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, DGH, false, MRS_LOWER, id_aa64isar1_dgh,
-	    id_aa64isar1_dgh_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, BF16, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, DGH, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar1_dgh, id_aa64isar1_dgh_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, BF16, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar1_bf16, id_aa64isar1_bf16_caps),
-	MRS_FIELD(ID_AA64ISAR1, SPECRES, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64ISAR1, SPECRES, false, MRS_LOWER, 0,
 	    id_aa64isar1_specres),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, SB, false, MRS_LOWER, id_aa64isar1_sb,
-	    id_aa64isar1_sb_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, FRINTTS, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, SB, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar1_sb, id_aa64isar1_sb_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, FRINTTS, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar1_frintts, id_aa64isar1_frintts_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, GPI, false, MRS_EXACT, id_aa64isar1_gpi,
-	    id_aa64isar1_gpi_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, GPA, false, MRS_EXACT, id_aa64isar1_gpa,
-	    id_aa64isar1_gpa_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, LRCPC, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, GPI, false, MRS_LOWER, 0,
+	    id_aa64isar1_gpi, id_aa64isar1_gpi_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, GPA, false, MRS_LOWER, 0,
+	    id_aa64isar1_gpa, id_aa64isar1_gpa_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, LRCPC, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar1_lrcpc, id_aa64isar1_lrcpc_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, FCMA, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, FCMA, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar1_fcma, id_aa64isar1_fcma_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, JSCVT, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, JSCVT, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar1_jscvt, id_aa64isar1_jscvt_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, API, false, MRS_EXACT, id_aa64isar1_api,
-	    id_aa64isar1_api_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, APA, false, MRS_EXACT, id_aa64isar1_apa,
-	    id_aa64isar1_apa_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR1, DPB, false, MRS_LOWER, id_aa64isar1_dpb,
-	    id_aa64isar1_dpb_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, API, false, MRS_LOWER, 0,
+	    id_aa64isar1_api, id_aa64isar1_api_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, APA, false, MRS_LOWER, 0,
+	    id_aa64isar1_apa, id_aa64isar1_apa_caps),
+	MRS_FIELD_HWCAP(ID_AA64ISAR1, DPB, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64isar1_dpb, id_aa64isar1_dpb_caps),
 	MRS_FIELD_END,
 };
 
@@ -957,17 +957,17 @@ static const struct mrs_field_value id_aa64isar2_wfxt[] = {
 };
 
 static const struct mrs_field id_aa64isar2_fields[] = {
-	MRS_FIELD(ID_AA64ISAR2, PAC_frac, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64ISAR2, PAC_frac, false, MRS_LOWER, 0,
 	    id_aa64isar2_pac_frac),
-	MRS_FIELD(ID_AA64ISAR2, BC, false, MRS_EXACT, id_aa64isar2_bc),
-	MRS_FIELD(ID_AA64ISAR2, MOPS, false, MRS_EXACT, id_aa64isar2_mops),
-	MRS_FIELD_HWCAP(ID_AA64ISAR2, APA3, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64ISAR2, BC, false, MRS_LOWER, 0, id_aa64isar2_bc),
+	MRS_FIELD(ID_AA64ISAR2, MOPS, false, MRS_LOWER, 0, id_aa64isar2_mops),
+	MRS_FIELD_HWCAP(ID_AA64ISAR2, APA3, false, MRS_LOWER, 0,
 	    id_aa64isar2_apa3, id_aa64isar2_apa3_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR2, GPA3, false, MRS_EXACT,
+	MRS_FIELD_HWCAP(ID_AA64ISAR2, GPA3, false, MRS_LOWER, 0,
 	    id_aa64isar2_gpa3, id_aa64isar2_gpa3_caps),
-	MRS_FIELD_HWCAP(ID_AA64ISAR2, RPRES, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ISAR2, RPRES, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64isar2_rpres, id_aa64isar2_rpres_caps),
-	MRS_FIELD(ID_AA64ISAR2, WFxT, false, MRS_EXACT, id_aa64isar2_wfxt),
+	MRS_FIELD(ID_AA64ISAR2, WFxT, false, MRS_LOWER, 0, id_aa64isar2_wfxt),
 	MRS_FIELD_END,
 };
 
@@ -1062,27 +1062,30 @@ static const struct mrs_field_value id_aa64mmfr0_parange[] = {
 };
 
 static const struct mrs_field id_aa64mmfr0_fields[] = {
-	MRS_FIELD(ID_AA64MMFR0, ECV, false, MRS_EXACT, id_aa64mmfr0_ecv),
-	MRS_FIELD(ID_AA64MMFR0, FGT, false, MRS_EXACT, id_aa64mmfr0_fgt),
-	MRS_FIELD(ID_AA64MMFR0, ExS, false, MRS_EXACT, id_aa64mmfr0_exs),
-	MRS_FIELD(ID_AA64MMFR0, TGran4_2, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, ECV, false, MRS_LOWER, 0, id_aa64mmfr0_ecv),
+	MRS_FIELD(ID_AA64MMFR0, FGT, false, MRS_LOWER, 0, id_aa64mmfr0_fgt),
+	MRS_FIELD(ID_AA64MMFR0, ExS, false, MRS_LOWER, 0, id_aa64mmfr0_exs),
+	MRS_FIELD(ID_AA64MMFR0, TGran4_2, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_tgran4_2),
-	MRS_FIELD(ID_AA64MMFR0, TGran64_2, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, TGran64_2, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_tgran64_2),
-	MRS_FIELD(ID_AA64MMFR0, TGran16_2, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, TGran16_2, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_tgran16_2),
-	MRS_FIELD(ID_AA64MMFR0, TGran4, false, MRS_EXACT, id_aa64mmfr0_tgran4),
-	MRS_FIELD(ID_AA64MMFR0, TGran64, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, TGran4, false, MRS_LOWER, 0,
+	    id_aa64mmfr0_tgran4),
+	MRS_FIELD(ID_AA64MMFR0, TGran64, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_tgran64),
-	MRS_FIELD(ID_AA64MMFR0, TGran16, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, TGran16, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_tgran16),
-	MRS_FIELD(ID_AA64MMFR0, BigEndEL0, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, BigEndEL0, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_bigendel0),
-	MRS_FIELD(ID_AA64MMFR0, SNSMem, false, MRS_EXACT, id_aa64mmfr0_snsmem),
-	MRS_FIELD(ID_AA64MMFR0, BigEnd, false, MRS_EXACT, id_aa64mmfr0_bigend),
-	MRS_FIELD(ID_AA64MMFR0, ASIDBits, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, SNSMem, false, MRS_LOWER, 0,
+	    id_aa64mmfr0_snsmem),
+	MRS_FIELD(ID_AA64MMFR0, BigEnd, false, MRS_LOWER, 0,
+	    id_aa64mmfr0_bigend),
+	MRS_FIELD(ID_AA64MMFR0, ASIDBits, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_asidbits),
-	MRS_FIELD(ID_AA64MMFR0, PARange, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR0, PARange, false, MRS_LOWER, 0,
 	    id_aa64mmfr0_parange),
 	MRS_FIELD_END,
 };
@@ -1177,24 +1180,26 @@ static const struct mrs_field_value id_aa64mmfr1_hafdbs[] = {
 };
 
 static const struct mrs_field id_aa64mmfr1_fields[] = {
-	MRS_FIELD(ID_AA64MMFR1, CMOVW, false, MRS_EXACT, id_aa64mmfr1_cmovw),
-	MRS_FIELD(ID_AA64MMFR1, TIDCP1, false, MRS_EXACT, id_aa64mmfr1_tidcp1),
-	MRS_FIELD(ID_AA64MMFR1, nTLBPA, false, MRS_EXACT, id_aa64mmfr1_ntlbpa),
-	MRS_FIELD_HWCAP(ID_AA64MMFR1, AFP, false, MRS_LOWER, id_aa64mmfr1_afp,
-	    id_aa64mmfr1_afp_caps),
-	MRS_FIELD(ID_AA64MMFR1, HCX, false, MRS_EXACT, id_aa64mmfr1_hcx),
-	MRS_FIELD(ID_AA64MMFR1, ETS, false, MRS_EXACT, id_aa64mmfr1_ets),
-	MRS_FIELD(ID_AA64MMFR1, TWED, false, MRS_EXACT, id_aa64mmfr1_twed),
-	MRS_FIELD(ID_AA64MMFR1, XNX, false, MRS_EXACT, id_aa64mmfr1_xnx),
-	MRS_FIELD(ID_AA64MMFR1, SpecSEI, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR1, CMOVW, false, MRS_LOWER, 0, id_aa64mmfr1_cmovw),
+	MRS_FIELD(ID_AA64MMFR1, TIDCP1, false, MRS_LOWER, 0,
+	    id_aa64mmfr1_tidcp1),
+	MRS_FIELD(ID_AA64MMFR1, nTLBPA, false, MRS_LOWER, 0,
+	    id_aa64mmfr1_ntlbpa),
+	MRS_FIELD_HWCAP(ID_AA64MMFR1, AFP, false, MRS_LOWER, 0,
+	    id_aa64mmfr1_afp, id_aa64mmfr1_afp_caps),
+	MRS_FIELD(ID_AA64MMFR1, HCX, false, MRS_LOWER, 0, id_aa64mmfr1_hcx),
+	MRS_FIELD(ID_AA64MMFR1, ETS, false, MRS_LOWER, 0, id_aa64mmfr1_ets),
+	MRS_FIELD(ID_AA64MMFR1, TWED, false, MRS_LOWER, 0, id_aa64mmfr1_twed),
+	MRS_FIELD(ID_AA64MMFR1, XNX, false, MRS_LOWER, 0, id_aa64mmfr1_xnx),
+	MRS_FIELD(ID_AA64MMFR1, SpecSEI, false, MRS_LOWER, 0,
 	    id_aa64mmfr1_specsei),
-	MRS_FIELD(ID_AA64MMFR1, PAN, false, MRS_EXACT, id_aa64mmfr1_pan),
-	MRS_FIELD(ID_AA64MMFR1, LO, false, MRS_EXACT, id_aa64mmfr1_lo),
-	MRS_FIELD(ID_AA64MMFR1, HPDS, false, MRS_EXACT, id_aa64mmfr1_hpds),
-	MRS_FIELD(ID_AA64MMFR1, VH, false, MRS_EXACT, id_aa64mmfr1_vh),
-	MRS_FIELD(ID_AA64MMFR1, VMIDBits, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR1, PAN, false, MRS_LOWER, 0, id_aa64mmfr1_pan),
+	MRS_FIELD(ID_AA64MMFR1, LO, false, MRS_LOWER, 0, id_aa64mmfr1_lo),
+	MRS_FIELD(ID_AA64MMFR1, HPDS, false, MRS_LOWER, 0, id_aa64mmfr1_hpds),
+	MRS_FIELD(ID_AA64MMFR1, VH, false, MRS_LOWER, 0, id_aa64mmfr1_vh),
+	MRS_FIELD(ID_AA64MMFR1, VMIDBits, false, MRS_LOWER, 0,
 	    id_aa64mmfr1_vmidbits),
-	MRS_FIELD(ID_AA64MMFR1, HAFDBS, false, MRS_EXACT, id_aa64mmfr1_hafdbs),
+	MRS_FIELD(ID_AA64MMFR1, HAFDBS, false, MRS_LOWER, 0, id_aa64mmfr1_hafdbs),
 	MRS_FIELD_END,
 };
 
@@ -1288,23 +1293,23 @@ static const struct mrs_field_value id_aa64mmfr2_cnp[] = {
 };
 
 static const struct mrs_field id_aa64mmfr2_fields[] = {
-	MRS_FIELD(ID_AA64MMFR2, E0PD, false, MRS_EXACT, id_aa64mmfr2_e0pd),
-	MRS_FIELD(ID_AA64MMFR2, EVT, false, MRS_EXACT, id_aa64mmfr2_evt),
-	MRS_FIELD(ID_AA64MMFR2, BBM, false, MRS_EXACT, id_aa64mmfr2_bbm),
-	MRS_FIELD(ID_AA64MMFR2, TTL, false, MRS_EXACT, id_aa64mmfr2_ttl),
-	MRS_FIELD(ID_AA64MMFR2, FWB, false, MRS_EXACT, id_aa64mmfr2_fwb),
-	MRS_FIELD(ID_AA64MMFR2, IDS, false, MRS_EXACT, id_aa64mmfr2_ids),
-	MRS_FIELD_HWCAP(ID_AA64MMFR2, AT, false, MRS_LOWER, id_aa64mmfr2_at,
-	    id_aa64mmfr2_at_caps),
-	MRS_FIELD(ID_AA64MMFR2, ST, false, MRS_EXACT, id_aa64mmfr2_st),
-	MRS_FIELD(ID_AA64MMFR2, NV, false, MRS_EXACT, id_aa64mmfr2_nv),
-	MRS_FIELD(ID_AA64MMFR2, CCIDX, false, MRS_EXACT, id_aa64mmfr2_ccidx),
-	MRS_FIELD(ID_AA64MMFR2, VARange, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR2, E0PD, false, MRS_LOWER, 0, id_aa64mmfr2_e0pd),
+	MRS_FIELD(ID_AA64MMFR2, EVT, false, MRS_LOWER, 0, id_aa64mmfr2_evt),
+	MRS_FIELD(ID_AA64MMFR2, BBM, false, MRS_LOWER, 0, id_aa64mmfr2_bbm),
+	MRS_FIELD(ID_AA64MMFR2, TTL, false, MRS_LOWER, 0, id_aa64mmfr2_ttl),
+	MRS_FIELD(ID_AA64MMFR2, FWB, false, MRS_LOWER, 0, id_aa64mmfr2_fwb),
+	MRS_FIELD(ID_AA64MMFR2, IDS, false, MRS_LOWER, 0, id_aa64mmfr2_ids),
+	MRS_FIELD_HWCAP(ID_AA64MMFR2, AT, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64mmfr2_at, id_aa64mmfr2_at_caps),
+	MRS_FIELD(ID_AA64MMFR2, ST, false, MRS_LOWER, 0, id_aa64mmfr2_st),
+	MRS_FIELD(ID_AA64MMFR2, NV, false, MRS_LOWER, 0, id_aa64mmfr2_nv),
+	MRS_FIELD(ID_AA64MMFR2, CCIDX, false, MRS_LOWER, 0, id_aa64mmfr2_ccidx),
+	MRS_FIELD(ID_AA64MMFR2, VARange, false, MRS_LOWER, 0,
 	    id_aa64mmfr2_varange),
-	MRS_FIELD(ID_AA64MMFR2, IESB, false, MRS_EXACT, id_aa64mmfr2_iesb),
-	MRS_FIELD(ID_AA64MMFR2, LSM, false, MRS_EXACT, id_aa64mmfr2_lsm),
-	MRS_FIELD(ID_AA64MMFR2, UAO, false, MRS_EXACT, id_aa64mmfr2_uao),
-	MRS_FIELD(ID_AA64MMFR2, CnP, false, MRS_EXACT, id_aa64mmfr2_cnp),
+	MRS_FIELD(ID_AA64MMFR2, IESB, false, MRS_LOWER, 0, id_aa64mmfr2_iesb),
+	MRS_FIELD(ID_AA64MMFR2, LSM, false, MRS_LOWER, 0, id_aa64mmfr2_lsm),
+	MRS_FIELD(ID_AA64MMFR2, UAO, false, MRS_LOWER, 0, id_aa64mmfr2_uao),
+	MRS_FIELD(ID_AA64MMFR2, CnP, false, MRS_LOWER, 0, id_aa64mmfr2_cnp),
 	MRS_FIELD_END,
 };
 
@@ -1331,11 +1336,12 @@ static const struct mrs_field_value id_aa64mmfr3_tcrx[] = {
 };
 
 static const struct mrs_field id_aa64mmfr3_fields[] = {
-	MRS_FIELD(ID_AA64MMFR3, Spec_FPACC, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64MMFR3, Spec_FPACC, false, MRS_LOWER, 0,
 	    id_aa64mmfr3_spec_fpacc),
-	MRS_FIELD(ID_AA64MMFR3, MEC, false, MRS_EXACT, id_aa64mmfr3_mec),
-	MRS_FIELD(ID_AA64MMFR3, SCTLRX, false, MRS_EXACT, id_aa64mmfr3_sctlrx),
-	MRS_FIELD(ID_AA64MMFR3, TCRX, false, MRS_EXACT, id_aa64mmfr3_tcrx),
+	MRS_FIELD(ID_AA64MMFR3, MEC, false, MRS_LOWER, 0, id_aa64mmfr3_mec),
+	MRS_FIELD(ID_AA64MMFR3, SCTLRX, false, MRS_LOWER, 0,
+	    id_aa64mmfr3_sctlrx),
+	MRS_FIELD(ID_AA64MMFR3, TCRX, false, MRS_LOWER, 0, id_aa64mmfr3_tcrx),
 	MRS_FIELD_END,
 };
 
@@ -1468,26 +1474,28 @@ static const struct mrs_field_value id_aa64pfr0_el0[] = {
 };
 
 static const struct mrs_field id_aa64pfr0_fields[] = {
-	MRS_FIELD(ID_AA64PFR0, CSV3, false, MRS_EXACT, id_aa64pfr0_csv3),
-	MRS_FIELD(ID_AA64PFR0, CSV2, false, MRS_EXACT, id_aa64pfr0_csv2),
-	MRS_FIELD(ID_AA64PFR0, RME, false, MRS_EXACT, id_aa64pfr0_rme),
-	MRS_FIELD_HWCAP(ID_AA64PFR0, DIT, false, MRS_LOWER, id_aa64pfr0_dit,
-	    id_aa64pfr0_dit_caps),
-	MRS_FIELD(ID_AA64PFR0, AMU, false, MRS_EXACT, id_aa64pfr0_amu),
-	MRS_FIELD(ID_AA64PFR0, MPAM, false, MRS_EXACT, id_aa64pfr0_mpam),
-	MRS_FIELD(ID_AA64PFR0, SEL2, false, MRS_EXACT, id_aa64pfr0_sel2),
-	MRS_FIELD_HWCAP_SPLIT(ID_AA64PFR0, SVE, false, MRS_LOWER, MRS_EXACT,
-	    id_aa64pfr0_sve, id_aa64pfr0_sve_caps),
-	MRS_FIELD(ID_AA64PFR0, RAS, false, MRS_EXACT, id_aa64pfr0_ras),
-	MRS_FIELD(ID_AA64PFR0, GIC, false, MRS_EXACT, id_aa64pfr0_gic),
-	MRS_FIELD_HWCAP(ID_AA64PFR0, AdvSIMD, true, MRS_LOWER,
+	MRS_FIELD(ID_AA64PFR0, CSV3, false, MRS_LOWER, 0, id_aa64pfr0_csv3),
+	MRS_FIELD(ID_AA64PFR0, CSV2, false, MRS_LOWER, 0, id_aa64pfr0_csv2),
+	MRS_FIELD(ID_AA64PFR0, RME, false, MRS_LOWER, 0, id_aa64pfr0_rme),
+	MRS_FIELD_HWCAP(ID_AA64PFR0, DIT, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64pfr0_dit, id_aa64pfr0_dit_caps),
+	MRS_FIELD(ID_AA64PFR0, AMU, false, MRS_LOWER, 0, id_aa64pfr0_amu),
+	MRS_FIELD(ID_AA64PFR0, MPAM, false, MRS_LOWER, 0, id_aa64pfr0_mpam),
+	MRS_FIELD(ID_AA64PFR0, SEL2, false, MRS_LOWER, 0, id_aa64pfr0_sel2),
+	MRS_FIELD_HWCAP(ID_AA64PFR0, SVE, false, MRS_LOWER,
+	    MRS_FREEBSD, id_aa64pfr0_sve, id_aa64pfr0_sve_caps),
+	MRS_FIELD(ID_AA64PFR0, RAS, false, MRS_LOWER, 0, id_aa64pfr0_ras),
+	MRS_FIELD(ID_AA64PFR0, GIC, false, MRS_LOWER, 0, id_aa64pfr0_gic),
+	MRS_FIELD_HWCAP(ID_AA64PFR0, AdvSIMD, true, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64pfr0_advsimd, id_aa64pfr0_advsimd_caps),
-	MRS_FIELD_HWCAP(ID_AA64PFR0, FP, true,  MRS_LOWER, id_aa64pfr0_fp,
-	    id_aa64pfr0_fp_caps),
-	MRS_FIELD(ID_AA64PFR0, EL3, false, MRS_EXACT, id_aa64pfr0_el3),
-	MRS_FIELD(ID_AA64PFR0, EL2, false, MRS_EXACT, id_aa64pfr0_el2),
-	MRS_FIELD(ID_AA64PFR0, EL1, false, MRS_LOWER, id_aa64pfr0_el1),
-	MRS_FIELD(ID_AA64PFR0, EL0, false, MRS_LOWER, id_aa64pfr0_el0),
+	MRS_FIELD_HWCAP(ID_AA64PFR0, FP, true,  MRS_LOWER, MRS_USERSPACE,
+	    id_aa64pfr0_fp, id_aa64pfr0_fp_caps),
+	MRS_FIELD(ID_AA64PFR0, EL3, false, MRS_LOWER, 0, id_aa64pfr0_el3),
+	MRS_FIELD(ID_AA64PFR0, EL2, false, MRS_LOWER, 0, id_aa64pfr0_el2),
+	MRS_FIELD(ID_AA64PFR0, EL1, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64pfr0_el1),
+	MRS_FIELD(ID_AA64PFR0, EL0, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64pfr0_el0),
 	MRS_FIELD_END,
 };
 
@@ -1561,21 +1569,21 @@ static const struct mrs_field_hwcap id_aa64pfr1_bt_caps[] = {
 };
 
 static const struct mrs_field id_aa64pfr1_fields[] = {
-	MRS_FIELD(ID_AA64PFR1, NMI, false, MRS_EXACT, id_aa64pfr1_nmi),
-	MRS_FIELD(ID_AA64PFR1, CSV2_frac, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64PFR1, NMI, false, MRS_LOWER, 0, id_aa64pfr1_nmi),
+	MRS_FIELD(ID_AA64PFR1, CSV2_frac, false, MRS_LOWER, 0,
 	    id_aa64pfr1_csv2_frac),
-	MRS_FIELD(ID_AA64PFR1, RNDR_trap, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64PFR1, RNDR_trap, false, MRS_LOWER, 0,
 	    id_aa64pfr1_rndr_trap),
-	MRS_FIELD(ID_AA64PFR1, SME, false, MRS_EXACT, id_aa64pfr1_sme),
-	MRS_FIELD(ID_AA64PFR1, MPAM_frac, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64PFR1, SME, false, MRS_LOWER, 0, id_aa64pfr1_sme),
+	MRS_FIELD(ID_AA64PFR1, MPAM_frac, false, MRS_LOWER, 0,
 	    id_aa64pfr1_mpam_frac),
-	MRS_FIELD(ID_AA64PFR1, RAS_frac, false, MRS_EXACT,
+	MRS_FIELD(ID_AA64PFR1, RAS_frac, false, MRS_LOWER, 0,
 	    id_aa64pfr1_ras_frac),
-	MRS_FIELD(ID_AA64PFR1, MTE, false, MRS_EXACT, id_aa64pfr1_mte),
-	MRS_FIELD_HWCAP(ID_AA64PFR1, SSBS, false, MRS_LOWER, id_aa64pfr1_ssbs,
-	    id_aa64pfr1_ssbs_caps),
-	MRS_FIELD_HWCAP_SPLIT(ID_AA64PFR1, BT, false, MRS_LOWER, MRS_EXACT,
-	    id_aa64pfr1_bt, id_aa64pfr1_bt_caps),
+	MRS_FIELD(ID_AA64PFR1, MTE, false, MRS_LOWER, 0, id_aa64pfr1_mte),
+	MRS_FIELD_HWCAP(ID_AA64PFR1, SSBS, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64pfr1_ssbs, id_aa64pfr1_ssbs_caps),
+	MRS_FIELD_HWCAP(ID_AA64PFR1, BT, false, MRS_LOWER,
+	    MRS_FREEBSD, id_aa64pfr1_bt, id_aa64pfr1_bt_caps),
 	MRS_FIELD_END,
 };
 
@@ -1685,23 +1693,23 @@ static const struct mrs_field_hwcap id_aa64zfr0_svever_caps[] = {
 };
 
 static const struct mrs_field id_aa64zfr0_fields[] = {
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, F64MM, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, F64MM, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64zfr0_f64mm, id_aa64zfr0_f64mm_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, F32MM, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, F32MM, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64zfr0_f32mm, id_aa64zfr0_f32mm_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, I8MM, false, MRS_LOWER, id_aa64zfr0_i8mm,
-	    id_aa64zfr0_i8mm_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, SM4, false, MRS_LOWER, id_aa64zfr0_sm4,
-	    id_aa64zfr0_sm4_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, SHA3, false, MRS_LOWER, id_aa64zfr0_sha3,
-	    id_aa64zfr0_sha3_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, BF16, false, MRS_LOWER, id_aa64zfr0_bf16,
-	    id_aa64zfr0_bf16_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, BitPerm, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, I8MM, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64zfr0_i8mm, id_aa64zfr0_i8mm_caps),
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, SM4, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64zfr0_sm4, id_aa64zfr0_sm4_caps),
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, SHA3, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64zfr0_sha3, id_aa64zfr0_sha3_caps),
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, BF16, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64zfr0_bf16, id_aa64zfr0_bf16_caps),
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, BitPerm, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64zfr0_bitperm, id_aa64zfr0_bitperm_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, AES, false, MRS_LOWER, id_aa64zfr0_aes,
-	    id_aa64zfr0_aes_caps),
-	MRS_FIELD_HWCAP(ID_AA64ZFR0, SVEver, false, MRS_LOWER,
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, AES, false, MRS_LOWER, MRS_USERSPACE,
+	    id_aa64zfr0_aes, id_aa64zfr0_aes_caps),
+	MRS_FIELD_HWCAP(ID_AA64ZFR0, SVEver, false, MRS_LOWER, MRS_USERSPACE,
 	    id_aa64zfr0_svever, id_aa64zfr0_svever_caps),
 	MRS_FIELD_END,
 };
@@ -1767,17 +1775,19 @@ static const struct mrs_field_value id_isar5_sevl[] = {
 };
 
 static const struct mrs_field id_isar5_fields[] = {
-	MRS_FIELD(ID_ISAR5, VCMA, false, MRS_LOWER, id_isar5_vcma),
-	MRS_FIELD(ID_ISAR5, RDM, false, MRS_LOWER, id_isar5_rdm),
-	MRS_FIELD_HWCAP(ID_ISAR5, CRC32, false, MRS_LOWER, id_isar5_crc32,
-	    id_isar5_crc32_caps),
-	MRS_FIELD_HWCAP(ID_ISAR5, SHA2, false, MRS_LOWER, id_isar5_sha2,
-	    id_isar5_sha2_caps),
-	MRS_FIELD_HWCAP(ID_ISAR5, SHA1, false, MRS_LOWER, id_isar5_sha1,
-	    id_isar5_sha1_caps),
-	MRS_FIELD_HWCAP(ID_ISAR5, AES, false, MRS_LOWER, id_isar5_aes,
-	    id_isar5_aes_caps),
-	MRS_FIELD(ID_ISAR5, SEVL, false, MRS_LOWER, id_isar5_sevl),
+	MRS_FIELD(ID_ISAR5, VCMA, false, MRS_LOWER,MRS_USERSPACE,
+	    id_isar5_vcma),
+	MRS_FIELD(ID_ISAR5, RDM, false, MRS_LOWER, MRS_USERSPACE, id_isar5_rdm),
+	MRS_FIELD_HWCAP(ID_ISAR5, CRC32, false, MRS_LOWER, MRS_USERSPACE,
+	    id_isar5_crc32, id_isar5_crc32_caps),
+	MRS_FIELD_HWCAP(ID_ISAR5, SHA2, false, MRS_LOWER, MRS_USERSPACE,
+	    id_isar5_sha2, id_isar5_sha2_caps),
+	MRS_FIELD_HWCAP(ID_ISAR5, SHA1, false, MRS_LOWER, MRS_USERSPACE,
+	    id_isar5_sha1, id_isar5_sha1_caps),
+	MRS_FIELD_HWCAP(ID_ISAR5, AES, false, MRS_LOWER, MRS_USERSPACE,
+	    id_isar5_aes, id_isar5_aes_caps),
+	MRS_FIELD(ID_ISAR5, SEVL, false, MRS_LOWER, MRS_USERSPACE,
+	    id_isar5_sevl),
 	MRS_FIELD_END,
 };
 
@@ -1830,14 +1840,19 @@ static const struct mrs_field_value mvfr0_simdreg[] = {
 };
 
 static const struct mrs_field mvfr0_fields[] = {
-	MRS_FIELD(MVFR0, FPRound, false, MRS_LOWER, mvfr0_fpround),
-	MRS_FIELD(MVFR0, FPSqrt, false, MRS_LOWER, mvfr0_fpsqrt),
-	MRS_FIELD(MVFR0, FPDivide, false, MRS_LOWER, mvfr0_fpdivide),
-	MRS_FIELD(MVFR0, FPTrap, false, MRS_LOWER, mvfr0_fptrap),
-	MRS_FIELD_HWCAP(MVFR0, FPDP, false, MRS_LOWER, mvfr0_fpdp,
-	    mvfr0_fpdp_caps),
-	MRS_FIELD(MVFR0, FPSP, false, MRS_LOWER, mvfr0_fpsp),
-	MRS_FIELD(MVFR0, SIMDReg, false, MRS_LOWER, mvfr0_simdreg),
+	MRS_FIELD(MVFR0, FPRound, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr0_fpround),
+	MRS_FIELD(MVFR0, FPSqrt, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr0_fpsqrt),
+	MRS_FIELD(MVFR0, FPDivide, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr0_fpdivide),
+	MRS_FIELD(MVFR0, FPTrap, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr0_fptrap),
+	MRS_FIELD_HWCAP(MVFR0, FPDP, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr0_fpdp, mvfr0_fpdp_caps),
+	MRS_FIELD(MVFR0, FPSP, false, MRS_LOWER, MRS_USERSPACE, mvfr0_fpsp),
+	MRS_FIELD(MVFR0, SIMDReg, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr0_simdreg),
 	MRS_FIELD_END,
 };
 
@@ -1898,16 +1913,19 @@ static const struct mrs_field_value mvfr1_fpftz[] = {
 };
 
 static const struct mrs_field mvfr1_fields[] = {
-	MRS_FIELD_HWCAP(MVFR1, SIMDFMAC, false, MRS_LOWER, mvfr1_simdfmac,
-	    mvfr1_simdfmac_caps),
-	MRS_FIELD(MVFR1, FPHP, false, MRS_LOWER, mvfr1_fphp),
-	MRS_FIELD(MVFR1, SIMDHP, false, MRS_LOWER, mvfr1_simdhp),
-	MRS_FIELD(MVFR1, SIMDSP, false, MRS_LOWER, mvfr1_simdsp),
-	MRS_FIELD(MVFR1, SIMDInt, false, MRS_LOWER, mvfr1_simdint),
-	MRS_FIELD_HWCAP(MVFR1, SIMDLS, false, MRS_LOWER, mvfr1_simdls,
-	    mvfr1_simdls_caps),
-	MRS_FIELD(MVFR1, FPDNaN, false, MRS_LOWER, mvfr1_fpdnan),
-	MRS_FIELD(MVFR1, FPFtZ, false, MRS_LOWER, mvfr1_fpftz),
+	MRS_FIELD_HWCAP(MVFR1, SIMDFMAC, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr1_simdfmac, mvfr1_simdfmac_caps),
+	MRS_FIELD(MVFR1, FPHP, false, MRS_LOWER, MRS_USERSPACE, mvfr1_fphp),
+	MRS_FIELD(MVFR1, SIMDHP, false, MRS_LOWER, MRS_USERSPACE, mvfr1_simdhp),
+	MRS_FIELD(MVFR1, SIMDSP, false, MRS_LOWER, MRS_USERSPACE, mvfr1_simdsp),
+	MRS_FIELD(MVFR1, SIMDInt, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr1_simdint),
+	MRS_FIELD_HWCAP(MVFR1, SIMDLS, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr1_simdls, mvfr1_simdls_caps),
+	MRS_FIELD(MVFR1, FPDNaN, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr1_fpdnan),
+	MRS_FIELD(MVFR1, FPFtZ, false, MRS_LOWER, MRS_USERSPACE,
+	    mvfr1_fpftz),
 	MRS_FIELD_END,
 };
 #endif /* COMPAT_FREEBSD32 */
@@ -2208,15 +2226,23 @@ update_special_regs(u_int cpu)
 
 		fields = user_regs[i].fields;
 		for (j = 0; fields[j].type != 0; j++) {
+			u_int type;
+
 			/* Update the FreeBSD userspace ID register view */
+			type = ((fields[j].type & MRS_FREEBSD) != 0) ?
+			    fields[j].type :
+			    (MRS_EXACT | (fields[j].type & MRS_SAFE_MASK));
 			user_reg = update_special_reg_field(user_reg,
-			    fields[j].type >> MRS_TYPE_FBSD_SHIFT, value,
-			    fields[j].width, fields[j].shift, fields[j].sign);
+			    type, value, fields[j].width, fields[j].shift,
+			    fields[j].sign);
 
 			/* Update the Linux userspace ID register view */
+			type = ((fields[j].type & MRS_LINUX) != 0) ?
+			    fields[j].type :
+			    (MRS_EXACT | (fields[j].type & MRS_SAFE_MASK));
 			l_user_reg = update_special_reg_field(l_user_reg,
-			    fields[j].type >> MRS_TYPE_LNX_SHIFT, value,
-			    fields[j].width, fields[j].shift, fields[j].sign);
+			    type, value, fields[j].width, fields[j].shift,
+			    fields[j].sign);
 
 			/* Update the kernel ID register view */
 			kern_reg = update_lower_register(kern_reg, value,