From patchwork Mon Feb 17 14:04:15 2025 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ryan Roberts X-Patchwork-Id: 13977896 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 0A29EC021A9 for ; Mon, 17 Feb 2025 14:04:49 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 7FC49280054; Mon, 17 Feb 2025 09:04:49 -0500 (EST) Received: by kanga.kvack.org (Postfix, from userid 40) id 7AB3C28004D; Mon, 17 Feb 2025 09:04:49 -0500 (EST) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 62592280054; Mon, 17 Feb 2025 09:04:49 -0500 (EST) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0013.hostedemail.com [216.40.44.13]) by kanga.kvack.org (Postfix) with ESMTP id 3FB1B28004D for ; Mon, 17 Feb 2025 09:04:49 -0500 (EST) Received: from smtpin26.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id A674BC0446 for ; Mon, 17 Feb 2025 14:04:48 +0000 (UTC) X-FDA: 83129607456.26.FC0AF9B Received: from foss.arm.com (foss.arm.com [217.140.110.172]) by imf09.hostedemail.com (Postfix) with ESMTP id 09153140019 for ; Mon, 17 Feb 2025 14:04:46 +0000 (UTC) Authentication-Results: imf09.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf09.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1739801087; 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-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=UCOUTcTfw4qYTSuXaw58P4F2TMysB+Npd4FFe2C6z/o=; b=Dk/ZxwwKLGlC4mcyQP+UcOsYDuAR8EGctBhK4nVmXmmxijTbHjrvmfdsAtQZbtp2QRNAG3 D4RxXW1We1MANDkMLPwszI6ZDyO+3T3sInzPRFIjHAVbWUZDThqJSUKLqMwlx3eHVQkDeU g4yIgScPi6Dl+p0DCywZw90h3NM41TA= ARC-Authentication-Results: i=1; imf09.hostedemail.com; dkim=none; dmarc=pass (policy=none) header.from=arm.com; spf=pass (imf09.hostedemail.com: domain of ryan.roberts@arm.com designates 217.140.110.172 as permitted sender) smtp.mailfrom=ryan.roberts@arm.com ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1739801087; a=rsa-sha256; cv=none; b=ZWplHo4nriTV/jRwMeHSwuYP7xK3cfEcTwjMcTJGHmdIiyt2LBSuFAmqNyhVlkGZbFKlxI 7tqDNGElFUoU8MfzmQE8u+EVQWpSkjUe4c5McYgyqUk5Yc6LJSnvGccvLt18R9Jax2J8m6 haUwbm8m0NEqu/DlQQYRwsw0wcTqa/k= Received: from usa-sjc-imap-foss1.foss.arm.com (unknown [10.121.207.14]) by usa-sjc-mx-foss1.foss.arm.com (Postfix) with ESMTP id 78A2216F8; Mon, 17 Feb 2025 06:05:05 -0800 (PST) Received: from e125769.cambridge.arm.com (e125769.cambridge.arm.com [10.1.196.27]) by usa-sjc-imap-foss1.foss.arm.com (Postfix) with ESMTPSA id 043963F6A8; Mon, 17 Feb 2025 06:04:40 -0800 (PST) From: Ryan Roberts To: Catalin Marinas , Will Deacon , Huacai Chen , WANG Xuerui , Thomas Bogendoerfer , "James E.J. Bottomley" , Helge Deller , Madhavan Srinivasan , Michael Ellerman , Nicholas Piggin , Christophe Leroy , Naveen N Rao , Paul Walmsley , Palmer Dabbelt , Albert Ou , Heiko Carstens , Vasily Gorbik , Alexander Gordeev , Christian Borntraeger , Sven Schnelle , Gerald Schaefer , "David S. Miller" , Andreas Larsson , Arnd Bergmann , Muchun Song , Andrew Morton , Uladzislau Rezki , Christoph Hellwig , David Hildenbrand , "Matthew Wilcox (Oracle)" , Mark Rutland , Anshuman Khandual , Dev Jain , Kevin Brodsky , Alexandre Ghiti Cc: Ryan Roberts , linux-arm-kernel@lists.infradead.org, linux-mm@kvack.org, linux-kernel@vger.kernel.org, stable@vger.kernel.org Subject: [PATCH v2 2/4] arm64: hugetlb: Fix huge_ptep_get_and_clear() for non-present ptes Date: Mon, 17 Feb 2025 14:04:15 +0000 Message-ID: <20250217140419.1702389-3-ryan.roberts@arm.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250217140419.1702389-1-ryan.roberts@arm.com> References: <20250217140419.1702389-1-ryan.roberts@arm.com> MIME-Version: 1.0 X-Rspam-User: X-Rspamd-Server: rspam09 X-Rspamd-Queue-Id: 09153140019 X-Stat-Signature: p4fyzgmuqgn4q4ftkwu7qufin3uhi8gy X-HE-Tag: 1739801086-233630 X-HE-Meta: U2FsdGVkX1+o6hYkp4b873rx2KyrFfNx5r2P5cQq5yRKK7uddLSfP/dB+xKWkp6o3o0hE/5Bz3R9gUMv7qTiNnYM7iYYxFWjwif6Uf83iCY7O4tboSDJyTF9Js0/KELBphuENetYXouKFQUwXb3MvQGJNPS7YsDH8IoBgZaSkUNOqSmUTKkODcBDlae0T5TDkf0U59mTBI5EThG4kkJ7t97DMkXxriygU8/4cYDiqJQWj0BI4Axt8cXbZirVbkxrs64YlVKkFUAcih4ITEq26vHiTmLvjvnfcdxrtRuxs2E87ns4JqD7n2DdJM2JUahCD1m1xAD4Nsz2WsssnZ8NL4nx8UO1AfMrtUnWupENTLjHzef5WJRDZo26BFZ5jkWdNb5b4ZMZeXreQn4doO6McjlSd4L3zfM265kj3SdVYxO59Adn2A1461DyOxadev1qhv0Vcl7tdDWyuENYmGCwlVwThSqYTEW7vqNXVB2WaYeBEueVEfINlKuVIk+VJ/S2UBdvrrCezaMsb7d66PRgqtsx2vnOypt1pAN8X4AWzQXK5AmDvaxo86qhp/DlanNf90Xc0sUyZYvqWe8DNgQMhaDbzC5/l2uIvl387vj7Xjp+H9HjVRfHkiIBwrBFBaNX28b7qNinmNyCjWnVzUZgxfB1NMjK16j51SKtzyjgtNhj9Xrle6eTMj2VPVlzG1SXaOdFVyP1SVLAZfZZm6AbfxS9OoMsjtgdCQXK4gD5KbmTYRHGKByGqNSvRBqBupLSAdCmtezesKI59Hk83ObLGiXzcLxx/aTz6sTSWepT6B9rsV0O2vzV7eov+4ascCtSbDZ/SXHhbEKcKhWlaBw+f9SycfSUmgiBawvN9apswVWBe+z9Lk/YvQWVMC+BspZb9Bp48tLZRM2yyvDAkTodjPHDKnUQwkUgAz+NQeZgNj4JamArvE0gzMtNPMWi9kUoT0iA+kDkuUE+GgLBNpg OUYRMMIL PmLa42n/WatBHL7zbj+Y37m85XM/UbvyWsgm8sv/5QhbdTBwQ3RPOMv/dvwL8f4UrpouBOKlvrl4xTBBuEIizQW6P1x2DGZbNUhaIA9+dIUgXYiY/1R6NIdJdSBpvuJl0lNs8sEpoxS4dUC/ICPnYqn5T0nywprsjp5et5r+K+jzYDKvbRgURcquDhHgaDdt9DQCfDQ5N3f17rLFugxh+ieROxm5BNzh0nWO6 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: arm64 supports multiple huge_pte sizes. Some of the sizes are covered by a single pte entry at a particular level (PMD_SIZE, PUD_SIZE), and some are covered by multiple ptes at a particular level (CONT_PTE_SIZE, CONT_PMD_SIZE). So the function has to figure out the size from the huge_pte pointer. This was previously done by walking the pgtable to determine the level and by using the PTE_CONT bit to determine the number of ptes at the level. But the PTE_CONT bit is only valid when the pte is present. For non-present pte values (e.g. markers, migration entries), the previous implementation was therefore erroniously determining the size. There is at least one known caller in core-mm, move_huge_pte(), which may call huge_ptep_get_and_clear() for a non-present pte. So we must be robust to this case. Additionally the "regular" ptep_get_and_clear() is robust to being called for non-present ptes so it makes sense to follow the behaviour. Fix this by using the new sz parameter which is now provided to the function. Additionally when clearing each pte in a contig range, don't gather the access and dirty bits if the pte is not present. An alternative approach that would not require API changes would be to store the PTE_CONT bit in a spare bit in the swap entry pte for the non-present case. But it felt cleaner to follow other APIs' lead and just pass in the size. As an aside, PTE_CONT is bit 52, which corresponds to bit 40 in the swap entry offset field (layout of non-present pte). Since hugetlb is never swapped to disk, this field will only be populated for markers, which always set this bit to 0 and hwpoison swap entries, which set the offset field to a PFN; So it would only ever be 1 for a 52-bit PVA system where memory in that high half was poisoned (I think!). So in practice, this bit would almost always be zero for non-present ptes and we would only clear the first entry if it was actually a contiguous block. That's probably a less severe symptom than if it was always interpretted as 1 and cleared out potentially-present neighboring PTEs. Cc: stable@vger.kernel.org Fixes: 66b3923a1a0f ("arm64: hugetlb: add support for PTE contiguous bit") Signed-off-by: Ryan Roberts Reviewed-by: Catalin Marinas --- arch/arm64/mm/hugetlbpage.c | 40 ++++++++++++++++--------------------- 1 file changed, 17 insertions(+), 23 deletions(-) diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 06db4649af91..614b2feddba2 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -163,24 +163,23 @@ static pte_t get_clear_contig(struct mm_struct *mm, unsigned long pgsize, unsigned long ncontig) { - pte_t orig_pte = __ptep_get(ptep); - unsigned long i; - - for (i = 0; i < ncontig; i++, addr += pgsize, ptep++) { - pte_t pte = __ptep_get_and_clear(mm, addr, ptep); - - /* - * If HW_AFDBM is enabled, then the HW could turn on - * the dirty or accessed bit for any page in the set, - * so check them all. - */ - if (pte_dirty(pte)) - orig_pte = pte_mkdirty(orig_pte); - - if (pte_young(pte)) - orig_pte = pte_mkyoung(orig_pte); + pte_t pte, tmp_pte; + bool present; + + pte = __ptep_get_and_clear(mm, addr, ptep); + present = pte_present(pte); + while (--ncontig) { + ptep++; + addr += pgsize; + tmp_pte = __ptep_get_and_clear(mm, addr, ptep); + if (present) { + if (pte_dirty(tmp_pte)) + pte = pte_mkdirty(pte); + if (pte_young(tmp_pte)) + pte = pte_mkyoung(pte); + } } - return orig_pte; + return pte; } static pte_t get_clear_contig_flush(struct mm_struct *mm, @@ -401,13 +400,8 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, { int ncontig; size_t pgsize; - pte_t orig_pte = __ptep_get(ptep); - - if (!pte_cont(orig_pte)) - return __ptep_get_and_clear(mm, addr, ptep); - - ncontig = find_num_contig(mm, addr, ptep, &pgsize); + ncontig = num_contig_ptes(sz, &pgsize); return get_clear_contig(mm, addr, ptep, pgsize, ncontig); }