From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (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 778061FDA6F for ; Mon, 27 Jan 2025 09:36:42 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970605; cv=none; b=UTM1VM9NMHxgffpPL9j5SEKwPaapUcHQNO4HuIDlGcfNgHgfxp65V1MGZjqXQl7Fu6D2gwtEjoRTXanxXQ7CcaCgH0FH4KtwhTWhtJOG+oSvXeMhUlEdI0fMoh70r94FN0I4kODbSWplZUw5bRCHIE+tH1DzSmuvt8vqKGKFDd4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970605; c=relaxed/simple; bh=lXPN0zAr41aya+3WNiJQA3eWzEBSucGk/JihnpGrsD4=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=B7N7tjL1pc8U/xbWkUntP7Nzd6D/MYBdqsR3p8/d58Al07q+UXQnAqdwd6PjtReuK5RM+XTuvkiXH0i/LKSGEdGXg8ICYvdVQlUxO717piHYnRePot016KRuAuafCyVCg4ylnMJy+dRJf6IMQyRJIGyL3zMwklF0cjL0kGwD5dU= 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=3AYVy1ND; arc=none smtp.client-ip=209.85.221.43 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="3AYVy1ND" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-385e27c75f4so3700016f8f.2 for ; Mon, 27 Jan 2025 01:36:42 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970601; x=1738575401; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=YlgUGAmuTWGVKaOGr6DQU8bhY7gyR7CYcPHPJxmYPTE=; b=3AYVy1ND+PIRB6ripZu2soHejPtm4WuIryRbEN/nxR9TUiDvHO22YlULbrQ0mMW6bD KmZy8Td3TdYoc7o7e3UoaP/25Mw/tK0fuc6S+80u7oIQ/6Bc4WC0KqEDaX/aSbAGrD++ 5HQMoDZVj7tWgTDfhWVB+UBYOnFAUNniYahFL4kyVC3uP7nUlBHjraj5LMIR8RgfpJ2j Z+HDU2rJyBzfI1NNdgoUtKH6DNaT3O0As9xsZdngZTWSb8IzXH2dd+MUOffj6kAt/cFn w/9fs7pLdmHcncvgNNWFHm0j5V1xVRtdBeQA3nIHnePsdUDWRKQgSoKYc894q+BM6O/y WFyQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970601; x=1738575401; 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=YlgUGAmuTWGVKaOGr6DQU8bhY7gyR7CYcPHPJxmYPTE=; b=OAsNVBQYDHCFX3JvYqAZiCe/jv47ZyB6BA2RH5TSXhxMRIFqGu0qkOC2ynnBCtgitq MvGRGFWnpO8Cx3b66q57j7wd7JRH6bOPiDlYEB6rYBXTzveDhkPCjv5rsfPf6VrMh+dC 1hCKllSg2nn4ihtKqgRO0CKlO8Lt+C7mqyfCeQrJp8a+TvNUjElFP7Vdj91jferv22Gt HAELk5afxJ8DRhVWjqdWggfOIwPTI0ZnShDoq26ZBDyTt411HUWEibM6h1f6JqiKgg0h GhR39pJYBpquM5N7IwPRcAB5Mrhj52WpwAXaOp+drvTX/lKaBq77DHiN4cKqAm45Wrao Ga6w== X-Forwarded-Encrypted: i=1; AJvYcCWx+0Y2GPaznfT+CUfNrHJ5WxVWjymNPLXryK67ZPAvowQ+a+po6XaXGLsUhbvw8jiCoyGyazAJh2XwMPE=@vger.kernel.org X-Gm-Message-State: AOJu0Yys4N37Kh2K+zTm+1xrbMByWyPDSVr6KdfUXdyBVzGyAnwdfQea Nm7KclopSbhH7bmLKW/YYJRDNPghmHUxoZeSryUU3rVlNfnU03KUqHq2/f6mq/g= X-Gm-Gg: ASbGncvFr0pBzJqg5eoCIs0+Z27E7Pth+K4WEEBjCLQkMXX7s0qWUnzPJ0Vw+WNfIc7 mZl3V7PTpBTvelawUkNkW70JVQupKGJnVYmidOuxF5RURDu3CRPjrX9aakRm7JgV6V8fh3zUZNt CGdvAFgmRmTWuJtM1ViUU2gZNqEfnJ2X8fZ9AAEvQbkaFijdPbaJUkpRvBrMQo6HGn9W8rx2vdG O9br791E2wKtlexB4AYEI2c0vBq9Mjd/RdAkbznFXVhhFJ0+4BiUuQNQPafSqdOpGHt6XrKyWuQ z44Slb1LhIArUqY9t5aiNrRRFv4o+wA= X-Google-Smtp-Source: AGHT+IHUUXHJ5coMzJl68ATLI/2WB7Q+b+nPXfERL8/PDwCduzlj4e0CTpfsp9bAQ08qd/jskgeAvg== X-Received: by 2002:a05:6000:1445:b0:386:37f5:99f6 with SMTP id ffacd0b85a97d-38bf59ed62fmr33321912f8f.53.1737970600263; Mon, 27 Jan 2025 01:36:40 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a176490sm10314205f8f.1.2025.01.27.01.36.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:36:39 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 1/9] riscv: Safely remove huge_pte_offset() when manipulating NAPOT ptes Date: Mon, 27 Jan 2025 10:35:22 +0100 Message-Id: <20250127093530.19548-2-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" The pte_t pointer is expected to point to the first entry of the NAPOT mapping so no need to use huge_pte_offset(), similarly to what is done in arm64. Signed-off-by: Alexandre Ghiti --- arch/riscv/mm/hugetlbpage.c | 2 -- 1 file changed, 2 deletions(-) diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 42314f093922..6b09cd1ef41c 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -276,7 +276,6 @@ int huge_ptep_set_access_flags(struct vm_area_struct *v= ma, =20 order =3D napot_cont_order(pte); pte_num =3D napot_pte_num(order); - ptep =3D huge_pte_offset(mm, addr, napot_cont_size(order)); orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); =20 if (pte_dirty(orig_pte)) @@ -322,7 +321,6 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, =20 order =3D napot_cont_order(pte); pte_num =3D napot_pte_num(order); - ptep =3D huge_pte_offset(mm, addr, napot_cont_size(order)); orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); =20 orig_pte =3D pte_wrprotect(orig_pte); --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wm1-f45.google.com (mail-wm1-f45.google.com [209.85.128.45]) (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 583C71FCF54 for ; Mon, 27 Jan 2025 09:37:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970666; cv=none; b=o5bNYeHHYH8KkJoP+GJriArJJRkq85bBvQBAWz/hPe9n7SJpDHqrLLg6eOu65hjc05XQ+3248e34N0XCKcZ0WQUKnVg8WVhVuIBxZ6ZU4kK77mNWD2TXgKcnah4S+lfmoWAEFJ6siC5a11E7btLYHOR+1r4jN3Z/8iyJAhenlII= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970666; c=relaxed/simple; bh=knvC3ewRAGKFJi63GL/o3OnAPF43kpnTZQgrFVQVc1U=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=HsyB0OrTAzjW3xTjhWkeF8lPlf1pVUwLdMmQcMZoXdUkcdGHqG2+xB9lYnRRvT/fDIq9CYqzoDyzDHov7W1wk8FYDX7mB75UTJZ9CSyuR6ia7VyV9loQexJ/6cayzhQqQzjQZmiQtllTv54z99cMYINvCjZzZu1aWnIUsZSSfQg= 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=gLsgr/E3; arc=none smtp.client-ip=209.85.128.45 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="gLsgr/E3" Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-4361f65ca01so44569795e9.1 for ; Mon, 27 Jan 2025 01:37:44 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970662; x=1738575462; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=Pa3kN5Pj/U9dm1V/qwQhRimY+zw1O6zUoccW70uHpSw=; b=gLsgr/E3nTkH+41yPXkx/H9CNFGDm1K8Ay0xw8POemj+Vdl8pX35fiBkaTWdpWDHKl NO82cxHYm8hUxqiZ3HkVGIChhXn3C9FM/HFp+kf422CjKLx8RcGLRpTgd//25PgCylds vgEnze1qVDRCTbWrNmkwjQZ5rPav+OvkwyT4kvQ67rAa6WnHYtyafQHegEbpfzhk80VY waAWDmo+ACpypvloIl2yZt2lNDvh0FC5Ttfe8jiLxRf1EWkom9TlTp4LU357xvsd/R6F kDGUY/5GkBiq6o2CZtxvgjsYfgaoBnAPplQ9UnhCCpRyEJvTzfj6sAJUrSyTqlw8tKV9 OXKQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970662; x=1738575462; 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=Pa3kN5Pj/U9dm1V/qwQhRimY+zw1O6zUoccW70uHpSw=; b=ja0FwuBwlAPpnMZ8FnDfZzQlG0kccbBSens8xTwvPGW1sfLeY6v2eGSEvD8FC4SsfD //8K3KzaUVS+id73ETjYUBUTOvQOTD6Jl9FzrGTS4i+S6PwN+wTEsLaHxD3eu8pINI26 iGvs7/6/9Tkkt0KoXxHYGfQbzspeXwPR+SRxlBBtA2U2R5FJaWd7ywTHqG0valk5EAIR rP/JFF2aKbLTIroVJWqEY4XJsjivYPQcu+6dp3fi+bwD8R+FktLTbIIRI7pb8ObUBHfN /62DBViIGZhlJf/beohw9ILsSbUBygKGTkSWVlh5+iTxX0SaFK5R01IVhcNv5OmiHVQr nb0A== X-Forwarded-Encrypted: i=1; AJvYcCVYJ2LcVh6+aYycRf//0xy8rLsEqVfM9eB/F62YtCp6L2uNd7UBbf3GPY1olC1PK2Q+szQCpb7AhVPrp0I=@vger.kernel.org X-Gm-Message-State: AOJu0YzA/q495CDetXsIeG77MUQTCpA3WsWK/JAjkD0odjcx6Pch4GO8 dlXEhQj5pEroQMSal3W3aa7SjaLhdjvHBflnVebgeeCGt7nYg4/uVLtUa+ARAzQ= X-Gm-Gg: ASbGncvV5YeZNhckj6sIt7FB5QURcBo2UEnF/JOkqzf7WqIOU0HYCd5KG2uxWd0EHr/ ixtR6TnRsW6kCMiCowiNJKJlExlMjZRxjiqHP8XzYWs5v+fpN2wLT/19bWM2rSRweguP+mkALQL q3ev2jJv4IfuqcyiftDbMns28xAW+LfNxTq05jfvbeedCwr9R7bYo/cpXkTBJKHT+Gpt6+mK8my bEfTOTPHZyjYxc8UrsZn04BKAWd7w/jJpMZMVsjpdYjx2fM98f8AA60gjKJFYvYTABenI/jej29 aLjf7XytjwcMHEOhi/dFPhDJQ0f3OdQ= X-Google-Smtp-Source: AGHT+IHlygR1Rem42sW1brqnRYg+b7cppikaFDk94wrGvPPrCI76J4t5Wx9vdAYW3HFrhkgLyStnBg== X-Received: by 2002:a05:600c:4f05:b0:434:fe62:28c1 with SMTP id 5b1f17b1804b1-438913ef83bmr346516855e9.18.1737970662539; Mon, 27 Jan 2025 01:37:42 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-438b1718741sm100844135e9.0.2025.01.27.01.37.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:37:42 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 2/9] riscv: Restore the pfn in a NAPOT pte when manipulated by core mm code Date: Mon, 27 Jan 2025 10:35:23 +0100 Message-Id: <20250127093530.19548-3-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" The core mm code expects to be able to extract the pfn from a pte. NAPOT mappings work differently since its ptes actually point to the first pfn of the mapping, the other bits being used to encode the size of the mapping. So modify ptep_get() so that it returns a pte value that contains the *real* pfn (which is then different from what the HW expects) and right before storing the ptes to the page table, reset the pfn LSBs to the size of the mapping. And make sure that all NAPOT mappings are set using set_ptes(). Signed-off-by: Alexandre Ghiti --- arch/riscv/include/asm/pgtable-64.h | 11 ++++ arch/riscv/include/asm/pgtable.h | 91 ++++++++++++++++++++++++++--- arch/riscv/mm/hugetlbpage.c | 9 +-- 3 files changed, 96 insertions(+), 15 deletions(-) diff --git a/arch/riscv/include/asm/pgtable-64.h b/arch/riscv/include/asm/p= gtable-64.h index 0897dd99ab8d..cddbe426f618 100644 --- a/arch/riscv/include/asm/pgtable-64.h +++ b/arch/riscv/include/asm/pgtable-64.h @@ -104,6 +104,17 @@ enum napot_cont_order { #define napot_cont_mask(order) (~(napot_cont_size(order) - 1UL)) #define napot_pte_num(order) BIT(order) =20 +static inline bool is_napot_order(unsigned int order) +{ + unsigned int napot_order; + + for_each_napot_order(napot_order) + if (order =3D=3D napot_order) + return true; + + return false; +} + #ifdef CONFIG_RISCV_ISA_SVNAPOT #define HUGE_MAX_HSTATE (2 + (NAPOT_ORDER_MAX - NAPOT_CONT_ORDER_BASE)) #else diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index 050fdc49b5ad..82b264423b25 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -296,6 +296,8 @@ static inline unsigned long pte_napot(pte_t pte) return pte_val(pte) & _PAGE_NAPOT; } =20 +#define pte_valid_napot(pte) (pte_present(pte) && pte_napot(pte)) + static inline pte_t pte_mknapot(pte_t pte, unsigned int order) { int pos =3D order - 1 + _PAGE_PFN_SHIFT; @@ -305,6 +307,12 @@ static inline pte_t pte_mknapot(pte_t pte, unsigned in= t order) return __pte((pte_val(pte) & napot_mask) | napot_bit | _PAGE_NAPOT); } =20 +/* pte at entry must *not* encode the mapping size in the pfn LSBs. */ +static inline pte_t pte_clear_napot(pte_t pte) +{ + return __pte(pte_val(pte) & ~_PAGE_NAPOT); +} + #else =20 static __always_inline bool has_svnapot(void) { return false; } @@ -314,17 +322,14 @@ static inline unsigned long pte_napot(pte_t pte) return 0; } =20 +#define pte_valid_napot(pte) false + #endif /* CONFIG_RISCV_ISA_SVNAPOT */ =20 /* Yields the page frame number (PFN) of a page table entry */ static inline unsigned long pte_pfn(pte_t pte) { - unsigned long res =3D __page_val_to_pfn(pte_val(pte)); - - if (has_svnapot() && pte_napot(pte)) - res =3D res & (res - 1UL); - - return res; + return __page_val_to_pfn(pte_val(pte)); } =20 #define pte_page(x) pfn_to_page(pte_pfn(x)) @@ -559,8 +564,13 @@ static inline void __set_pte_at(struct mm_struct *mm, = pte_t *ptep, pte_t pteval) =20 #define PFN_PTE_SHIFT _PAGE_PFN_SHIFT =20 -static inline void set_ptes(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pteval, unsigned int nr) +static inline pte_t __ptep_get(pte_t *ptep) +{ + return READ_ONCE(*ptep); +} + +static inline void __set_ptes(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pteval, unsigned int nr) { page_table_check_ptes_set(mm, ptep, pteval, nr); =20 @@ -569,10 +579,13 @@ static inline void set_ptes(struct mm_struct *mm, uns= igned long addr, if (--nr =3D=3D 0) break; ptep++; + + if (unlikely(pte_valid_napot(pteval))) + continue; + pte_val(pteval) +=3D 1 << _PAGE_PFN_SHIFT; } } -#define set_ptes set_ptes =20 static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -627,6 +640,66 @@ static inline int ptep_clear_flush_young(struct vm_are= a_struct *vma, return ptep_test_and_clear_young(vma, address, ptep); } =20 +#ifdef CONFIG_RISCV_ISA_SVNAPOT +static inline void set_ptes(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pteval, unsigned int nr) +{ + if (unlikely(pte_valid_napot(pteval))) { + unsigned int order =3D ilog2(nr); + + if (!is_napot_order(order)) { + /* + * Something's weird, we are given a NAPOT pte but the + * size of the mapping is not a known NAPOT mapping + * size, so clear the NAPOT bit and map this without + * NAPOT support: core mm only manipulates pte with the + * real pfn so we know the pte is valid without the N + * bit. + */ + pr_err("Incorrect NAPOT mapping, resetting.\n"); + pteval =3D pte_clear_napot(pteval); + } else { + /* + * NAPOT ptes that arrive here only have the N bit set + * and their pfn does not contain the mapping size, so + * set that here. + */ + pteval =3D pte_mknapot(pteval, order); + } + } + + __set_ptes(mm, addr, ptep, pteval, nr); +} +#define set_ptes set_ptes + +static inline pte_t ptep_get(pte_t *ptep) +{ + pte_t pte =3D __ptep_get(ptep); + + /* + * The pte we load has the N bit set and the size of the mapping in + * the pfn LSBs: keep the N bit and replace the mapping size with + * the *real* pfn since the core mm code expects to find it there. + * The mapping size will be reset just before being written to the + * page table in set_ptes(). + */ + if (unlikely(pte_valid_napot(pte))) { + unsigned int order =3D napot_cont_order(pte); + int pos =3D order - 1 + _PAGE_PFN_SHIFT; + unsigned long napot_mask =3D ~GENMASK(pos, _PAGE_PFN_SHIFT); + pte_t *orig_ptep =3D PTR_ALIGN_DOWN(ptep, sizeof(*ptep) * napot_pte_num(= order)); + + pte =3D __pte((pte_val(pte) & napot_mask) + ((ptep - orig_ptep) << _PAGE= _PFN_SHIFT)); + } + + return pte; +} +#define ptep_get ptep_get +#else +#define set_ptes __set_ptes +#define ptep_get __ptep_get +#endif /* CONFIG_RISCV_ISA_SVNAPOT */ + #define pgprot_nx pgprot_nx static inline pgprot_t pgprot_nx(pgprot_t _prot) { diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 6b09cd1ef41c..59ed26ce6857 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -256,8 +256,7 @@ void set_huge_pte_at(struct mm_struct *mm, =20 clear_flush(mm, addr, ptep, pgsize, pte_num); =20 - for (i =3D 0; i < pte_num; i++, ptep++, addr +=3D pgsize) - set_pte_at(mm, addr, ptep, pte); + set_ptes(mm, addr, ptep, pte, pte_num); } =20 int huge_ptep_set_access_flags(struct vm_area_struct *vma, @@ -284,8 +283,7 @@ int huge_ptep_set_access_flags(struct vm_area_struct *v= ma, if (pte_young(orig_pte)) pte =3D pte_mkyoung(pte); =20 - for (i =3D 0; i < pte_num; i++, addr +=3D PAGE_SIZE, ptep++) - set_pte_at(mm, addr, ptep, pte); + set_ptes(mm, addr, ptep, pte, pte_num); =20 return true; } @@ -325,8 +323,7 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, =20 orig_pte =3D pte_wrprotect(orig_pte); =20 - for (i =3D 0; i < pte_num; i++, addr +=3D PAGE_SIZE, ptep++) - set_pte_at(mm, addr, ptep, orig_pte); + set_ptes(mm, addr, ptep, orig_pte, pte_num); } =20 pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wr1-f45.google.com (mail-wr1-f45.google.com [209.85.221.45]) (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 224C21FDA85 for ; Mon, 27 Jan 2025 09:38:45 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.45 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970728; cv=none; b=J9YmA0NRVKyRiQK2lccsNsdUhhwa7KUwjGkQYbKnWm2mkSdPxCKcCmazgvzkrWhJ+s+fRfISUPXuGCGwjuo7ulV7+Uq4lI+zAommRFUMP6PiU40hch0EMJSdwbQv3QyMNYyZPRbvxUrtrLwfeAdgNUt/9LJpmp1E4iwOlIjzyCM= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970728; c=relaxed/simple; bh=i5SJWyrxIqoJt+2QpNw+pbWezwQS9Qq15Z+nTFxTe2k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=tdBPKZA06YuO+m4BQaT+wBtl6abig5mIhDeLEOAPMjgqxI+z02Y0tGOOIh0oDdxDJ/G9dUh5JP06h+LOMpmBujJlyb+mTdyZBxDBOSgBiWuhQxS16MS303H3Vxs40qawdRuryxszxa9KiPcStoiiHpE2i5uE5ug+nx/Nt5/RNY0= 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=NW7CKV+n; arc=none smtp.client-ip=209.85.221.45 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="NW7CKV+n" Received: by mail-wr1-f45.google.com with SMTP id ffacd0b85a97d-38632b8ae71so3368670f8f.0 for ; Mon, 27 Jan 2025 01:38:45 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970724; x=1738575524; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=kgdyYq7XD2Yilje0JoNAbIWlWrTDbtDHltbsUNmCh+Y=; b=NW7CKV+ntM/eqTylQ8o18eEmoxjb156OFZEEQXuhQcb3PK+U46AtPh85OB1Lyj2Esy mrIgEFps38FdGKA1w6tMVvLcE9xkupr+CJ8Jk++QDFbrxrzONpQhIVkn6XuDsjbPEXDr 5N/JYxClZwmTd6G8g6sPJjw+TVu9pIzo060Rp41kDp13tFUdfKfJRw0h9vIVemSFwOzv FNY+A39sgyTXdfPDwEF2c+TRTG+3Eiaaj2lLR1HqIMfMfDhyElIW7Xu6SXHt+zngJ3Es T4tlqeyOMLE8sGZgkED1hyzOAjV8y+/3ClnUGD2gqa6oxgRbpVxn1H2AolyiS/WTBIqp Qt0g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970724; x=1738575524; 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=kgdyYq7XD2Yilje0JoNAbIWlWrTDbtDHltbsUNmCh+Y=; b=TgKHNqx0oIRR6DMOY7h9SVGy+ABunAE7M26KWP3ea59mwuIbC4aIJLNCxwZ/iGKbpm 0f6IWRumNYErNoJ61S0eTv6YA8Eff1fB716KsKpR7nX8/uDRgCk4PDCA+ue62qgs0N95 1QMKbVwTFQpSpkBbxI/cKwhSMPotPRN/7D7a+RVCinOqzAnJtjECiDFcFK3mVKqVW15U RIMkUaphOH9W67t3OpZB3vmHQ5FZ1ZK+CcEnpqJLz/auJMoNp6ZwfvOHRHqKeSKYcrLH YYOVhrs5znx9DwhJ0URihu0c0kCF/c3OMc3QjF89rBq4bb5vqzp2VxUyQmeDhBJ82mzD FcEw== X-Forwarded-Encrypted: i=1; AJvYcCUH0kL9l2mPn3a6O6Nrgfnu2f/qcXqz7EBL4bWe5SoOc7SSwpFKD7Xjn5RpNesT92gsge2f6QsiZ0wCf14=@vger.kernel.org X-Gm-Message-State: AOJu0YxBk3alh0EalhBUrjdHsDIT99K5x90DbJ/aW+jhHFt+kRwDkiYN nV6p5zlwnFh2KBmcSZs89FSiSkKLRADWVjV+Z5jW6pDfbqfnoGO8ammJB6H/0zs= X-Gm-Gg: ASbGncufW+BeCrNZR+UnO3eHFB4Gsl+MTTL4x0Uf0iphojHiWvJex4vNyjqrrBB6dhQ A3Fxyl9/7coGJqnkPl/UuTt/5oPVy5UkkJVAe0NsLya6A0KxF77hwKak4AWP9Hm2oo+Wdzar5Ch GJX3gXsB7Lecbpa5xpwzYVWOFv4ku7cE5x7/Ewruv8ZuJr1KVX6+7oAcmgStn9RzLheEA43v50O EPGICdOIHK28cAZwKos80sjWaSDHPXgTp0HbrBo7N0xdABtuuFQ15LkecDHrZrKd099fQ7dyPj3 Zg3MR0z+TYvYiEIRToIg8VcQe3ve+0A= X-Google-Smtp-Source: AGHT+IHF4Wz5gcDgdKwuRpBVbD6zHBbXFDhSzsPT6V4k0QqTqrpmiB0ymgyz8XwZE3Dv5j9kSPHaVA== X-Received: by 2002:a5d:4312:0:b0:388:e377:8a1b with SMTP id ffacd0b85a97d-38bf57950eemr28290614f8f.28.1737970724282; Mon, 27 Jan 2025 01:38:44 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a1baf65sm10687893f8f.64.2025.01.27.01.38.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:38:43 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 3/9] mm: Use common huge_ptep_get() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:24 +0100 Message-Id: <20250127093530.19548-4-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" After some adjustments, both architectures have the same implementation so move it to the generic code. Signed-off-by: Alexandre Ghiti --- arch/arm64/Kconfig | 1 + arch/arm64/include/asm/hugetlb.h | 3 +- arch/arm64/include/asm/pgtable.h | 48 +++++++++++++++++++++++++--- arch/arm64/mm/hugetlbpage.c | 55 ++------------------------------ arch/riscv/Kconfig | 1 + arch/riscv/include/asm/hugetlb.h | 6 ++-- arch/riscv/include/asm/pgtable.h | 36 +++++++++++++++++++++ arch/riscv/mm/hugetlbpage.c | 45 ++++++-------------------- include/linux/hugetlb_contpte.h | 12 +++++++ mm/Kconfig | 3 ++ mm/Makefile | 1 + mm/hugetlb_contpte.c | 44 +++++++++++++++++++++++++ 12 files changed, 157 insertions(+), 98 deletions(-) create mode 100644 include/linux/hugetlb_contpte.h create mode 100644 mm/hugetlb_contpte.c diff --git a/arch/arm64/Kconfig b/arch/arm64/Kconfig index 100570a048c5..fb85d33bfe98 100644 --- a/arch/arm64/Kconfig +++ b/arch/arm64/Kconfig @@ -111,6 +111,7 @@ config ARM64 select ARCH_WANT_DEFAULT_BPF_JIT select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT select ARCH_WANT_FRAME_POINTERS + select ARCH_WANT_GENERAL_HUGETLB_CONTPTE select ARCH_WANT_HUGE_PMD_SHARE if ARM64_4K_PAGES || (ARM64_16K_PAGES && = !ARM64_VA_BITS_36) select ARCH_WANT_LD_ORPHAN_WARN select ARCH_WANTS_EXECMEM_LATE if EXECMEM diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index c6dff3e69539..27d7f4bdd724 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -13,6 +13,7 @@ #include #include #include +#include =20 #ifdef CONFIG_ARCH_ENABLE_HUGEPAGE_MIGRATION #define arch_hugetlb_migration_supported arch_hugetlb_migration_supported @@ -53,8 +54,6 @@ extern pte_t huge_ptep_clear_flush(struct vm_area_struct = *vma, #define __HAVE_ARCH_HUGE_PTE_CLEAR extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long sz); -#define __HAVE_ARCH_HUGE_PTEP_GET -extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t= *ptep); =20 void __init arm64_hugetlb_cma_reserve(void); =20 diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgta= ble.h index 6986345b537a..cebbfcfb0e53 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -420,9 +420,10 @@ static inline pte_t pte_advance_pfn(pte_t pte, unsigne= d long nr) return pfn_pte(pte_pfn(pte) + nr, pte_pgprot(pte)); } =20 -static inline void __set_ptes(struct mm_struct *mm, - unsigned long __always_unused addr, - pte_t *ptep, pte_t pte, unsigned int nr) +static inline void ___set_ptes(struct mm_struct *mm, + unsigned long __always_unused addr, + pte_t *ptep, pte_t pte, unsigned int nr, + size_t pgsize) { page_table_check_ptes_set(mm, ptep, pte, nr); __sync_cache_and_tags(pte, nr); @@ -433,10 +434,15 @@ static inline void __set_ptes(struct mm_struct *mm, if (--nr =3D=3D 0) break; ptep++; - pte =3D pte_advance_pfn(pte, 1); + pte =3D pte_advance_pfn(pte, pgsize >> PAGE_SHIFT); } } =20 +#define __set_ptes(mm, addr, ptep, pte, nr) \ + ___set_ptes(mm, addr, ptep, pte, nr, PAGE_SIZE) + +#define set_contptes ___set_ptes + /* * Hugetlb definitions. */ @@ -1825,6 +1831,40 @@ static inline void clear_young_dirty_ptes(struct vm_= area_struct *vma, =20 #endif /* CONFIG_ARM64_CONTPTE */ =20 +static inline int arch_contpte_get_num_contig(pte_t *ptep, + unsigned long size, + size_t *pgsize) +{ + int contig_ptes =3D 0; + + if (pgsize) + *pgsize =3D size; + + switch (size) { +#ifndef __PAGETABLE_PMD_FOLDED + case PUD_SIZE: + if (pud_sect_supported()) + contig_ptes =3D 1; + break; +#endif + case PMD_SIZE: + contig_ptes =3D 1; + break; + case CONT_PMD_SIZE: + if (pgsize) + *pgsize =3D PMD_SIZE; + contig_ptes =3D CONT_PMDS; + break; + case CONT_PTE_SIZE: + if (pgsize) + *pgsize =3D PAGE_SIZE; + contig_ptes =3D CONT_PTES; + break; + } + + return contig_ptes; +} + #endif /* !__ASSEMBLY__ */ =20 #endif /* __ASM_PGTABLE_H */ diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 3215adf48a1b..3458461adb90 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -98,57 +98,6 @@ static int find_num_contig(struct mm_struct *mm, unsigne= d long addr, return CONT_PTES; } =20 -static inline int num_contig_ptes(unsigned long size, size_t *pgsize) -{ - int contig_ptes =3D 0; - - *pgsize =3D size; - - switch (size) { -#ifndef __PAGETABLE_PMD_FOLDED - case PUD_SIZE: - if (pud_sect_supported()) - contig_ptes =3D 1; - break; -#endif - case PMD_SIZE: - contig_ptes =3D 1; - break; - case CONT_PMD_SIZE: - *pgsize =3D PMD_SIZE; - contig_ptes =3D CONT_PMDS; - break; - case CONT_PTE_SIZE: - *pgsize =3D PAGE_SIZE; - contig_ptes =3D CONT_PTES; - break; - } - - return contig_ptes; -} - -pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - int ncontig, i; - size_t pgsize; - pte_t orig_pte =3D __ptep_get(ptep); - - if (!pte_present(orig_pte) || !pte_cont(orig_pte)) - return orig_pte; - - ncontig =3D num_contig_ptes(page_size(pte_page(orig_pte)), &pgsize); - for (i =3D 0; i < ncontig; i++, ptep++) { - pte_t pte =3D __ptep_get(ptep); - - if (pte_dirty(pte)) - orig_pte =3D pte_mkdirty(orig_pte); - - if (pte_young(pte)) - orig_pte =3D pte_mkyoung(orig_pte); - } - return orig_pte; -} - /* * Changing some bits of contiguous entries requires us to follow a * Break-Before-Make approach, breaking the whole contiguous set @@ -229,7 +178,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned lon= g addr, unsigned long pfn, dpfn; pgprot_t hugeprot; =20 - ncontig =3D num_contig_ptes(sz, &pgsize); + ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); =20 if (!pte_present(pte)) { for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize) @@ -390,7 +339,7 @@ void huge_pte_clear(struct mm_struct *mm, unsigned long= addr, int i, ncontig; size_t pgsize; =20 - ncontig =3D num_contig_ptes(sz, &pgsize); + ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); =20 for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) __pte_clear(mm, addr, ptep); diff --git a/arch/riscv/Kconfig b/arch/riscv/Kconfig index d4a7ca0388c0..2fe8c68fba85 100644 --- a/arch/riscv/Kconfig +++ b/arch/riscv/Kconfig @@ -78,6 +78,7 @@ config RISCV select ARCH_WANT_DEFAULT_TOPDOWN_MMAP_LAYOUT if MMU select ARCH_WANT_FRAME_POINTERS select ARCH_WANT_GENERAL_HUGETLB if !RISCV_ISA_SVNAPOT + select ARCH_WANT_GENERAL_HUGETLB_CONTPTE if RISCV_ISA_SVNAPOT select ARCH_WANT_HUGE_PMD_SHARE if 64BIT select ARCH_WANT_LD_ORPHAN_WARN if !XIP_KERNEL select ARCH_WANT_OPTIMIZE_DAX_VMEMMAP diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index faf3624d8057..d9f9bfb84908 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -4,6 +4,9 @@ =20 #include #include +#ifdef CONFIG_ARCH_WANT_GENERAL_HUGETLB_CONTPTE +#include +#endif =20 static inline void arch_clear_hugetlb_flags(struct folio *folio) { @@ -43,9 +46,6 @@ int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty); =20 -#define __HAVE_ARCH_HUGE_PTEP_GET -pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep); - pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte =20 diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index 82b264423b25..d4e6427b8ca9 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -296,6 +296,8 @@ static inline unsigned long pte_napot(pte_t pte) return pte_val(pte) & _PAGE_NAPOT; } =20 +#define pte_cont pte_napot + #define pte_valid_napot(pte) (pte_present(pte) && pte_napot(pte)) =20 static inline pte_t pte_mknapot(pte_t pte, unsigned int order) @@ -587,6 +589,38 @@ static inline void __set_ptes(struct mm_struct *mm, un= signed long addr, } } =20 +#ifdef CONFIG_RISCV_ISA_SVNAPOT +static inline int arch_contpte_get_num_contig(pte_t *ptep, unsigned long s= ize, + size_t *pgsize) +{ + unsigned long hugepage_shift; + pte_t __pte; + + if (size >=3D PGDIR_SIZE) + hugepage_shift =3D PGDIR_SHIFT; + else if (size >=3D P4D_SIZE) + hugepage_shift =3D P4D_SHIFT; + else if (size >=3D PUD_SIZE) + hugepage_shift =3D PUD_SHIFT; + else if (size >=3D PMD_SIZE) + hugepage_shift =3D PMD_SHIFT; + else + hugepage_shift =3D PAGE_SHIFT; + + if (pgsize) + *pgsize =3D BIT(hugepage_shift); + + /* We must read the raw value of the pte to get the size of the mapping */ + __pte =3D __ptep_get(ptep); + + /* Make sure __pte is not a swap entry */ + if (pte_valid_napot(__pte)) + return napot_pte_num(napot_cont_order(__pte)); + + return size >> hugepage_shift; +} +#endif + static inline void pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { @@ -671,6 +705,8 @@ static inline void set_ptes(struct mm_struct *mm, unsig= ned long addr, __set_ptes(mm, addr, ptep, pteval, nr); } #define set_ptes set_ptes +#define set_contptes(mm, addr, ptep, pte, nr, pgsize) \ + set_ptes(mm, addr, ptep, pte, nr) =20 static inline pte_t ptep_get(pte_t *ptep) { diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 59ed26ce6857..d51863824540 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -3,30 +3,6 @@ #include =20 #ifdef CONFIG_RISCV_ISA_SVNAPOT -pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) -{ - unsigned long pte_num; - int i; - pte_t orig_pte =3D ptep_get(ptep); - - if (!pte_present(orig_pte) || !pte_napot(orig_pte)) - return orig_pte; - - pte_num =3D napot_pte_num(napot_cont_order(orig_pte)); - - for (i =3D 0; i < pte_num; i++, ptep++) { - pte_t pte =3D ptep_get(ptep); - - if (pte_dirty(pte)) - orig_pte =3D pte_mkdirty(orig_pte); - - if (pte_young(pte)) - orig_pte =3D pte_mkyoung(orig_pte); - } - - return orig_pte; -} - pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, @@ -266,15 +242,13 @@ int huge_ptep_set_access_flags(struct vm_area_struct = *vma, int dirty) { struct mm_struct *mm =3D vma->vm_mm; - unsigned long order; pte_t orig_pte; - int i, pte_num; + int pte_num; =20 if (!pte_napot(pte)) return ptep_set_access_flags(vma, addr, ptep, pte, dirty); =20 - order =3D napot_cont_order(pte); - pte_num =3D napot_pte_num(order); + pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); =20 if (pte_dirty(orig_pte)) @@ -298,7 +272,7 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, 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 arch_contpte_get_num_contig(ptep, 0, NULL); =20 return get_clear_contig(mm, addr, ptep, pte_num); } @@ -308,17 +282,15 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, pte_t *ptep) { pte_t pte =3D ptep_get(ptep); - unsigned long order; pte_t orig_pte; - int i, pte_num; + int pte_num; =20 if (!pte_napot(pte)) { ptep_set_wrprotect(mm, addr, ptep); return; } =20 - order =3D napot_cont_order(pte); - pte_num =3D napot_pte_num(order); + pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); =20 orig_pte =3D pte_wrprotect(orig_pte); @@ -336,7 +308,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, if (!pte_napot(pte)) return ptep_clear_flush(vma, addr, ptep); =20 - pte_num =3D napot_pte_num(napot_cont_order(pte)); + pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); =20 return get_clear_contig_flush(vma->vm_mm, addr, ptep, pte_num); } @@ -346,6 +318,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 @@ -354,8 +327,8 @@ 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 arch_contpte_get_num_contig(ptep, sz, &pgsize); + for (i =3D 0; i < pte_num; i++, addr +=3D pgsize, ptep++) pte_clear(mm, addr, ptep); } =20 diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h new file mode 100644 index 000000000000..ec4189cd65b8 --- /dev/null +++ b/include/linux/hugetlb_contpte.h @@ -0,0 +1,12 @@ +/* SPDX-License-Identifier: GPL-2.0-only */ +/* + * Copyright (C) 2024 Rivos Inc. + */ + +#ifndef _LINUX_HUGETLB_CONTPTE_H +#define _LINUX_HUGETLB_CONTPTE_H + +#define __HAVE_ARCH_HUGE_PTEP_GET +extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t= *ptep); + +#endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/Kconfig b/mm/Kconfig index 84000b016808..8cd38de612ce 100644 --- a/mm/Kconfig +++ b/mm/Kconfig @@ -810,6 +810,9 @@ config NOMMU_INITIAL_TRIM_EXCESS config ARCH_WANT_GENERAL_HUGETLB bool =20 +config ARCH_WANT_GENERAL_HUGETLB_CONTPTE + bool + config ARCH_WANTS_THP_SWAP def_bool n =20 diff --git a/mm/Makefile b/mm/Makefile index dba52bb0da8a..1c1250fbb020 100644 --- a/mm/Makefile +++ b/mm/Makefile @@ -96,6 +96,7 @@ obj-$(CONFIG_MIGRATION) +=3D migrate.o obj-$(CONFIG_NUMA) +=3D memory-tiers.o obj-$(CONFIG_DEVICE_MIGRATION) +=3D migrate_device.o obj-$(CONFIG_TRANSPARENT_HUGEPAGE) +=3D huge_memory.o khugepaged.o +obj-$(CONFIG_ARCH_WANT_GENERAL_HUGETLB_CONTPTE) +=3D hugetlb_contpte.o obj-$(CONFIG_PAGE_COUNTER) +=3D page_counter.o obj-$(CONFIG_MEMCG_V1) +=3D memcontrol-v1.o obj-$(CONFIG_MEMCG) +=3D memcontrol.o vmpressure.o diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c new file mode 100644 index 000000000000..a03e91d3efb1 --- /dev/null +++ b/mm/hugetlb_contpte.c @@ -0,0 +1,44 @@ +// SPDX-License-Identifier: GPL-2.0-only +/* + * Copyright 2025 Rivos Inc. + */ + +#include +#include +#include + +/* + * Any arch that wants to use that needs to define: + * - __ptep_get() + * - pte_cont() + * - arch_contpte_get_num_contig() + */ + +/* + * This file implements the following contpte aware API: + * - huge_ptep_get() + */ + +pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) +{ + int ncontig, i; + pte_t orig_pte =3D __ptep_get(ptep); + + if (!pte_present(orig_pte) || !pte_cont(orig_pte)) + return orig_pte; + + ncontig =3D arch_contpte_get_num_contig(ptep, + page_size(pte_page(orig_pte)), + NULL); + + for (i =3D 0; i < ncontig; i++, ptep++) { + pte_t pte =3D __ptep_get(ptep); + + if (pte_dirty(pte)) + orig_pte =3D pte_mkdirty(orig_pte); + + if (pte_young(pte)) + orig_pte =3D pte_mkyoung(orig_pte); + } + return orig_pte; +} --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wr1-f43.google.com (mail-wr1-f43.google.com [209.85.221.43]) (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 1DD511FCFE6 for ; Mon, 27 Jan 2025 09:39:47 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.43 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970790; cv=none; b=UPtjc9GyaM0UImy6nahUIgk9pqSHh2zlJaQdjr6IBJoVe9n146+sjzSm4IuAH1dXL88Y5XL0+p6YQB3KoFcrWRgEpL7N9k6MImQm1KYBVv+54/ql/c5blNgGpI9MlIhsM+gGcQ0/ZaZKivRsn07UPBlKJdmFRv56Gs1AFzV9GRs= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970790; c=relaxed/simple; bh=vd9dV6HI9Y9nx4zxQFirJTNfZNmJcEUWkFlo4moi9uQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=QZQ/Uo80h1be7gODPFv9N3Eiqleoz3XO2oV2OcGOe738MeLbJMuLD7t1+Y8mGofN9QVYqUOJnl3x5PRMcFo+Gi9BBzojzZxSAsn81Jxm5r2DVO6L4TY3kkGdONytLSeQWjjbtHDS9qDDXg3Nuo/3ItEFgVW5e6HnjkEjhWEhZW0= 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=ErXYdb78; arc=none smtp.client-ip=209.85.221.43 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="ErXYdb78" Received: by mail-wr1-f43.google.com with SMTP id ffacd0b85a97d-38a34e8410bso2071629f8f.2 for ; Mon, 27 Jan 2025 01:39:47 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970786; x=1738575586; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=8mhN3d8PsNley3p53cGFp5ftMvicJk5x5kFgKHD2MsE=; b=ErXYdb78EV9P7eoXatCMdnGhEWHjS0kdVNAqMnNtjI8jfKdKwJfcdKfqQ1QW58s5dp LpZDqgtwXrNz6lM6aiwYUfOiSAvO1/inw1/vawILHGqs9pkNDhSzZoCVLVXGPY5opy/s vwxdIAvxi9C8d6CoElEXTZ9LUFTETO54C0tEBsSao5VU0yGofzoH52wFmrMIe9xXZanU Tu1yG5fq/74RJLpg/XeFSu6dhqeo7UMPhrseTy8xvksNZImjEEqcwi8u6vMTwhpLAX4T gG0Jy0UvP9OHzj0t5WCodzmATEy2fjHK/Sb37AGcmH1IAHqEhpeQKrKbIyjMAOqkR38G 7iPA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970786; x=1738575586; 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=8mhN3d8PsNley3p53cGFp5ftMvicJk5x5kFgKHD2MsE=; b=c78tZH5uS3yRA+SVRJGJuq9Au2+nu5iox8P2sb3n3a1RAOUf/OJ2tjqjuqbgnPv3Wr PdKC8XhusJBtpkaOr/ib0Ex3Uw2EMWd0DAcrvwLGc30asV0Mh/C6I/9Tu86pIQxhTO0p LxLPAlqOtJBHqeFcqrauYGbu0ZUVLRk+eqYaSd6xwzG1iSWT6UtcNkKSPbTRyHHlPnqg cnZd6UCQBlqtdk7raeGADFN05yMnugm2aSf2WzIx2BUhh9kuWYHkQvayMF49UqLvUKZS FrPFL+bAo6dXgEN4EYzNFImW2ad67B6Dnem7eav40AWOxuP1VOoCkHnvT2grq3mW7nEe RMSA== X-Forwarded-Encrypted: i=1; AJvYcCUg8HMWWn4fhod+WSISxAC+GYJUxdUlbZurYKQDHihDw4r3juvjxklZeI4WuOIp+qD2PVQS54M2E4pDfuM=@vger.kernel.org X-Gm-Message-State: AOJu0Ywl2S4HpmhPFCEKutr+IwnE2MO4P1aSlVAxPzB2PB/LVbKHS8gS NEj6umaYyxPLkxHQeyQXacERVkmwJIjP+pubslKI7hSWPQ4jHVJzNNrsdemMNfmiiFP3mLyrMrp K X-Gm-Gg: ASbGncs9zX1+4WvXJ67ToAs9EF8+8lvB18GKFCFown6uqs031a5nkEiSHapXeEeTjce WJoq8CBPnv6Z1GwUasw+MmEAuGmzrasHt1TVcC1lTZM0w8/3hTTjwiTy3YAMMzidi+gyoTtfntV 0HUFoOEqvP2bnUHwnddiyda8PoVaupe229lKn+zlgptL2SXnVrsvXHpWGUxw8cZ80Xy8HLJr4UX PqZP42RJhmnSIW5mb49qxADGGwdp6PQHfqOHM7rZY3DDID4GgZXuPQOKkwlL9FdJ3prikW86bDU R4Njo5HRZp004FZW0fIblSWwbsiN9q8= X-Google-Smtp-Source: AGHT+IFb60eslNQdePOaLfXv36Z0OpFdyDEXUXYChc5sJwAPhp8i6cvPTkFCm9BP5tmum6xqjAkWnA== X-Received: by 2002:a05:6000:4022:b0:385:e013:73f6 with SMTP id ffacd0b85a97d-38bf59eff21mr37315469f8f.50.1737970786287; Mon, 27 Jan 2025 01:39:46 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a1bb040sm10590537f8f.67.2025.01.27.01.39.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:39:46 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 4/9] mm: Use common set_huge_pte_at() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:25 +0100 Message-Id: <20250127093530.19548-5-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" After some adjustments, both architectures have the same implementation so move it to the generic code. Signed-off-by: Alexandre Ghiti --- arch/arm64/include/asm/hugetlb.h | 3 -- arch/arm64/mm/hugetlbpage.c | 56 ----------------------------- arch/riscv/include/asm/hugetlb.h | 5 --- arch/riscv/include/asm/pgtable.h | 8 +++-- arch/riscv/mm/hugetlbpage.c | 62 -------------------------------- include/linux/hugetlb_contpte.h | 5 +++ mm/hugetlb_contpte.c | 59 ++++++++++++++++++++++++++++++ 7 files changed, 69 insertions(+), 129 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index 27d7f4bdd724..40d87a563093 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -35,9 +35,6 @@ static inline void arch_clear_hugetlb_flags(struct folio = *folio) =20 pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte -#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT -extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte, unsigned long sz); #define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 3458461adb90..02de680a6a0d 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -145,62 +145,6 @@ static pte_t get_clear_contig_flush(struct mm_struct *= mm, return orig_pte; } =20 -/* - * Changing some bits of contiguous entries requires us to follow a - * Break-Before-Make approach, breaking the whole contiguous set - * before we can change any entries. See ARM DDI 0487A.k_iss10775, - * "Misprogramming of the Contiguous bit", page D4-1762. - * - * This helper performs the break step for use cases where the - * original pte is not needed. - */ -static void clear_flush(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long pgsize, - unsigned long ncontig) -{ - struct vm_area_struct vma =3D TLB_FLUSH_VMA(mm, 0); - unsigned long i, saddr =3D addr; - - for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) - __ptep_get_and_clear(mm, addr, ptep); - - flush_tlb_range(&vma, saddr, addr); -} - -void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, pte_t pte, unsigned long sz) -{ - size_t pgsize; - int i; - int ncontig; - unsigned long pfn, dpfn; - pgprot_t hugeprot; - - ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); - - if (!pte_present(pte)) { - for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize) - __set_ptes(mm, addr, ptep, pte, 1); - return; - } - - if (!pte_cont(pte)) { - __set_ptes(mm, addr, ptep, pte, 1); - return; - } - - pfn =3D pte_pfn(pte); - dpfn =3D pgsize >> PAGE_SHIFT; - hugeprot =3D pte_pgprot(pte); - - clear_flush(mm, addr, ptep, pgsize, ncontig); - - for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize, pfn +=3D dpfn) - __set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1); -} - pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz) { diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index d9f9bfb84908..28cbf5d761e1 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -24,11 +24,6 @@ bool arch_hugetlb_migration_supported(struct hstate *h); void huge_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long sz); =20 -#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT -void set_huge_pte_at(struct mm_struct *mm, - unsigned long addr, pte_t *ptep, pte_t pte, - unsigned long sz); - #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index d4e6427b8ca9..74d29d0af172 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -634,9 +634,8 @@ extern int ptep_set_access_flags(struct vm_area_struct = *vma, unsigned long addre extern int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned = long address, pte_t *ptep); =20 -#define __HAVE_ARCH_PTEP_GET_AND_CLEAR -static inline pte_t ptep_get_and_clear(struct mm_struct *mm, - unsigned long address, pte_t *ptep) +static inline pte_t __ptep_get_and_clear(struct mm_struct *mm, + unsigned long address, pte_t *ptep) { pte_t pte =3D __pte(atomic_long_xchg((atomic_long_t *)ptep, 0)); =20 @@ -736,6 +735,9 @@ static inline pte_t ptep_get(pte_t *ptep) #define ptep_get __ptep_get #endif /* CONFIG_RISCV_ISA_SVNAPOT */ =20 +#define __HAVE_ARCH_PTEP_GET_AND_CLEAR +#define ptep_get_and_clear __ptep_get_and_clear + #define pgprot_nx pgprot_nx static inline pgprot_t pgprot_nx(pgprot_t _prot) { diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index d51863824540..0ecb2846c3f0 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -173,68 +173,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -static void clear_flush(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long pgsize, - unsigned long ncontig) -{ - struct vm_area_struct vma =3D TLB_FLUSH_VMA(mm, 0); - unsigned long i, saddr =3D addr; - - for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) - ptep_get_and_clear(mm, addr, ptep); - - flush_tlb_range(&vma, saddr, addr); -} - -/* - * 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 - * PTEs invalid, then issue SFENCE.VMA instruction(s) covering all 4 KiB r= egions - * within the range, [...] then update the PTE(s), as described in Section - * 4.2.1.". That's the equivalent of the Break-Before-Make approach used by - * arm64. - */ -void set_huge_pte_at(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - pte_t pte, - unsigned long sz) -{ - unsigned long hugepage_shift, pgsize; - int i, pte_num; - - 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; - - if (!pte_present(pte)) { - for (i =3D 0; i < pte_num; i++, ptep++, addr +=3D pgsize) - set_ptes(mm, addr, ptep, pte, 1); - return; - } - - if (!pte_napot(pte)) { - set_ptes(mm, addr, ptep, pte, 1); - return; - } - - clear_flush(mm, addr, ptep, pgsize, pte_num); - - set_ptes(mm, addr, ptep, pte, pte_num); -} - int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h index ec4189cd65b8..7acd734a75e8 100644 --- a/include/linux/hugetlb_contpte.h +++ b/include/linux/hugetlb_contpte.h @@ -9,4 +9,9 @@ #define __HAVE_ARCH_HUGE_PTEP_GET extern pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t= *ptep); =20 +#define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT +extern void set_huge_pte_at(struct mm_struct *mm, + unsigned long addr, pte_t *ptep, pte_t pte, + unsigned long sz); + #endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c index a03e91d3efb1..677d714fd10d 100644 --- a/mm/hugetlb_contpte.c +++ b/mm/hugetlb_contpte.c @@ -10,6 +10,8 @@ /* * Any arch that wants to use that needs to define: * - __ptep_get() + * - __set_ptes() + * - __ptep_get_and_clear() * - pte_cont() * - arch_contpte_get_num_contig() */ @@ -17,6 +19,7 @@ /* * This file implements the following contpte aware API: * - huge_ptep_get() + * - set_huge_pte_at() */ =20 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -42,3 +45,59 @@ pte_t huge_ptep_get(struct mm_struct *mm, unsigned long = addr, pte_t *ptep) } return orig_pte; } + +/* + * ARM64: Changing some bits of contiguous entries requires us to follow a + * Break-Before-Make approach, breaking the whole contiguous set + * before we can change any entries. See ARM DDI 0487A.k_iss10775, + * "Misprogramming of the Contiguous bit", page D4-1762. + * + * RISCV: When dealing with NAPOT mappings, the privileged specification + * indicates that "if an update needs to be made, the OS generally should = first + * mark all of the PTEs invalid, then issue SFENCE.VMA instruction(s) cove= ring + * all 4 KiB regions within the range, [...] then update the PTE(s), as + * described in Section 4.2.1.". That's the equivalent of the Break-Before= -Make + * approach used by arm64. + * + * This helper performs the break step for use cases where the + * original pte is not needed. + */ +static void clear_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + struct vm_area_struct vma =3D TLB_FLUSH_VMA(mm, 0); + unsigned long i, saddr =3D addr; + + for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) + __ptep_get_and_clear(mm, addr, ptep); + + flush_tlb_range(&vma, saddr, addr); +} + +void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, pte_t pte, unsigned long sz) +{ + size_t pgsize; + int i; + int ncontig; + + ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); + + if (!pte_present(pte)) { + for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize) + __set_ptes(mm, addr, ptep, pte, 1); + return; + } + + if (!pte_cont(pte)) { + __set_ptes(mm, addr, ptep, pte, 1); + return; + } + + clear_flush(mm, addr, ptep, pgsize, ncontig); + + set_contptes(mm, addr, ptep, pte, ncontig, pgsize); +} --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 A6737179BF for ; Mon, 27 Jan 2025 09:40:49 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970851; cv=none; b=NbYUWLBZ58Nd2yZhcwQte1+UpmqiEhDl4s7DMUyDfG3YUeYlI4mnOh/xvoHw2OPAv+pkM0shg6HsId5RMyvQKYY2KZYxBBU5ZsVDln355I8rHcQqXXBYj9/cKgb46xeDgBFzHyWvzuJlJgrTuHmdN0gehGU5VxuloEA36PTjy5A= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970851; c=relaxed/simple; bh=4EjSeaFjma1YikaTz+Rh4jKxoWqT0DluxLNjgPqesDQ=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Sizb1iwZxI0Wd5mwFElRiJeizfwmFwajpOA+xiWD8QC9YatSUJIRdbPELJKVMLEQ/TbZa7MhCOhxyvAsxb7kXkPHdsKmnSKpDSlbrrWVIHcEB86mKSb3Bg4GA1hEmAGdBywkTltZV+rV2qkdrWgOAeZ6aFe1MwQHBp9CXUp034s= 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=TxTaWALp; arc=none smtp.client-ip=209.85.128.51 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="TxTaWALp" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-436202dd730so28980985e9.2 for ; Mon, 27 Jan 2025 01:40:49 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970848; x=1738575648; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=WRFnXJIF4/2q4SeWU0XB4ffUEopf6Q+wLHMkPdh3cGw=; b=TxTaWALp3iJczbbjYoCB9E05x6gIdDPBfq1n6/2Q8V6Hi50cBFeszBer59QT0NpK/j KHbCTbJhdH2B3GMlTXKtKTwifhkh0/cRw25n3EAYYgNX9uNTr9RUvOjq7F96ES5rEt/P iJ3rd+D0Ui0+CR2aFACCkje5vaWI2ciFKZsKcDdXbJ0JK2n7VWj15Uln8Xw0Urvf/6zp NMbaYzDZVFKMrlOzuN6v2YAkcCIP/WBn5yqwGu14dwVaN6kveAPPez5nh+pCvk6dzOeC HsLq6Df1nFBduZJDTHFUunVboBBGL6Lly5ywJGJExkWUn3nOcc9L1DA8LjD7RdXYM4RL y0lA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970848; x=1738575648; 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=WRFnXJIF4/2q4SeWU0XB4ffUEopf6Q+wLHMkPdh3cGw=; b=uzwuUlfZPsnNr+aPipm7kZNOGN+jD5qe/MDCpGc9CZWpQQ6NoGlZaltg1+0YFYn0Fn OEErIT2dnAtE+iuPsy5Da+gZoB5T+5GtxDIAYapFcQqFHhRJbs3WlJUhPmKwU+pqTfuu 9sJu69jro8yjHpsJjvGD6vcaY+hSbZCboRAc/nJUj9IuVKD387CD2Ri6v6N/qXowotUb HlTK2pEhCKAx14/yuxOpIjJYpKGqbsZze0hDaEocn1t/iwxp1lqURI9qJ5vWplS1hINV BRyqD5I3eHQ6lZbgkD+NlHeJ5kvK9+HTw7uiVrwDQIiserpMloEDZ4YchyjovZqT6Vdp Y7Rg== X-Forwarded-Encrypted: i=1; AJvYcCX2ur1urGD2S/Bq+jAjhjYcmoIP8DObsQNBCJcA0x36xQ57IFb3FbbAA+WXa5g6JNxVEqP6fUTJA4E9y3M=@vger.kernel.org X-Gm-Message-State: AOJu0YxAYqH7YbYTWxuRjDvUzhWGB5RxZzQ0c0Qzv4+uqAf5QqqdxKTK cizmahGfkV6SVaIcXnzQ97fc8l4zsjZT6tfkoraxs+q5WKIFArAJWGbP/ysHOnc= X-Gm-Gg: ASbGncusn8WXovT7uujEZQ1I7vzHUZPCjhEQJlyiYcNXs2AwEXeim7I1NlQkK9vJf2M jPStL2FD8/xjG958Ti17WAhPWi5wiCuv3JLAvR+DpNh4U7ElBspnLUgSOuEewe7DGq6Mf6847Yw F/R0QWwZAXFyMhNtOwz86CzmR/VVMzC2anBnrqJ3+a27VVahRKlE2hNAlrsm4/zEg5/B+vja4HM /Js4Hhter37dEnTQDQ917fc5JIiRjGlLQdkdyuxhuujO2+mOxT+lb2XC225Nbo/xp74UtUKFDnP gbu+eBXgzZUCIEtmLfEI4Xe1duMaLbc= X-Google-Smtp-Source: AGHT+IHaxudRMH2a6X9Kau2FejbNNa+aNZH7OQ4Z4KpCCzwiphcNEJX34OXuuFlJfN/dPYRcVT3pPw== X-Received: by 2002:a05:600c:6c9a:b0:438:a240:c54 with SMTP id 5b1f17b1804b1-438a2400d95mr279659705e9.9.1737970847952; Mon, 27 Jan 2025 01:40:47 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-438bd57517fsm122917795e9.38.2025.01.27.01.40.46 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:40:47 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 5/9] mm: Use common huge_pte_clear() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:26 +0100 Message-Id: <20250127093530.19548-6-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" Both architectures have the same implementation so move it to generic code. Signed-off-by: Alexandre Ghiti --- arch/arm64/include/asm/hugetlb.h | 3 --- arch/arm64/mm/hugetlbpage.c | 12 ------------ arch/riscv/include/asm/hugetlb.h | 4 ---- arch/riscv/include/asm/pgtable.h | 5 +++-- arch/riscv/mm/hugetlbpage.c | 19 ------------------- include/linux/hugetlb_contpte.h | 4 ++++ mm/hugetlb_contpte.c | 14 ++++++++++++++ 7 files changed, 21 insertions(+), 40 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index 40d87a563093..e4acaedea149 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -48,9 +48,6 @@ extern void huge_ptep_set_wrprotect(struct mm_struct *mm, #define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH extern pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); -#define __HAVE_ARCH_HUGE_PTE_CLEAR -extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, unsigned long sz); =20 void __init arm64_hugetlb_cma_reserve(void); =20 diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 02de680a6a0d..541358f50b64 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -277,18 +277,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -void huge_pte_clear(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, unsigned long sz) -{ - int i, ncontig; - size_t pgsize; - - ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); - - for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) - __pte_clear(mm, addr, ptep); -} - pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index 28cbf5d761e1..ca9930cdf2e6 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -20,10 +20,6 @@ bool arch_hugetlb_migration_supported(struct hstate *h); #endif =20 #ifdef CONFIG_RISCV_ISA_SVNAPOT -#define __HAVE_ARCH_HUGE_PTE_CLEAR -void huge_pte_clear(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, unsigned long sz); - #define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index 74d29d0af172..08b24c0a579b 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -621,8 +621,8 @@ static inline int arch_contpte_get_num_contig(pte_t *pt= ep, unsigned long size, } #endif =20 -static inline void pte_clear(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) +static inline void __pte_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) { __set_pte_at(mm, ptep, __pte(0)); } @@ -737,6 +737,7 @@ static inline pte_t ptep_get(pte_t *ptep) =20 #define __HAVE_ARCH_PTEP_GET_AND_CLEAR #define ptep_get_and_clear __ptep_get_and_clear +#define pte_clear __pte_clear =20 #define pgprot_nx pgprot_nx static inline pgprot_t pgprot_nx(pgprot_t _prot) diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 0ecb2846c3f0..e2093e7266a5 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -251,25 +251,6 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, return get_clear_contig_flush(vma->vm_mm, addr, ptep, pte_num); } =20 -void huge_pte_clear(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long sz) -{ - size_t pgsize; - pte_t pte =3D ptep_get(ptep); - int i, pte_num; - - if (!pte_napot(pte)) { - pte_clear(mm, addr, ptep); - return; - } - - pte_num =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); - for (i =3D 0; i < pte_num; i++, addr +=3D pgsize, ptep++) - pte_clear(mm, addr, ptep); -} - static bool is_napot_size(unsigned long size) { unsigned long order; diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h index 7acd734a75e8..d9892a047b2b 100644 --- a/include/linux/hugetlb_contpte.h +++ b/include/linux/hugetlb_contpte.h @@ -14,4 +14,8 @@ extern void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte, unsigned long sz); =20 +#define __HAVE_ARCH_HUGE_PTE_CLEAR +extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz); + #endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c index 677d714fd10d..c76d6b3d0121 100644 --- a/mm/hugetlb_contpte.c +++ b/mm/hugetlb_contpte.c @@ -12,6 +12,7 @@ * - __ptep_get() * - __set_ptes() * - __ptep_get_and_clear() + * - __pte_clear() * - pte_cont() * - arch_contpte_get_num_contig() */ @@ -20,6 +21,7 @@ * This file implements the following contpte aware API: * - huge_ptep_get() * - set_huge_pte_at() + * - huge_pte_clear() */ =20 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -101,3 +103,15 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned lo= ng addr, =20 set_contptes(mm, addr, ptep, pte, ncontig, pgsize); } + +void huge_pte_clear(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, unsigned long sz) +{ + int i, ncontig; + size_t pgsize; + + ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); + + for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) + __pte_clear(mm, addr, ptep); +} --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wm1-f51.google.com (mail-wm1-f51.google.com [209.85.128.51]) (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 1AD02179BF for ; Mon, 27 Jan 2025 09:41:50 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.51 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970913; cv=none; b=otLpg9kL7JaataTK15QmZ/1oK9S8XbA3EiSw7gBMNXaO/qN858L5heDon8D4NdDXfCzSDqi1XmRncCBvDjn+2rpOnWYC3mdyTiGnHCRGH0JVb+iRgOorsi6GoTG1QlDzhdhbFRyC2eFwCN9NSZKeUZUGZy5I74Ct+tEnZU9CBe0= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970913; c=relaxed/simple; bh=wnlhWBIrY7S3vay9E0tvvsZWstynmDSXSh9cQxqW//k=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=NrjpJuuxYkQMdElPaLbg5bPX1PDuvjI28aE2rPKQkD7vqsRRnh0tb9Sr1BnyWO3veRGoVzg357PZQPh6eGErUjOBj4g/ieCtPFjUe39GGQvg/QGbZusWtdD9+Z5PgRU4ynpUQybwN1Rlp/pbzzKEUBHo/3v3drkALM5JKxLK/bw= 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=H4GKkIxp; arc=none smtp.client-ip=209.85.128.51 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="H4GKkIxp" Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-436341f575fso45374625e9.1 for ; Mon, 27 Jan 2025 01:41:50 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970909; x=1738575709; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=/Ib7BO4DbRcQ5HoSRv1ee1R7qySu3xzgQBO2hzqpTQY=; b=H4GKkIxpmPKG2ey2Am62MWynZzumtGlLu32IHRTg3hlqvbUJJZiRE+eURsOVSiKAEk JIZ2f0ZSBfWAnAtzpGs74bc4XsOSklNQdaV7jj/XV1gcjzK51j6w2o65fbhK2VQZrkGN g04Gg/Exo3uAZcDSAboexzELKe7v0iBsT+mD6efx82HRFRlAEAqmrhVC8zV3QYI5gSrY uPyIGhX5cNNx4eenjQHg3bL9fC2DYGgRVmdF3MQjE513A7/AvOQjJPRsVt3pqS0MGpg1 HtS+Ip+5JVeuVw4U9a8ncD7Xf//Ish7UcHIVMX4gC8zDZfm4YctjYBtZGspkUNoBocMe nNzg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970909; x=1738575709; 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=/Ib7BO4DbRcQ5HoSRv1ee1R7qySu3xzgQBO2hzqpTQY=; b=rHQ0ejyPpzcsZ59PWlWe+cmYRGZbjQTho8fOQ2RBYZQYgGsYJVBAT+JsRtnW3iriC3 Rl3AKkM3/PXe2q8vVVGXrldSKEbt922VbEqxFiCNQLubTpU8duFvaOR/7fhUZPIx2zW7 mFomOW5MWRq4+PyD7mSYUAf1cFJuiL1R/QGXCH+/JmwXbmXi675XYbsOWVp0rjcE5bNf 2+VG3K+dgPLdHFqvXCvr9uJyWedcpzzBQ1mM5/OR5NxbFthAlrh6caIw3HQgrwFRYSma bo4C4GY6ejbhP7WFYFmkfNXbvrsvWzAbDLE+Fx2erB2+N1mMDYKFjnaWduV32iaj6xV6 P8xg== X-Forwarded-Encrypted: i=1; AJvYcCXZLghNMv2Y0q/ctt7oHAFc5kJ1yDMxPH5JhSstj0LSrTblnqS07vlYrfdKnhQ2OecnQlGPz+fTshkqik4=@vger.kernel.org X-Gm-Message-State: AOJu0Yw7aADkSRtb4wWW2Fuj+dQBPbSHi+P7z9RinbdxObNrtMsNvFE6 qwozrqlCknZ9HKlYc978s7TqYh88btgEKNjENxqTMDRnrW4sJU4xTS4VSOYDpVBtByJik12WwzD f X-Gm-Gg: ASbGncuIRrffkeTw5mjga7OaReXWott5GZI/zlVQ8nBKKi0LTgKh90TMnAnZJKmJ9bp 3ZsEKAWLBMnY4yFQKSo86FUGt/7xQnYfLkOLYJ4G5NcFnWYbAVGYcV7eimPTp282YLo9ew/cm8H 2g9qMYbr11r/p7/PuIw7Dyz/QgasZJ2tGZl/eU95Qu/jBG7X4old2zeq+MzeQ54LH/k0iUwHE41 w0l2PE2nztRHiWtCXldjSCXa7t2H9ptg2kFLcf83iNPoP7vfy8dITRCtCRIyo7TRdFtG8UEMtUi 4EwLG7VRpaMCqHPnuQm0LWSmbakDru0= X-Google-Smtp-Source: AGHT+IE0wvAkHX9Lz2nK7eyxGx0auM1eq+y4AS6IYBZCccECBQROh0UBY1MLjeLntJwSdARX6LIQ6w== X-Received: by 2002:a5d:64a3:0:b0:385:f909:eb2c with SMTP id ffacd0b85a97d-38bf57a77a2mr48324115f8f.38.1737970909255; Mon, 27 Jan 2025 01:41:49 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a1c42fcsm10707051f8f.96.2025.01.27.01.41.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:41:49 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 6/9] mm: Use common huge_ptep_get_and_clear() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:27 +0100 Message-Id: <20250127093530.19548-7-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" After some adjustments, both architectures have the same implementation so move it to the generic code. Note that get_clear_contig() function is duplicated in the generic and the arm64 code because it is still used by some arm64 functions that will, in the next commits, be moved to the generic code. Once all have been moved, the arm64 version will be removed. Signed-off-by: Alexandre Ghiti --- arch/arm64/include/asm/hugetlb.h | 3 -- arch/arm64/include/asm/pgtable.h | 15 ++++++++-- arch/arm64/mm/hugetlbpage.c | 19 ++----------- arch/riscv/include/asm/hugetlb.h | 4 --- arch/riscv/include/asm/pgtable.h | 4 ++- arch/riscv/mm/hugetlbpage.c | 23 ++++----------- include/linux/hugetlb_contpte.h | 4 +++ mm/hugetlb_contpte.c | 48 ++++++++++++++++++++++++++++++-- 8 files changed, 72 insertions(+), 48 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index e4acaedea149..5c605a0a2017 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -39,9 +39,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shift,= vm_flags_t flags); extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty); -#define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR -extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm, - unsigned long addr, pte_t *ptep); #define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT extern void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep); diff --git a/arch/arm64/include/asm/pgtable.h b/arch/arm64/include/asm/pgta= ble.h index cebbfcfb0e53..c339b568ac51 100644 --- a/arch/arm64/include/asm/pgtable.h +++ b/arch/arm64/include/asm/pgtable.h @@ -1831,12 +1831,23 @@ static inline void clear_young_dirty_ptes(struct vm= _area_struct *vma, =20 #endif /* CONFIG_ARM64_CONTPTE */ =20 -static inline int arch_contpte_get_num_contig(pte_t *ptep, - unsigned long size, +extern int find_num_contig(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, size_t *pgsize); + +static inline int arch_contpte_get_num_contig(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, unsigned long size, size_t *pgsize) { int contig_ptes =3D 0; =20 + /* + * If the size is not passed, we need to go through the page table to + * find out the number of contiguous ptes. + */ + if (size =3D=3D 0) + return find_num_contig(mm, addr, ptep, pgsize); + if (pgsize) *pgsize =3D size; =20 diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 541358f50b64..0b7a53fee55d 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -79,8 +79,8 @@ bool arch_hugetlb_migration_supported(struct hstate *h) } #endif =20 -static int find_num_contig(struct mm_struct *mm, unsigned long addr, - pte_t *ptep, size_t *pgsize) +int find_num_contig(struct mm_struct *mm, unsigned long addr, + pte_t *ptep, size_t *pgsize) { pgd_t *pgdp =3D pgd_offset(mm, addr); p4d_t *p4dp; @@ -277,21 +277,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) -{ - int ncontig; - size_t pgsize; - pte_t orig_pte =3D __ptep_get(ptep); - - if (!pte_cont(orig_pte)) - return __ptep_get_and_clear(mm, addr, ptep); - - ncontig =3D find_num_contig(mm, addr, ptep, &pgsize); - - return get_clear_contig(mm, addr, ptep, pgsize, ncontig); -} - /* * huge_ptep_set_access_flags will update access flags (dirty, accesssed) * and write permission. diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index ca9930cdf2e6..0fbb6b19df79 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -20,10 +20,6 @@ bool arch_hugetlb_migration_supported(struct hstate *h); #endif =20 #ifdef CONFIG_RISCV_ISA_SVNAPOT -#define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, - unsigned long addr, pte_t *ptep); - #define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index 08b24c0a579b..705d666e014d 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -590,7 +590,9 @@ static inline void __set_ptes(struct mm_struct *mm, uns= igned long addr, } =20 #ifdef CONFIG_RISCV_ISA_SVNAPOT -static inline int arch_contpte_get_num_contig(pte_t *ptep, unsigned long s= ize, +static inline int arch_contpte_get_num_contig(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, unsigned long size, size_t *pgsize) { unsigned long hugepage_shift; diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index e2093e7266a5..b44023336fd9 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -186,7 +186,8 @@ int huge_ptep_set_access_flags(struct vm_area_struct *v= ma, if (!pte_napot(pte)) return ptep_set_access_flags(vma, addr, ptep, pte, dirty); =20 - pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); + pte_num =3D arch_contpte_get_num_contig(vma->vm_mm, addr, ptep, 0, NULL); + orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); =20 if (pte_dirty(orig_pte)) @@ -200,21 +201,6 @@ int huge_ptep_set_access_flags(struct vm_area_struct *= vma, return true; } =20 -pte_t huge_ptep_get_and_clear(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep) -{ - pte_t orig_pte =3D ptep_get(ptep); - int pte_num; - - if (!pte_napot(orig_pte)) - return ptep_get_and_clear(mm, addr, ptep); - - pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); - - return get_clear_contig(mm, addr, ptep, pte_num); -} - void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -228,7 +214,8 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, return; } =20 - pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); + pte_num =3D arch_contpte_get_num_contig(mm, addr, ptep, 0, NULL); + orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); =20 orig_pte =3D pte_wrprotect(orig_pte); @@ -246,7 +233,7 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, if (!pte_napot(pte)) return ptep_clear_flush(vma, addr, ptep); =20 - pte_num =3D arch_contpte_get_num_contig(ptep, 0, NULL); + pte_num =3D arch_contpte_get_num_contig(vma->vm_mm, addr, ptep, 0, NULL); =20 return get_clear_contig_flush(vma->vm_mm, addr, ptep, pte_num); } diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h index d9892a047b2b..20d3a3e14e14 100644 --- a/include/linux/hugetlb_contpte.h +++ b/include/linux/hugetlb_contpte.h @@ -18,4 +18,8 @@ extern void set_huge_pte_at(struct mm_struct *mm, extern void huge_pte_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep, unsigned long sz); =20 +#define __HAVE_ARCH_HUGE_PTEP_GET_AND_CLEAR +extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep); + #endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c index c76d6b3d0121..0c86c6f77c29 100644 --- a/mm/hugetlb_contpte.c +++ b/mm/hugetlb_contpte.c @@ -22,6 +22,7 @@ * - huge_ptep_get() * - set_huge_pte_at() * - huge_pte_clear() + * - huge_ptep_get_and_clear() */ =20 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -32,7 +33,7 @@ pte_t huge_ptep_get(struct mm_struct *mm, unsigned long a= ddr, pte_t *ptep) if (!pte_present(orig_pte) || !pte_cont(orig_pte)) return orig_pte; =20 - ncontig =3D arch_contpte_get_num_contig(ptep, + ncontig =3D arch_contpte_get_num_contig(mm, addr, ptep, page_size(pte_page(orig_pte)), NULL); =20 @@ -86,7 +87,7 @@ void set_huge_pte_at(struct mm_struct *mm, unsigned long = addr, int i; int ncontig; =20 - ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); + ncontig =3D arch_contpte_get_num_contig(mm, addr, ptep, sz, &pgsize); =20 if (!pte_present(pte)) { for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize) @@ -110,8 +111,49 @@ void huge_pte_clear(struct mm_struct *mm, unsigned lon= g addr, int i, ncontig; size_t pgsize; =20 - ncontig =3D arch_contpte_get_num_contig(ptep, sz, &pgsize); + ncontig =3D arch_contpte_get_num_contig(mm, addr, ptep, sz, &pgsize); =20 for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) __pte_clear(mm, addr, ptep); } + +static pte_t get_clear_contig(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + pte_t orig_pte =3D __ptep_get(ptep); + unsigned long i; + + for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) { + pte_t pte =3D __ptep_get_and_clear(mm, addr, ptep); + + /* + * If HW_AFDBM (arm64) or Svadu (riscv) 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 =3D pte_mkdirty(orig_pte); + + if (pte_young(pte)) + orig_pte =3D pte_mkyoung(orig_pte); + } + return orig_pte; +} + +pte_t huge_ptep_get_and_clear(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + int ncontig; + size_t pgsize; + pte_t orig_pte =3D __ptep_get(ptep); + + if (!pte_cont(orig_pte)) + return __ptep_get_and_clear(mm, addr, ptep); + + ncontig =3D arch_contpte_get_num_contig(mm, addr, ptep, 0, &pgsize); + + return get_clear_contig(mm, addr, ptep, pgsize, ncontig); +} --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wm1-f44.google.com (mail-wm1-f44.google.com [209.85.128.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 BB8711FC7CE for ; Mon, 27 Jan 2025 09:42:52 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.44 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970974; cv=none; b=FvChh4ZbBYMTVuJE4CqBJVmFrUE5CnepzgtJ7GZ/4Ux7l/5E3iX2flSZkwNVLUY2MaHqCSQpTEOM0PtqFQ/Q4v9p695M3as6dcOIHw9jBF5PzSah/yZbLpvpu5BZeq7qAJ0JOnmJhmBt9BQ72XsGCygJcZ9pL6LAdKPrSs6JsRo= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737970974; c=relaxed/simple; bh=QANFJVXLP1apybrPYnJKLv/rvC7j9qLbw20VMB32a9E=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=Kk1IdcaZspPh6kTOqd9fuRDA+MRyGnFjApHbDCOtJ0vsN4x8EUozSk/uCBT1XFcjxinQtqSSuK+XZVSMIDL6L5dbLsBxlsa7NeiYpOj26j6sAX70Ebsl3Zk1s4vIxv4u2bU0QaonM8wxxkI6V9p9kd41IeEZVk3GThqkTSxjlFA= 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=SFrYMCgY; arc=none smtp.client-ip=209.85.128.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="SFrYMCgY" Received: by mail-wm1-f44.google.com with SMTP id 5b1f17b1804b1-43675b1155bso48216775e9.2 for ; Mon, 27 Jan 2025 01:42:52 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737970971; x=1738575771; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=GkmyUQAgkdeDfCGOVLuC8IWvmfEC8o5jHyW1gtJjCzs=; b=SFrYMCgYns+7sLJe9pDGgej22josj/ncIHUGDsbdZoDfQ32OSWizLWxNhq0tGNcVeU FFkfKdYAKrdC+ME26PJ7CbTRJYsexr1wYpCLH4lpm1s+qwFegv2QYCkuZrFTRE3lNk9e YXOfIIvpFxrcCWd2uaxw43AKHo5grLEOo5stWL2BBuM2whlLUxIN1pQ/KKgZic8c3H+x t+BU0oQXcyTUuF2zFhlX9O7e9+bLPkocNwPzkUKPEJbOyucTJuxhDmkm2bPTdaEz1rka TqdTB9ypiQiaJZ8PUaPIPXs6LURFUUvWmCllxbfFYlMnk+3Hulxal63BDCD1Evu6VEyA Wdqg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737970971; x=1738575771; 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=GkmyUQAgkdeDfCGOVLuC8IWvmfEC8o5jHyW1gtJjCzs=; b=Ypb0d3+Nvdwgf5P+RLCmhtVV+NfB6Lp9NcQN68R6FJX/lgwIPAako+ZBgCey8dj/8s A3QMTh6mIGn4NL4/cIa7nHi+fJfgtIq2E8oyxa5mp+bxIaYqO/KPqx5/K88a4dkADmut 5Y+CXqi/O+RIXdk8s2SM1AvROPGHqE/g4oNLYsy7F0p/yUTX+HOoDtx4wzDk8Qz0Cx8s uDsHsZdXILCjB/XIW+zaCrA27L5jhh5MUd3shgm5aSVqc/bVgUZ2d0n0XRf+Gy8m8O0Z Z5cjKt+kW8tRxmvLXQwgLfrxJf0O8eo1hLUp9kdMkvzRDYQGH22jA/17+nVHWdnPY5vt nB8Q== X-Forwarded-Encrypted: i=1; AJvYcCUaYJlmPxYN1fQHYAXQXwYpcyb6V39fHUbUYTSHbWC9kEBpaaW/UWuRLxrzvYq98+JzOyuUVlj3V6DoDpo=@vger.kernel.org X-Gm-Message-State: AOJu0YwKqqcci+KVlMVaXM1IChv/vZFNeYD5Ckl4n5qn2K6ZD45X9k1d REiqlhNs7mxQbOTiOXPFPkDhV6DR4F61JKyXNaKjq7bhR8TuIBGMFCAfLHI0LIo= X-Gm-Gg: ASbGncuCDfGar86PJqSQh1dSAMBngZx0w0gm5QVpicNsSzd5cNreRZ14AxI2IdU3ZYA lcOB5jYgOToM0llSdi1ijEYciAlHn5vdGYj1dGGwMhVRT9LcwEe9GWHtdyH+nGYPeD1Phks//Wd xU4Z6xXIsybijtaIu1I6gwfVdUpt1RB5jW5TPA7pbIlky+kSrZDoqp9oBawqlUlMsbQyjrHZDZq r2jr/PQPF+Ikvj7cUNx5Gitm9FU5ELLtCv+PL+icro50Ep0jTTbo/VhxDGf9iSsGqHuMO6t4aRP fEDzmCvhYb5wyxbtaCqhlOPs0C4QMAg= X-Google-Smtp-Source: AGHT+IFkGD+876PDgJO8tAmQAHU0ol+3F5plCgX8+RfXXi3SGv5kqaXmgh3Sp+SaS77G8Nc/FNbA7g== X-Received: by 2002:a05:6000:1ac6:b0:385:f07b:93da with SMTP id ffacd0b85a97d-38bf57bf69bmr33979049f8f.47.1737970970947; Mon, 27 Jan 2025 01:42:50 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a17d6edsm10380540f8f.40.2025.01.27.01.42.49 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:42:50 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 7/9] mm: Use common huge_ptep_set_access_flags() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:28 +0100 Message-Id: <20250127093530.19548-8-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" Both architectures have almost the same implementation: __cont_access_flags_changed() is also correct on riscv and brings the same benefits (ie don't do anything if the flags are unchanged). As in the previous commit, get_clear_contig_flush() is duplicated in both the arch and the generic codes, it will be removed from the arch code when the last reference there gets moved to the generic code. Signed-off-by: Alexandre Ghiti --- arch/arm64/include/asm/hugetlb.h | 4 -- arch/arm64/mm/hugetlbpage.c | 65 --------------------------- arch/riscv/include/asm/hugetlb.h | 5 --- arch/riscv/include/asm/pgtable.h | 7 +-- arch/riscv/mm/hugetlbpage.c | 28 ------------ arch/riscv/mm/pgtable.c | 6 +-- include/linux/hugetlb_contpte.h | 5 +++ mm/hugetlb_contpte.c | 75 ++++++++++++++++++++++++++++++++ 8 files changed, 87 insertions(+), 108 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index 5c605a0a2017..654f5f2f03a3 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -35,10 +35,6 @@ static inline void arch_clear_hugetlb_flags(struct folio= *folio) =20 pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte -#define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS -extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep, - pte_t pte, int dirty); #define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT extern void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep); diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 0b7a53fee55d..643ba2043f0f 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -277,71 +277,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -/* - * huge_ptep_set_access_flags will update access flags (dirty, accesssed) - * and write permission. - * - * For a contiguous huge pte range we need to check whether or not write - * permission has to change only on the first pte in the set. Then for - * all the contiguous ptes we need to check whether or not there is a - * discrepancy between dirty or young. - */ -static int __cont_access_flags_changed(pte_t *ptep, pte_t pte, int ncontig) -{ - int i; - - if (pte_write(pte) !=3D pte_write(__ptep_get(ptep))) - return 1; - - for (i =3D 0; i < ncontig; i++) { - pte_t orig_pte =3D __ptep_get(ptep + i); - - if (pte_dirty(pte) !=3D pte_dirty(orig_pte)) - return 1; - - if (pte_young(pte) !=3D pte_young(orig_pte)) - return 1; - } - - return 0; -} - -int huge_ptep_set_access_flags(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep, - pte_t pte, int dirty) -{ - int ncontig, i; - size_t pgsize =3D 0; - unsigned long pfn =3D pte_pfn(pte), dpfn; - struct mm_struct *mm =3D vma->vm_mm; - pgprot_t hugeprot; - pte_t orig_pte; - - if (!pte_cont(pte)) - return __ptep_set_access_flags(vma, addr, ptep, pte, dirty); - - ncontig =3D find_num_contig(mm, addr, ptep, &pgsize); - dpfn =3D pgsize >> PAGE_SHIFT; - - if (!__cont_access_flags_changed(ptep, pte, ncontig)) - return 0; - - orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); - - /* Make sure we don't lose the dirty or young state */ - if (pte_dirty(orig_pte)) - pte =3D pte_mkdirty(pte); - - if (pte_young(orig_pte)) - pte =3D pte_mkyoung(pte); - - hugeprot =3D pte_pgprot(pte); - for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize, pfn +=3D dpfn) - __set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1); - - return 1; -} - void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) { diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index 0fbb6b19df79..bf533c2cef84 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -28,11 +28,6 @@ pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep); =20 -#define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS -int huge_ptep_set_access_flags(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep, - pte_t pte, int dirty); - pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte =20 diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index 705d666e014d..290d5fbfe031 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -629,9 +629,8 @@ static inline void __pte_clear(struct mm_struct *mm, __set_pte_at(mm, ptep, __pte(0)); } =20 -#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS /* defined in mm/pgtable.c */ -extern int ptep_set_access_flags(struct vm_area_struct *vma, unsigned long= address, - pte_t *ptep, pte_t entry, int dirty); +extern int __ptep_set_access_flags(struct vm_area_struct *vma, unsigned lo= ng address, + pte_t *ptep, pte_t entry, int dirty); #define __HAVE_ARCH_PTEP_TEST_AND_CLEAR_YOUNG /* defined in mm/pgtable.c */ extern int ptep_test_and_clear_young(struct vm_area_struct *vma, unsigned = long address, pte_t *ptep); @@ -740,6 +739,8 @@ static inline pte_t ptep_get(pte_t *ptep) #define __HAVE_ARCH_PTEP_GET_AND_CLEAR #define ptep_get_and_clear __ptep_get_and_clear #define pte_clear __pte_clear +#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS +#define ptep_set_access_flags __ptep_set_access_flags =20 #define pgprot_nx pgprot_nx static inline pgprot_t pgprot_nx(pgprot_t _prot) diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index b44023336fd9..0e2ca7327479 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -173,34 +173,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -int huge_ptep_set_access_flags(struct vm_area_struct *vma, - unsigned long addr, - pte_t *ptep, - pte_t pte, - int dirty) -{ - struct mm_struct *mm =3D vma->vm_mm; - pte_t orig_pte; - int pte_num; - - if (!pte_napot(pte)) - return ptep_set_access_flags(vma, addr, ptep, pte, dirty); - - pte_num =3D arch_contpte_get_num_contig(vma->vm_mm, addr, ptep, 0, NULL); - - orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); - - if (pte_dirty(orig_pte)) - pte =3D pte_mkdirty(pte); - - if (pte_young(orig_pte)) - pte =3D pte_mkyoung(pte); - - set_ptes(mm, addr, ptep, pte, pte_num); - - return true; -} - void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep) diff --git a/arch/riscv/mm/pgtable.c b/arch/riscv/mm/pgtable.c index 4ae67324f992..af8b3769a349 100644 --- a/arch/riscv/mm/pgtable.c +++ b/arch/riscv/mm/pgtable.c @@ -5,9 +5,9 @@ #include #include =20 -int ptep_set_access_flags(struct vm_area_struct *vma, - unsigned long address, pte_t *ptep, - pte_t entry, int dirty) +int __ptep_set_access_flags(struct vm_area_struct *vma, + unsigned long address, pte_t *ptep, + pte_t entry, int dirty) { asm goto(ALTERNATIVE("nop", "j %l[svvptc]", 0, RISCV_ISA_EXT_SVVPTC, 1) : : : : svvptc); diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h index 20d3a3e14e14..fea47035ac38 100644 --- a/include/linux/hugetlb_contpte.h +++ b/include/linux/hugetlb_contpte.h @@ -22,4 +22,9 @@ extern void huge_pte_clear(struct mm_struct *mm, unsigned= long addr, extern pte_t huge_ptep_get_and_clear(struct mm_struct *mm, unsigned long addr, pte_t *ptep); =20 +#define __HAVE_ARCH_HUGE_PTEP_SET_ACCESS_FLAGS +extern int huge_ptep_set_access_flags(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, + pte_t pte, int dirty); + #endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c index 0c86c6f77c29..49950c1ce615 100644 --- a/mm/hugetlb_contpte.c +++ b/mm/hugetlb_contpte.c @@ -13,6 +13,7 @@ * - __set_ptes() * - __ptep_get_and_clear() * - __pte_clear() + * - __ptep_set_access_flags() * - pte_cont() * - arch_contpte_get_num_contig() */ @@ -23,6 +24,7 @@ * - set_huge_pte_at() * - huge_pte_clear() * - huge_ptep_get_and_clear() + * - huge_ptep_set_access_flags() */ =20 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -157,3 +159,76 @@ pte_t huge_ptep_get_and_clear(struct mm_struct *mm, =20 return get_clear_contig(mm, addr, ptep, pgsize, ncontig); } + +/* + * huge_ptep_set_access_flags will update access flags (dirty, accesssed) + * and write permission. + * + * For a contiguous huge pte range we need to check whether or not write + * permission has to change only on the first pte in the set. Then for + * all the contiguous ptes we need to check whether or not there is a + * discrepancy between dirty or young. + */ +static int __cont_access_flags_changed(pte_t *ptep, pte_t pte, int ncontig) +{ + int i; + + if (pte_write(pte) !=3D pte_write(__ptep_get(ptep))) + return 1; + + for (i =3D 0; i < ncontig; i++) { + pte_t orig_pte =3D __ptep_get(ptep + i); + + if (pte_dirty(pte) !=3D pte_dirty(orig_pte)) + return 1; + + if (pte_young(pte) !=3D pte_young(orig_pte)) + return 1; + } + + return 0; +} + +static pte_t get_clear_contig_flush(struct mm_struct *mm, + unsigned long addr, + pte_t *ptep, + unsigned long pgsize, + unsigned long ncontig) +{ + pte_t orig_pte =3D get_clear_contig(mm, addr, ptep, pgsize, ncontig); + struct vm_area_struct vma =3D TLB_FLUSH_VMA(mm, 0); + + flush_tlb_range(&vma, addr, addr + (pgsize * ncontig)); + return orig_pte; +} + +int huge_ptep_set_access_flags(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep, + pte_t pte, int dirty) +{ + int ncontig; + size_t pgsize =3D 0; + struct mm_struct *mm =3D vma->vm_mm; + pte_t orig_pte; + + if (!pte_cont(pte)) + return __ptep_set_access_flags(vma, addr, ptep, pte, dirty); + + ncontig =3D arch_contpte_get_num_contig(vma->vm_mm, addr, ptep, 0, &pgsiz= e); + + if (!__cont_access_flags_changed(ptep, pte, ncontig)) + return 0; + + orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); + + /* Make sure we don't lose the dirty or young state */ + if (pte_dirty(orig_pte)) + pte =3D pte_mkdirty(pte); + + if (pte_young(orig_pte)) + pte =3D pte_mkyoung(pte); + + set_contptes(mm, addr, ptep, pte, ncontig, pgsize); + + return 1; +} --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wr1-f41.google.com (mail-wr1-f41.google.com [209.85.221.41]) (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 4955B1D540 for ; Mon, 27 Jan 2025 09:43:53 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.221.41 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737971036; cv=none; b=aq5YPoQpk5lQ6t+z7clPzseF4Z/ywYSU2Gv2GAYsekCC4wF2dxyxc0T/0GbtUjDwmODKupi66yk2HzbFzf7XPmG4r9VsKisIQ4MA+JWUQ288RlRQnA1FG/+aQ/p1Kn1gpRQ9DTfxzGyF4P3ST6IEwscucqo6i3ZZm+kt4TYnP3w= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737971036; c=relaxed/simple; bh=W4BU+7ZxHze8a03+hdx9R9TLCBIXkq4dSl9lYttp77g=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=cEFmimTlJv/YNnDvqTNCg3fxT8tuhgOvd0rksJ5LJGfh3uiSiy9r8PDTp6WwAcHT6nnF6JoxYxAlMC6NceLOl6pPJ77Qei+dWOHzj/uKJOV572tcEqU2dECPYSGamM33FFPwk1TSvUqWdGcFNbY2sqnzuiBMUlMOloBlWtPkyyM= 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=1OtYMwuZ; arc=none smtp.client-ip=209.85.221.41 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="1OtYMwuZ" Received: by mail-wr1-f41.google.com with SMTP id ffacd0b85a97d-38a25d4b9d4so2206319f8f.0 for ; Mon, 27 Jan 2025 01:43:53 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737971032; x=1738575832; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=C5hVtVN5ts8qRfTru3U6IxaXR2nRBQvNb9/UQuUojb8=; b=1OtYMwuZ+HIUd08opbq0z+OVzPutCVV7BMI/rRs1nx2p04iQo/Y95hm5WyZgLPy1xi jmSV+Wp14WBAJ5Rmwp34wWPmaUdq908zec14MQ6wKZ+ZkimtF7+8dVH1PXwwCcm3CnTz Bx1kXymXZzWXvj1jxo/jm7ZtRic19RsBgJF6f6t5G9tnFQ5upH0JN0hm//NZfg+fnac3 PDDT22phDrVT/PGypRejbLVe5vX/ySAhv10NDSv9MQc9yjwXjQGTnSU92Drs0R4aLTN4 F1n8PMBw1/wsoubWV6lbHXEG/FEYk4UJufEJfpNMMTKE9BePqOsJiKPsTimZuJeS6RVV s8jQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737971032; x=1738575832; 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=C5hVtVN5ts8qRfTru3U6IxaXR2nRBQvNb9/UQuUojb8=; b=I7lh7Pku0t+ouqeJBl6GfoFjz/KTLtWp+g6IcuD+Psqbbgz84DMBjljJqNQQac1zrW MFfM3BNwzGD6TWu5vm8jwR64Tc22G3DW/qQwxrM2aqtwlJ85ot3Dhp1/uWBjDcso2+/w AdMqziins676UXB2ERznWkEfn800wrb+/KO3A8pz3b4AMLjN2YCEBWQMHSa2VeiYltJP Iw5WguQovn8tYtTcgKZz2KeKG7HmejTTFzAV0t15jG/yVdLfkk/AzaRh49AAulsCcsK/ +rMT5jhOBLBKio19lsYM2T0SOPDgHhx3WnQJPPTXh3UJ9ObAT23PJVvCcjSq1vBPjpZt s2Kw== X-Forwarded-Encrypted: i=1; AJvYcCWSKOaOokYyjf/5qf7BJ7HprBC5My4Eg0jw07GKvuqKrABGZYHtOzrTFspp95ftPJKVpCFeHqA/9QZhFDs=@vger.kernel.org X-Gm-Message-State: AOJu0Yz+UlafrvObgiMFvo+ZXVda0ErR6r+nGqKKjUnq3RPZJV0Qr4pQ wudB5SAr5T1avWByxOkaGHyAv7RzOZ2spBs0j5ZX3gpF3h/Qeh7ew53yVwG8lk0= X-Gm-Gg: ASbGnctM886Ip5O+8xx7yU/SEmJZiUGfLe3BVQwXO2lV59Sos2AQHJ8TJkjwTVvaIEq ugvu9HQVRicsROvTaasqsZw3K9qnMFSgBS+Zj7rGxp1lcQVqUnaVGDXgcougG128dPUPIInp4jF 6IF/PeCv3eQnaayKMf1QsP+6iWk5mHF6arbY6f8DdUjqvAK3MpNHIa4fIBG9ghXHCkcQ+0i/+YX VPdR8/7EY41tA6aQUbid67ZRsgdI27nhJlhOpcbJ9PlSZb1avoWY6fP6rsYDtDsqdIWFMhMmC4d offwxtNFoSTDOrZSmcwc2/97Dv/kaB4= X-Google-Smtp-Source: AGHT+IFXkE/IMZA1k4v5FDtRJn2j5Onh6MT51lwkeaLHVsBqz96ACklS2Q489STBeMVgKrxepukPbg== X-Received: by 2002:a05:6000:18a8:b0:385:f69a:7e5f with SMTP id ffacd0b85a97d-38bf57a9a86mr46329622f8f.38.1737971032476; Mon, 27 Jan 2025 01:43:52 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-38c2a17d6a6sm10405111f8f.26.2025.01.27.01.43.51 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:43:52 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 8/9] mm: Use common huge_ptep_set_wrprotect() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:29 +0100 Message-Id: <20250127093530.19548-9-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" After some adjustments, both architectures have the same implementation so move it to the generic code. Signed-off-by: Alexandre Ghiti --- arch/arm64/include/asm/hugetlb.h | 3 --- arch/arm64/mm/hugetlbpage.c | 27 --------------------------- arch/riscv/include/asm/hugetlb.h | 4 ---- arch/riscv/include/asm/pgtable.h | 7 ++++--- arch/riscv/mm/hugetlbpage.c | 22 ---------------------- include/linux/hugetlb_contpte.h | 4 ++++ mm/hugetlb_contpte.c | 22 ++++++++++++++++++++++ 7 files changed, 30 insertions(+), 59 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index 654f5f2f03a3..fd1de0caad3f 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -35,9 +35,6 @@ static inline void arch_clear_hugetlb_flags(struct folio = *folio) =20 pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte -#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT -extern void huge_ptep_set_wrprotect(struct mm_struct *mm, - unsigned long addr, pte_t *ptep); #define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH extern pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 643ba2043f0f..0430cb41f381 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -277,33 +277,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -void huge_ptep_set_wrprotect(struct mm_struct *mm, - unsigned long addr, pte_t *ptep) -{ - unsigned long pfn, dpfn; - pgprot_t hugeprot; - int ncontig, i; - size_t pgsize; - pte_t pte; - - if (!pte_cont(__ptep_get(ptep))) { - __ptep_set_wrprotect(mm, addr, ptep); - return; - } - - ncontig =3D find_num_contig(mm, addr, ptep, &pgsize); - dpfn =3D pgsize >> PAGE_SHIFT; - - pte =3D get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); - pte =3D pte_wrprotect(pte); - - hugeprot =3D pte_pgprot(pte); - pfn =3D pte_pfn(pte); - - for (i =3D 0; i < ncontig; i++, ptep++, addr +=3D pgsize, pfn +=3D dpfn) - __set_ptes(mm, addr, ptep, pfn_pte(pfn, hugeprot), 1); -} - pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) { diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index bf533c2cef84..4c692dd82779 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -24,10 +24,6 @@ bool arch_hugetlb_migration_supported(struct hstate *h); pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep); =20 -#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT -void huge_ptep_set_wrprotect(struct mm_struct *mm, - unsigned long addr, pte_t *ptep); - pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte =20 diff --git a/arch/riscv/include/asm/pgtable.h b/arch/riscv/include/asm/pgta= ble.h index 290d5fbfe031..5a29153a4013 100644 --- a/arch/riscv/include/asm/pgtable.h +++ b/arch/riscv/include/asm/pgtable.h @@ -645,9 +645,8 @@ static inline pte_t __ptep_get_and_clear(struct mm_stru= ct *mm, return pte; } =20 -#define __HAVE_ARCH_PTEP_SET_WRPROTECT -static inline void ptep_set_wrprotect(struct mm_struct *mm, - unsigned long address, pte_t *ptep) +static inline void __ptep_set_wrprotect(struct mm_struct *mm, + unsigned long address, pte_t *ptep) { atomic_long_and(~(unsigned long)_PAGE_WRITE, (atomic_long_t *)ptep); } @@ -741,6 +740,8 @@ static inline pte_t ptep_get(pte_t *ptep) #define pte_clear __pte_clear #define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS #define ptep_set_access_flags __ptep_set_access_flags +#define __HAVE_ARCH_PTEP_SET_WRPROTECT +#define ptep_set_wrprotect __ptep_set_wrprotect =20 #define pgprot_nx pgprot_nx static inline pgprot_t pgprot_nx(pgprot_t _prot) diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 0e2ca7327479..8963a4e77742 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -173,28 +173,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -void huge_ptep_set_wrprotect(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep) -{ - pte_t pte =3D ptep_get(ptep); - pte_t orig_pte; - int pte_num; - - if (!pte_napot(pte)) { - ptep_set_wrprotect(mm, addr, ptep); - return; - } - - pte_num =3D arch_contpte_get_num_contig(mm, addr, ptep, 0, NULL); - - orig_pte =3D get_clear_contig_flush(mm, addr, ptep, pte_num); - - orig_pte =3D pte_wrprotect(orig_pte); - - set_ptes(mm, addr, ptep, orig_pte, pte_num); -} - pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, unsigned long addr, pte_t *ptep) diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h index fea47035ac38..02bce0ed93d8 100644 --- a/include/linux/hugetlb_contpte.h +++ b/include/linux/hugetlb_contpte.h @@ -27,4 +27,8 @@ extern int huge_ptep_set_access_flags(struct vm_area_stru= ct *vma, unsigned long addr, pte_t *ptep, pte_t pte, int dirty); =20 +#define __HAVE_ARCH_HUGE_PTEP_SET_WRPROTECT +extern void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep); + #endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c index 49950c1ce615..de505350ef48 100644 --- a/mm/hugetlb_contpte.c +++ b/mm/hugetlb_contpte.c @@ -14,6 +14,7 @@ * - __ptep_get_and_clear() * - __pte_clear() * - __ptep_set_access_flags() + * - __ptep_set_wrprotect() * - pte_cont() * - arch_contpte_get_num_contig() */ @@ -25,6 +26,7 @@ * - huge_pte_clear() * - huge_ptep_get_and_clear() * - huge_ptep_set_access_flags() + * - huge_ptep_set_wrprotect() */ =20 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -232,3 +234,23 @@ int huge_ptep_set_access_flags(struct vm_area_struct *= vma, =20 return 1; } + +void huge_ptep_set_wrprotect(struct mm_struct *mm, + unsigned long addr, pte_t *ptep) +{ + int ncontig; + size_t pgsize; + pte_t pte; + + if (!pte_cont(__ptep_get(ptep))) { + __ptep_set_wrprotect(mm, addr, ptep); + return; + } + + ncontig =3D arch_contpte_get_num_contig(mm, addr, ptep, 0, &pgsize); + + pte =3D get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); + pte =3D pte_wrprotect(pte); + + set_contptes(mm, addr, ptep, pte, ncontig, pgsize); +} --=20 2.39.2 From nobody Thu Jan 30 19:12:51 2025 Received: from mail-wm1-f54.google.com (mail-wm1-f54.google.com [209.85.128.54]) (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 CF9551D540 for ; Mon, 27 Jan 2025 09:44:55 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=209.85.128.54 ARC-Seal: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737971097; cv=none; b=gCXd+ixCAOL2gi9g66NA5hILtGOhGyCzSbjCTo6Y+o+O75Ja1jT5EuJYOkdUUAO5yvppUhLDy+HTR0dHwQLjgoKhal5qbyRjdTv/o7YwfQg9bDbcJihRZv2Iw92tbaY/oevzrJGQJ8a0r9CG80uXJhOQTRMiS5O+vqeYdi19zK4= ARC-Message-Signature: i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1737971097; c=relaxed/simple; bh=PSchjF5Jmjs41tdwt8Wkn5yndoX5vdBb27NiQ+75iCA=; h=From:To:Cc:Subject:Date:Message-Id:In-Reply-To:References: MIME-Version; b=rmu2+nzyw0lditcFgUczCAsmSn2LYl5JVIywBE3QytfubeZbJv46ZhRERXe+dSS4VX/5DLn/on21MjzK1mtzfC4OA4+PENeX/sDKMI9TRjYgsv2O99xOLH28aq5Gb18CUb70JCvHlRMkNTAPm0q0wvXv7YbSAiQIR+FOCtJC80A= 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=nWVOmM8V; arc=none smtp.client-ip=209.85.128.54 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="nWVOmM8V" Received: by mail-wm1-f54.google.com with SMTP id 5b1f17b1804b1-4364a37a1d7so43285515e9.3 for ; Mon, 27 Jan 2025 01:44:55 -0800 (PST) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=rivosinc-com.20230601.gappssmtp.com; s=20230601; t=1737971094; x=1738575894; darn=vger.kernel.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to; bh=jsGp3DbjRPLkoj2kwFjv1+EJYiVm/DSEknC/OoKntbQ=; b=nWVOmM8V62L7ip3wZaEHxR6P9YES08p1e+MXsD6eGysJUfAqqp85/CmZY/1fXbIny/ UheamcwmisM84g2efbvMz/S3dIun4hy22OeS9QWV8Be8Xh6PjQLuBRHD85ayWdThsQ23 RMm5fkPkkVhXmTUrFWkzGCOAnccORCXAR/zeVJWOtcaCMWyBRwUKkNbLUnPJBa7WG7RO L7LpqcWe5f3VNbwB+o6+j/FwFyytrlIzRmAlGQiTjiWidZOXaeifxlobApIsQWKaY7op X4fr3frhZCVL7x7lBXrEv4sDNce6zhRgERUI0DndDwj/jBsUQo97bu6IxSCR+T4oLAij 869g== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1737971094; x=1738575894; 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=jsGp3DbjRPLkoj2kwFjv1+EJYiVm/DSEknC/OoKntbQ=; b=rSwZNu6/AfoMUJCnCLIbtwxluL0URdk8wbplgTs+hUJW2gQrxsG+vCjpHAM+2x0L/4 8DRORWausCaBwcxwptVHM+bLHp3XotBSkrHTU1WiNXvuzGexFO/LzqP0UPcSuduQvHsx rPBlmokg7JZBepNI90gs7ia23PaYKIRE8ryZU/6WhshTcPPeKp4FgJEzO/PSxODCNCzL hLsmvVQdqHI/pApDgMz8h8nSxOSf7xFDjkAlXqVnJn6litGPapJIB5esbwRUp1Jkqukc Ow4/VYgOTFfWzS5tit/Bn+WgZbGi5dIdaGNVN+KHIZPtZXazeYkV3e31xAeQ0fSOXObn r40Q== X-Forwarded-Encrypted: i=1; AJvYcCWr1yPVcLpUren9MPxt97RxfH3UxAOsjZLwsnAbMkaOsAzEMTjqhJPvyq9yRIl7525qHwgKCaf2BRQW6C8=@vger.kernel.org X-Gm-Message-State: AOJu0Yxj2rjzpfJX0hOgQV3PQeIQGWhCN4KQq7wHTdIOmG17z6oGXhKF +PWwlC0CYqjYkpW1C0ZFGzt1hiuUwmTN6AKv3p9igaiixq5PrCZ3ltE3NxgfJz0= X-Gm-Gg: ASbGncuqcEfJNJYTA6DYJJPi/E+XnWcUXhxJkoTQfgAD35HNrxN0FXJRN5VfmFQ6hfK LLrepCtJQw5WtnHBvjGbGF8B8lV5oXferGv2pxbg6hlfvQkZFOeEOPAfLDM3iqJ86RBlqunjDd1 YxgCWsmwRHYZ3VbghrcKxyesuVtO9N4jZHDikf52id8oiowiQ8wIGZFtSh2hi5hm+99deoxI+9T 8pzj+LjYYyELbme9DHl8K4ZkR07cn+fDcwYc05tVjoITRxb0VKHVfKCRda2f+ZuphQOJ2neLA6V MTyAACy1XM7Eb1/WbmLEhLcbmTiux8s= X-Google-Smtp-Source: AGHT+IFDaK9cNMo23MROO6bkzC2nQlBGexsaacNWVhEd87bHI/6OEZGcK91epmkFjxQ01HSL43+DVA== X-Received: by 2002:a05:600c:1ca9:b0:434:f297:8e78 with SMTP id 5b1f17b1804b1-438913cb65fmr390606995e9.7.1737971094091; Mon, 27 Jan 2025 01:44:54 -0800 (PST) Received: from alex-rivos.ba.rivosinc.com ([2001:861:3382:ef90:3e22:3e78:ce5a:32c3]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-438bd47eecasm124006275e9.6.2025.01.27.01.44.53 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 27 Jan 2025 01:44:53 -0800 (PST) From: Alexandre Ghiti To: Catalin Marinas , Will Deacon , Ryan Roberts , Mark Rutland , Paul Walmsley , Palmer Dabbelt , Albert Ou , Andrew Morton , linux-arm-kernel@lists.infradead.org, linux-kernel@vger.kernel.org, linux-riscv@lists.infradead.org, linux-mm@kvack.org Cc: Alexandre Ghiti Subject: [PATCH v4 9/9] mm: Use common huge_ptep_clear_flush() function for riscv/arm64 Date: Mon, 27 Jan 2025 10:35:30 +0100 Message-Id: <20250127093530.19548-10-alexghiti@rivosinc.com> X-Mailer: git-send-email 2.39.2 In-Reply-To: <20250127093530.19548-1-alexghiti@rivosinc.com> References: <20250127093530.19548-1-alexghiti@rivosinc.com> 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" After some adjustments, both architectures have the same implementation so move it to the generic code. Signed-off-by: Alexandre Ghiti --- arch/arm64/include/asm/hugetlb.h | 3 -- arch/arm64/mm/hugetlbpage.c | 61 -------------------------------- arch/riscv/include/asm/hugetlb.h | 7 +--- arch/riscv/mm/hugetlbpage.c | 51 -------------------------- include/linux/hugetlb_contpte.h | 4 +++ mm/hugetlb_contpte.c | 15 ++++++++ 6 files changed, 20 insertions(+), 121 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/huge= tlb.h index fd1de0caad3f..3f79e4b76711 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -35,9 +35,6 @@ static inline void arch_clear_hugetlb_flags(struct folio = *folio) =20 pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte -#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH -extern pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep); =20 void __init arm64_hugetlb_cma_reserve(void); =20 diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index 0430cb41f381..270e4580e12a 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -98,53 +98,6 @@ int find_num_contig(struct mm_struct *mm, unsigned long = addr, return CONT_PTES; } =20 -/* - * Changing some bits of contiguous entries requires us to follow a - * Break-Before-Make approach, breaking the whole contiguous set - * before we can change any entries. See ARM DDI 0487A.k_iss10775, - * "Misprogramming of the Contiguous bit", page D4-1762. - * - * This helper performs the break step. - */ -static pte_t get_clear_contig(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long pgsize, - unsigned long ncontig) -{ - pte_t orig_pte =3D __ptep_get(ptep); - unsigned long i; - - for (i =3D 0; i < ncontig; i++, addr +=3D pgsize, ptep++) { - pte_t pte =3D __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 =3D pte_mkdirty(orig_pte); - - if (pte_young(pte)) - orig_pte =3D pte_mkyoung(orig_pte); - } - return orig_pte; -} - -static pte_t get_clear_contig_flush(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long pgsize, - unsigned long ncontig) -{ - pte_t orig_pte =3D get_clear_contig(mm, addr, ptep, pgsize, ncontig); - struct vm_area_struct vma =3D TLB_FLUSH_VMA(mm, 0); - - flush_tlb_range(&vma, addr, addr + (pgsize * ncontig)); - return orig_pte; -} - pte_t *huge_pte_alloc(struct mm_struct *mm, struct vm_area_struct *vma, unsigned long addr, unsigned long sz) { @@ -277,20 +230,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep) -{ - struct mm_struct *mm =3D vma->vm_mm; - size_t pgsize; - int ncontig; - - if (!pte_cont(__ptep_get(ptep))) - return ptep_clear_flush(vma, addr, ptep); - - ncontig =3D find_num_contig(mm, addr, ptep, &pgsize); - return get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); -} - static int __init hugetlbpage_init(void) { if (pud_sect_supported()) diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/huge= tlb.h index 4c692dd82779..63c7e4fa342a 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -20,14 +20,9 @@ bool arch_hugetlb_migration_supported(struct hstate *h); #endif =20 #ifdef CONFIG_RISCV_ISA_SVNAPOT -#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH -pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, - unsigned long addr, pte_t *ptep); - pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags= ); #define arch_make_huge_pte arch_make_huge_pte - -#endif /*CONFIG_RISCV_ISA_SVNAPOT*/ +#endif /* CONFIG_RISCV_ISA_SVNAPOT */ =20 #include =20 diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index 8963a4e77742..ea1ae3a43d45 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -121,42 +121,6 @@ unsigned long hugetlb_mask_last_page(struct hstate *h) return 0UL; } =20 -static pte_t get_clear_contig(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long pte_num) -{ - 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); - } - - return orig_pte; -} - -static pte_t get_clear_contig_flush(struct mm_struct *mm, - unsigned long addr, - pte_t *ptep, - unsigned long pte_num) -{ - pte_t orig_pte =3D get_clear_contig(mm, addr, ptep, pte_num); - struct vm_area_struct vma =3D TLB_FLUSH_VMA(mm, 0); - bool valid =3D !pte_none(orig_pte); - - if (valid) - flush_tlb_range(&vma, addr, addr + (PAGE_SIZE * pte_num)); - - return orig_pte; -} - pte_t arch_make_huge_pte(pte_t entry, unsigned int shift, vm_flags_t flags) { unsigned long order; @@ -173,21 +137,6 @@ pte_t arch_make_huge_pte(pte_t entry, unsigned int shi= ft, vm_flags_t flags) return entry; } =20 -pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, - unsigned long addr, - pte_t *ptep) -{ - pte_t pte =3D ptep_get(ptep); - int pte_num; - - if (!pte_napot(pte)) - return ptep_clear_flush(vma, addr, ptep); - - pte_num =3D arch_contpte_get_num_contig(vma->vm_mm, addr, ptep, 0, NULL); - - return get_clear_contig_flush(vma->vm_mm, addr, ptep, pte_num); -} - static bool is_napot_size(unsigned long size) { unsigned long order; diff --git a/include/linux/hugetlb_contpte.h b/include/linux/hugetlb_contpt= e.h index 02bce0ed93d8..911b9cd4aa4d 100644 --- a/include/linux/hugetlb_contpte.h +++ b/include/linux/hugetlb_contpte.h @@ -31,4 +31,8 @@ extern int huge_ptep_set_access_flags(struct vm_area_stru= ct *vma, extern void huge_ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, pte_t *ptep); =20 +#define __HAVE_ARCH_HUGE_PTEP_CLEAR_FLUSH +extern pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep); + #endif /* _LINUX_HUGETLB_CONTPTE_H */ diff --git a/mm/hugetlb_contpte.c b/mm/hugetlb_contpte.c index de505350ef48..d27c7599ce74 100644 --- a/mm/hugetlb_contpte.c +++ b/mm/hugetlb_contpte.c @@ -27,6 +27,7 @@ * - huge_ptep_get_and_clear() * - huge_ptep_set_access_flags() * - huge_ptep_set_wrprotect() + * - huge_ptep_clear_flush() */ =20 pte_t huge_ptep_get(struct mm_struct *mm, unsigned long addr, pte_t *ptep) @@ -254,3 +255,17 @@ void huge_ptep_set_wrprotect(struct mm_struct *mm, =20 set_contptes(mm, addr, ptep, pte, ncontig, pgsize); } + +pte_t huge_ptep_clear_flush(struct vm_area_struct *vma, + unsigned long addr, pte_t *ptep) +{ + struct mm_struct *mm =3D vma->vm_mm; + size_t pgsize; + int ncontig; + + if (!pte_cont(__ptep_get(ptep))) + return ptep_clear_flush(vma, addr, ptep); + + ncontig =3D arch_contpte_get_num_contig(mm, addr, ptep, 0, &pgsize); + return get_clear_contig_flush(mm, addr, ptep, pgsize, ncontig); +} --=20 2.39.2