Skip to content

Commit e0b5a79

Browse files
ouptonMarc Zyngier
authored andcommitted
KVM: arm64: nv: Use FGT write trap of MDSCR_EL1 when available
Marc reports that the performance of running an L3 guest has regressed by 60% as a result of setting MDCR_EL2.TDA to hide bad architecture. That's of course terrible for the single user of recursive NV ;-) While there's nothing to be done on non-FGT systems, take advantage of the precise write trap of MDSCR_EL1 and leave the rest of the debug registers untrapped. Reported-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Oliver Upton <oliver.upton@linux.dev> Reviewed-by: Joey Gouly <joey.gouly@arm.com> Signed-off-by: Marc Zyngier <maz@kernel.org>
1 parent fb10ddf commit e0b5a79

File tree

2 files changed

+15
-4
lines changed

2 files changed

+15
-4
lines changed

arch/arm64/kvm/config.c

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1489,6 +1489,14 @@ static void __compute_hfgwtr(struct kvm_vcpu *vcpu)
14891489
*vcpu_fgt(vcpu, HFGWTR_EL2) |= HFGWTR_EL2_TCR_EL1;
14901490
}
14911491

1492+
static void __compute_hdfgwtr(struct kvm_vcpu *vcpu)
1493+
{
1494+
__compute_fgt(vcpu, HDFGWTR_EL2);
1495+
1496+
if (is_hyp_ctxt(vcpu))
1497+
*vcpu_fgt(vcpu, HDFGWTR_EL2) |= HDFGWTR_EL2_MDSCR_EL1;
1498+
}
1499+
14921500
void kvm_vcpu_load_fgt(struct kvm_vcpu *vcpu)
14931501
{
14941502
if (!cpus_have_final_cap(ARM64_HAS_FGT))
@@ -1498,7 +1506,7 @@ void kvm_vcpu_load_fgt(struct kvm_vcpu *vcpu)
14981506
__compute_hfgwtr(vcpu);
14991507
__compute_fgt(vcpu, HFGITR_EL2);
15001508
__compute_fgt(vcpu, HDFGRTR_EL2);
1501-
__compute_fgt(vcpu, HDFGWTR_EL2);
1509+
__compute_hdfgwtr(vcpu);
15021510
__compute_fgt(vcpu, HAFGRTR_EL2);
15031511

15041512
if (!cpus_have_final_cap(ARM64_HAS_FGT2))

arch/arm64/kvm/nested.c

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1859,13 +1859,16 @@ void kvm_nested_setup_mdcr_el2(struct kvm_vcpu *vcpu)
18591859
{
18601860
u64 guest_mdcr = __vcpu_sys_reg(vcpu, MDCR_EL2);
18611861

1862+
if (is_nested_ctxt(vcpu))
1863+
vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE);
18621864
/*
18631865
* In yet another example where FEAT_NV2 is fscking broken, accesses
18641866
* to MDSCR_EL1 are redirected to the VNCR despite having an effect
18651867
* at EL2. Use a big hammer to apply sanity.
1868+
*
1869+
* Unless of course we have FEAT_FGT, in which case we can precisely
1870+
* trap MDSCR_EL1.
18661871
*/
1867-
if (is_hyp_ctxt(vcpu))
1872+
else if (!cpus_have_final_cap(ARM64_HAS_FGT))
18681873
vcpu->arch.mdcr_el2 |= MDCR_EL2_TDA;
1869-
else
1870-
vcpu->arch.mdcr_el2 |= (guest_mdcr & NV_MDCR_GUEST_INCLUDE);
18711874
}

0 commit comments

Comments
 (0)