Skip to content

Commit

Permalink
KVM: arm64: Don't save FP traps in default cptr_el2 value
Browse files Browse the repository at this point in the history
kvm_get_reset_cptr_el2() is called at vcpu init before the vcpu is
loaded. Since the linked commit, the fp state was moved from the vcpu to
host data but it shouldn't be accessed at this point.

Move the bits that require guest_owns_fp_regs() out of the default value
and into just before they're used in activate and deactivate traps. This
fixes the following bug when nvhe && vcpu_has_sve() == true:

 BUG: using smp_processor_id() in preemptible [00000000] code: lkvm/118
 caller is debug_smp_processor_id+0x20/0x30
 CPU: 0 UID: 0 PID: 118 Comm: lkvm Not tainted 6.12.0-rc1+ torvalds#35
 Hardware name: FVP Base RevC (DT)
 Call trace:
  dump_backtrace+0xfc/0x120
  show_stack+0x24/0x38
  dump_stack_lvl+0x3c/0x98
  dump_stack+0x18/0x28
  check_preemption_disabled+0xe0/0xe8
  debug_smp_processor_id+0x20/0x30
  guest_owns_fp_regs+0x1c/0xb0
  kvm_arch_vcpu_ioctl+0xcfc/0xe10
  kvm_vcpu_ioctl+0x6c4/0x8a0
  __arm64_sys_ioctl+0x9c/0xe0
  invoke_syscall+0x4c/0x110
  el0_svc_common+0xb8/0xf0
  do_el0_svc+0x28/0x40
  el0_svc+0x4c/0xc0
  el0t_64_sync_handler+0x84/0x100
  el0t_64_sync+0x190/0x198

Fixes: 5294afd ("KVM: arm64: Exclude FP ownership from kvm_vcpu_arch")
Signed-off-by: James Clark <james.clark@linaro.org>
Message-Id: <20241112105032.793274-1-james.clark@linaro.org>
  • Loading branch information
james-c-linaro authored and Patchew Applier committed Nov 12, 2024
1 parent 2d5404c commit ebbf142
Show file tree
Hide file tree
Showing 2 changed files with 11 additions and 7 deletions.
15 changes: 9 additions & 6 deletions arch/arm64/include/asm/kvm_emulate.h
Original file line number Diff line number Diff line change
Expand Up @@ -624,16 +624,12 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)
val |= CPACR_EL1_SMEN_EL1EN;
} else if (has_hvhe()) {
val = CPACR_ELx_FPEN;

if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
if (!vcpu_has_sve(vcpu))
val |= CPACR_ELx_ZEN;
if (cpus_have_final_cap(ARM64_SME))
val |= CPACR_ELx_SMEN;
} else {
val = CPTR_NVHE_EL2_RES1;

if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
val |= CPTR_EL2_TZ;
if (cpus_have_final_cap(ARM64_SME))
val &= ~CPTR_EL2_TSM;
}
Expand All @@ -643,8 +639,15 @@ static __always_inline u64 kvm_get_reset_cptr_el2(struct kvm_vcpu *vcpu)

static __always_inline void kvm_reset_cptr_el2(struct kvm_vcpu *vcpu)
{
u64 val = kvm_get_reset_cptr_el2(vcpu);
u64 val = vcpu->arch.cptr_el2;

if (has_hvhe()) {
if (!guest_owns_fp_regs())
val |= CPACR_ELx_ZEN;
} else if (!has_vhe()) {
if (vcpu_has_sve(vcpu) && guest_owns_fp_regs())
val |= CPTR_EL2_TZ;
}
kvm_write_cptr_el2(val);
}

Expand Down
3 changes: 2 additions & 1 deletion arch/arm64/kvm/hyp/nvhe/switch.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,8 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
val |= CPTR_EL2_TFP | CPTR_EL2_TZ;

__activate_traps_fpsimd32(vcpu);
}
} else if (!has_hvhe() && vcpu_has_sve(vcpu))
val |= CPTR_EL2_TZ;

kvm_write_cptr_el2(val);
write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
Expand Down

0 comments on commit ebbf142

Please sign in to comment.