From patchwork Sat Jul 29 01:35:24 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Sean Christopherson X-Patchwork-Id: 128040 Return-Path: Delivered-To: ouuuleilei@gmail.com Received: by 2002:a59:918b:0:b0:3e4:2afc:c1 with SMTP id s11csp902874vqg; Sat, 29 Jul 2023 00:48:26 -0700 (PDT) X-Google-Smtp-Source: APBJJlEUSXNDRLBiTPQwUiqe094OhnQTCrNzGyMlKxnPn6wId8VG3ekfFrVS8/2kWy7bZwiCy+/7 X-Received: by 2002:a17:90a:de90:b0:267:f5d1:1dd3 with SMTP id n16-20020a17090ade9000b00267f5d11dd3mr3523071pjv.11.1690616905987; Sat, 29 Jul 2023 00:48:25 -0700 (PDT) ARC-Seal: i=1; a=rsa-sha256; t=1690616905; cv=none; d=google.com; s=arc-20160816; b=RDxGK2SH1qI8EliX7z32Mm2cZCXGaFOA2J0id5fYPaktGCLDlkXdEAsFjnUtoOd39W hOC/Zpq58sdJsr4nvIeA5gnYDmvhCtWlL49XacDbH5su3YDXqLcW3lhHnJ0E0C8GBXvD pU3/0ncegNPI0LjYd/Z72R0f6tXXWsP52wsgNzYrwRczlggvHSSTv6SDcA0IRzCeMShs 5P+zkfgZv5+GMGZOL2KcPGgqurLe+mmfMi7NPVb25R4ZrBxKI42MSjm+W4akpBt9kAwN ix0aWKdC2xStS9jlu1d2ATCMMsuzIxOrEMyEfrHtegeMkt7CEu4wMMeICqcOjAULdIKi grpA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=arc-20160816; h=list-id:precedence:cc:to:from:subject:message-id:references :mime-version:in-reply-to:date:reply-to:dkim-signature; bh=XilozmZkv3qT4uvOk9OGfExlIfdE0xODj7rqa2Bh8PM=; fh=J37Q4aKtoxdyy+p3BpF2uV3z0maXFfn3A5M61jlSlO0=; b=VaTUETnzWf/wEkjyP3Phai4Uh00VQN4Wn8kzXT7WIKM+6CkgPbML/b7TyzD0trYPAu rUnZt2sfxqOTByuKlKkHKyjzRltUuDuSXrlA2Wl/qr9jYrQNJVByx+n4REwslA4MS90T hm0UNMAR6QHZjfq1H3nMzdIKNpXi4lwAtBdqj0WPJxcHH5VJ+6SABMQZyRRmY+kvM/ex HtdAvoICFy/9s3vNtcijwTIOOnvh3q+i1kynzNln63SmF73A2mIQdTtqKNcwKB5wQaym giQJMJ2yqwquRxlgMOzrIGA4EXOIJLYyygyD5fmt/GtW0TASqV/O0JqM2nMX8YcvDlTA W3Cw== ARC-Authentication-Results: i=1; mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=hO+4fiF1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: from out1.vger.email (out1.vger.email. [2620:137:e000::1:20]) by mx.google.com with ESMTP id ob13-20020a17090b390d00b002675d988010si4422814pjb.91.2023.07.29.00.48.13; Sat, 29 Jul 2023 00:48:25 -0700 (PDT) Received-SPF: pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) client-ip=2620:137:e000::1:20; Authentication-Results: mx.google.com; dkim=pass header.i=@google.com header.s=20221208 header.b=hO+4fiF1; spf=pass (google.com: domain of linux-kernel-owner@vger.kernel.org designates 2620:137:e000::1:20 as permitted sender) smtp.mailfrom=linux-kernel-owner@vger.kernel.org; dmarc=pass (p=REJECT sp=REJECT dis=NONE) header.from=google.com Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S237648AbjG2Bh4 (ORCPT + 99 others); Fri, 28 Jul 2023 21:37:56 -0400 Received: from lindbergh.monkeyblade.net ([23.128.96.19]:47628 "EHLO lindbergh.monkeyblade.net" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S237641AbjG2Bh3 (ORCPT ); Fri, 28 Jul 2023 21:37:29 -0400 Received: from mail-yb1-xb49.google.com (mail-yb1-xb49.google.com [IPv6:2607:f8b0:4864:20::b49]) by lindbergh.monkeyblade.net (Postfix) with ESMTPS id 9A67C5244 for ; Fri, 28 Jul 2023 18:37:07 -0700 (PDT) Received: by mail-yb1-xb49.google.com with SMTP id 3f1490d57ef6-d063bd0bae8so2556409276.0 for ; Fri, 28 Jul 2023 18:37:07 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1690594579; x=1691199379; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:from:to:cc:subject:date:message-id:reply-to; bh=XilozmZkv3qT4uvOk9OGfExlIfdE0xODj7rqa2Bh8PM=; b=hO+4fiF1fkHnVD3UtJj0dyBOtLlEfJYvUvCIOLPoBwDENVolx+BkFi91s6HNCqGH+j btF/f+3/6aZZs711i2sxid1ZXbFkwyF9VUwB5BnTZ9cTQHcX3D9mXN3x42LvCtn3cpy7 0h82vDAJxNZQqiQjV29unyyftMYVH15pLRpV3MwOAUnrpchjL9e6b9Cm9kikbVKI29UH alm0EEIP5+Ul5poFOocf7Haz6qYJe6L80hnqP7PX07ohKA11ufDJLc2sIFgWCTKKZe2p bAVrpvUfXDZekQdfVf4BXGh56pVVZMRFZNbCb0h4jH9pAngMRbqvuqVgOgF7pU6SxXBj ivfA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1690594579; x=1691199379; h=cc:to:from:subject:message-id:references:mime-version:in-reply-to :date:reply-to:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=XilozmZkv3qT4uvOk9OGfExlIfdE0xODj7rqa2Bh8PM=; b=Pqv1DGd+rr1lEzYTgksRIJjDwMk3vKxn5TnjIb/eCNnR3sE7bAmu6kRcKPH/GaYAI5 7DijELtgEXL4neRxLFFLKay7rWjlMbux0MzfaoeozyUX9w3P8GQ9SHi34rUDl3WUhCwc gOLiNm5JafNypsZcTuM5Wl5ajX2qzdSPV8BZP8FAYKnQ5OyuWp1sC5xLWbPy5q2IQ4aq GAkEovB39q5klD0lkm0OU+FIlKPVTu8E/GVT5sPpln7CnLklNwMYcaCM4uHTQc0wKIJU X05pQutQEsHehclKGJ8kU2sscQaZzz+ENFxZYAAAKm871CgmW4dzIa/AO7U9JkdBpzIk GsjA== X-Gm-Message-State: ABy/qLa6Sw7z7ZSaGcHbXIPa7vJM3plBNotUUxkH/Io+N7Wd7Iz/u8Lr 7KcskYFCycaIrWaKfqJib8y7Tuu4+aI= X-Received: from zagreus.c.googlers.com ([fda3:e722:ac3:cc00:7f:e700:c0a8:5c37]) (user=seanjc job=sendgmr) by 2002:a25:69c7:0:b0:d07:f1ed:521a with SMTP id e190-20020a2569c7000000b00d07f1ed521amr18224ybc.4.1690594578971; Fri, 28 Jul 2023 18:36:18 -0700 (PDT) Reply-To: Sean Christopherson Date: Fri, 28 Jul 2023 18:35:24 -0700 In-Reply-To: <20230729013535.1070024-1-seanjc@google.com> Mime-Version: 1.0 References: <20230729013535.1070024-1-seanjc@google.com> X-Mailer: git-send-email 2.41.0.487.g6d72f3e995-goog Message-ID: <20230729013535.1070024-19-seanjc@google.com> Subject: [PATCH v4 18/29] KVM: x86: Add a new page-track hook to handle memslot deletion From: Sean Christopherson To: Sean Christopherson , Paolo Bonzini , Zhenyu Wang , Zhi Wang Cc: kvm@vger.kernel.org, intel-gvt-dev@lists.freedesktop.org, intel-gfx@lists.freedesktop.org, linux-kernel@vger.kernel.org, Yan Zhao , Yongwei Ma , Ben Gardon X-Spam-Status: No, score=-9.6 required=5.0 tests=BAYES_00,DKIMWL_WL_MED, DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,DKIM_VALID_EF,RCVD_IN_DNSWL_NONE, SPF_HELO_NONE,SPF_PASS,T_SCC_BODY_TEXT_LINE,USER_IN_DEF_DKIM_WL autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on lindbergh.monkeyblade.net Precedence: bulk List-ID: X-Mailing-List: linux-kernel@vger.kernel.org X-getmail-retrieved-from-mailbox: INBOX X-GMAIL-THRID: 1772740312746152296 X-GMAIL-MSGID: 1772740312746152296 From: Yan Zhao Add a new page-track hook, track_remove_region(), that is called when a memslot DELETE operation is about to be committed. The "remove" hook will be used by KVMGT and will effectively replace the existing track_flush_slot() altogether now that KVM itself doesn't rely on the "flush" hook either. The "flush" hook is flawed as it's invoked before the memslot operation is guaranteed to succeed, i.e. KVM might ultimately keep the existing memslot without notifying external page track users, a.k.a. KVMGT. In practice, this can't currently happen on x86, but there are no guarantees that won't change in the future, not to mention that "flush" does a very poor job of describing what is happening. Pass in the gfn+nr_pages instead of the slot itself so external users, i.e. KVMGT, don't need to exposed to KVM internals (memslots). This will help set the stage for additional cleanups to the page-track APIs. Opportunistically align the existing srcu_read_lock_held() usage so that the new case doesn't stand out like a sore thumb (and not aligning the new code makes bots unhappy). Cc: Zhenyu Wang Tested-by: Yongwei Ma Signed-off-by: Yan Zhao Co-developed-by: Sean Christopherson Signed-off-by: Sean Christopherson --- arch/x86/include/asm/kvm_page_track.h | 12 ++++++++++++ arch/x86/kvm/mmu/page_track.c | 27 +++++++++++++++++++++++++-- arch/x86/kvm/x86.c | 3 +++ 3 files changed, 40 insertions(+), 2 deletions(-) diff --git a/arch/x86/include/asm/kvm_page_track.h b/arch/x86/include/asm/kvm_page_track.h index f744682648e7..cfd36c22b467 100644 --- a/arch/x86/include/asm/kvm_page_track.h +++ b/arch/x86/include/asm/kvm_page_track.h @@ -43,6 +43,17 @@ struct kvm_page_track_notifier_node { */ void (*track_flush_slot)(struct kvm *kvm, struct kvm_memory_slot *slot, struct kvm_page_track_notifier_node *node); + + /* + * Invoked when a memory region is removed from the guest. Or in KVM + * terms, when a memslot is deleted. + * + * @gfn: base gfn of the region being removed + * @nr_pages: number of pages in the to-be-removed region + * @node: this node + */ + void (*track_remove_region)(gfn_t gfn, unsigned long nr_pages, + struct kvm_page_track_notifier_node *node); }; int kvm_page_track_init(struct kvm *kvm); @@ -75,6 +86,7 @@ kvm_page_track_unregister_notifier(struct kvm *kvm, void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, int bytes); void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot); +void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot); bool kvm_page_track_has_external_user(struct kvm *kvm); diff --git a/arch/x86/kvm/mmu/page_track.c b/arch/x86/kvm/mmu/page_track.c index e6de9638e560..d971c28be99d 100644 --- a/arch/x86/kvm/mmu/page_track.c +++ b/arch/x86/kvm/mmu/page_track.c @@ -270,7 +270,7 @@ void kvm_page_track_write(struct kvm_vcpu *vcpu, gpa_t gpa, const u8 *new, idx = srcu_read_lock(&head->track_srcu); hlist_for_each_entry_srcu(n, &head->track_notifier_list, node, - srcu_read_lock_held(&head->track_srcu)) + srcu_read_lock_held(&head->track_srcu)) if (n->track_write) n->track_write(gpa, new, bytes, n); srcu_read_unlock(&head->track_srcu, idx); @@ -298,12 +298,35 @@ void kvm_page_track_flush_slot(struct kvm *kvm, struct kvm_memory_slot *slot) idx = srcu_read_lock(&head->track_srcu); hlist_for_each_entry_srcu(n, &head->track_notifier_list, node, - srcu_read_lock_held(&head->track_srcu)) + srcu_read_lock_held(&head->track_srcu)) if (n->track_flush_slot) n->track_flush_slot(kvm, slot, n); srcu_read_unlock(&head->track_srcu, idx); } +/* + * Notify external page track nodes that a memory region is being removed from + * the VM, e.g. so that users can free any associated metadata. + */ +void kvm_page_track_delete_slot(struct kvm *kvm, struct kvm_memory_slot *slot) +{ + struct kvm_page_track_notifier_head *head; + struct kvm_page_track_notifier_node *n; + int idx; + + head = &kvm->arch.track_notifier_head; + + if (hlist_empty(&head->track_notifier_list)) + return; + + idx = srcu_read_lock(&head->track_srcu); + hlist_for_each_entry_srcu(n, &head->track_notifier_list, node, + srcu_read_lock_held(&head->track_srcu)) + if (n->track_remove_region) + n->track_remove_region(slot->base_gfn, slot->npages, n); + srcu_read_unlock(&head->track_srcu, idx); +} + bool kvm_page_track_has_external_user(struct kvm *kvm) { return hlist_empty(&kvm->arch.track_notifier_head.track_notifier_list); diff --git a/arch/x86/kvm/x86.c b/arch/x86/kvm/x86.c index 4394bb49051f..e9ecdf5fbdac 100644 --- a/arch/x86/kvm/x86.c +++ b/arch/x86/kvm/x86.c @@ -12767,6 +12767,9 @@ void kvm_arch_commit_memory_region(struct kvm *kvm, const struct kvm_memory_slot *new, enum kvm_mr_change change) { + if (change == KVM_MR_DELETE) + kvm_page_track_delete_slot(kvm, old); + if (!kvm->arch.n_requested_mmu_pages && (change == KVM_MR_CREATE || change == KVM_MR_DELETE)) { unsigned long nr_mmu_pages;