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:

committed by
Catalin Marinas

parent
a4023f6827
commit
82e0191a1a
@@ -106,9 +106,16 @@ el1_trap:
|
||||
* x0: ESR_EC
|
||||
*/
|
||||
|
||||
/* Guest accessed VFP/SIMD registers, save host, restore Guest */
|
||||
/*
|
||||
* We trap the first access to the FP/SIMD to save the host context
|
||||
* and restore the guest context lazily.
|
||||
* If FP/SIMD is not implemented, handle the trap and inject an
|
||||
* undefined instruction exception to the guest.
|
||||
*/
|
||||
alternative_if_not ARM64_HAS_NO_FPSIMD
|
||||
cmp x0, #ESR_ELx_EC_FP_ASIMD
|
||||
b.eq __fpsimd_guest_restore
|
||||
alternative_else_nop_endif
|
||||
|
||||
mrs x1, tpidr_el2
|
||||
mov x0, #ARM_EXCEPTION_TRAP
|
||||
|
@@ -21,6 +21,7 @@
|
||||
#include <asm/kvm_asm.h>
|
||||
#include <asm/kvm_emulate.h>
|
||||
#include <asm/kvm_hyp.h>
|
||||
#include <asm/fpsimd.h>
|
||||
|
||||
static bool __hyp_text __fpsimd_enabled_nvhe(void)
|
||||
{
|
||||
@@ -76,9 +77,11 @@ static void __hyp_text __activate_traps(struct kvm_vcpu *vcpu)
|
||||
* traps are only taken to EL2 if the operation would not otherwise
|
||||
* trap to EL1. Therefore, always make sure that for 32-bit guests,
|
||||
* we set FPEXC.EN to prevent traps to EL1, when setting the TFP bit.
|
||||
* If FP/ASIMD is not implemented, FPEXC is UNDEFINED and any access to
|
||||
* it will cause an exception.
|
||||
*/
|
||||
val = vcpu->arch.hcr_el2;
|
||||
if (!(val & HCR_RW)) {
|
||||
if (!(val & HCR_RW) && system_supports_fpsimd()) {
|
||||
write_sysreg(1 << 30, fpexc32_el2);
|
||||
isb();
|
||||
}
|
||||
|
Reference in New Issue
Block a user