From: Marc Zyngier <maz@kernel.org>
To: Mark Brown <broonie@kernel.org>
Cc: Catalin Marinas <catalin.marinas@arm.com>,
Will Deacon <will@kernel.org>,
Oliver Upton <oliver.upton@linux.dev>,
James Morse <james.morse@arm.com>,
Suzuki K Poulose <suzuki.poulose@arm.com>,
Jonathan Corbet <corbet@lwn.net>, Shuah Khan <shuah@kernel.org>,
linux-arm-kernel@lists.infradead.org,
linux-kernel@vger.kernel.org, Dave Martin <dave.martin@arm.com>,
kvmarm@lists.linux.dev, linux-doc@vger.kernel.org,
linux-kselftest@vger.kernel.org
Subject: Re: [PATCH v4 03/14] arm64/fpsimd: Support FEAT_FPMR
Date: Fri, 23 Feb 2024 11:07:02 +0000 [thread overview]
Message-ID: <86r0h330dl.wl-maz@kernel.org> (raw)
In-Reply-To: <20240122-arm64-2023-dpisa-v4-3-776e094861df@kernel.org>
On Mon, 22 Jan 2024 16:28:06 +0000,
Mark Brown <broonie@kernel.org> wrote:
>
> FEAT_FPMR defines a new EL0 accessible register FPMR use to configure the
> FP8 related features added to the architecture at the same time. Detect
> support for this register and context switch it for EL0 when present.
>
> Due to the sharing of responsibility for saving floating point state
> between the host kernel and KVM FP8 support is not yet implemented in KVM
> and a stub similar to that used for SVCR is provided for FPMR in order to
> avoid bisection issues. To make it easier to share host state with the
> hypervisor we store FPMR as a hardened usercopy field in uw (along with
> some padding).
>
> Signed-off-by: Mark Brown <broonie@kernel.org>
> ---
> arch/arm64/include/asm/cpufeature.h | 5 +++++
> arch/arm64/include/asm/fpsimd.h | 2 ++
> arch/arm64/include/asm/kvm_host.h | 1 +
> arch/arm64/include/asm/processor.h | 4 ++++
> arch/arm64/kernel/cpufeature.c | 9 +++++++++
> arch/arm64/kernel/fpsimd.c | 13 +++++++++++++
> arch/arm64/kvm/fpsimd.c | 1 +
> arch/arm64/tools/cpucaps | 1 +
> 8 files changed, 36 insertions(+)
>
> diff --git a/arch/arm64/include/asm/cpufeature.h b/arch/arm64/include/asm/cpufeature.h
> index 21c824edf8ce..34fcdbc65d7d 100644
> --- a/arch/arm64/include/asm/cpufeature.h
> +++ b/arch/arm64/include/asm/cpufeature.h
> @@ -768,6 +768,11 @@ static __always_inline bool system_supports_tpidr2(void)
> return system_supports_sme();
> }
>
> +static __always_inline bool system_supports_fpmr(void)
> +{
> + return alternative_has_cap_unlikely(ARM64_HAS_FPMR);
> +}
> +
> static __always_inline bool system_supports_cnp(void)
> {
> return alternative_has_cap_unlikely(ARM64_HAS_CNP);
> diff --git a/arch/arm64/include/asm/fpsimd.h b/arch/arm64/include/asm/fpsimd.h
> index 50e5f25d3024..6cf72b0d2c04 100644
> --- a/arch/arm64/include/asm/fpsimd.h
> +++ b/arch/arm64/include/asm/fpsimd.h
> @@ -89,6 +89,7 @@ struct cpu_fp_state {
> void *sve_state;
> void *sme_state;
> u64 *svcr;
> + unsigned long *fpmr;
> unsigned int sve_vl;
> unsigned int sme_vl;
> enum fp_type *fp_type;
> @@ -154,6 +155,7 @@ extern void cpu_enable_sve(const struct arm64_cpu_capabilities *__unused);
> extern void cpu_enable_sme(const struct arm64_cpu_capabilities *__unused);
> extern void cpu_enable_sme2(const struct arm64_cpu_capabilities *__unused);
> extern void cpu_enable_fa64(const struct arm64_cpu_capabilities *__unused);
> +extern void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__unused);
>
> extern u64 read_smcr_features(void);
>
> diff --git a/arch/arm64/include/asm/kvm_host.h b/arch/arm64/include/asm/kvm_host.h
> index 21c57b812569..7993694a54af 100644
> --- a/arch/arm64/include/asm/kvm_host.h
> +++ b/arch/arm64/include/asm/kvm_host.h
> @@ -543,6 +543,7 @@ struct kvm_vcpu_arch {
> enum fp_type fp_type;
> unsigned int sve_max_vl;
> u64 svcr;
> + unsigned long fpmr;
As this directly represents a register, I'd rather you use a type that
represents the size of that register unambiguously (u64).
>
> /* Stage 2 paging state used by the hardware on next switch */
> struct kvm_s2_mmu *hw_mmu;
> diff --git a/arch/arm64/include/asm/processor.h b/arch/arm64/include/asm/processor.h
> index 5b0a04810b23..b453c66d3fae 100644
> --- a/arch/arm64/include/asm/processor.h
> +++ b/arch/arm64/include/asm/processor.h
> @@ -155,6 +155,8 @@ struct thread_struct {
> struct {
> unsigned long tp_value; /* TLS register */
> unsigned long tp2_value;
> + unsigned long fpmr;
> + unsigned long pad;
> struct user_fpsimd_state fpsimd_state;
> } uw;
>
> @@ -253,6 +255,8 @@ static inline void arch_thread_struct_whitelist(unsigned long *offset,
> BUILD_BUG_ON(sizeof_field(struct thread_struct, uw) !=
> sizeof_field(struct thread_struct, uw.tp_value) +
> sizeof_field(struct thread_struct, uw.tp2_value) +
> + sizeof_field(struct thread_struct, uw.fpmr) +
> + sizeof_field(struct thread_struct, uw.pad) +
> sizeof_field(struct thread_struct, uw.fpsimd_state));
>
> *offset = offsetof(struct thread_struct, uw);
> diff --git a/arch/arm64/kernel/cpufeature.c b/arch/arm64/kernel/cpufeature.c
> index eae59ec0f4b0..0263565f617a 100644
> --- a/arch/arm64/kernel/cpufeature.c
> +++ b/arch/arm64/kernel/cpufeature.c
> @@ -272,6 +272,7 @@ static const struct arm64_ftr_bits ftr_id_aa64pfr1[] = {
> };
>
> static const struct arm64_ftr_bits ftr_id_aa64pfr2[] = {
> + ARM64_FTR_BITS(FTR_VISIBLE, FTR_STRICT, FTR_LOWER_SAFE, ID_AA64PFR2_EL1_FPMR_SHIFT, 4, 0),
> ARM64_FTR_END,
> };
>
> @@ -2767,6 +2768,14 @@ static const struct arm64_cpu_capabilities arm64_features[] = {
> .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> .matches = has_lpa2,
> },
> + {
> + .desc = "FPMR",
> + .type = ARM64_CPUCAP_SYSTEM_FEATURE,
> + .capability = ARM64_HAS_FPMR,
> + .matches = has_cpuid_feature,
> + .cpu_enable = cpu_enable_fpmr,
> + ARM64_CPUID_FIELDS(ID_AA64PFR2_EL1, FPMR, IMP)
> + },
> {},
> };
>
> diff --git a/arch/arm64/kernel/fpsimd.c b/arch/arm64/kernel/fpsimd.c
> index a5dc6f764195..8e24b5e5e192 100644
> --- a/arch/arm64/kernel/fpsimd.c
> +++ b/arch/arm64/kernel/fpsimd.c
> @@ -359,6 +359,9 @@ static void task_fpsimd_load(void)
> WARN_ON(preemptible());
> WARN_ON(test_thread_flag(TIF_KERNEL_FPSTATE));
>
> + if (system_supports_fpmr())
> + write_sysreg_s(current->thread.uw.fpmr, SYS_FPMR);
> +
> if (system_supports_sve() || system_supports_sme()) {
> switch (current->thread.fp_type) {
> case FP_STATE_FPSIMD:
> @@ -446,6 +449,9 @@ static void fpsimd_save_user_state(void)
> if (test_thread_flag(TIF_FOREIGN_FPSTATE))
> return;
>
> + if (system_supports_fpmr())
> + *(last->fpmr) = read_sysreg_s(SYS_FPMR);
> +
> /*
> * If a task is in a syscall the ABI allows us to only
> * preserve the state shared with FPSIMD so don't bother
> @@ -688,6 +694,12 @@ static void sve_to_fpsimd(struct task_struct *task)
> }
> }
>
> +void cpu_enable_fpmr(const struct arm64_cpu_capabilities *__always_unused p)
> +{
> + write_sysreg_s(read_sysreg_s(SYS_SCTLR_EL1) | SCTLR_EL1_EnFPM_MASK,
> + SYS_SCTLR_EL1);
> +}
> +
> #ifdef CONFIG_ARM64_SVE
> /*
> * Call __sve_free() directly only if you know task can't be scheduled
> @@ -1680,6 +1692,7 @@ static void fpsimd_bind_task_to_cpu(void)
> last->sve_vl = task_get_sve_vl(current);
> last->sme_vl = task_get_sme_vl(current);
> last->svcr = ¤t->thread.svcr;
> + last->fpmr = ¤t->thread.uw.fpmr;
> last->fp_type = ¤t->thread.fp_type;
> last->to_save = FP_STATE_CURRENT;
> current->thread.fpsimd_cpu = smp_processor_id();
> diff --git a/arch/arm64/kvm/fpsimd.c b/arch/arm64/kvm/fpsimd.c
> index 8c1d0d4853df..e3e611e30e91 100644
> --- a/arch/arm64/kvm/fpsimd.c
> +++ b/arch/arm64/kvm/fpsimd.c
> @@ -153,6 +153,7 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
> fp_state.sve_vl = vcpu->arch.sve_max_vl;
> fp_state.sme_state = NULL;
> fp_state.svcr = &vcpu->arch.svcr;
> + fp_state.fpmr = &vcpu->arch.fpmr;
> fp_state.fp_type = &vcpu->arch.fp_type;
Given the number of fields you keep track of, it would make a lot more
sense if these FP-related fields were in their own little structure
and tracked by a single pointer (I don't think there is a case where
we track them independently).
Thanks,
M.
--
Without deviation from the norm, progress is not possible.
_______________________________________________
linux-arm-kernel mailing list
linux-arm-kernel@lists.infradead.org
http://lists.infradead.org/mailman/listinfo/linux-arm-kernel
next prev parent reply other threads:[~2024-02-23 11:07 UTC|newest]
Thread overview: 21+ messages / expand[flat|nested] mbox.gz Atom feed top
2024-01-22 16:28 [PATCH v4 00/14] arm64: Support for 2023 DPISA extensions Mark Brown
2024-01-22 16:28 ` [PATCH v4 01/14] arm64/cpufeature: Hook new identification registers up to cpufeature Mark Brown
2024-01-22 16:28 ` [PATCH v4 02/14] arm64/fpsimd: Enable host kernel access to FPMR Mark Brown
2024-02-23 11:34 ` Marc Zyngier
2024-01-22 16:28 ` [PATCH v4 03/14] arm64/fpsimd: Support FEAT_FPMR Mark Brown
2024-02-23 11:07 ` Marc Zyngier [this message]
2024-03-06 16:41 ` Mark Brown
2024-01-22 16:28 ` [PATCH v4 04/14] arm64/signal: Add FPMR signal handling Mark Brown
2024-01-22 16:28 ` [PATCH v4 05/14] arm64/ptrace: Expose FPMR via ptrace Mark Brown
2024-01-22 16:28 ` [PATCH v4 06/14] arm64/hwcap: Define hwcaps for 2023 DPISA features Mark Brown
2024-01-22 16:28 ` [PATCH v4 07/14] kselftest/arm64: Handle FPMR context in generic signal frame parser Mark Brown
2024-01-22 16:28 ` [PATCH v4 08/14] kselftest/arm64: Add basic FPMR test Mark Brown
2024-01-22 16:28 ` [PATCH v4 09/14] kselftest/arm64: Add 2023 DPISA hwcap test coverage Mark Brown
2024-01-22 16:28 ` [PATCH v4 10/14] KVM: arm64: Share all userspace hardened thread data with the hypervisor Mark Brown
2024-01-22 16:28 ` [PATCH v4 11/14] KVM: arm64: Add newly allocated ID registers to register descriptions Mark Brown
2024-02-23 11:33 ` Marc Zyngier
2024-01-22 16:28 ` [PATCH v4 12/14] KVM: arm64: Support FEAT_FPMR for guests Mark Brown
2024-02-23 11:18 ` Marc Zyngier
2024-02-23 14:46 ` Mark Brown
2024-01-22 16:28 ` [PATCH v4 13/14] KVM: arm64: selftests: Document feature registers added in 2023 extensions Mark Brown
2024-01-22 16:28 ` [PATCH v4 14/14] KVM: arm64: selftests: Teach get-reg-list about FPMR Mark Brown
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=86r0h330dl.wl-maz@kernel.org \
--to=maz@kernel.org \
--cc=broonie@kernel.org \
--cc=catalin.marinas@arm.com \
--cc=corbet@lwn.net \
--cc=dave.martin@arm.com \
--cc=james.morse@arm.com \
--cc=kvmarm@lists.linux.dev \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-doc@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-kselftest@vger.kernel.org \
--cc=oliver.upton@linux.dev \
--cc=shuah@kernel.org \
--cc=suzuki.poulose@arm.com \
--cc=will@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).