Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

Merge branch kvm-arm64/nv-debug into kvmarm-master/next

* kvm-arm64/nv-debug:
: .
: Fix handling of MDSCR_EL1 in NV context, which is unfortunately
: mishandled by the architecture. Patches courtesy of Oliver Upton
: (20250917203125.283116-2-oliver.upton@linux.dev)
: .
KVM: arm64: nv: Apply guest's MDCR traps in nested context
KVM: arm64: nv: Trap debug registers when in hyp context

Signed-off-by: Marc Zyngier <maz@kernel.org>

+35
+2
arch/arm64/include/asm/kvm_nested.h
··· 83 83 extern void kvm_nested_flush_hwstate(struct kvm_vcpu *vcpu); 84 84 extern void kvm_nested_sync_hwstate(struct kvm_vcpu *vcpu); 85 85 86 + extern void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu); 87 + 86 88 struct kvm_s2_trans { 87 89 phys_addr_t output; 88 90 unsigned long block_size;
+3
arch/arm64/kvm/debug.c
··· 56 56 if (!kvm_guest_owns_debug_regs(vcpu)) 57 57 vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; 58 58 59 + if (vcpu_has_nv(vcpu)) 60 + kvm_nested_setup_mdcr_el2(vcpu); 61 + 59 62 /* Write MDCR_EL2 directly if we're already at EL2 */ 60 63 if (has_vhe()) 61 64 write_sysreg(vcpu->arch.mdcr_el2, mdcr_el2);
+30
arch/arm64/kvm/nested.c
··· 1796 1796 if (unlikely(vcpu_test_and_clear_flag(vcpu, NESTED_SERROR_PENDING))) 1797 1797 kvm_inject_serror_esr(vcpu, vcpu_get_vsesr(vcpu)); 1798 1798 } 1799 + 1800 + /* 1801 + * KVM unconditionally sets most of these traps anyway but use an allowlist 1802 + * to document the guest hypervisor traps that may take precedence and guard 1803 + * against future changes to the non-nested trap configuration. 1804 + */ 1805 + #define NV_MDCR_GUEST_INCLUDE (MDCR_EL2_TDE | \ 1806 + MDCR_EL2_TDA | \ 1807 + MDCR_EL2_TDRA | \ 1808 + MDCR_EL2_TTRF | \ 1809 + MDCR_EL2_TPMS | \ 1810 + MDCR_EL2_TPM | \ 1811 + MDCR_EL2_TPMCR | \ 1812 + MDCR_EL2_TDCC | \ 1813 + MDCR_EL2_TDOSA) 1814 + 1815 + void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu) 1816 + { 1817 + u64 guest_mdcr = __vcpu_sys_reg(vcpu, MDCR_EL2); 1818 + 1819 + /* 1820 + * In yet another example where FEAT_NV2 is fscking broken, accesses 1821 + * to MDSCR_EL1 are redirected to the VNCR despite having an effect 1822 + * at EL2. Use a big hammer to apply sanity. 1823 + */ 1824 + if (is_hyp_ctxt(vcpu)) 1825 + vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA; 1826 + else 1827 + vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE); 1828 + }