]> git.ipfire.org Git - thirdparty/linux.git/commitdiff
KVM: arm64: Spin off helper for programming CPTR traps
authorOliver Upton <oliver.upton@linux.dev>
Thu, 20 Jun 2024 16:46:45 +0000 (16:46 +0000)
committerOliver Upton <oliver.upton@linux.dev>
Thu, 20 Jun 2024 19:04:10 +0000 (19:04 +0000)
A subsequent change to KVM will add preliminary support for merging a
guest hypervisor's CPTR traps with that of KVM. Prepare by spinning off
a new helper for managing CPTR traps.

Avoid reading CPACR_EL1 for the baseline trap config, and start off with
the most restrictive set of traps that is subsequently relaxed.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20240620164653.1130714-9-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/hyp/vhe/switch.c

index 8fbb6a2e0559d7e7d8d90ce11b618f35a723c46e..667ed4f558af108dbfb97c790041b103bf30edc0 100644 (file)
@@ -65,6 +65,29 @@ static u64 __compute_hcr(struct kvm_vcpu *vcpu)
        return hcr | (__vcpu_sys_reg(vcpu, HCR_EL2) & ~NV_HCR_GUEST_EXCLUDE);
 }
 
+static void __activate_cptr_traps(struct kvm_vcpu *vcpu)
+{
+       /*
+        * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
+        * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
+        * except for some missing controls, such as TAM.
+        * In this case, CPTR_EL2.TAM has the same position with or without
+        * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
+        * shift value for trapping the AMU accesses.
+        */
+       u64 val = CPACR_ELx_TTA | CPTR_EL2_TAM;
+
+       if (guest_owns_fp_regs()) {
+               val |= CPACR_ELx_FPEN;
+               if (vcpu_has_sve(vcpu))
+                       val |= CPACR_ELx_ZEN;
+       } else {
+               __activate_traps_fpsimd32(vcpu);
+       }
+
+       write_sysreg(val, cpacr_el1);
+}
+
 static void __activate_traps(struct kvm_vcpu *vcpu)
 {
        u64 val;
@@ -91,30 +114,7 @@ static void __activate_traps(struct kvm_vcpu *vcpu)
                }
        }
 
-       val = read_sysreg(cpacr_el1);
-       val |= CPACR_ELx_TTA;
-       val &= ~(CPACR_ELx_ZEN | CPACR_ELx_SMEN);
-
-       /*
-        * With VHE (HCR.E2H == 1), accesses to CPACR_EL1 are routed to
-        * CPTR_EL2. In general, CPACR_EL1 has the same layout as CPTR_EL2,
-        * except for some missing controls, such as TAM.
-        * In this case, CPTR_EL2.TAM has the same position with or without
-        * VHE (HCR.E2H == 1) which allows us to use here the CPTR_EL2.TAM
-        * shift value for trapping the AMU accesses.
-        */
-
-       val |= CPTR_EL2_TAM;
-
-       if (guest_owns_fp_regs()) {
-               if (vcpu_has_sve(vcpu))
-                       val |= CPACR_ELx_ZEN;
-       } else {
-               val &= ~CPACR_ELx_FPEN;
-               __activate_traps_fpsimd32(vcpu);
-       }
-
-       write_sysreg(val, cpacr_el1);
+       __activate_cptr_traps(vcpu);
 
        write_sysreg(__this_cpu_read(kvm_hyp_vector), vbar_el1);
 }