ANDROID: KVM: arm64: Specialize deactivate fpsimd traps on guest fpsimd trap

The code for deactivating traps, to be able to update the fpsimd
registers, is the only code in this file that is n/vhe specific.
Move it to specialized functions.

This is also needed for the subsequent patch, since the logic for
deciding which traps to enable/disable will get more complex.

No functional change intended.

Signed-off-by: Fuad Tabba <tabba@google.com>

Bug: 267291591
Change-Id: Ia0477450aa9319a46a91b3c31c1910ad02fbe246
This commit is contained in:
Fuad Tabba
2023-03-22 13:13:10 +00:00
committed by Lee Jones
parent fef7691974
commit 0532339bb0
3 changed files with 23 additions and 14 deletions

View File

@@ -150,6 +150,8 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
static void kvm_hyp_handle_fpsimd_host(struct kvm_vcpu *vcpu);
static void __deactivate_fpsimd_traps(struct kvm_vcpu *vcpu);
/*
* We trap the first access to the FP/SIMD to save the host context and
* restore the guest context lazily.
@@ -160,7 +162,6 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
{
bool sve_guest;
u8 esr_ec;
u64 reg;
if (!system_supports_fpsimd())
return false;
@@ -175,19 +176,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
/* Valid trap. Switch the context: */
/* First disable enough traps to allow us to update the registers */
if (has_vhe()) {
reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
if (sve_guest)
reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
sysreg_clear_set(cpacr_el1, 0, reg);
} else {
reg = CPTR_EL2_TFP;
if (sve_guest)
reg |= CPTR_EL2_TZ;
sysreg_clear_set(cptr_el2, reg, 0);
}
__deactivate_fpsimd_traps(vcpu);
isb();
/* Write out the host state if it's in the registers */

View File

@@ -108,6 +108,16 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
write_sysreg(__kvm_hyp_host_vector, vbar_el2);
}
static void __deactivate_fpsimd_traps(struct kvm_vcpu *vcpu)
{
u64 reg = CPTR_EL2_TFP;
if (vcpu_has_sve(vcpu))
reg |= CPTR_EL2_TZ;
sysreg_clear_set(cptr_el2, reg, 0);
}
/* Save VGICv3 state on non-VHE systems */
static void __hyp_vgic_save_state(struct kvm_vcpu *vcpu)
{

View File

@@ -102,6 +102,16 @@ void deactivate_traps_vhe_put(struct kvm_vcpu *vcpu)
__deactivate_traps_common(vcpu);
}
static void __deactivate_fpsimd_traps(struct kvm_vcpu *vcpu)
{
u64 reg = CPACR_EL1_FPEN_EL0EN | CPACR_EL1_FPEN_EL1EN;
if (vcpu_has_sve(vcpu))
reg |= CPACR_EL1_ZEN_EL0EN | CPACR_EL1_ZEN_EL1EN;
sysreg_clear_set(cpacr_el1, 0, reg);
}
static void kvm_hyp_handle_fpsimd_host(struct kvm_vcpu *vcpu)
{
__fpsimd_save_state(vcpu->arch.host_fpsimd_state);