From mboxrd@z Thu Jan 1 00:00:00 1970 From: Junaid Shahid Subject: [PATCH v3 5/8] kvm: x86: mmu: Introduce a no-tracking version of mmu_spte_update Date: Tue, 6 Dec 2016 16:46:14 -0800 Message-ID: <1481071577-40250-6-git-send-email-junaids@google.com> References: <1481071577-40250-1-git-send-email-junaids@google.com> Cc: andreslc@google.com, pfeiner@google.com, pbonzini@redhat.com, guangrong.xiao@linux.intel.com To: kvm@vger.kernel.org Return-path: Received: from mail-pg0-f52.google.com ([74.125.83.52]:34295 "EHLO mail-pg0-f52.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1753306AbcLGAqY (ORCPT ); Tue, 6 Dec 2016 19:46:24 -0500 Received: by mail-pg0-f52.google.com with SMTP id x23so155020680pgx.1 for ; Tue, 06 Dec 2016 16:46:23 -0800 (PST) In-Reply-To: <1481071577-40250-1-git-send-email-junaids@google.com> Sender: kvm-owner@vger.kernel.org List-ID: mmu_spte_update() tracks changes in the accessed/dirty state of the SPTE being updated and calls kvm_set_pfn_accessed/dirty appropriately. However, in some cases (e.g. when aging the SPTE), this shouldn't be done. mmu_spte_update_no_track() is introduced for use in such cases. Signed-off-by: Junaid Shahid --- arch/x86/kvm/mmu.c | 42 ++++++++++++++++++++++++++++-------------- 1 file changed, 28 insertions(+), 14 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index a9cd1df..3f66fd3 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -527,6 +527,31 @@ static void mmu_spte_set(u64 *sptep, u64 new_spte) __set_spte(sptep, new_spte); } +/* + * Update the SPTE (excluding the PFN), but do not track changes in its + * accessed/dirty status. + */ +static u64 mmu_spte_update_no_track(u64 *sptep, u64 new_spte) +{ + u64 old_spte = *sptep; + + WARN_ON(!is_shadow_present_pte(new_spte)); + + if (!is_shadow_present_pte(old_spte)) { + mmu_spte_set(sptep, new_spte); + return old_spte; + } + + if (!spte_has_volatile_bits(old_spte)) + __update_clear_spte_fast(sptep, new_spte); + else + old_spte = __update_clear_spte_slow(sptep, new_spte); + + WARN_ON(spte_to_pfn(old_spte) != spte_to_pfn(new_spte)); + + return old_spte; +} + /* Rules for using mmu_spte_update: * Update the state bits, it means the mapped pfn is not changed. * @@ -540,22 +565,11 @@ static void mmu_spte_set(u64 *sptep, u64 new_spte) */ static bool mmu_spte_update(u64 *sptep, u64 new_spte) { - u64 old_spte = *sptep; bool flush = false; + u64 old_spte = mmu_spte_update_no_track(sptep, new_spte); - WARN_ON(!is_shadow_present_pte(new_spte)); - - if (!is_shadow_present_pte(old_spte)) { - mmu_spte_set(sptep, new_spte); - return flush; - } - - if (!spte_has_volatile_bits(old_spte)) - __update_clear_spte_fast(sptep, new_spte); - else - old_spte = __update_clear_spte_slow(sptep, new_spte); - - WARN_ON(spte_to_pfn(old_spte) != spte_to_pfn(new_spte)); + if (!is_shadow_present_pte(old_spte)) + return false; /* * For the spte updated out of mmu-lock is safe, since -- 2.8.0.rc3.226.g39d4020