Skip to content

Commit 2fd5b4b

Browse files
Fuad TabbaMarc Zyngier
authored andcommitted
KVM: arm64: Calculate cptr_el2 traps on activating traps
Similar to VHE, calculate the value of cptr_el2 from scratch on activate traps. This removes the need to store cptr_el2 in every vcpu structure. Moreover, some traps, such as whether the guest owns the fp registers, need to be set on every vcpu run. Reported-by: James Clark <[email protected]> Fixes: 5294afd ("KVM: arm64: Exclude FP ownership from kvm_vcpu_arch") Signed-off-by: Fuad Tabba <[email protected]> Link: https://lore.kernel.org/r/[email protected] Signed-off-by: Marc Zyngier <[email protected]>
1 parent 092e7b2 commit 2fd5b4b

File tree

4 files changed

+32
-63
lines changed

4 files changed

+32
-63
lines changed

arch/arm64/include/asm/kvm_host.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -708,7 +708,6 @@ struct kvm_vcpu_arch {
708708
u64 hcr_el2;
709709
u64 hcrx_el2;
710710
u64 mdcr_el2;
711-
u64 cptr_el2;
712711

713712
/* Exception Information */
714713
struct kvm_vcpu_fault_info fault;

arch/arm64/kvm/arm.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1546,7 +1546,6 @@ static int kvm_arch_vcpu_ioctl_vcpu_init(struct kvm_vcpu *vcpu,
15461546
}
15471547

15481548
vcpu_reset_hcr(vcpu);
1549-
vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
15501549

15511550
/*
15521551
* Handle the "start in power-off" case.

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

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -83,44 +83,6 @@ static void pvm_init_traps_hcr(struct kvm_vcpu *vcpu)
8383
vcpu->arch.hcr_el2 = val;
8484
}
8585

86-
static void pvm_init_traps_cptr(struct kvm_vcpu *vcpu)
87-
{
88-
struct kvm *kvm = vcpu->kvm;
89-
u64 val = vcpu->arch.cptr_el2;
90-
91-
if (!has_hvhe()) {
92-
val |= CPTR_NVHE_EL2_RES1;
93-
val &= ~(CPTR_NVHE_EL2_RES0);
94-
}
95-
96-
if (!kvm_has_feat(kvm, ID_AA64PFR0_EL1, AMU, IMP))
97-
val |= CPTR_EL2_TAM;
98-
99-
/* SVE can be disabled by userspace even if supported. */
100-
if (!vcpu_has_sve(vcpu)) {
101-
if (has_hvhe())
102-
val &= ~(CPACR_ELx_ZEN);
103-
else
104-
val |= CPTR_EL2_TZ;
105-
}
106-
107-
/* No SME support in KVM. */
108-
BUG_ON(kvm_has_feat(kvm, ID_AA64PFR1_EL1, SME, IMP));
109-
if (has_hvhe())
110-
val &= ~(CPACR_ELx_SMEN);
111-
else
112-
val |= CPTR_EL2_TSM;
113-
114-
if (!kvm_has_feat(kvm, ID_AA64DFR0_EL1, TraceVer, IMP)) {
115-
if (has_hvhe())
116-
val |= CPACR_EL1_TTA;
117-
else
118-
val |= CPTR_EL2_TTA;
119-
}
120-
121-
vcpu->arch.cptr_el2 = val;
122-
}
123-
12486
static void pvm_init_traps_mdcr(struct kvm_vcpu *vcpu)
12587
{
12688
struct kvm *kvm = vcpu->kvm;
@@ -191,7 +153,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
191153
struct kvm_vcpu *vcpu = &hyp_vcpu->vcpu;
192154
int ret;
193155

194-
vcpu->arch.cptr_el2 = kvm_get_reset_cptr_el2(vcpu);
195156
vcpu->arch.mdcr_el2 = 0;
196157

197158
pkvm_vcpu_reset_hcr(vcpu);
@@ -204,7 +165,6 @@ static int pkvm_vcpu_init_traps(struct pkvm_hyp_vcpu *hyp_vcpu)
204165
return ret;
205166

206167
pvm_init_traps_hcr(vcpu);
207-
pvm_init_traps_cptr(vcpu);
208168
pvm_init_traps_mdcr(vcpu);
209169

210170
return 0;
@@ -644,8 +604,6 @@ int __pkvm_init_vcpu(pkvm_handle_t handle, struct kvm_vcpu *host_vcpu,
644604
return ret;
645605
}
646606

647-
hyp_vcpu->vcpu.arch.cptr_el2 = kvm_get_reset_cptr_el2(&hyp_vcpu->vcpu);
648-
649607
return 0;
650608
}
651609

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

Lines changed: 32 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -35,33 +35,46 @@ DEFINE_PER_CPU(unsigned long, kvm_hyp_vector);
3535

3636
extern void kvm_nvhe_prepare_backtrace(unsigned long fp, unsigned long pc);
3737

38-
static void __activate_traps(struct kvm_vcpu *vcpu)
38+
static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
3939
{
40-
u64 val;
40+
u64 val = CPTR_EL2_TAM; /* Same bit irrespective of E2H */
4141

42-
___activate_traps(vcpu, vcpu->arch.hcr_el2);
43-
__activate_traps_common(vcpu);
42+
if (has_hvhe()) {
43+
val |= CPACR_ELx_TTA;
4444

45-
val = vcpu->arch.cptr_el2;
46-
val |= CPTR_EL2_TAM; /* Same bit irrespective of E2H */
47-
val |= has_hvhe() ? CPACR_EL1_TTA : CPTR_EL2_TTA;
48-
if (cpus_have_final_cap(ARM64_SME)) {
49-
if (has_hvhe())
50-
val &= ~CPACR_ELx_SMEN;
51-
else
52-
val |= CPTR_EL2_TSM;
53-
}
45+
if (guest_owns_fp_regs()) {
46+
val |= CPACR_ELx_FPEN;
47+
if (vcpu_has_sve(vcpu))
48+
val |= CPACR_ELx_ZEN;
49+
}
50+
} else {
51+
val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1;
5452

55-
if (!guest_owns_fp_regs()) {
56-
if (has_hvhe())
57-
val &= ~(CPACR_ELx_FPEN | CPACR_ELx_ZEN);
58-
else
59-
val |= CPTR_EL2_TFP | CPTR_EL2_TZ;
53+
/*
54+
* Always trap SME since it's not supported in KVM.
55+
* TSM is RES1 if SME isn't implemented.
56+
*/
57+
val |= CPTR_EL2_TSM;
6058

61-
__activate_traps_fpsimd32(vcpu);
59+
if (!vcpu_has_sve(vcpu) || !guest_owns_fp_regs())
60+
val |= CPTR_EL2_TZ;
61+
62+
if (!guest_owns_fp_regs())
63+
val |= CPTR_EL2_TFP;
6264
}
6365

66+
if (!guest_owns_fp_regs())
67+
__activate_traps_fpsimd32(vcpu);
68+
6469
kvm_write_cptr_el2(val);
70+
}
71+
72+
static void __activate_traps(struct kvm_vcpu *vcpu)
73+
{
74+
___activate_traps(vcpu, vcpu->arch.hcr_el2);
75+
__activate_traps_common(vcpu);
76+
__activate_cptr_traps(vcpu);
77+
6578
write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el2);
6679

6780
if (cpus_have_final_cap(ARM64_WORKAROUND_SPECULATIVE_AT)) {

0 commit comments

Comments
 (0)