Skip to content

Commit 8383741

Browse files
author
Marc Zyngier
committed
KVM: arm64: Get rid of host SVE tracking/saving
The SVE host tracking in KVM is pretty involved. It relies on a set of flags tracking the ownership of the SVE register, as well as that of the EL0 access. It is also pretty scary: __hyp_sve_save_host() computes a thread_struct pointer and obtains a sve_state which gets directly accessed without further ado, even on nVHE. How can this even work? The answer to that is that it doesn't, and that this is mostly dead code. Closer examination shows that on executing a syscall, userspace loses its SVE state entirely. This is part of the ABI. Another thing to notice is that although the kernel provides helpers such as kernel_neon_begin()/end(), they only deal with the FP/NEON state, and not SVE. Given that you can only execute a guest as the result of a syscall, and that the kernel cannot use SVE by itself, it becomes pretty obvious that there is never any host SVE state to save, and that this code is only there to increase confusion. Get rid of the TIF_SVE tracking and host save infrastructure altogether. Reviewed-by: Mark Brown <[email protected]> Signed-off-by: Marc Zyngier <[email protected]>
1 parent 892fd25 commit 8383741

File tree

3 files changed

+8
-40
lines changed

3 files changed

+8
-40
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -411,7 +411,6 @@ struct kvm_vcpu_arch {
411411
#define KVM_ARM64_DEBUG_DIRTY (1 << 0)
412412
#define KVM_ARM64_FP_ENABLED (1 << 1) /* guest FP regs loaded */
413413
#define KVM_ARM64_FP_HOST (1 << 2) /* host FP regs loaded */
414-
#define KVM_ARM64_HOST_SVE_IN_USE (1 << 3) /* backup for host TIF_SVE */
415414
#define KVM_ARM64_HOST_SVE_ENABLED (1 << 4) /* SVE enabled for EL0 */
416415
#define KVM_ARM64_GUEST_HAS_SVE (1 << 5) /* SVE exposed to guest */
417416
#define KVM_ARM64_VCPU_SVE_FINALIZED (1 << 6) /* SVE config completed */

arch/arm64/kvm/fpsimd.c

Lines changed: 5 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -66,22 +66,15 @@ int kvm_arch_vcpu_run_map_fp(struct kvm_vcpu *vcpu)
6666
*
6767
* Here, we just set the correct metadata to indicate that the FPSIMD
6868
* state in the cpu regs (if any) belongs to current on the host.
69-
*
70-
* TIF_SVE is backed up here, since it may get clobbered with guest state.
71-
* This flag is restored by kvm_arch_vcpu_put_fp(vcpu).
7269
*/
7370
void kvm_arch_vcpu_load_fp(struct kvm_vcpu *vcpu)
7471
{
7572
BUG_ON(!current->mm);
73+
BUG_ON(test_thread_flag(TIF_SVE));
7674

77-
vcpu->arch.flags &= ~(KVM_ARM64_FP_ENABLED |
78-
KVM_ARM64_HOST_SVE_IN_USE |
79-
KVM_ARM64_HOST_SVE_ENABLED);
75+
vcpu->arch.flags &= ~KVM_ARM64_FP_ENABLED;
8076
vcpu->arch.flags |= KVM_ARM64_FP_HOST;
8177

82-
if (test_thread_flag(TIF_SVE))
83-
vcpu->arch.flags |= KVM_ARM64_HOST_SVE_IN_USE;
84-
8578
if (read_sysreg(cpacr_el1) & CPACR_EL1_ZEN_EL0EN)
8679
vcpu->arch.flags |= KVM_ARM64_HOST_SVE_ENABLED;
8780
}
@@ -115,13 +108,11 @@ void kvm_arch_vcpu_ctxsync_fp(struct kvm_vcpu *vcpu)
115108
void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
116109
{
117110
unsigned long flags;
118-
bool host_has_sve = system_supports_sve();
119-
bool guest_has_sve = vcpu_has_sve(vcpu);
120111

121112
local_irq_save(flags);
122113

123114
if (vcpu->arch.flags & KVM_ARM64_FP_ENABLED) {
124-
if (guest_has_sve) {
115+
if (vcpu_has_sve(vcpu)) {
125116
__vcpu_sys_reg(vcpu, ZCR_EL1) = read_sysreg_el1(SYS_ZCR);
126117

127118
/* Restore the VL that was saved when bound to the CPU */
@@ -131,7 +122,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
131122
}
132123

133124
fpsimd_save_and_flush_cpu_state();
134-
} else if (has_vhe() && host_has_sve) {
125+
} else if (has_vhe() && system_supports_sve()) {
135126
/*
136127
* The FPSIMD/SVE state in the CPU has not been touched, and we
137128
* have SVE (and VHE): CPACR_EL1 (alias CPTR_EL2) has been
@@ -145,8 +136,7 @@ void kvm_arch_vcpu_put_fp(struct kvm_vcpu *vcpu)
145136
sysreg_clear_set(CPACR_EL1, CPACR_EL1_ZEN_EL0EN, 0);
146137
}
147138

148-
update_thread_flag(TIF_SVE,
149-
vcpu->arch.flags & KVM_ARM64_HOST_SVE_IN_USE);
139+
update_thread_flag(TIF_SVE, 0);
150140

151141
local_irq_restore(flags);
152142
}

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

Lines changed: 3 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -143,16 +143,6 @@ static inline bool __populate_fault_info(struct kvm_vcpu *vcpu)
143143
return __get_fault_info(vcpu->arch.fault.esr_el2, &vcpu->arch.fault);
144144
}
145145

146-
static inline void __hyp_sve_save_host(struct kvm_vcpu *vcpu)
147-
{
148-
struct thread_struct *thread;
149-
150-
thread = container_of(vcpu->arch.host_fpsimd_state, struct thread_struct,
151-
uw.fpsimd_state);
152-
153-
__sve_save_state(sve_pffr(thread), &vcpu->arch.host_fpsimd_state->fpsr);
154-
}
155-
156146
static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
157147
{
158148
sve_cond_update_zcr_vq(vcpu_sve_max_vq(vcpu) - 1, SYS_ZCR_EL2);
@@ -169,21 +159,14 @@ static inline void __hyp_sve_restore_guest(struct kvm_vcpu *vcpu)
169159
*/
170160
static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
171161
{
172-
bool sve_guest, sve_host;
162+
bool sve_guest;
173163
u8 esr_ec;
174164
u64 reg;
175165

176166
if (!system_supports_fpsimd())
177167
return false;
178168

179-
if (system_supports_sve()) {
180-
sve_guest = vcpu_has_sve(vcpu);
181-
sve_host = vcpu->arch.flags & KVM_ARM64_HOST_SVE_IN_USE;
182-
} else {
183-
sve_guest = false;
184-
sve_host = false;
185-
}
186-
169+
sve_guest = vcpu_has_sve(vcpu);
187170
esr_ec = kvm_vcpu_trap_get_class(vcpu);
188171

189172
/* Don't handle SVE traps for non-SVE vcpus here: */
@@ -207,11 +190,7 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
207190
isb();
208191

209192
if (vcpu->arch.flags & KVM_ARM64_FP_HOST) {
210-
if (sve_host)
211-
__hyp_sve_save_host(vcpu);
212-
else
213-
__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
214-
193+
__fpsimd_save_state(vcpu->arch.host_fpsimd_state);
215194
vcpu->arch.flags &= ~KVM_ARM64_FP_HOST;
216195
}
217196

0 commit comments

Comments
 (0)