arm64: Support systems without FP/ASIMD

The arm64 kernel assumes that FP/ASIMD units are always present
and accesses the FP/ASIMD specific registers unconditionally. This
could cause problems when they are absent. This patch adds the
support for kernel handling systems without FP/ASIMD by skipping the
register access within the kernel. For kvm, we trap the accesses
to FP/ASIMD and inject an undefined instruction exception to the VM.

The callers of the exported kernel_neon_begin_partial() should
make sure that the FP/ASIMD is supported.

Cc: Will Deacon <will.deacon@arm.com>
Cc: Christoffer Dall <christoffer.dall@linaro.org>
Cc: Ard Biesheuvel <ard.biesheuvel@linaro.org>
Signed-off-by: Suzuki K Poulose <suzuki.poulose@arm.com>
Reviewed-by: Marc Zyngier <marc.zyngier@arm.com>
[catalin.marinas@arm.com: add comment on the ARM64_HAS_NO_FPSIMD conflict and the new location]
Signed-off-by: Catalin Marinas <catalin.marinas@arm.com>
This commit is contained in:
Suzuki K Poulose
2016-11-08 13:56:21 +00:00
committed by Catalin Marinas
parent a4023f6827
commit 82e0191a1a
7 changed files with 65 additions and 4 deletions

View File

@@ -38,8 +38,13 @@
#define ARM64_HAS_32BIT_EL0 13
#define ARM64_HYP_OFFSET_LOW 14
#define ARM64_MISMATCHED_CACHE_LINE_SIZE 15
/*
* The macro below will be moved to asm/cpucaps.h together with the
* ARM64_NCAPS update.
*/
#define ARM64_HAS_NO_FPSIMD 16
#define ARM64_NCAPS 16
#define ARM64_NCAPS 17
#ifndef __ASSEMBLY__
@@ -231,6 +236,11 @@ static inline bool system_supports_mixed_endian_el0(void)
return id_aa64mmfr0_mixed_endian_el0(read_system_reg(SYS_ID_AA64MMFR0_EL1));
}
static inline bool system_supports_fpsimd(void)
{
return !cpus_have_const_cap(ARM64_HAS_NO_FPSIMD);
}
#endif /* __ASSEMBLY__ */
#endif

View File

@@ -9,8 +9,9 @@
*/
#include <linux/types.h>
#include <asm/fpsimd.h>
#define cpu_has_neon() (1)
#define cpu_has_neon() system_supports_fpsimd()
#define kernel_neon_begin() kernel_neon_begin_partial(32)