Skip to content

Commit d933e21

Browse files
mrutland-armgregkh
authored andcommitted
KVM: arm64: Remove host FPSIMD saving for non-protected KVM
[ Upstream commit 8eca7f6 ] Now that the host eagerly saves its own FPSIMD/SVE/SME state, non-protected KVM never needs to save the host FPSIMD/SVE/SME state, and the code to do this is never used. Protected KVM still needs to save/restore the host FPSIMD/SVE state to avoid leaking guest state to the host (and to avoid revealing to the host whether the guest used FPSIMD/SVE/SME), and that code needs to be retained. Remove the unused code and data structures. To avoid the need for a stub copy of kvm_hyp_save_fpsimd_host() in the VHE hyp code, the nVHE/hVHE version is moved into the shared switch header, where it is only invoked when KVM is in protected mode. Signed-off-by: Mark Rutland <[email protected]> Reviewed-by: Mark Brown <[email protected]> Tested-by: Mark Brown <[email protected]> Acked-by: Will Deacon <[email protected]> Cc: Catalin Marinas <[email protected]> Cc: Fuad Tabba <[email protected]> Cc: Marc Zyngier <[email protected]> Cc: Oliver Upton <[email protected]> Reviewed-by: Oliver Upton <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]> [CPACR_EL1_ZEN -> CPACR_ELx_ZEN -- broonie] Signed-off-by: Mark Brown <[email protected]> Signed-off-by: Greg Kroah-Hartman <[email protected]>
1 parent 900b444 commit d933e21

File tree

7 files changed

+29
-64
lines changed

7 files changed

+29
-64
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -613,23 +613,13 @@ struct kvm_host_data {
613613
struct kvm_cpu_context host_ctxt;
614614

615615
/*
616-
* All pointers in this union are hyp VA.
616+
* Hyp VA.
617617
* sve_state is only used in pKVM and if system_supports_sve().
618618
*/
619-
union {
620-
struct user_fpsimd_state *fpsimd_state;
621-
struct cpu_sve_state *sve_state;
622-
};
623-
624-
union {
625-
/* HYP VA pointer to the host storage for FPMR */
626-
u64 *fpmr_ptr;
627-
/*
628-
* Used by pKVM only, as it needs to provide storage
629-
* for the host
630-
*/
631-
u64 fpmr;
632-
};
619+
struct cpu_sve_state *sve_state;
620+
621+
/* Used by pKVM only. */
622+
u64 fpmr;
633623

634624
/* Ownership of the FP regs */
635625
enum {

arch/arm64/kvm/arm.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2468,14 +2468,6 @@ static void finalize_init_hyp_mode(void)
24682468
per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state =
24692469
kern_hyp_va(sve_state);
24702470
}
2471-
} else {
2472-
for_each_possible_cpu(cpu) {
2473-
struct user_fpsimd_state *fpsimd_state;
2474-
2475-
fpsimd_state = &per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->host_ctxt.fp_regs;
2476-
per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->fpsimd_state =
2477-
kern_hyp_va(fpsimd_state);
2478-
}
24792471
}
24802472
}
24812473

arch/arm64/kvm/fpsimd.c

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -64,8 +64,6 @@ void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
6464
*/
6565
fpsimd_save_and_flush_cpu_state();
6666
*host_data_ptr(fp_owner) = FP_STATE_FREE;
67-
*host_data_ptr(fpsimd_state) = NULL;
68-
*host_data_ptr(fpmr_ptr) = NULL;
6967

7068
vcpu_clear_flag(vcpu, HOST_SVE_ENABLED);
7169
if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)

arch/arm64/kvm/hyp/include/hyp/switch.h

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -375,7 +375,28 @@ static inline void __hyp_sve_save_host(void)
375375
true);
376376
}
377377

