]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
KVM: arm64: Factor out helper for selecting exception target EL
authorOliver Upton <oliver.upton@linux.dev>
Tue, 8 Jul 2025 17:25:20 +0000 (10:25 -0700)
committerOliver Upton <oliver.upton@linux.dev>
Tue, 8 Jul 2025 18:36:35 +0000 (11:36 -0700)
Pull out the exception target selection from pend_sync_exception() for
general use. Use PSR_MODE_ELxh as a shorthand for the target EL, as
SP_ELx selection is handled further along in the hyp's exception
emulation.

Reviewed-by: Marc Zyngier <maz@kernel.org>
Link: https://lore.kernel.org/r/20250708172532.1699409-16-oliver.upton@linux.dev
Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
arch/arm64/kvm/inject_fault.c

index 10773a8ef4cbb3d3296d21c5e81e79ebcee4a56e..4df42a41d0abd696bcf8f3ce600ed375d7c46e49 100644 (file)
 #include <asm/kvm_nested.h>
 #include <asm/esr.h>
 
-static void pend_sync_exception(struct kvm_vcpu *vcpu)
+static unsigned int exception_target_el(struct kvm_vcpu *vcpu)
 {
        /* If not nesting, EL1 is the only possible exception target */
-       if (likely(!vcpu_has_nv(vcpu))) {
-               kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
-               return;
-       }
+       if (likely(!vcpu_has_nv(vcpu)))
+               return PSR_MODE_EL1h;
 
        /*
         * With NV, we need to pick between EL1 and EL2. Note that we
@@ -32,23 +30,25 @@ static void pend_sync_exception(struct kvm_vcpu *vcpu)
        switch(*vcpu_cpsr(vcpu) & PSR_MODE_MASK) {
        case PSR_MODE_EL2h:
        case PSR_MODE_EL2t:
-               kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SYNC);
-               break;
+               return PSR_MODE_EL2h;
        case PSR_MODE_EL1h:
        case PSR_MODE_EL1t:
-               kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
-               break;
+               return PSR_MODE_EL1h;
        case PSR_MODE_EL0t:
-               if (vcpu_el2_tge_is_set(vcpu))
-                       kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SYNC);
-               else
-                       kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
-               break;
+               return vcpu_el2_tge_is_set(vcpu) ? PSR_MODE_EL2h : PSR_MODE_EL1h;
        default:
                BUG();
        }
 }
 
+static void pend_sync_exception(struct kvm_vcpu *vcpu)
+{
+       if (exception_target_el(vcpu) == PSR_MODE_EL1h)
+               kvm_pend_exception(vcpu, EXCEPT_AA64_EL1_SYNC);
+       else
+               kvm_pend_exception(vcpu, EXCEPT_AA64_EL2_SYNC);
+}
+
 static bool match_target_el(struct kvm_vcpu *vcpu, unsigned long target)
 {
        return (vcpu_get_flag(vcpu, EXCEPT_MASK) == target);