Skip to content

Commit 8eca7f6

Browse files
mrutland-armMarc Zyngier
authored andcommitted
KVM: arm64: Remove host FPSIMD saving for non-protected KVM
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]>
1 parent fbc7e61 commit 8eca7f6

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
@@ -624,23 +624,13 @@ struct kvm_host_data {
624624
struct kvm_cpu_context host_ctxt;
625625

626626
/*
627-
* All pointers in this union are hyp VA.
627+
* Hyp VA.
628628
* sve_state is only used in pKVM and if system_supports_sve().
629629
*/
630-
union {
631-
struct user_fpsimd_state *fpsimd_state;
632-
struct cpu_sve_state *sve_state;
633-
};
634-
635-
union {
636-
/* HYP VA pointer to the host storage for FPMR */
637-
u64 *fpmr_ptr;
638-
/*
639-
* Used by pKVM only, as it needs to provide storage
640-
* for the host
641-
*/
642-
u64 fpmr;
643-
};
630+
struct cpu_sve_state *sve_state;
631+
632+
/* Used by pKVM only. */
633+
u64 fpmr;
644634

645635
/* Ownership of the FP regs */
646636
enum {

arch/arm64/kvm/arm.c

Lines changed: 0 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -2481,14 +2481,6 @@ static void finalize_init_hyp_mode(void)
24812481
per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->sve_state =
24822482
kern_hyp_va(sve_state);
24832483
}
2484-
} else {
2485-
for_each_possible_cpu(cpu) {
2486-
struct user_fpsimd_state *fpsimd_state;
2487-
2488-
fpsimd_state = &per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->host_ctxt.fp_regs;
2489-
per_cpu_ptr_nvhe_sym(kvm_host_data, cpu)->fpsimd_state =
2490-
kern_hyp_va(fpsimd_state);
2491-
}
24922484
}
24932485
}
24942486

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
host_data_clear_flag(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_EL1_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
@@ -192,34 +192,6 @@ static bool kvm_handle_pvm_sys64(struct kvm_vcpu *vcpu, u64 *exit_code)
192192
kvm_handle_pvm_sysreg(vcpu, exit_code));
193193
}
194194

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

416-
static void kvm_hyp_save_fpsimd_host(struct kvm_vcpu *vcpu)
417-
{
418-
__fpsimd_save_state(*host_data_ptr(fpsimd_state));
419-
420-
if (kvm_has_fpmr(vcpu->kvm))
421-
**host_data_ptr(fpmr_ptr) = read_sysreg_s(SYS_FPMR);
422-
}
423-
424416
static bool kvm_hyp_handle_tlbi_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
425417
{
426418
int ret = -EINVAL;

0 commit comments

Comments
 (0)