arm64: fpsimd: Make sure SVE setup is complete before SIMD is used
authorSuzuki K Poulose <suzuki.poulose@arm.com>
Mon, 13 Jan 2020 23:30:18 +0000 (23:30 +0000)
committerWill Deacon <will@kernel.org>
Tue, 14 Jan 2020 17:11:21 +0000 (17:11 +0000)
In-kernel users of NEON rely on may_use_simd() to check if the SIMD
can be used. However, we must initialize the SVE before SIMD can
be used. Add a sanity check to make sure that we have completed the
SVE setup before anyone uses the SIMD.

Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Cc: Mark Rutland <mark.rutland@arm.com>
Cc: Will Deacon <will@kernel.org>
Reviewed-by: Ard Biesheuvel <ardb@kernel.org>
Reviewed-by: Catalin Marinas <catalin.marinas@arm.com>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Signed-off-by: Will Deacon <will@kernel.org>
arch/arm64/include/asm/simd.h

index 7434844..89cba26 100644 (file)
@@ -26,6 +26,8 @@ DECLARE_PER_CPU(bool, fpsimd_context_busy);
 static __must_check inline bool may_use_simd(void)
 {
        /*
+        * We must make sure that the SVE has been initialized properly
+        * before using the SIMD in kernel.
         * fpsimd_context_busy is only set while preemption is disabled,
         * and is clear whenever preemption is enabled. Since
         * this_cpu_read() is atomic w.r.t. preemption, fpsimd_context_busy
@@ -33,8 +35,10 @@ static __must_check inline bool may_use_simd(void)
         * migrated, and if it's clear we cannot be migrated to a CPU
         * where it is set.
         */
-       return !in_irq() && !irqs_disabled() && !in_nmi() &&
-               !this_cpu_read(fpsimd_context_busy);
+       return !WARN_ON(!system_capabilities_finalized()) &&
+              system_supports_fpsimd() &&
+              !in_irq() && !irqs_disabled() && !in_nmi() &&
+              !this_cpu_read(fpsimd_context_busy);
 }
 
 #else /* ! CONFIG_KERNEL_MODE_NEON */