From patchwork Sat Oct 20 03:15:37 2018 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Junaid Shahid X-Patchwork-Id: 10650251 Return-Path: Received: from mail.wl.linuxfoundation.org (pdx-wl-mail.web.codeaurora.org [172.30.200.125]) by pdx-korg-patchwork-2.web.codeaurora.org (Postfix) with ESMTP id 8298C13A9 for ; Sat, 20 Oct 2018 03:16:16 +0000 (UTC) Received: from mail.wl.linuxfoundation.org (localhost [127.0.0.1]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id 7301E201F5 for ; Sat, 20 Oct 2018 03:16:16 +0000 (UTC) Received: by mail.wl.linuxfoundation.org (Postfix, from userid 486) id 67873205A8; Sat, 20 Oct 2018 03:16:16 +0000 (UTC) X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on pdx-wl-mail.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-15.5 required=2.0 tests=BAYES_00,DKIM_SIGNED, DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI,RCVD_IN_DNSWL_HI, USER_IN_DEF_DKIM_WL autolearn=ham version=3.3.1 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by mail.wl.linuxfoundation.org (Postfix) with ESMTP id D714A201F5 for ; Sat, 20 Oct 2018 03:16:15 +0000 (UTC) Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S1726566AbeJTLZF (ORCPT ); Sat, 20 Oct 2018 07:25:05 -0400 Received: from mail-oi1-f201.google.com ([209.85.167.201]:55292 "EHLO mail-oi1-f201.google.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1726489AbeJTLZF (ORCPT ); Sat, 20 Oct 2018 07:25:05 -0400 Received: by mail-oi1-f201.google.com with SMTP id y68-v6so24473448oie.21 for ; Fri, 19 Oct 2018 20:16:12 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20161025; h=date:in-reply-to:message-id:mime-version:references:subject:from:to :cc; bh=ZCR+kRvKZR626WPQIHDrJftKctTy4XEqFLzojcgbC7E=; b=Arpe383rXkO1KhKQQuMsM83Tu6w/crkRpmKDzAPADHs/ifSO2NXO1EIRaeBe7KyKlb Vg4PvaiM3e5SBVP0au20/KcL2EwPbUM9uv6Iia80yyDdKObDN43q1h1U0UdVcfqua0qx HsEqHJZ//vvurajgGqGby2flnKI/ceX47fsZZD+RnayDOpI5gRg5KkbVTSxdfNUq7C2e +q1amM2n8rwq4wnHyaRkV4HwUw2QIpmfgoggi+PN0bzqQef+DcFfdKsXm5K2Lvx5POa1 W9dyCkPEp7Fh8he1TPX12NjrQAHRUoCHJLQhAYHugvJA9iDoV4MSozgMbO4qjOgcFYsz RAuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20161025; h=x-gm-message-state:date:in-reply-to:message-id:mime-version :references:subject:from:to:cc; bh=ZCR+kRvKZR626WPQIHDrJftKctTy4XEqFLzojcgbC7E=; b=qc0QEXYpa7j4zoVPB//r2HRgkuxPGgcY7608C/MQRbY/8i6Sgtij+1OD9Etda4CwT9 WFIwqtGXannMc/CSbgCtZ65Z5thayEJD6i/B8yb31oac+MXAdy0Jz6ZB9NfO0YGj4b+E 6Isj5boDIa9DvYMZXt/BOCOedNIgpP1ERQihLu4DX8DRDkEgfMaVTirmTcuWCMsMpK1h /tTsJVQKuDn3B4lHCDBGu3ZQFRwAXIIE/6Fir7gE3W6YRkfcoVN33o282S6c0rLJyEpZ EydWFEoQGqEz4OtpZAsNnTZpNgsSRx9bJk50pQxRu1jnXI2trEuNwYN4572aPeuaYQqg hC9w== X-Gm-Message-State: ABuFfohTh/N0I8umCPOu8artZb89pLvMDYMHbcFdXHWf4in8psOYqFqI QmyM1U997dYAYC7wk3sXXJ4NLOxlpcAD X-Google-Smtp-Source: ACcGV61wjJxDSut4QTkB7Cv9bHoeIrbxLAg+YaICgdO1eOxQxXCKcgoe1Obz4M5FqvgypLiNkuwDlnbEGWyn X-Received: by 2002:a9d:3c41:: with SMTP id j1mr29072800ote.12.1540005372520; Fri, 19 Oct 2018 20:16:12 -0700 (PDT) Date: Fri, 19 Oct 2018 20:15:37 -0700 In-Reply-To: <20181020031543.124399-1-junaids@google.com> Message-Id: <20181020031543.124399-5-junaids@google.com> Mime-Version: 1.0 References: <20181020031543.124399-1-junaids@google.com> X-Mailer: git-send-email 2.19.1.568.g152ad8e336-goog Subject: [PATCH 04/10] kvm: mmu: x86: Add dirty bit clearing notification hook From: Junaid Shahid To: pbonzini@redhat.com Cc: kvm@vger.kernel.org, pfeiner@google.com Sender: kvm-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: kvm@vger.kernel.org X-Virus-Scanned: ClamAV using ClamSMTP Add a hook to notify when an SPTE's dirty bit is cleared outside of the dirty logging path. Signed-off-by: Junaid Shahid --- arch/x86/kvm/mmu.c | 42 +++++++++++++++++++++++++----------------- 1 file changed, 25 insertions(+), 17 deletions(-) diff --git a/arch/x86/kvm/mmu.c b/arch/x86/kvm/mmu.c index 0d71a775763e..3162cdd6698c 100644 --- a/arch/x86/kvm/mmu.c +++ b/arch/x86/kvm/mmu.c @@ -701,6 +701,10 @@ static void mmu_spte_set(u64 *sptep, u64 new_spte) __set_spte(sptep, new_spte); } +static void spte_dirty_mask_cleared(struct kvm *kvm, u64 *sptep) +{ +} + /* * Update the SPTE (excluding the PFN), but do not track changes in its * accessed/dirty status. @@ -737,7 +741,7 @@ static u64 mmu_spte_update_no_track(u64 *sptep, u64 new_spte) * * Returns true if the TLB needs to be flushed */ -static bool mmu_spte_update(u64 *sptep, u64 new_spte) +static bool mmu_spte_update(struct kvm *kvm, u64 *sptep, u64 new_spte) { bool flush = false; u64 old_spte = mmu_spte_update_no_track(sptep, new_spte); @@ -767,6 +771,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte) if (is_dirty_spte(old_spte) && !is_dirty_spte(new_spte)) { flush = true; kvm_set_pfn_dirty(spte_to_pfn(old_spte)); + spte_dirty_mask_cleared(kvm, sptep); } return flush; @@ -778,7 +783,7 @@ static bool mmu_spte_update(u64 *sptep, u64 new_spte) * state bits, it is used to clear the last level sptep. * Returns non-zero if the PTE was previously valid. */ -static int mmu_spte_clear_track_bits(u64 *sptep) +static int mmu_spte_clear_track_bits(struct kvm *kvm, u64 *sptep) { kvm_pfn_t pfn; u64 old_spte = *sptep; @@ -803,8 +808,10 @@ static int mmu_spte_clear_track_bits(u64 *sptep) if (is_accessed_spte(old_spte)) kvm_set_pfn_accessed(pfn); - if (is_dirty_spte(old_spte)) + if (is_dirty_spte(old_spte)) { kvm_set_pfn_dirty(pfn); + spte_dirty_mask_cleared(kvm, sptep); + } return 1; } @@ -1301,9 +1308,10 @@ static void __pte_list_remove(u64 *spte, struct kvm_rmap_head *rmap_head) } } -static void pte_list_remove(struct kvm_rmap_head *rmap_head, u64 *sptep) +static void pte_list_remove(struct kvm *kvm, struct kvm_rmap_head *rmap_head, + u64 *sptep) { - mmu_spte_clear_track_bits(sptep); + mmu_spte_clear_track_bits(kvm, sptep); __pte_list_remove(sptep, rmap_head); } @@ -1436,7 +1444,7 @@ static u64 *rmap_get_next(struct rmap_iterator *iter) static void drop_spte(struct kvm *kvm, u64 *sptep) { - if (mmu_spte_clear_track_bits(sptep)) + if (mmu_spte_clear_track_bits(kvm, sptep)) rmap_remove(kvm, sptep); } @@ -1489,7 +1497,7 @@ static bool spte_test_and_clear_writable(u64 *sptep) * * Return true if tlb need be flushed. */ -static bool spte_write_protect(u64 *sptep, bool pt_protect) +static bool spte_write_protect(struct kvm *kvm, u64 *sptep, bool pt_protect) { u64 spte = *sptep; @@ -1501,7 +1509,7 @@ static bool spte_write_protect(u64 *sptep, bool pt_protect) if (pt_protect) { spte &= ~(PT_WRITABLE_MASK | SPTE_MMU_WRITEABLE); - return mmu_spte_update(sptep, spte); + return mmu_spte_update(kvm, sptep, spte); } return spte_test_and_clear_writable(sptep); @@ -1516,7 +1524,7 @@ static bool __rmap_write_protect(struct kvm *kvm, bool flush = false; for_each_rmap_spte(rmap_head, &iter, sptep) - flush |= spte_write_protect(sptep, pt_protect); + flush |= spte_write_protect(kvm, sptep, pt_protect); return flush; } @@ -1568,7 +1576,7 @@ static bool __rmap_test_and_clear_dirty(struct kvm *kvm, return dirty; } -static bool spte_set_dirty(u64 *sptep) +static bool spte_set_dirty(struct kvm *kvm, u64 *sptep) { u64 spte = *sptep; @@ -1576,7 +1584,7 @@ static bool spte_set_dirty(u64 *sptep) spte |= shadow_dirty_mask; - return mmu_spte_update(sptep, spte); + return mmu_spte_update(kvm, sptep, spte); } static bool __rmap_set_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head) @@ -1587,7 +1595,7 @@ static bool __rmap_set_dirty(struct kvm *kvm, struct kvm_rmap_head *rmap_head) for_each_rmap_spte(rmap_head, &iter, sptep) if (spte_ad_enabled(*sptep)) - flush |= spte_set_dirty(sptep); + flush |= spte_set_dirty(kvm, sptep); return flush; } @@ -1723,7 +1731,7 @@ static bool kvm_zap_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head) while ((sptep = rmap_get_first(rmap_head, &iter))) { rmap_printk("%s: spte %p %llx.\n", __func__, sptep, *sptep); - pte_list_remove(rmap_head, sptep); + pte_list_remove(kvm, rmap_head, sptep); flush = true; } @@ -1759,7 +1767,7 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, need_flush = 1; if (pte_write(*ptep)) { - pte_list_remove(rmap_head, sptep); + pte_list_remove(kvm, rmap_head, sptep); goto restart; } else { new_spte = *sptep & ~PT64_BASE_ADDR_MASK; @@ -1770,7 +1778,7 @@ static int kvm_set_pte_rmapp(struct kvm *kvm, struct kvm_rmap_head *rmap_head, new_spte = mark_spte_for_access_track(new_spte); - mmu_spte_clear_track_bits(sptep); + mmu_spte_clear_track_bits(kvm, sptep); mmu_spte_set(sptep, new_spte); } } @@ -2969,7 +2977,7 @@ static int set_spte(struct kvm_vcpu *vcpu, u64 *sptep, spte = mark_spte_for_access_track(spte); set_pte: - if (mmu_spte_update(sptep, spte)) + if (mmu_spte_update(vcpu->kvm, sptep, spte)) ret |= SET_SPTE_NEED_REMOTE_TLB_FLUSH; done: return ret; @@ -5720,7 +5728,7 @@ static bool kvm_mmu_zap_collapsible_spte(struct kvm *kvm, if (sp->role.direct && !kvm_is_reserved_pfn(pfn) && PageTransCompoundMap(pfn_to_page(pfn))) { - pte_list_remove(rmap_head, sptep); + pte_list_remove(kvm, rmap_head, sptep); need_tlb_flush = 1; goto restart; }