diff options
| author | Oliver Upton <oliver.upton@linux.dev> | 2025-09-17 13:31:25 -0700 | 
|---|---|---|
| committer | Marc Zyngier <maz@kernel.org> | 2025-09-18 16:46:20 +0100 | 
| commit | 3af1105c4fa362d17d577b55d2b8a7c4609f16fc (patch) | |
| tree | ce8e9148d1e9fa0e7a342d422f41c6b7164877f8 | |
| parent | 4a684088421d5a1ffb3b13243c58a9078c99e4b9 (diff) | |
KVM: arm64: nv: Apply guest's MDCR traps in nested context
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>
| -rw-r--r-- | arch/arm64/kvm/nested.c | 19 | 
1 files changed, 19 insertions, 0 deletions
| diff --git a/arch/arm64/kvm/nested.c b/arch/arm64/kvm/nested.c index 9559c64e7e0c..61542d6fd8f5 100644 --- a/arch/arm64/kvm/nested.c +++ b/arch/arm64/kvm/nested.c @@ -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);  } | 
