Page MenuHomeFreeBSD

D55960.diff
No OneTemporary

D55960.diff

diff --git a/sys/arm64/arm64/identcpu.c b/sys/arm64/arm64/identcpu.c
--- a/sys/arm64/arm64/identcpu.c
+++ b/sys/arm64/arm64/identcpu.c
@@ -1838,6 +1838,11 @@
MRS_FIELD_VALUE_END,
};
+static const struct mrs_field_hwcap id_aa64pfr1_mte_caps[] = {
+ MRS_HWCAP(2, HWCAP2_MTE, ID_AA64PFR1_MTE_MTE),
+ MRS_HWCAP_END
+};
+
static const struct mrs_field_value id_aa64pfr1_ssbs[] = {
MRS_FIELD_VALUE(ID_AA64PFR1_SSBS_NONE, ""),
MRS_FIELD_VALUE(ID_AA64PFR1_SSBS_PSTATE, "PSTATE.SSBS"),
@@ -1878,7 +1883,8 @@
id_aa64pfr1_mpam_frac),
MRS_FIELD(ID_AA64PFR1, RAS_frac, false, MRS_LOWER, 0,
id_aa64pfr1_ras_frac),
- MRS_FIELD(ID_AA64PFR1, MTE, false, MRS_LOWER, 0, id_aa64pfr1_mte),
+ MRS_FIELD_HWCAP(ID_AA64PFR1, MTE, false, MRS_LOWER, MRS_FREEBSD,
+ id_aa64pfr1_mte, id_aa64pfr1_mte_caps),
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,
diff --git a/sys/arm64/arm64/locore.S b/sys/arm64/arm64/locore.S
--- a/sys/arm64/arm64/locore.S
+++ b/sys/arm64/arm64/locore.S
@@ -1123,6 +1123,9 @@
* Setup SCTLR.
*/
ldr x1, =SCTLR_MMU_ON
+ CHECK_CPU_FEAT(x2, ID_AA64PFR1, MTE, MTE2, .Lno_mte)
+ orr x1, x1, SCTLR_ATA
+.Lno_mte:
msr sctlr_el1, x1
isb
diff --git a/sys/arm64/arm64/mte.c b/sys/arm64/arm64/mte.c
--- a/sys/arm64/arm64/mte.c
+++ b/sys/arm64/arm64/mte.c
@@ -278,6 +278,51 @@
return (false);
}
+static cpu_feat_en
+mte_check(const struct cpu_feat *feat __unused, u_int midr __unused)
+{
+ uint64_t id_aa64pfr1;
+
+ get_kernel_reg(ID_AA64PFR1_EL1, &id_aa64pfr1);
+ if (ID_AA64PFR1_MTE_VAL(id_aa64pfr1) == ID_AA64PFR1_MTE_NONE)
+ return (FEAT_ALWAYS_DISABLE);
+ return (FEAT_DEFAULT_ENABLE);
+}
+
+static bool
+mte_enable(const struct cpu_feat *feat __unused,
+ cpu_feat_errata errata_status __unused, u_int *errata_list __unused,
+ u_int errata_count __unused)
+{
+ uint64_t id_aa64pfr1;
+
+ pmap_change_dmap_attr(VM_MEMATTR_TAGGED);
+
+ get_kernel_reg(ID_AA64PFR1_EL1, &id_aa64pfr1);
+ mte_version = ID_AA64PFR1_MTE_VAL(id_aa64pfr1) >> ID_AA64PFR1_MTE_SHIFT;
+
+ if (ID_AA64PFR1_MTE_frac_VAL(id_aa64pfr1) != ID_AA64PFR1_MTE_frac_NONE)
+ mte_flags |= MTE_HAS_ASYNC;
+
+ return (true);
+}
+
+static void
+mte_disabled(const struct cpu_feat *feat __unused)
+{
+ /*
+ * MTE may be disabled, mask out the ID fields we expose to
+ * userspace and the rest of the kernel so they don't try to
+ * use it.
+ */
+ update_special_reg(ID_AA64PFR1_EL1, ID_AA64PFR1_MTE_MASK, 0);
+
+}
+
+CPU_FEAT(feat_mte, "Memory Tagging",
+ mte_check, NULL, mte_enable, mte_disabled,
+ CPU_FEAT_AFTER_DEV | CPU_FEAT_SYSTEM);
+
void
mte_fork(struct thread *new_td, struct thread *orig_td)
{

File Metadata

Mime Type
text/plain
Expires
Wed, Mar 25, 5:45 AM (4 h, 10 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30139405
Default Alt Text
D55960.diff (2 KB)

Event Timeline