]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
KVM: arm64: nv: Apply guest's MDCR traps in nested context
authorOliver Upton <oliver.upton@linux.dev>
Wed, 17 Sep 2025 20:31:25 +0000 (13:31 -0700)
committerMarc Zyngier <maz@kernel.org>
Thu, 18 Sep 2025 15:46:20 +0000 (16:46 +0100)
KVM needs to ensure the guest hypervisor's traps take effect when the
vCPU is in a nested context. While supporting infrastructure is in place
for most of the EL2 trap registers, MDCR_EL2 is not.

Fold the guest's trap configuration into the effective MDCR_EL2. Apply
it directly to the in-memory representation as it gets recomputed on
every vcpu_load() anyway.

Signed-off-by: Oliver Upton <oliver.upton@linux.dev>
Signed-off-by: Marc Zyngier <maz@kernel.org>
arch/arm64/kvm/nested.c

index 9559c64e7e0c01f7a43451759a6a7e05a95f6899..61542d6fd8f5ef956279b472b611e8805a27a88f 100644 (file)
@@ -1797,8 +1797,25 @@ void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu)
                kvm_inject_serror_esr(vcpu, vcpu_get_vsesr(vcpu));
 }
 
+/*
+ * KVM unconditionally sets most of these traps anyway but use an allowlist
+ * to document the guest hypervisor traps that may take precedence and guard
+ * against future changes to the non-nested trap configuration.
+ */
+#define NV_MDCR_GUEST_INCLUDE  (MDCR_EL2_TDE   |       \
+                                MDCR_EL2_TDA   |       \
+                                MDCR_EL2_TDRA  |       \
+                                MDCR_EL2_TTRF  |       \
+                                MDCR_EL2_TPMS  |       \
+                                MDCR_EL2_TPM   |       \
+                                MDCR_EL2_TPMCR |       \
+                                MDCR_EL2_TDCC  |       \
+                                MDCR_EL2_TDOSA)
+
 void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
 {
+       u64 guest_mdcr = __vcpu_sys_reg(vcpu, MDCR_EL2);
+
        /*
         * In yet another example where FEAT_NV2 is fscking broken, accesses
         * to MDSCR_EL1 are redirected to the VNCR despite having an effect
@@ -1806,4 +1823,6 @@ void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
         */
        if (is_hyp_ctxt(vcpu))
                vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
+       else
+               vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE);
 }