From patchwork Fri May 26 23:44:32 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Yu Zhao X-Patchwork-Id: 13257444 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 93A9AC7EE37 for ; Fri, 26 May 2023 23:44:56 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id D2E5D280005; Fri, 26 May 2023 19:44:53 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id CB7D3280001; Fri, 26 May 2023 19:44:53 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id B587E280005; Fri, 26 May 2023 19:44:53 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0012.hostedemail.com [216.40.44.12]) by kanga.kvack.org (Postfix) with ESMTP id A90AE280001 for ; Fri, 26 May 2023 19:44:53 -0400 (EDT) Received: from smtpin11.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay01.hostedemail.com (Postfix) with ESMTP id 83F641C7EF5 for ; Fri, 26 May 2023 23:44:53 +0000 (UTC) X-FDA: 80834038866.11.EB0B97A Received: from mail-yb1-f202.google.com (mail-yb1-f202.google.com [209.85.219.202]) by imf27.hostedemail.com (Postfix) with ESMTP id C6C2340002 for ; Fri, 26 May 2023 23:44:51 +0000 (UTC) Authentication-Results: imf27.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=k8BERP9A; spf=pass (imf27.hostedemail.com: domain of 3ckRxZAYKCOkjfkSLZRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--yuzhao.bounces.google.com designates 209.85.219.202 as permitted sender) smtp.mailfrom=3ckRxZAYKCOkjfkSLZRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--yuzhao.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1685144691; a=rsa-sha256; cv=none; b=FKhb5+QFgF8b0WBUbkouYW4DTsEiQLpOUgFSFeAvTXYfOmHA9EKO9o3hPj1ljcFFf0uKJw oUCZknVXR47bwEuL5uC1QaIBdpBjMFX3tEtqGB9tT8j8cxikxx23kCobpeVH3hmt/JMxVE qyXEeGeNwQlpRI2XrDaeftMPJmUjmzk= ARC-Authentication-Results: i=1; imf27.hostedemail.com; dkim=pass header.d=google.com header.s=20221208 header.b=k8BERP9A; spf=pass (imf27.hostedemail.com: domain of 3ckRxZAYKCOkjfkSLZRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--yuzhao.bounces.google.com designates 209.85.219.202 as permitted sender) smtp.mailfrom=3ckRxZAYKCOkjfkSLZRZZRWP.NZXWTYfi-XXVgLNV.ZcR@flex--yuzhao.bounces.google.com; dmarc=pass (policy=reject) header.from=google.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1685144691; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=SAnqMQmXLaJfeZI+VeXqIwvB0doaLL+gp8U5/HUId5I=; b=4BLJuD+qnpvdMqkXGRkRz56J4DW6G7YwZgDwQP0w0M4rA5WrKbhFsNaHxEP5zwE2qa1KDE Iy+wpt1VajCDH7ECXKlKwVTRGVCljVv6c8An5IoYA36IjGptqYiMiC/ShejdhFounUXtz0 OeIovAn5a+xf5lY8XP7+2izSZq9ZiO4= Received: by mail-yb1-f202.google.com with SMTP id 3f1490d57ef6-bacd408046cso2802351276.3 for ; Fri, 26 May 2023 16:44:51 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=google.com; s=20221208; t=1685144691; x=1687736691; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:from:to:cc:subject:date:message-id:reply-to; bh=SAnqMQmXLaJfeZI+VeXqIwvB0doaLL+gp8U5/HUId5I=; b=k8BERP9A+6Uiw+Uaig20mMncTvjKAsRCKq+HC63zo5f14BiSqxPWFPVFrxvd4dUkfQ bKRY2Xn6Sj5cpDeqFqXaOaTxVBSBg6TnHG9z0eetRbywYU3ie/H8/CJOp1+Ez2wWWiIG CY1cPbCWNOAs/19D6iZC6kEHwAF0m7RMLVET0mpluU6zBeVTNhcDLR1hhBJpslaBZ/Nm 0fQXpAKGqnmpqrKCUVaNiYpgSsJF+6ODE5plgt1dvul/aWCITvYKB/5mkPp/iio/HINg 59adq2fXr8dYaO8RPmc4VSfW2nQVaqhTR9xX4O6C0F0j/4E6MdCu9N0KSqKFRTup9DJ6 82/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20221208; t=1685144691; x=1687736691; h=cc:to:from:subject:references:mime-version:message-id:in-reply-to :date:x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=SAnqMQmXLaJfeZI+VeXqIwvB0doaLL+gp8U5/HUId5I=; b=Q+g3fMYyEouYSdH8eKs0a2BiAhHg5UeihnL/xVmYDDly7pUZv4C7/q43r5vQ8N0ADa Rm6pwbTO5MZVb9JQiqbYH6sSXl/NhMUupQSkAVeAbKlBardPC1/HCe8vftpXAW9PXtLv DAlfODM2qA0gcrE7Ohaj26VzALA09vZadfk+7lw+k2FOiLGVnIFLPZSUC4U0Q7Dj7hLk ZW3Deiuf6f7ZPr+Qa6vigD+tEVBl9Yi04JjB172jQsay2xUijmJA9deidD80DwFwIua/ hHZ4YaAl8n0MF3U7Fj/mjCXZI1h0TRby23YlFRl9tnRwfBT1rrZqyGDZQqQmSRjZfwJ/ y7yg== X-Gm-Message-State: AC+VfDw3ApYOQZvToug9IX5mGSkT7WY4wN9Go9HwN+hdo1XYccFHfgYH Ksl1dl2pnwlHRX3Hh3JxKLBknNMRDeQ= X-Google-Smtp-Source: ACHHUZ56f5xRS5UFm0fGZF6KKL2sEC5mGRlgoj/Qp341qhbzjJy6m3cfCKx+HZdIQ3EgPejfKdLHbTHVxEI= X-Received: from yuzhao.bld.corp.google.com ([2620:15c:183:200:910f:8a15:592b:2087]) (user=yuzhao job=sendgmr) by 2002:a25:8211:0:b0:ba6:e7ee:bb99 with SMTP id q17-20020a258211000000b00ba6e7eebb99mr1850590ybk.12.1685144690927; Fri, 26 May 2023 16:44:50 -0700 (PDT) Date: Fri, 26 May 2023 17:44:32 -0600 In-Reply-To: <20230526234435.662652-1-yuzhao@google.com> Message-Id: <20230526234435.662652-8-yuzhao@google.com> Mime-Version: 1.0 References: <20230526234435.662652-1-yuzhao@google.com> X-Mailer: git-send-email 2.41.0.rc0.172.g3f132b7071-goog Subject: [PATCH mm-unstable v2 07/10] kvm/powerpc: add kvm_arch_test_clear_young() From: Yu Zhao To: Andrew Morton , Paolo Bonzini Cc: Alistair Popple , Anup Patel , Ben Gardon , Borislav Petkov , Catalin Marinas , Chao Peng , Christophe Leroy , Dave Hansen , Fabiano Rosas , Gaosheng Cui , Gavin Shan , "H. Peter Anvin" , Ingo Molnar , James Morse , "Jason A. Donenfeld" , Jason Gunthorpe , Jonathan Corbet , Marc Zyngier , Masami Hiramatsu , Michael Ellerman , Michael Larabel , Mike Rapoport , Nicholas Piggin , Oliver Upton , Paul Mackerras , Peter Xu , Sean Christopherson , Steven Rostedt , Suzuki K Poulose , Thomas Gleixner , Thomas Huth , Will Deacon , Zenghui Yu , kvmarm@lists.linux.dev, kvm@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linux-doc@vger.kernel.org, linux-kernel@vger.kernel.org, linux-mm@kvack.org, linuxppc-dev@lists.ozlabs.org, linux-trace-kernel@vger.kernel.org, x86@kernel.org, linux-mm@google.com, Yu Zhao X-Rspamd-Server: rspam08 X-Rspamd-Queue-Id: C6C2340002 X-Stat-Signature: cdxxaoyoxm76dwie77o4ts8x6bi48i9a X-Rspam-User: X-HE-Tag: 1685144691-364560 X-HE-Meta: U2FsdGVkX18GzbxuDbWe7srPA+KMXKzipcfHatE+b2HnpVs8UZ5HShNc15tMjFjqrRQjwY3Q4W9amEVNwVJZkKxsmC7SSbyhlfFhTTGedzIWRVR56nf0QRQpram0DlN4iCAE7kU5/CkrVVhLmMrOJ1hxH8NJ9/sHu1ytuj7nmj0AXR4ieAxSVMyI9yRvc3t417dfly+glMyS0uqauQbCmtNGin1bEyo0uUIgeeD9Y9K25494mTjxEItx5uJvENYOZsXabV8TYML0ugaRne1Gf1KNYVXDRQwit/6yMPZrhC/VufZprY/S2XXivQgXLwBLDrcRzsD4zFV2w3xNMenk8NlwlKjUyk0L1PZBq7MoSGAfxe3QUZiCna2cHX5JVMvmMl0uoWvnuyTJWP3i0nhJFFgyBEXxanPeTkgCTAvM0UovsyKX6CxV9bQURPWLaxvpV0qTkInpoK/OuTXacwRhUpB4A5yDLYzFaSSCersOldzZjuunQ2qa+zaf4r2jBXIiNGD2UPlhhD4k3BVnnb6nxDKYTQAca9v9iP9e9UrjeYfvFe3VVkZDZY8tYqQCW1RCdoKhdapj+4RQ5MS5jNEel5UXWuVaCaVae37xJbauPlVe4t4wclnw2tyWPAEAmrGYUgJ8pxekE7JbX/esBL653lnDfagLvKoHwuNV1dDa7grvECvFnSfH46wVSfPQmGoiM5lKkG1/fmq7nmmJkT+1jBQrZlbMJWYJdEiX3QgJmncg+6kop1kadc+6diiDiJAe+vNmWUnDSgS+k+rLRokfW/AxDSaQ3IEv0JLNlfPJUNSi3Hg5Ndhf5zL3+bh0p1cqcKpGPq5wiWjJoLdtSBHsfJ16Bvy9esq4XQgQ6UmiCN/80QgfprzuV4lUTDidXi2sPi3g6yEBAbyUWxyw2a21ijVCiEQ1xr+pkzrkXQeChGiIjLWVPmuCqm9njScaHLb8o/dJ6roNKTrq8n9m95k x72ki8P6 Cmm8FybulAYe5RutEvBXsfeFSZqNsBUZ8bdi3vKO1W0DMXV4L2laFL/VPEjMQrx/r6z83K66Cz0sQ5Qca4eTtXyzyrgdaaIFa8TdsaJNe3qkqq9S9NKJUY9J1jEMf1xaSF1X/MZ0USwrjkDAyWiIYnXiQssh7o9BdAKjq4u9IlWA4yic19jTmjRIY4AaiAQblJx0rXFY3DbEfKwBtPjldX7SpJ3WXDSU3HurpcKyLIga8+5mDtz448yg8Yu9tcb+Hsi96zL1BDsuF345j0ARyO1TZiOJF5uOhrPGLADLZqShmJoyIYx6vn/He1EdWSJNyUaS9jWXZP9j0dmRxqG//gjOVdpdBr+TN1G7kc11LcajEhepvAYeho1Hh9bfuHEy5ogpalSgFcmB/QO3St0IBk0LPij0S9bXHAYhtDEknHDn4aoKQAMYgrFERWGTnB+rG5Zn5iY3yh/Hqz5f99jL7C6mlt9WItpAeHjS0jxR1xN7irenQiBAwvKCK4uztfTOIZsWSXY0hqoy6TBXi32HybUZyNUB2ATtYKHovnRRREm96iJnt4P6VPsyOR8Dnh87jUMK8zUn/oYuLwqT4A00zsdyFhKp6m7tNwLOTtFTGytwZg90JmftwTJ5ODpn7RfUboR5XDNqL6UQRxIKipuZM86z4XA== X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: Implement kvm_arch_test_clear_young() to support the fast path in mmu_notifier_ops->test_clear_young(). It focuses on a simple case, i.e., radix MMU sets the accessed bit in KVM PTEs and VMs are not nested, where it can rely on RCU and pte_xchg() to safely clear the accessed bit without taking kvm->mmu_lock. Complex cases fall back to the existing slow path where kvm->mmu_lock is then taken. Signed-off-by: Yu Zhao --- arch/powerpc/include/asm/kvm_host.h | 8 ++++ arch/powerpc/include/asm/kvm_ppc.h | 1 + arch/powerpc/kvm/book3s.c | 6 +++ arch/powerpc/kvm/book3s.h | 1 + arch/powerpc/kvm/book3s_64_mmu_radix.c | 59 ++++++++++++++++++++++++++ arch/powerpc/kvm/book3s_hv.c | 5 +++ 6 files changed, 80 insertions(+) diff --git a/arch/powerpc/include/asm/kvm_host.h b/arch/powerpc/include/asm/kvm_host.h index 14ee0dece853..75c260ea8a9e 100644 --- a/arch/powerpc/include/asm/kvm_host.h +++ b/arch/powerpc/include/asm/kvm_host.h @@ -883,4 +883,12 @@ static inline void kvm_arch_sched_in(struct kvm_vcpu *vcpu, int cpu) {} static inline void kvm_arch_vcpu_blocking(struct kvm_vcpu *vcpu) {} static inline void kvm_arch_vcpu_unblocking(struct kvm_vcpu *vcpu) {} +#define kvm_arch_has_test_clear_young kvm_arch_has_test_clear_young +static inline bool kvm_arch_has_test_clear_young(void) +{ + return IS_ENABLED(CONFIG_KVM_BOOK3S_HV_POSSIBLE) && + cpu_has_feature(CPU_FTR_HVMODE) && cpu_has_feature(CPU_FTR_ARCH_300) && + radix_enabled(); +} + #endif /* __POWERPC_KVM_HOST_H__ */ diff --git a/arch/powerpc/include/asm/kvm_ppc.h b/arch/powerpc/include/asm/kvm_ppc.h index 79a9c0bb8bba..ff1af6a7b44f 100644 --- a/arch/powerpc/include/asm/kvm_ppc.h +++ b/arch/powerpc/include/asm/kvm_ppc.h @@ -287,6 +287,7 @@ struct kvmppc_ops { bool (*unmap_gfn_range)(struct kvm *kvm, struct kvm_gfn_range *range); bool (*age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range); bool (*test_age_gfn)(struct kvm *kvm, struct kvm_gfn_range *range); + bool (*test_clear_young)(struct kvm *kvm, struct kvm_gfn_range *range); bool (*set_spte_gfn)(struct kvm *kvm, struct kvm_gfn_range *range); void (*free_memslot)(struct kvm_memory_slot *slot); int (*init_vm)(struct kvm *kvm); diff --git a/arch/powerpc/kvm/book3s.c b/arch/powerpc/kvm/book3s.c index 686d8d9eda3e..37bf40b0c4ff 100644 --- a/arch/powerpc/kvm/book3s.c +++ b/arch/powerpc/kvm/book3s.c @@ -899,6 +899,12 @@ bool kvm_test_age_gfn(struct kvm *kvm, struct kvm_gfn_range *range) return kvm->arch.kvm_ops->test_age_gfn(kvm, range); } +bool kvm_arch_test_clear_young(struct kvm *kvm, struct kvm_gfn_range *range) +{ + return !kvm->arch.kvm_ops->test_clear_young || + kvm->arch.kvm_ops->test_clear_young(kvm, range); +} + bool kvm_set_spte_gfn(struct kvm *kvm, struct kvm_gfn_range *range) { return kvm->arch.kvm_ops->set_spte_gfn(kvm, range); diff --git a/arch/powerpc/kvm/book3s.h b/arch/powerpc/kvm/book3s.h index 58391b4b32ed..fa2659e21ccc 100644 --- a/arch/powerpc/kvm/book3s.h +++ b/arch/powerpc/kvm/book3s.h @@ -12,6 +12,7 @@ extern void kvmppc_core_flush_memslot_hv(struct kvm *kvm, extern bool kvm_unmap_gfn_range_hv(struct kvm *kvm, struct kvm_gfn_range *range); extern bool kvm_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range); extern bool kvm_test_age_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range); +extern bool kvm_test_clear_young_hv(struct kvm *kvm, struct kvm_gfn_range *range); extern bool kvm_set_spte_gfn_hv(struct kvm *kvm, struct kvm_gfn_range *range); extern int kvmppc_mmu_init_pr(struct kvm_vcpu *vcpu); diff --git a/arch/powerpc/kvm/book3s_64_mmu_radix.c b/arch/powerpc/kvm/book3s_64_mmu_radix.c index 3b65b3b11041..0a392e9a100a 100644 --- a/arch/powerpc/kvm/book3s_64_mmu_radix.c +++ b/arch/powerpc/kvm/book3s_64_mmu_radix.c @@ -1088,6 +1088,65 @@ bool kvm_test_age_radix(struct kvm *kvm, struct kvm_memory_slot *memslot, return ref; } +bool kvm_test_clear_young_hv(struct kvm *kvm, struct kvm_gfn_range *range) +{ + bool err; + gfn_t gfn = range->start; + + rcu_read_lock(); + + err = !kvm_is_radix(kvm); + if (err) + goto unlock; + + /* + * Case 1: This function kvmppc_switch_mmu_to_hpt() + * + * rcu_read_lock() + * Test kvm_is_radix() kvm->arch.radix = 0 + * Use kvm->arch.pgtable synchronize_rcu() + * rcu_read_unlock() + * kvmppc_free_radix() + * + * + * Case 2: This function kvmppc_switch_mmu_to_radix() + * + * kvmppc_init_vm_radix() + * smp_wmb() + * Test kvm_is_radix() kvm->arch.radix = 1 + * smp_rmb() + * Use kvm->arch.pgtable + */ + smp_rmb(); + + while (gfn < range->end) { + pte_t *ptep; + pte_t old, new; + unsigned int shift; + + ptep = find_kvm_secondary_pte_unlocked(kvm, gfn * PAGE_SIZE, &shift); + if (!ptep) + goto next; + + VM_WARN_ON_ONCE(!page_count(virt_to_page(ptep))); + + old = READ_ONCE(*ptep); + if (!pte_present(old) || !pte_young(old)) + goto next; + + new = pte_mkold(old); + + if (kvm_should_clear_young(range, gfn)) + pte_xchg(ptep, old, new); +next: + gfn += shift ? BIT(shift - PAGE_SHIFT) : 1; + } +unlock: + rcu_read_unlock(); + + return err; +} + /* Returns the number of PAGE_SIZE pages that are dirty */ static int kvm_radix_test_clear_dirty(struct kvm *kvm, struct kvm_memory_slot *memslot, int pagenum) diff --git a/arch/powerpc/kvm/book3s_hv.c b/arch/powerpc/kvm/book3s_hv.c index 130bafdb1430..20a81ec9fde8 100644 --- a/arch/powerpc/kvm/book3s_hv.c +++ b/arch/powerpc/kvm/book3s_hv.c @@ -5262,6 +5262,8 @@ int kvmppc_switch_mmu_to_hpt(struct kvm *kvm) spin_lock(&kvm->mmu_lock); kvm->arch.radix = 0; spin_unlock(&kvm->mmu_lock); + /* see the comments in kvm_test_clear_young_hv() */ + synchronize_rcu(); kvmppc_free_radix(kvm); lpcr = LPCR_VPM1; @@ -5286,6 +5288,8 @@ int kvmppc_switch_mmu_to_radix(struct kvm *kvm) if (err) return err; kvmppc_rmap_reset(kvm); + /* see the comments in kvm_test_clear_young_hv() */ + smp_wmb(); /* Mutual exclusion with kvm_unmap_gfn_range etc. */ spin_lock(&kvm->mmu_lock); kvm->arch.radix = 1; @@ -6185,6 +6189,7 @@ static struct kvmppc_ops kvm_ops_hv = { .unmap_gfn_range = kvm_unmap_gfn_range_hv, .age_gfn = kvm_age_gfn_hv, .test_age_gfn = kvm_test_age_gfn_hv, + .test_clear_young = kvm_test_clear_young_hv, .set_spte_gfn = kvm_set_spte_gfn_hv, .free_memslot = kvmppc_core_free_memslot_hv, .init_vm = kvmppc_core_init_vm_hv,