From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1754721AbdHZIEu (ORCPT ); Sat, 26 Aug 2017 04:04:50 -0400 Received: from terminus.zytor.com ([65.50.211.136]:42277 "EHLO terminus.zytor.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1751868AbdHZIEq (ORCPT ); Sat, 26 Aug 2017 04:04:46 -0400 Date: Sat, 26 Aug 2017 01:00:03 -0700 From: tip-bot for Brijesh Singh Message-ID: Cc: sfr@canb.auug.org.au, hpa@zytor.com, linux-kernel@vger.kernel.org, rkrcmar@redhat.com, tglx@linutronix.de, brijesh.singh@amd.com, peterz@infradead.org, mingo@kernel.org, torvalds@linux-foundation.org, thomas.lendacky@amd.com, pbonzini@redhat.com Reply-To: linux-kernel@vger.kernel.org, hpa@zytor.com, sfr@canb.auug.org.au, thomas.lendacky@amd.com, pbonzini@redhat.com, torvalds@linux-foundation.org, brijesh.singh@amd.com, peterz@infradead.org, mingo@kernel.org, tglx@linutronix.de, rkrcmar@redhat.com In-Reply-To: <20170825205540.123531-1-brijesh.singh@amd.com> References: <20170825205540.123531-1-brijesh.singh@amd.com> To: linux-tip-commits@vger.kernel.org Subject: [tip:x86/mm] kvm/x86: Avoid clearing the C-bit in rsvd_bits() Git-Commit-ID: ea2800ddb20d6e66042051a61f66e6bea4fa0db7 X-Mailer: tip-git-log-daemon Robot-ID: Robot-Unsubscribe: Contact to get blacklisted from these emails MIME-Version: 1.0 Content-Transfer-Encoding: 8bit Content-Type: text/plain; charset=UTF-8 Content-Disposition: inline Sender: linux-kernel-owner@vger.kernel.org List-ID: X-Mailing-List: linux-kernel@vger.kernel.org Commit-ID: ea2800ddb20d6e66042051a61f66e6bea4fa0db7 Gitweb: http://git.kernel.org/tip/ea2800ddb20d6e66042051a61f66e6bea4fa0db7 Author: Brijesh Singh AuthorDate: Fri, 25 Aug 2017 15:55:40 -0500 Committer: Ingo Molnar CommitDate: Sat, 26 Aug 2017 09:23:00 +0200 kvm/x86: Avoid clearing the C-bit in rsvd_bits() The following commit: d0ec49d4de90 ("kvm/x86/svm: Support Secure Memory Encryption within KVM") uses __sme_clr() to remove the C-bit in rsvd_bits(). rsvd_bits() is just a simple function to return some 1 bits. Applying a mask based on properties of the host MMU is incorrect. Additionally, the masks computed by __reset_rsvds_bits_mask also apply to guest page tables, where the C bit is reserved since we don't emulate SME. The fix is to clear the C-bit from rsvd_bits_mask array after it has been populated from __reset_rsvds_bits_mask() Suggested-by: Paolo Bonzini Signed-off-by: Brijesh Singh Acked-by: Paolo Bonzini Cc: Linus Torvalds Cc: Peter Zijlstra Cc: Radim Krčmář Cc: Stephen Rothwell Cc: Thomas Gleixner Cc: Tom Lendacky Cc: kvm@vger.kernel.org Cc: paolo.bonzini@gmail.com Fixes: d0ec49d ("kvm/x86/svm: Support Secure Memory Encryption within KVM") Link: http://lkml.kernel.org/r/20170825205540.123531-1-brijesh.singh@amd.com Signed-off-by: Ingo Molnar --- arch/x86/kvm/mmu.c | 30 +++++++++++++++++++++++++++--- arch/x86/kvm/mmu.h | 2 +- 2 files changed, 28 insertions(+), 4 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index ccb70b8..04d7508 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -4109,16 +4109,28 @@ void reset_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) { bool uses_nx = context->nx || context->base_role.smep_andnot_wp; + struct rsvd_bits_validate *shadow_zero_check; + int i; /* * Passing "true" to the last argument is okay; it adds a check * on bit 8 of the SPTEs which KVM doesn't use anyway. */ - __reset_rsvds_bits_mask(vcpu, &context->shadow_zero_check, + shadow_zero_check = &context->shadow_zero_check; + __reset_rsvds_bits_mask(vcpu, shadow_zero_check, boot_cpu_data.x86_phys_bits, context->shadow_root_level, uses_nx, guest_cpuid_has_gbpages(vcpu), is_pse(vcpu), true); + + if (!shadow_me_mask) + return; + + for (i = context->shadow_root_level; --i >= 0;) { + shadow_zero_check->rsvd_bits_mask[0][i] &= ~shadow_me_mask; + shadow_zero_check->rsvd_bits_mask[1][i] &= ~shadow_me_mask; + } + } EXPORT_SYMBOL_GPL(reset_shadow_zero_bits_mask); @@ -4136,17 +4148,29 @@ static void reset_tdp_shadow_zero_bits_mask(struct kvm_vcpu *vcpu, struct kvm_mmu *context) { + struct rsvd_bits_validate *shadow_zero_check; + int i; + + shadow_zero_check = &context->shadow_zero_check; + if (boot_cpu_is_amd()) - __reset_rsvds_bits_mask(vcpu, &context->shadow_zero_check, + __reset_rsvds_bits_mask(vcpu, shadow_zero_check, boot_cpu_data.x86_phys_bits, context->shadow_root_level, false, boot_cpu_has(X86_FEATURE_GBPAGES), true, true); else - __reset_rsvds_bits_mask_ept(&context->shadow_zero_check, + __reset_rsvds_bits_mask_ept(shadow_zero_check, boot_cpu_data.x86_phys_bits, false); + if (!shadow_me_mask) + return; + + for (i = context->shadow_root_level; --i >= 0;) { + shadow_zero_check->rsvd_bits_mask[0][i] &= ~shadow_me_mask; + shadow_zero_check->rsvd_bits_mask[1][i] &= ~shadow_me_mask; + } } /* diff --git a/arch/x86/kvm/mmu.h b/arch/x86/kvm/mmu.h index 3cc7255..d7d248a 100644 --- a/arch/x86/kvm/mmu.h +++ b/arch/x86/kvm/mmu.h @@ -48,7 +48,7 @@ static inline u64 rsvd_bits(int s, int e) { - return __sme_clr(((1ULL << (e - s + 1)) - 1) << s); + return ((1ULL << (e - s + 1)) - 1) << s; } void kvm_mmu_set_mmio_spte_mask(u64 mmio_mask, u64 mmio_value);