From nobody Wed Dec 17 17:30:49 2025 Received: from mail-wr1-f44.google.com (mail-wr1-f44.google.com [209.85.221.44]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id C580A21ABCC for ; Mon, 17 Mar 2025 07:25:58 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742196361; cv=none; b=rI7bpuL8aV02OuT5Gqd3Yb8CCQZOV++SbjZYVLVckxRDS5sZ+bYAen+2bEKzvmzeuu1IY6V6TdbFSvBsyzDjmh/2ZsMEHqrFBF8s8h3C1pZFCG8b+L7ouRmQncHpWZ3brL8kdA3kbe4Nzw62b9VKoNnXQ7UYWqbwGd5E+750mKE= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1742196361; c=relaxed/simple; bh=WLAseXMIobgoPi2SfhEUrHpYJNesug4mAmigjE7aaTM=; h=From:To:Cc:Subject:Date:Message-Id:MIME-Version; b=ZSV10gbc3GyNUK6eyyQ7JnX4g/yfAqhQRG7xt08kT3/n12+ZMnWV+6HRVE08Dc1tVVqzn+wOyMwfj8ZX39WxZx6xUhrZYTXTGSrxFXpsbVyjdXa5GpHCCQ9O2zd9GUfImDKUSET1YD6kzCF1Bm8yIMmBk+CEG75v2r4xwxsB1VY= ARC-Authentication-Results: i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com; spf=pass smtp.mailfrom=rivosinc.com; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b=2lhYLSly; arc=none smtp.client-ip=209.85.221.44 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=rivosinc.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=rivosinc-com.20230601.gappssmtp.com header.i=@rivosinc-com.20230601.gappssmtp.com header.b="2lhYLSly" Received: by mail-wr1-f44.google.com with SMTP id ffacd0b85a97d-39143200ddaso2506575f8f.1 for ; Mon, 17 Mar 2025 00:25:58 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1742196357; x=1742801157; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:from:to:cc:subject:date:message-id:reply-to; bh=l2Rgxfmy4wvi0IV1iIeDi36GnLsMRf14zDXApk09KVM=; b=2lhYLSlySA42bxDoziQbgLFYlj3wNDWf6JlYZD1g9KAXZVdQb/BC1xrMMTRyDGOtxx t5o/ojm7L9gS2JNt0XjHo+18ojzV31pLO1x2kQtq2dzw/+vGiiP+dLr445HJYGuWw8KR 15yfTBzHO5puChIv5R+KVfTnisIEtHnHGJYXoFHaTZcPQswmwE6SMsXBCwU8oXfQ96Lo woMqziodehrcYblxDQqppkz+ncUGLqCXobkeC9B9LoC2ej6ZX9PtdPPznxin0DXcWZGv vdVV2c1QqjMkRgukad07htpspd8eJKyoYh21Dkl11IUPbkMyp+vMYx7elJ3iYIJY7Ucr tRbw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1742196357; x=1742801157; h=content-transfer-encoding:mime-version:message-id:date:subject:cc :to:from:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=l2Rgxfmy4wvi0IV1iIeDi36GnLsMRf14zDXApk09KVM=; b=hWiWrCOwt1poFRq0bdHQpZjBp/zmrSuIs5NIlY7GkDIJCMnVloP0CzUmZIaRrKHDq8 SJjCmQ1JDdmRyhedna7kO/jvzpAubcH2FBMChIazFSuKuzWOT7j1TKQDq7NeEEBjHbZG YzY6dUAbo/XvU5L9hBoWalfCveea/FEWrzLVUOO+aRtfweMkpWb9VEb858TtT3f6bHuE 15oewdaRHrsx+Io5/vbNSNkDBGHDyjTXKmltfqGeGvyPD+xTatV4XSbpduaYjKOurs0c BavF/8beuPcC48TLoxvnlE8cKYsQt4baQ4Zsh7Er4h+RC6Z1y+I7Uyu0dHdQLSnHI+vm 8X6g== X-Forwarded-Encrypted: i=1; AJvYcCUgXv+mNFr59q3mXPW/dlC88g5eYExYqguz2PUa2eYtRCutcOKrHghLUNpHHgx1vHngKZ1JY5YqO4Gu13g=@vger.kernel.org X-Gm-Message-State: AOJu0Ywflnjhe9PEHqdJiv4gCr0laz5L0o/nPHZne//dCzm9TL/B5QIW iir+amC+3EKCyRAtIZKcFbPqPuyJbM7h54LdpSJzn3v92MwwKhIG6vBri1neU+M= X-Gm-Gg: ASbGncuonSs7f6lstugFF9dRMXJYd81udZaKJjO01j9ZZXxnb22C2KKS8atxrgMZcm/ 1v2v5zu6B1TUEQM4uVc9GiEP89nJijnEG6YYVIPNIyXChrKQ7T+9B4rdN+djo6AJw/gpzOKO7fl H+gv03Z0omAxoDlyMcrENgHvjbDMTgF3OsvMVvLJQ+0fflZIkWS7O5qS8wzrPy+cleEEdiFl2Bw vngTTcdsvfQ0qpdG/5A1ZUlmWPDrqFz6hiCFh+KyG4VXqvat0Z/M+oZtmxUSa7DGuY/MWbZ97RL 01VkpzmXaaKQVg1BBAXt01ZNrSYuhcPAobsGF6iJA9+bVaGDmyT8e4mJyDA/bq7cmg== X-Google-Smtp-Source: AGHT+IGFDMFLc6+xi+GWz3Dc64P/p7dYSStQUrPd9vMMUlqPXgkzGWncVuX7U3JZiTVznPWilKKpOg== X-Received: by 2002:a05:6000:18a8:b0:391:2d8f:dd56 with SMTP id ffacd0b85a97d-3971ded3840mr11909327f8f.29.1742196356823; Mon, 17 Mar 2025 00:25:56 -0700 (PDT) Received: from alex-rivos.ba.rivosinc.com ([31.32.81.187]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-395c8881187sm13887907f8f.41.2025.03.17.00.25.56 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 17 Mar 2025 00:25:56 -0700 (PDT) From: Alexandre Ghiti To: Paul Walmsley , Palmer Dabbelt , Alexandre Ghiti , Qinglin Pan , Andrew Jones , Ryan Roberts , linux-riscv@lists.infradead.org, linux-kernel@vger.kernel.org Cc: Alexandre Ghiti Subject: [PATCH] riscv: Fix hugetlb retrieval of number of ptes in case of !present pte Date: Mon, 17 Mar 2025 08:25:51 +0100 Message-Id: <20250317072551.572169-1-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable Content-Type: text/plain; charset="utf-8" Ryan sent a fix [1] for arm64 that applies to riscv too: in some hugetlb functions, we must not use the pte value to get the size of a mapping because the pte may not be present. So use the already present size parameter for huge_pte_clear() and the newly introduced size parameter for huge_ptep_get_and_clear(). And make sure to gather A/D bits only on present ptes. Fixes: 82a1a1f3bfb6 ("riscv: mm: support Svnapot in hugetlb page") Link: https://lore.kernel.org/all/20250217140419.1702389-1-ryan.roberts@arm= .com/ [1] Signed-off-by: Alexandre Ghiti --- arch/riscv/mm/hugetlbpage.c | 76 ++++++++++++++++++++++--------------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index b4a78a4b35cf..375dd96bb4a0 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -148,22 +148,25 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) static pte_t get_clear_contig(struct mm_struct *mm, unsigned long addr, pte_t *ptep, - unsigned long pte_num) + unsigned long ncontig) { - pte_t orig_pte =3D ptep_get(ptep); - unsigned long i; - - for (i =3D 0; i < pte_num; i++, addr +=3D PAGE_SIZE, ptep++) { - pte_t pte =3D ptep_get_and_clear(mm, addr, ptep); - - if (pte_dirty(pte)) - orig_pte =3D pte_mkdirty(orig_pte); - - if (pte_young(pte)) - orig_pte =3D pte_mkyoung(orig_pte); + pte_t pte, tmp_pte; + bool present; + + pte =3D ptep_get_and_clear(mm, addr, ptep); + present =3D pte_present(pte); + while (--ncontig) { + ptep++; + addr +=3D PAGE_SIZE; + tmp_pte =3D ptep_get_and_clear(mm, addr, ptep); + if (present) { + if (pte_dirty(tmp_pte)) + pte =3D pte_mkdirty(pte); + if (pte_young(tmp_pte)) + pte =3D pte_mkyoung(pte); + } } - - return orig_pte; + return pte; } =20 static pte_t get_clear_contig_flush(struct mm_struct *mm, @@ -212,6 +215,26 @@ static void clear_flush(struct mm_struct *mm, flush_tlb_range(&vma, saddr, addr); } =20 +static int num_contig_ptes_from_size(unsigned long sz, size_t *pgsize) +{ + unsigned long hugepage_shift; + + if (sz >=3D PGDIR_SIZE) + hugepage_shift =3D PGDIR_SHIFT; + else if (sz >=3D P4D_SIZE) + hugepage_shift =3D P4D_SHIFT; + else if (sz >=3D PUD_SIZE) + hugepage_shift =3D PUD_SHIFT; + else if (sz >=3D PMD_SIZE) + hugepage_shift =3D PMD_SHIFT; + else + hugepage_shift =3D PAGE_SHIFT; + + *pgsize =3D 1 << hugepage_shift; + + return sz >> hugepage_shift; +} + /* * When dealing with NAPOT mappings, the privileged specification indicate= s that * "if an update needs to be made, the OS generally should first mark all = of the @@ -226,22 +249,10 @@ void set_huge_pte_at(struct mm_struct *mm, pte_t pte, unsigned long sz) { - unsigned long hugepage_shift, pgsize; + size_t pgsize; int i, pte_num; =20 - if (sz >=3D PGDIR_SIZE) - hugepage_shift =3D PGDIR_SHIFT; - else if (sz >=3D P4D_SIZE) - hugepage_shift =3D P4D_SHIFT; - else if (sz >=3D PUD_SIZE) - hugepage_shift =3D PUD_SHIFT; - else if (sz >=3D PMD_SIZE) - hugepage_shift =3D PMD_SHIFT; - else - hugepage_shift =3D PAGE_SHIFT; - - pte_num =3D sz >> hugepage_shift; - pgsize =3D 1 << hugepage_shift; + pte_num =3D num_contig_ptes_from_size(sz, &pgsize); =20 if (!pte_present(pte)) { for (i =3D 0; i < pte_num; i++, ptep++, addr +=3D pgsize) @@ -295,13 +306,14 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long sz) { + size_t pgsize; pte_t orig_pte =3D ptep_get(ptep); int pte_num; =20 if (!pte_napot(orig_pte)) return ptep_get_and_clear(mm, addr, ptep); =20 - pte_num =3D napot_pte_num(napot_cont_order(orig_pte)); + pte_num =3D num_contig_ptes_from_size(sz, &pgsize); =20 return get_clear_contig(mm, addr, ptep, pte_num); } @@ -351,6 +363,7 @@ void huge_pte_clear(struct mm_struct *mm, pte_t *ptep, unsigned long sz) { + size_t pgsize; pte_t pte =3D ptep_get(ptep); int i, pte_num; =20 @@ -359,8 +372,9 @@ void huge_pte_clear(struct mm_struct *mm, return; } =20 - pte_num =3D napot_pte_num(napot_cont_order(pte)); - for (i =3D 0; i < pte_num; i++, addr +=3D PAGE_SIZE, ptep++) + pte_num =3D num_contig_ptes_from_size(sz, &pgsize); + + for (i =3D 0; i < pte_num; i++, addr +=3D pgsize, ptep++) pte_clear(mm, addr, ptep); } =20 --=20 2.39.2