378-
static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu);
378+
static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
379+
{
380+
/*
381+
* Non-protected kvm relies on the host restoring its sve state.
382+
* Protected kvm restores the host's sve state as not to reveal that
383+
* fpsimd was used by a guest nor leak upper sve bits.
384+
*/
385+
if (system_supports_sve()) {
386+
__hyp_sve_save_host();
387+
388+
/* Re-enable SVE traps if not supported for the guest vcpu. */
389+
if (!vcpu_has_sve(vcpu))
390+
cpacr_clear_set(CPACR_ELx_ZEN, 0);
391+
392+
} else {
393+
__fpsimd_save_state(host_data_ptr(host_ctxt.fp_regs));
394+
}
395+
396+
if (kvm_has_fpmr(kern_hyp_va(vcpu->kvm)))
397+
*host_data_ptr(fpmr) = read_sysreg_s(SYS_FPMR);
398+
}
399+
379400

380401
/*
381402
* We trap the first access to the FP/SIMD to save the host context and
@@ -425,7 +446,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
425446
isb();
426447

427448
/* Write out the host state if it's in the registers */
428-
if (host_owns_fp_regs())
449+
if (is_protected_kvm_enabled() && host_owns_fp_regs())
429450
kvm_hyp_save_fpsimd_host(vcpu);
430451

431452
/* Restore the guest state */

arch/arm64/kvm/hyp/nvhe/hyp-main.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -83,7 +83,7 @@ static void fpsimd_sve_sync(struct kvm_vcpu *vcpu)
8383
if (system_supports_sve())
8484
__hyp_sve_restore_host();
8585
else
86-
__fpsimd_restore_state(*host_data_ptr(fpsimd_state));
86+
__fpsimd_restore_state(host_data_ptr(host_ctxt.fp_regs));
8787

8888
if (has_fpmr)
8989
write_sysreg_s(*host_data_ptr(fpmr), SYS_FPMR);

arch/arm64/kvm/hyp/nvhe/switch.c

Lines changed: 0 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -193,34 +193,6 @@ static bool kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu, u64 *exit_code)
193193
kvm_handle_pvm_sysreg(vcpu, exit_code));
194194
}
195195

196-
static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
197-
{
198-
/*
199-
* Non-protected kvm relies on the host restoring its sve state.
200-
* Protected kvm restores the host's sve state as not to reveal that
201-
* fpsimd was used by a guest nor leak upper sve bits.
202-
*/
203-
if (unlikely(is_protected_kvm_enabled() && system_supports_sve())) {
204-
__hyp_sve_save_host();
205-
206-
/* Re-enable SVE traps if not supported for the guest vcpu. */
207-
if (!vcpu_has_sve(vcpu))
208-
cpacr_clear_set(CPACR_ELx_ZEN, 0);
209-
210-
} else {
211-
__fpsimd_save_state(*host_data_ptr(fpsimd_state));
212-
}
213-
214-
if (kvm_has_fpmr(kern_hyp_va(vcpu->kvm))) {
215-
u64 val = read_sysreg_s(SYS_FPMR);
216-
217-
if (unlikely(is_protected_kvm_enabled()))
218-
*host_data_ptr(fpmr) = val;
219-
else
220-
**host_data_ptr(fpmr_ptr) = val;
221-
}
222-
}
223-
224196
static const exit_handler_fn hyp_exit_handlers[] = {
225197
[0 ... ESR_ELx_EC_MAX] = NULL,
226198
[ESR_ELx_EC_CP15_32] = kvm_hyp_handle_cp15_32,

arch/arm64/kvm/hyp/vhe/switch.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -309,14 +309,6 @@ static bool kvm_hyp_handle_eret(struct kvm_vcpu *vcpu, u64 *exit_code)
309309
return true;
310310
}
311311

312-
static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
313-
{
314-
__fpsimd_save_state(*host_data_ptr(fpsimd_state));
315-
316-
if (kvm_has_fpmr(vcpu->kvm))
317-
**host_data_ptr(fpmr_ptr) = read_sysreg_s(SYS_FPMR);
318-
}
319-
320312
static bool kvm_hyp_handle_tlbi_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
321313
{
322314
int ret = -EINVAL;

0 commit comments

Comments
 (0)