Skip to content

Commit ee14db3

Browse files
mrutland-armMarc Zyngier
authored andcommitted
KVM: arm64: Refactor CPTR trap deactivation
For historical reasons, the VHE and nVHE/hVHE implementations of __activate_cptr_traps() pair with a common implementation of __kvm_reset_cptr_el2(), which ideally would be named __deactivate_cptr_traps(). Rename __kvm_reset_cptr_el2() to __deactivate_cptr_traps(), and split it into separate VHE and nVHE/hVHE variants so that each can be paired with its corresponding implementation of __activate_cptr_traps(). At the same time, fold kvm_write_cptr_el2() into its callers. This makes it clear in-context whether a write is made to the CPACR_EL1 encoding or the CPTR_EL2 encoding, and removes the possibility of confusion as to whether kvm_write_cptr_el2() reformats the sysreg fields as cpacr_clear_set() does. In the nVHE/hVHE implementation of __activate_cptr_traps(), placing the sysreg writes within the if-else blocks requires that the call to __activate_traps_fpsimd32() is moved earlier, but as this was always called before writing to CPTR_EL2/CPACR_EL1, this should not result in a functional change. 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 407a99c commit ee14db3

File tree

3 files changed

+42
-47
lines changed

3 files changed

+42
-47
lines changed

arch/arm64/include/asm/kvm_emulate.h

Lines changed: 0 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -605,48 +605,6 @@ static __always_inline void kvm_incr_pc(struct kvm_vcpu *vcpu)
605605
__cpacr_to_cptr_set(clr, set));\
606606
} while (0)
607607

608-
static __always_inline void kvm_write_cptr_el2(u64 val)
609-
{
610-
if (has_vhe() || has_hvhe())
611-
write_sysreg(val, cpacr_el1);
612-
else
613-
write_sysreg(val, cptr_el2);
614-
}
615-
616-
/* Resets the value of cptr_el2 when returning to the host. */
617-
static __always_inline void __kvm_reset_cptr_el2(struct kvm *kvm)
618-
{
619-
u64 val;
620-
621-
if (has_vhe()) {
622-
val = (CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN);
623-
if (cpus_have_final_cap(ARM64_SME))
624-
val |= CPACR_EL1_SMEN_EL1EN;
625-
} else if (has_hvhe()) {
626-
val = CPACR_EL1_FPEN;
627-
628-
if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
629-
val |= CPACR_EL1_ZEN;
630-
if (cpus_have_final_cap(ARM64_SME))
631-
val |= CPACR_EL1_SMEN;
632-
} else {
633-
val = CPTR_NVHE_EL2_RES1;
634-
635-
if (kvm_has_sve(kvm) && guest_owns_fp_regs())
636-
val |= CPTR_EL2_TZ;
637-
if (!cpus_have_final_cap(ARM64_SME))
638-
val |= CPTR_EL2_TSM;
639-
}
640-
641-
kvm_write_cptr_el2(val);
642-
}
643-
644-
#ifdef __KVM_NVHE_HYPERVISOR__
645-
#define kvm_reset_cptr_el2(v) __kvm_reset_cptr_el2(kern_hyp_va((v)->kvm))
646-
#else
647-
#define kvm_reset_cptr_el2(v) __kvm_reset_cptr_el2((v)->kvm)
648-
#endif
649-
650608
/*
651609
* Returns a 'sanitised' view of CPTR_EL2, translating from nVHE to the VHE
652610
* format if E2H isn't set.

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

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
3939
{
4040
u64 val = CPTR_EL2_TAM; /* Same bit irrespective of E2H */
4141

42+
if (!guest_owns_fp_regs())
43+
__activate_traps_fpsimd32(vcpu);
44+
4245
if (has_hvhe()) {
4346
val |= CPACR_EL1_TTA;
4447

@@ -47,6 +50,8 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
4750
if (vcpu_has_sve(vcpu))
4851
val |= CPACR_EL1_ZEN;
4952
}
53+
54+
write_sysreg(val, cpacr_el1);
5055
} else {
5156
val |= CPTR_EL2_TTA | CPTR_NVHE_EL2_RES1;
5257

@@ -61,12 +66,34 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
6166

6267
if (!guest_owns_fp_regs())
6368
val |= CPTR_EL2_TFP;
69+
70+
write_sysreg(val, cptr_el2);
6471
}
72+
}
6573

66-
if (!guest_owns_fp_regs())
67-
__activate_traps_fpsimd32(vcpu);
74+
static void __deactivate_cptr_traps(struct kvm_vcpu *vcpu)
75+
{
76+
struct kvm *kvm = kern_hyp_va(vcpu->kvm);
6877

69-
kvm_write_cptr_el2(val);
78+
if (has_hvhe()) {
79+
u64 val = CPACR_EL1_FPEN;
80+
81+
if (!kvm_has_sve(kvm) || !guest_owns_fp_regs())
82+
val |= CPACR_EL1_ZEN;
83+
if (cpus_have_final_cap(ARM64_SME))
84+
val |= CPACR_EL1_SMEN;
85+
86+
write_sysreg(val, cpacr_el1);
87+
} else {
88+
u64 val = CPTR_NVHE_EL2_RES1;
89+
90+
if (kvm_has_sve(kvm) && guest_owns_fp_regs())
91+
val |= CPTR_EL2_TZ;
92+
if (!cpus_have_final_cap(ARM64_SME))
93+
val |= CPTR_EL2_TSM;
94+
95+
write_sysreg(val, cptr_el2);
96+
}
7097
}
7198

7299
static void __activate_traps(struct kvm_vcpu *vcpu)
@@ -119,7 +146,7 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
119146

120147
write_sysreg(this_cpu_ptr(&kvm_init_params)->hcr_el2, hcr_el2);
121148

122-
kvm_reset_cptr_el2(vcpu);
149+
__deactivate_cptr_traps(vcpu);
123150
write_sysreg(__kvm_hyp_host_vector, vbar_el2);
124151
}
125152

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

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,16 @@ static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
136136
write_sysreg(val, cpacr_el1);
137137
}
138138

139+
static void __deactivate_cptr_traps(struct kvm_vcpu *vcpu)
140+
{
141+
u64 val = CPACR_EL1_FPEN | CPACR_EL1_ZEN_EL1EN;
142+
143+
if (cpus_have_final_cap(ARM64_SME))
144+
val |= CPACR_EL1_SMEN_EL1EN;
145+
146+
write_sysreg(val, cpacr_el1);
147+
}
148+
139149
static void __activate_traps(struct kvm_vcpu *vcpu)
140150
{
141151
u64 val;
@@ -207,7 +217,7 @@ static void __deactivate_traps(struct kvm_vcpu *vcpu)
207217
*/
208218
asm(ALTERNATIVE("nop", "isb", ARM64_WORKAROUND_SPECULATIVE_AT));
209219

210-
kvm_reset_cptr_el2(vcpu);
220+
__deactivate_cptr_traps(vcpu);
211221

212222
if (!arm64_kernel_unmapped_at_el0())
213223
host_vectors = __this_cpu_read(this_cpu_vector);

0 commit comments

Comments
 (0)