From mboxrd@z Thu Jan 1 00:00:00 1970 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 7BD14C369DE for ; Fri, 25 Apr 2025 08:17:42 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 86CA56B0025; Fri, 25 Apr 2025 04:17:37 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 77A0C6B0029; Fri, 25 Apr 2025 04:17:37 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 4204F6B0027; Fri, 25 Apr 2025 04:17:37 -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 165876B0026 for ; Fri, 25 Apr 2025 04:17:37 -0400 (EDT) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay06.hostedemail.com (Postfix) with ESMTP id 05E17B9D07 for ; Fri, 25 Apr 2025 08:17:38 +0000 (UTC) X-FDA: 83371862196.26.935C44D Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by imf19.hostedemail.com (Postfix) with ESMTP id D0BD91A0008 for ; Fri, 25 Apr 2025 08:17:35 +0000 (UTC) Authentication-Results: imf19.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=aKGS12aZ; dmarc=pass (policy=quarantine) header.from=redhat.com; spf=pass (imf19.hostedemail.com: domain of dhildenb@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhildenb@redhat.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1745569055; a=rsa-sha256; cv=none; b=NObkYA87a8d/0GCLuWyjGslI5bVjK9PCbU4ezBE6WQ4Of9B/SqllHYUh45rbwHKcNqMkkf eMlHBiUY0k/uV/4K/phY8zoKyZehfIH0L5lodeK9IXMdGTovaj7LSNasAF0CrIehniu+sS Al35lhoNUY7K3w/h3f3yJ+McPrVumos= ARC-Authentication-Results: i=1; imf19.hostedemail.com; dkim=pass header.d=redhat.com header.s=mimecast20190719 header.b=aKGS12aZ; dmarc=pass (policy=quarantine) header.from=redhat.com; spf=pass (imf19.hostedemail.com: domain of dhildenb@redhat.com designates 170.10.129.124 as permitted sender) smtp.mailfrom=dhildenb@redhat.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1745569055; 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:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=/5qYX4fxmvotPEe9k1Ldxje/is/5r/CwZVYIsI3ib8k=; b=k8SRW7soW/23vCMkLf++5+KRWSq8AUIZYGPXv0pDr4LaYMb39VlPq7jNGKATUVs6rmdpt0 0oSK4PCeDCRGZoxNMR3lxypvbFGI4FB2hv6A6zoKFdzyP72mV238vDIbaEUZMP5aKzKDLc KZIjJoStdnPBNIDbc6FDbEBadVf9WLw= DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1745569055; h=from:from: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:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=/5qYX4fxmvotPEe9k1Ldxje/is/5r/CwZVYIsI3ib8k=; b=aKGS12aZh7ZfLVTcat6RB35n5EfibRiWRMShvXsgEpiVtVwW30nhBqtFPrfYjK7xaslCRr DPL4ijvJu0Dga5+pZvCi33CeigISpF4SNdWTtEsUBfk6NhVM7tjB2l3H8F3qjWbUl1nVjt INZcItjGZsabwxnWohBK7w2vBc/+ork= Received: from mail-wr1-f72.google.com (mail-wr1-f72.google.com [209.85.221.72]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-591-UVJLCOdwNji-qXPliOEvGg-1; Fri, 25 Apr 2025 04:17:31 -0400 X-MC-Unique: UVJLCOdwNji-qXPliOEvGg-1 X-Mimecast-MFC-AGG-ID: UVJLCOdwNji-qXPliOEvGg_1745569051 Received: by mail-wr1-f72.google.com with SMTP id ffacd0b85a97d-3912fe32a30so705684f8f.1 for ; Fri, 25 Apr 2025 01:17:31 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1745569050; x=1746173850; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=/5qYX4fxmvotPEe9k1Ldxje/is/5r/CwZVYIsI3ib8k=; b=eA9Q6312FI09Jee3s7IGRBt7It9h4cnPFxD6HDxubedhadrR5c9l0NfJG2k0l3bfm0 bK7y0/zO+cDNGZQcwagm0UPRj4nwpfDTojT8LvYrQfTsHdSW4tMpZjxVd+Hm7ApPUjYi FKE524rQMPzU8ua+chaOQP+zXfDL+moeW595WXOQ/RfTFyVheVtDZ/jPGBKMAPQ1quy3 QSDXZ3gioZw6IXPGiVGRXpJf7uG9E47K0tGR8vuRsHc1bmELt85olDmErGF8PGSniMQV 1el5d0W77q9bIqVrsh2A8ILL0z2tXR3tPrybTkPcxS8/tolSqnUvX/rNk0mPk6YDcdA+ l3OA== X-Gm-Message-State: AOJu0Yz8gajW1kZaKGMErZUxKob5TSc2iwLr7ChcVkGP4S7bQFztzqsi AMv2oDtCXJon+JgGz/CsXLlArxkCjqLSoFBHF3X0C/dVsVI+vbpItCHEsr/e6FboYWC+lh8owJU tSnB9eLNnBP5/0EOiRpUPqh1+UWjmCmAL66zW8KU65A4lLrll X-Gm-Gg: ASbGncvsP75EOkQI4QPt4Mo1tjfRBIg/L59VEuPYARRFvZ1rM6H73tLLxauK575kWQu RtmxDBT0Z9jtbCPYDhA/LgWsO5knfecJ/VWkWaZJaOYfh9+tdIPVPWXVP5TOPJBfh/gtHj2fnBq eKvrH7N+SuZxKaUIaqYmSSrIRa9VogBJl3QZA/z51dikiwBl6VmC3g+ChEl818lO4hPcf+WMMAW 6gN6C70lQaQInK12bcdAllHjjHd77FezXnWkYzW7XevS+6xrdts8SFWDnkN1Bj4jxtzfQ1V7M+o +VPzaIftWRd7L0HnBc/Q5HJ+saTCXmA4bQ2E4+M/8VLqnNzuss7YIcabwfSv1oeK4AkWIqM= X-Received: by 2002:a5d:5f81:0:b0:391:22a9:4408 with SMTP id ffacd0b85a97d-3a074e1f470mr1107774f8f.16.1745569050530; Fri, 25 Apr 2025 01:17:30 -0700 (PDT) X-Google-Smtp-Source: AGHT+IFJg971aqo8Jp2DD0sLjroPpaq2VGTsTlnda8tdZOkS/zEdxzp9UNRB8QDEhn4HU4OMmpqxNg== X-Received: by 2002:a5d:5f81:0:b0:391:22a9:4408 with SMTP id ffacd0b85a97d-3a074e1f470mr1107731f8f.16.1745569049967; Fri, 25 Apr 2025 01:17:29 -0700 (PDT) Received: from localhost (p200300cbc70f69006c5680f80c146d2a.dip0.t-ipconnect.de. [2003:cb:c70f:6900:6c56:80f8:c14:6d2a]) by smtp.gmail.com with UTF8SMTPSA id ffacd0b85a97d-3a073ca4cbcsm1599884f8f.25.2025.04.25.01.17.28 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 25 Apr 2025 01:17:29 -0700 (PDT) From: David Hildenbrand To: linux-kernel@vger.kernel.org Cc: linux-mm@kvack.org, x86@kernel.org, intel-gfx@lists.freedesktop.org, dri-devel@lists.freedesktop.org, linux-trace-kernel@vger.kernel.org, David Hildenbrand , Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Ingo Molnar , Borislav Petkov , "H. Peter Anvin" , Jani Nikula , Joonas Lahtinen , Rodrigo Vivi , Tvrtko Ursulin , David Airlie , Simona Vetter , Andrew Morton , Steven Rostedt , Masami Hiramatsu , Mathieu Desnoyers , "Liam R. Howlett" , Lorenzo Stoakes , Vlastimil Babka , Jann Horn , Pedro Falcato , Peter Xu Subject: [PATCH v1 05/11] mm: convert VM_PFNMAP tracking to pfnmap_track() + pfnmap_untrack() Date: Fri, 25 Apr 2025 10:17:09 +0200 Message-ID: <20250425081715.1341199-6-david@redhat.com> X-Mailer: git-send-email 2.49.0 In-Reply-To: <20250425081715.1341199-1-david@redhat.com> References: <20250425081715.1341199-1-david@redhat.com> MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: 8vvzY7OAfn9s5HB0qddT_-3VhbLt-54KgOP1H0UVExk_1745569051 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true X-Rspamd-Queue-Id: D0BD91A0008 X-Rspam-User: X-Rspamd-Server: rspam07 X-Stat-Signature: kxt63y8ju7y67b7swb1ab9s5wdfxpzo5 X-HE-Tag: 1745569055-874487 X-HE-Meta: U2FsdGVkX1+a7vcyIw+E54okDRDu0e2FQ4+TFZ2DiFf9XSp08GzzKVagnAWqZlhpbzuueOaCpDCXL/oh5oRW3wFUOLoY8jSedZBEa7rXbkrR5XMnbcTHPtnjOH1i0K4HcMmECAlFBh278AXGOo5GBXcf+ZIf6ILv3ENGjb5VImbomIF6gas9VTloZfeHfXSR19j156BJu33B3ttYtAOcxQ66KMq2ClmYEg8Nd0b/pl5xLMkpfFmvPAp9KYco4PVJlUoFmGZYkhAKOmtvR+aWWTfH0/KNnaxYeN4FGV1uQ2nLZWYzk7eW2zbcNPCaZixiisTSxAxUDLXb0PB3kfyqmCNROuTL8SLnQpRu97fDgK4p+pWqjQPGZpST21+fdG1HxhwHwOWT8MvUI/CeQ72N7tFXgmSWqqSekn2dkboKvH1Zx2orulXy8FfrZWfxtcxyhD1QWnUlYobNXCRIPa1Id0p3hbMDanJaqcbkt7+Er86uHMEHMtmmpvy6LALmBJg9SUGWdcB7Cmd1YfPXrzG6jRKdaujBeesavYWrGYdB7S/WH6ikGk/6w1jD/fdbAxmO3Q/gLf00zaJFl7/EwZg4KTm5i8A24QMMhGc+ryG3pAonjGTI2N8l/ZHTM1sKQvsISM+71Q8GHcAFjVQ7MbYqYAcSu21Jg5+K5sDkpMlvu0i6b1kOOjuQllkYySLs/xdk4wibtr382OLfj3scgSFhh2N5XpNWtlT0dcym4tEK92nQMNZSOISL+ywKpyWugpERcT6haPgkFXH2X4XZt4gARdAnnaThvWL6mkSDun5RnU2iMkTRbyBKu9rsagzxabrbcUQnu9JJXbIV2jvLuCd4U6OY7EgDxjz2n8+Em4HbQk+d9ZwerdCeRvR6jvmWW7CFVdubQqYvg0GhUGigvECJuATp6QGUfWSxcULL5qAkxQ0nq9q4nNlb47rRg9iyGqjHLTL6V3u19yQp8yMTT98 KtPlDn27 malKHF8kbWIWFOuZbPSeSHeXQ8zSUkpVgCyDwGLgTpcHOwzS/PWMJp5dIregOMCnCgrhTPCTNcki8dHkYa3a4dNhwQHSVIsgrdqFdx3HsnvoC9k3ljT3/uRlDfon9l2GNkYc7epCHJmZmaghFMmImnDdTvXUpeuKUhrB9QGw7RpyXZRfu5QxRCWu34puNPlyG6zhFgZ/CdZsx3J4AUcqS1BsZggK6gWIWfoaNu4DU6mxMPu3GnnHeUCd5ayeke+fZ/p80rBx2I5tnl2w5zHJ/QtY6rfiRCYZNpo/iteoc9CMFdInCICXbqgKQfYZt7wWECsvQHcRCOJ2WXlW++wrFd0i1J2+WZSoP28Qf9kBcLBrGbQ+tMuUW62bOzBwd/0l39BboRNB5QYK/cQz135axZ5nlNdU/sCebaTX8j1YQGeNCHQjAFp1CrtmYd/djnjvGG5odHf9NzsQLBfEnWFEAgn8dp72KUPXeuYfB2DRlZ2FPQBnm+TA79HLbugZDAt5ZzfDWwW7+66DH5sUGBcrsdtIAeqXS0ctsreA9 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: List-Subscribe: List-Unsubscribe: Let's use our new interface. In remap_pfn_range(), we'll now decide whether we have to track (full VMA covered) or only sanitize the pgprot (partial VMA covered). Remember what we have to untrack by linking it from the VMA. When duplicating VMAs (e.g., splitting, mremap, fork), we'll handle it similar to anon VMA names, and use a kref to share the tracking. Once the last VMA un-refs our tracking data, we'll do the untracking, which simplifies things a lot and should sort our various issues we saw recently, for example, when partially unmapping/zapping a tracked VMA. This change implies that we'll keep tracking the original PFN range even after splitting + partially unmapping it: not too bad, because it was not working reliably before. The only thing that kind-of worked before was shrinking such a mapping using mremap(): we managed to adjust the reservation in a hacky way, now we won't adjust the reservation but leave it around until all involved VMAs are gone. Signed-off-by: David Hildenbrand --- include/linux/mm_inline.h | 2 + include/linux/mm_types.h | 11 ++++++ kernel/fork.c | 54 ++++++++++++++++++++++++-- mm/memory.c | 81 +++++++++++++++++++++++++++++++-------- mm/mremap.c | 4 -- 5 files changed, 128 insertions(+), 24 deletions(-) diff --git a/include/linux/mm_inline.h b/include/linux/mm_inline.h index f9157a0c42a5c..89b518ff097e6 100644 --- a/include/linux/mm_inline.h +++ b/include/linux/mm_inline.h @@ -447,6 +447,8 @@ static inline bool anon_vma_name_eq(struct anon_vma_name *anon_name1, #endif /* CONFIG_ANON_VMA_NAME */ +void pfnmap_track_ctx_release(struct kref *ref); + static inline void init_tlb_flush_pending(struct mm_struct *mm) { atomic_set(&mm->tlb_flush_pending, 0); diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h index 56d07edd01f91..91124761cfda8 100644 --- a/include/linux/mm_types.h +++ b/include/linux/mm_types.h @@ -764,6 +764,14 @@ struct vma_numab_state { int prev_scan_seq; }; +#ifdef __HAVE_PFNMAP_TRACKING +struct pfnmap_track_ctx { + struct kref kref; + unsigned long pfn; + unsigned long size; +}; +#endif + /* * This struct describes a virtual memory area. There is one of these * per VM-area/task. A VM area is any part of the process virtual memory @@ -877,6 +885,9 @@ struct vm_area_struct { struct anon_vma_name *anon_name; #endif struct vm_userfaultfd_ctx vm_userfaultfd_ctx; +#ifdef __HAVE_PFNMAP_TRACKING + struct pfnmap_track_ctx *pfnmap_track_ctx; +#endif } __randomize_layout; #ifdef CONFIG_NUMA diff --git a/kernel/fork.c b/kernel/fork.c index 168681fc4b25a..ae518b8fe752c 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -481,7 +481,51 @@ static void vm_area_init_from(const struct vm_area_struct *src, #ifdef CONFIG_NUMA dest->vm_policy = src->vm_policy; #endif +#ifdef __HAVE_PFNMAP_TRACKING + dest->pfnmap_track_ctx = NULL; +#endif +} + +#ifdef __HAVE_PFNMAP_TRACKING +static inline int vma_pfnmap_track_ctx_dup(struct vm_area_struct *orig, + struct vm_area_struct *new) +{ + struct pfnmap_track_ctx *ctx = orig->pfnmap_track_ctx; + + if (likely(!ctx)) + return 0; + + /* + * We don't expect to ever hit this. If ever required, we would have + * to duplicate the tracking. + */ + if (unlikely(kref_read(&ctx->kref) >= REFCOUNT_MAX)) + return -ENOMEM; + kref_get(&ctx->kref); + new->pfnmap_track_ctx = ctx; + return 0; +} + +static inline void vma_pfnmap_track_ctx_release(struct vm_area_struct *vma) +{ + struct pfnmap_track_ctx *ctx = vma->pfnmap_track_ctx; + + if (likely(!ctx)) + return; + + kref_put(&ctx->kref, pfnmap_track_ctx_release); + vma->pfnmap_track_ctx = NULL; +} +#else +static inline int vma_pfnmap_track_ctx_dup(struct vm_area_struct *orig, + struct vm_area_struct *new) +{ + return 0; } +static inline void vma_pfnmap_track_ctx_release(struct vm_area_struct *vma) +{ +} +#endif struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) { @@ -493,6 +537,11 @@ struct vm_area_struct *vm_area_dup(struct vm_area_struct *orig) ASSERT_EXCLUSIVE_WRITER(orig->vm_flags); ASSERT_EXCLUSIVE_WRITER(orig->vm_file); vm_area_init_from(orig, new); + + if (vma_pfnmap_track_ctx_dup(orig, new)) { + kmem_cache_free(vm_area_cachep, new); + return NULL; + } vma_lock_init(new, true); INIT_LIST_HEAD(&new->anon_vma_chain); vma_numab_state_init(new); @@ -507,6 +556,7 @@ void vm_area_free(struct vm_area_struct *vma) vma_assert_detached(vma); vma_numab_state_free(vma); free_anon_vma_name(vma); + vma_pfnmap_track_ctx_release(vma); kmem_cache_free(vm_area_cachep, vma); } @@ -669,10 +719,6 @@ static __latent_entropy int dup_mmap(struct mm_struct *mm, if (!tmp) goto fail_nomem; - /* track_pfn_copy() will later take care of copying internal state. */ - if (unlikely(tmp->vm_flags & VM_PFNMAP)) - untrack_pfn_clear(tmp); - retval = vma_dup_policy(mpnt, tmp); if (retval) goto fail_nomem_policy; diff --git a/mm/memory.c b/mm/memory.c index c737a8625866a..eb2b3f10a97ec 100644 --- a/mm/memory.c +++ b/mm/memory.c @@ -1370,7 +1370,7 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) struct mm_struct *dst_mm = dst_vma->vm_mm; struct mm_struct *src_mm = src_vma->vm_mm; struct mmu_notifier_range range; - unsigned long next, pfn = 0; + unsigned long next; bool is_cow; int ret; @@ -1380,12 +1380,6 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) if (is_vm_hugetlb_page(src_vma)) return copy_hugetlb_page_range(dst_mm, src_mm, dst_vma, src_vma); - if (unlikely(src_vma->vm_flags & VM_PFNMAP)) { - ret = track_pfn_copy(dst_vma, src_vma, &pfn); - if (ret) - return ret; - } - /* * We need to invalidate the secondary MMU mappings only when * there could be a permission downgrade on the ptes of the @@ -1427,8 +1421,6 @@ copy_page_range(struct vm_area_struct *dst_vma, struct vm_area_struct *src_vma) raw_write_seqcount_end(&src_mm->write_protect_seq); mmu_notifier_invalidate_range_end(&range); } - if (ret && unlikely(src_vma->vm_flags & VM_PFNMAP)) - untrack_pfn_copy(dst_vma, pfn); return ret; } @@ -1923,9 +1915,6 @@ static void unmap_single_vma(struct mmu_gather *tlb, if (vma->vm_file) uprobe_munmap(vma, start, end); - if (unlikely(vma->vm_flags & VM_PFNMAP)) - untrack_pfn(vma, 0, 0, mm_wr_locked); - if (start != end) { if (unlikely(is_vm_hugetlb_page(vma))) { /* @@ -2871,6 +2860,36 @@ int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long addr, return error; } +#ifdef __HAVE_PFNMAP_TRACKING +static inline struct pfnmap_track_ctx *pfnmap_track_ctx_alloc(unsigned long pfn, + unsigned long size, pgprot_t *prot) +{ + struct pfnmap_track_ctx *ctx; + + if (pfnmap_track(pfn, size, prot)) + return ERR_PTR(-EINVAL); + + ctx = kmalloc(sizeof(*ctx), GFP_KERNEL); + if (unlikely(!ctx)) { + pfnmap_untrack(pfn, size); + return ERR_PTR(-ENOMEM); + } + + ctx->pfn = pfn; + ctx->size = size; + kref_init(&ctx->kref); + return ctx; +} + +void pfnmap_track_ctx_release(struct kref *ref) +{ + struct pfnmap_track_ctx *ctx = container_of(ref, struct pfnmap_track_ctx, kref); + + pfnmap_untrack(ctx->pfn, ctx->size); + kfree(ctx); +} +#endif /* __HAVE_PFNMAP_TRACKING */ + /** * remap_pfn_range - remap kernel memory to userspace * @vma: user vma to map to @@ -2883,20 +2902,50 @@ int remap_pfn_range_notrack(struct vm_area_struct *vma, unsigned long addr, * * Return: %0 on success, negative error code otherwise. */ +#ifdef __HAVE_PFNMAP_TRACKING int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, unsigned long pfn, unsigned long size, pgprot_t prot) { + struct pfnmap_track_ctx *ctx = NULL; int err; - err = track_pfn_remap(vma, &prot, pfn, addr, PAGE_ALIGN(size)); - if (err) + size = PAGE_ALIGN(size); + + /* + * If we cover the full VMA, we'll perform actual tracking, and + * remember to untrack when the last reference to our tracking + * context from a VMA goes away. + * + * If we only cover parts of the VMA, we'll only sanitize the + * pgprot. + */ + if (addr == vma->vm_start && addr + size == vma->vm_end) { + if (vma->pfnmap_track_ctx) + return -EINVAL; + ctx = pfnmap_track_ctx_alloc(pfn, size, &prot); + if (IS_ERR(ctx)) + return PTR_ERR(ctx); + } else if (pfnmap_sanitize_pgprot(pfn, size, &prot)) { return -EINVAL; + } err = remap_pfn_range_notrack(vma, addr, pfn, size, prot); - if (err) - untrack_pfn(vma, pfn, PAGE_ALIGN(size), true); + if (ctx) { + if (err) + kref_put(&ctx->kref, pfnmap_track_ctx_release); + else + vma->pfnmap_track_ctx = ctx; + } return err; } + +#else +int remap_pfn_range(struct vm_area_struct *vma, unsigned long addr, + unsigned long pfn, unsigned long size, pgprot_t prot) +{ + return remap_pfn_range_notrack(vma, addr, pfn, size, prot); +} +#endif EXPORT_SYMBOL(remap_pfn_range); /** diff --git a/mm/mremap.c b/mm/mremap.c index 7db9da609c84f..6e78e02f74bd3 100644 --- a/mm/mremap.c +++ b/mm/mremap.c @@ -1191,10 +1191,6 @@ static int copy_vma_and_data(struct vma_remap_struct *vrm, if (is_vm_hugetlb_page(vma)) clear_vma_resv_huge_pages(vma); - /* Tell pfnmap has moved from this vma */ - if (unlikely(vma->vm_flags & VM_PFNMAP)) - untrack_pfn_clear(vma); - *new_vma_ptr = new_vma; return err; } -- 2.49.0