Skip to content

Commit 0cfc85b

Browse files
committed
KVM: arm64: nv: Load guest FP state for ZCR_EL2 trap
Round out the ZCR_EL2 gymnastics by loading SVE state in the fast path when the guest hypervisor tries to access SVE state. Reviewed-by: Marc Zyngier <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Oliver Upton <[email protected]>
1 parent 493da2b commit 0cfc85b

File tree

2 files changed

+31
-0
lines changed

2 files changed

+31
-0
lines changed

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

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -371,6 +371,10 @@ static bool kvm_hyp_handle_fpsimd(struct kvm_vcpu *vcpu, u64 *exit_code)
371371
if (guest_hyp_fpsimd_traps_enabled(vcpu))
372372
return false;
373373
break;
374+
case ESR_ELx_EC_SYS64:
375+
if (WARN_ON_ONCE(!is_hyp_ctxt(vcpu)))
376+
return false;
377+
fallthrough;
374378
case ESR_ELx_EC_SVE:
375379
if (!sve_guest)
376380
return false;

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

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -288,11 +288,38 @@ static bool kvm_hyp_handle_cpacr_el1(struct kvm_vcpu *vcpu, u64 *exit_code)
288288
return true;
289289
}
290290

291+
static bool kvm_hyp_handle_zcr_el2(struct kvm_vcpu *vcpu, u64 *exit_code)
292+
{
293+
u32 sysreg = esr_sys64_to_sysreg(kvm_vcpu_get_esr(vcpu));
294+
295+
if (!vcpu_has_nv(vcpu))
296+
return false;
297+
298+
if (sysreg != SYS_ZCR_EL2)
299+
return false;
300+
301+
if (guest_owns_fp_regs())
302+
return false;
303+
304+
/*
305+
* ZCR_EL2 traps are handled in the slow path, with the expectation
306+
* that the guest's FP context has already been loaded onto the CPU.
307+
*
308+
* Load the guest's FP context and unconditionally forward to the
309+
* slow path for handling (i.e. return false).
310+
*/
311+
kvm_hyp_handle_fpsimd(vcpu, exit_code);
312+
return false;
313+
}
314+
291315
static bool kvm_hyp_handle_sysreg_vhe(struct kvm_vcpu *vcpu, u64 *exit_code)
292316
{
293317
if (kvm_hyp_handle_cpacr_el1(vcpu, exit_code))
294318
return true;
295319

320+
if (kvm_hyp_handle_zcr_el2(vcpu, exit_code))
321+
return true;
322+
296323
return kvm_hyp_handle_sysreg(vcpu, exit_code);
297324
}
298325

0 commit comments

Comments
 (0)