arm64/sme: Expose SMIDR through sysfs
authorMark Brown <broonie@kernel.org>
Tue, 7 Jun 2022 13:28:57 +0000 (14:28 +0100)
committerWill Deacon <will@kernel.org>
Thu, 23 Jun 2022 17:22:44 +0000 (18:22 +0100)
We currently expose MIDR and REVID to userspace through sysfs to enable it
to make decisions based on the specific implementation. Since SME supports
implementations where streaming mode is provided by a separate hardware
unit called a SMCU it provides a similar ID register SMIDR. Expose it to
userspace via sysfs when the system supports SME along with the other ID
registers.

Since we disable the SME priority mapping feature if it is supported by
hardware we currently mask out the SMPS bit which reports that it is
supported.

Signed-off-by: Mark Brown <broonie@kernel.org>
Link: https://lore.kernel.org/r/20220607132857.1358361-1-broonie@kernel.org
Signed-off-by: Will Deacon <will@kernel.org>
Documentation/ABI/testing/sysfs-devices-system-cpu
arch/arm64/include/asm/cpu.h
arch/arm64/kernel/cpuinfo.c

index bcc974d276dc4521367b3a12038526f1cc49e166..df79e129d09794cf9fc8d8c0606e8ded61a40609 100644 (file)
@@ -493,12 +493,13 @@ What:             /sys/devices/system/cpu/cpuX/regs/
                /sys/devices/system/cpu/cpuX/regs/identification/
                /sys/devices/system/cpu/cpuX/regs/identification/midr_el1
                /sys/devices/system/cpu/cpuX/regs/identification/revidr_el1
+               /sys/devices/system/cpu/cpuX/regs/identification/smidr_el1
 Date:          June 2016
 Contact:       Linux ARM Kernel Mailing list <linux-arm-kernel@lists.infradead.org>
 Description:   AArch64 CPU registers
 
                'identification' directory exposes the CPU ID registers for
-               identifying model and revision of the CPU.
+               identifying model and revision of the CPU and SMCU.
 
 What:          /sys/devices/system/cpu/aarch32_el0
 Date:          May 2021
index 115cdec1ae878202a1ed668555c38b559746d661..fd7a92219eea99697a64b0cbcc794c275ef5241c 100644 (file)
@@ -46,6 +46,7 @@ struct cpuinfo_arm64 {
        u64             reg_midr;
        u64             reg_revidr;
        u64             reg_gmid;
+       u64             reg_smidr;
 
        u64             reg_id_aa64dfr0;
        u64             reg_id_aa64dfr1;
index 8eff0a34ffd47547e0f3684a6b79745764e25d44..7f06df59df2b99b465bbb18cedd7a0451c320466 100644 (file)
@@ -267,6 +267,7 @@ static struct kobj_type cpuregs_kobj_type = {
 
 CPUREGS_ATTR_RO(midr_el1, midr);
 CPUREGS_ATTR_RO(revidr_el1, revidr);
+CPUREGS_ATTR_RO(smidr_el1, smidr);
 
 static struct attribute *cpuregs_id_attrs[] = {
        &cpuregs_attr_midr_el1.attr,
@@ -279,6 +280,16 @@ static const struct attribute_group cpuregs_attr_group = {
        .name = "identification"
 };
 
+static struct attribute *sme_cpuregs_id_attrs[] = {
+       &cpuregs_attr_smidr_el1.attr,
+       NULL
+};
+
+static const struct attribute_group sme_cpuregs_attr_group = {
+       .attrs = sme_cpuregs_id_attrs,
+       .name = "identification"
+};
+
 static int cpuid_cpu_online(unsigned int cpu)
 {
        int rc;
@@ -296,6 +307,8 @@ static int cpuid_cpu_online(unsigned int cpu)
        rc = sysfs_create_group(&info->kobj, &cpuregs_attr_group);
        if (rc)
                kobject_del(&info->kobj);
+       if (system_supports_sme())
+               rc = sysfs_merge_group(&info->kobj, &sme_cpuregs_attr_group);
 out:
        return rc;
 }
@@ -423,9 +436,17 @@ static void __cpuinfo_store_cpu(struct cpuinfo_arm64 *info)
                info->reg_zcr = read_zcr_features();
 
        if (IS_ENABLED(CONFIG_ARM64_SME) &&
-           id_aa64pfr1_sme(info->reg_id_aa64pfr1))
+           id_aa64pfr1_sme(info->reg_id_aa64pfr1)) {
                info->reg_smcr = read_smcr_features();
 
+               /*
+                * We mask out SMPS since even if the hardware
+                * supports priorities the kernel does not at present
+                * and we block access to them.
+                */
+               info->reg_smidr = read_cpuid(SMIDR_EL1) & ~SMIDR_EL1_SMPS;
+       }
+
        cpuinfo_detect_icache_policy(info);
 }