| From 112022bdb5bc372e00e6e43cb88ee38ea67b97bd Mon Sep 17 00:00:00 2001 |
| From: Sean Christopherson <seanjc@google.com> |
| Date: Tue, 22 Jun 2021 10:56:47 -0700 |
| Subject: KVM: x86/mmu: Treat NX as used (not reserved) for all !TDP shadow MMUs |
| |
| From: Sean Christopherson <seanjc@google.com> |
| |
| commit 112022bdb5bc372e00e6e43cb88ee38ea67b97bd upstream. |
| |
| Mark NX as being used for all non-nested shadow MMUs, as KVM will set the |
| NX bit for huge SPTEs if the iTLB mutli-hit mitigation is enabled. |
| Checking the mitigation itself is not sufficient as it can be toggled on |
| at any time and KVM doesn't reset MMU contexts when that happens. KVM |
| could reset the contexts, but that would require purging all SPTEs in all |
| MMUs, for no real benefit. And, KVM already forces EFER.NX=1 when TDP is |
| disabled (for WP=0, SMEP=1, NX=0), so technically NX is never reserved |
| for shadow MMUs. |
| |
| Fixes: b8e8c8303ff2 ("kvm: mmu: ITLB_MULTIHIT mitigation") |
| Cc: stable@vger.kernel.org |
| Signed-off-by: Sean Christopherson <seanjc@google.com> |
| Message-Id: <20210622175739.3610207-3-seanjc@google.com> |
| Signed-off-by: Paolo Bonzini <pbonzini@redhat.com> |
| Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org> |
| |
| --- |
| arch/x86/kvm/mmu/mmu.c | 10 +++++++++- |
| 1 file changed, 9 insertions(+), 1 deletion(-) |
| |
| --- a/arch/x86/kvm/mmu/mmu.c |
| +++ b/arch/x86/kvm/mmu/mmu.c |
| @@ -4133,7 +4133,15 @@ static void reset_rsvds_bits_mask_ept(st |
| void |
| reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) |
| { |
| - bool uses_nx = context->nx || |
| + /* |
| + * KVM uses NX when TDP is disabled to handle a variety of scenarios, |
| + * notably for huge SPTEs if iTLB multi-hit mitigation is enabled and |
| + * to generate correct permissions for CR0.WP=0/CR4.SMEP=1/EFER.NX=0. |
| + * The iTLB multi-hit workaround can be toggled at any time, so assume |
| + * NX can be used by any non-nested shadow MMU to avoid having to reset |
| + * MMU contexts. Note, KVM forces EFER.NX=1 when TDP is disabled. |
| + */ |
| + bool uses_nx = context->nx || !tdp_enabled || |
| context->mmu_role.base.smep_andnot_wp; |
| struct rsvd_bits_validate *shadow_zero_check; |
| int i; |