From d69d564964872f52c4a8f0db172d842eaf3b84cf Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Tue, 7 Jun 2022 14:28:57 +0100 Subject: [PATCH 1/3] arm64/sme: Expose SMIDR through sysfs 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 Link: https://lore.kernel.org/r/20220607132857.1358361-1-broonie@kernel.org Signed-off-by: Will Deacon --- .../ABI/testing/sysfs-devices-system-cpu | 3 ++- arch/arm64/include/asm/cpu.h | 1 + arch/arm64/kernel/cpuinfo.c | 23 ++++++++++++++++++- 3 files changed, 25 insertions(+), 2 deletions(-) diff --git a/Documentation/ABI/testing/sysfs-devices-system-cpu b/Documentation/ABI/testing/sysfs-devices-system-cpu index bcc974d276dc..df79e129d097 100644 --- a/Documentation/ABI/testing/sysfs-devices-system-cpu +++ b/Documentation/ABI/testing/sysfs-devices-system-cpu @@ -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 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 diff --git a/arch/arm64/include/asm/cpu.h b/arch/arm64/include/asm/cpu.h index 115cdec1ae87..fd7a92219eea 100644 --- a/arch/arm64/include/asm/cpu.h +++ b/arch/arm64/include/asm/cpu.h @@ -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; diff --git a/arch/arm64/kernel/cpuinfo.c b/arch/arm64/kernel/cpuinfo.c index 8eff0a34ffd4..7f06df59df2b 100644 --- a/arch/arm64/kernel/cpuinfo.c +++ b/arch/arm64/kernel/cpuinfo.c @@ -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); } From df07443f477a7ebd36c2f21705419979b9865c9f Mon Sep 17 00:00:00 2001 From: Mark Brown Date: Fri, 24 Jun 2022 18:21:08 +0100 Subject: [PATCH 2/3] arm64/signal: Clean up SVE/SME feature checking inconsistency Currently when restoring signal state we check to see if SVE is supported in restore_sigframe() but check to see if SVE is supported inside restore_sve_fpsimd_context(). This makes no real difference since SVE is always supported in systems with SME but looks a bit untidy and makes things slightly harder to follow, move the SVE check next to the SME one in restore_sve_fpsimd_context(). Signed-off-by: Mark Brown Link: https://lore.kernel.org/r/20220624172108.555000-1-broonie@kernel.org Signed-off-by: Will Deacon --- arch/arm64/kernel/signal.c | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/arch/arm64/kernel/signal.c b/arch/arm64/kernel/signal.c index b0980fbb6bc7..3e6d0352d7d3 100644 --- a/arch/arm64/kernel/signal.c +++ b/arch/arm64/kernel/signal.c @@ -280,6 +280,9 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) vl = task_get_sme_vl(current); } else { + if (!system_supports_sve()) + return -EINVAL; + vl = task_get_sve_vl(current); } @@ -342,9 +345,14 @@ static int restore_sve_fpsimd_context(struct user_ctxs *user) #else /* ! CONFIG_ARM64_SVE */ -/* Turn any non-optimised out attempts to use these into a link error: */ +static int restore_sve_fpsimd_context(struct user_ctxs *user) +{ + WARN_ON_ONCE(1); + return -EINVAL; +} + +/* Turn any non-optimised out attempts to use this into a link error: */ extern int preserve_sve_context(void __user *ctx); -extern int restore_sve_fpsimd_context(struct user_ctxs *user); #endif /* ! CONFIG_ARM64_SVE */ @@ -649,14 +657,10 @@ static int restore_sigframe(struct pt_regs *regs, if (!user.fpsimd) return -EINVAL; - if (user.sve) { - if (!system_supports_sve()) - return -EINVAL; - + if (user.sve) err = restore_sve_fpsimd_context(&user); - } else { + else err = restore_fpsimd_context(user.fpsimd); - } } if (err == 0 && system_supports_sme() && user.za) From 4139320d19e61093cfcd3fa1936c091f717fd3cf Mon Sep 17 00:00:00 2001 From: Schspa Shi Date: Wed, 29 Jun 2022 13:10:23 +0800 Subject: [PATCH 3/3] arm64/fpsimd: Remove duplicate SYS_SVCR read It seems to be a typo, remove the duplicate SYS_SVCR read. Signed-off-by: Schspa Shi Link: https://lore.kernel.org/r/20220629051023.18173-1-schspa@gmail.com Signed-off-by: Will Deacon --- arch/arm64/kernel/fpsimd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c index aecf3071efdd..dd63ffc3a2fa 100644 --- a/arch/arm64/kernel/fpsimd.c +++ b/arch/arm64/kernel/fpsimd.c @@ -445,7 +445,6 @@ static void fpsimd_save(void) if (system_supports_sme()) { u64 *svcr = last->svcr; - *svcr = read_sysreg_s(SYS_SVCR); *svcr = read_sysreg_s(SYS_SVCR);