From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: X-Spam-Checker-Version: SpamAssassin 3.4.0 (2014-02-07) on aws-us-west-2-korg-lkml-1.web.codeaurora.org X-Spam-Level: X-Spam-Status: No, score=-9.6 required=3.0 tests=DKIM_INVALID,DKIM_SIGNED, HEADER_FROM_DIFFERENT_DOMAINS,INCLUDES_PATCH,MAILING_LIST_MULTI,SIGNED_OFF_BY, SPF_HELO_NONE,SPF_PASS,UNPARSEABLE_RELAY,USER_AGENT_GIT autolearn=ham autolearn_force=no version=3.4.0 Received: from mail.kernel.org (mail.kernel.org [198.145.29.99]) by smtp.lore.kernel.org (Postfix) with ESMTP id E4C8CC43331 for ; Wed, 1 Apr 2020 18:39:41 +0000 (UTC) Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by mail.kernel.org (Postfix) with ESMTP id 8750320787 for ; Wed, 1 Apr 2020 18:39:41 +0000 (UTC) Authentication-Results: mail.kernel.org; dkim=fail reason="signature verification failed" (2048-bit key) header.d=oracle.com header.i=@oracle.com header.b="MX6pBycf" DMARC-Filter: OpenDMARC Filter v1.3.2 mail.kernel.org 8750320787 Authentication-Results: mail.kernel.org; dmarc=fail (p=none dis=none) header.from=oracle.com Authentication-Results: mail.kernel.org; spf=pass smtp.mailfrom=owner-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix) id 267C38E000A; Wed, 1 Apr 2020 14:39:41 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 23F0C8E0006; Wed, 1 Apr 2020 14:39:41 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 155818E000A; Wed, 1 Apr 2020 14:39:41 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from forelay.hostedemail.com (smtprelay0185.hostedemail.com [216.40.44.185]) by kanga.kvack.org (Postfix) with ESMTP id F3B228E0006 for ; Wed, 1 Apr 2020 14:39:40 -0400 (EDT) Received: from smtpin18.hostedemail.com (10.5.19.251.rfc1918.com [10.5.19.251]) by forelay04.hostedemail.com (Postfix) with ESMTP id A6DDC2C89 for ; Wed, 1 Apr 2020 18:39:40 +0000 (UTC) X-FDA: 76660149720.18.books28_373a574358d4d X-HE-Tag: books28_373a574358d4d X-Filterd-Recvd-Size: 17423 Received: from aserp2120.oracle.com (aserp2120.oracle.com [141.146.126.78]) by imf42.hostedemail.com (Postfix) with ESMTP for ; Wed, 1 Apr 2020 18:39:38 +0000 (UTC) Received: from pps.filterd (aserp2120.oracle.com [127.0.0.1]) by aserp2120.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 031I9XCK025255; Wed, 1 Apr 2020 18:39:18 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oracle.com; h=from : to : cc : subject : date : message-id : in-reply-to : references : mime-version : content-transfer-encoding; s=corp-2020-01-29; bh=HwiwJ4LOhyxHVhpbguiCOOVeqAsMYXYSXEp0In6apAk=; b=MX6pBycf9FbspfJQb5ImeVoHeWv4ClTO9HSHFcyuy/dPq/d1QOoVDz2fxoWgCDmgsgaI HbzMy5oTy1CT+RCPXss64lv0BIigw0S4pBHYLBrZEfRL/F6d1hhSI4+qRmBp7nTPUp3i GxV3CTYI506o97nKsOSZsNopKeBZkY1wlXEOUK0aW6cSUAWnLy7iiqxpZ0+f2yxJC+Sw xg4rMfU40HvWQRBiN890a3Q8pafqzGVrgg6qAUyvoavqZP7DKNVcQ1cdM2zY4viVhyUg pGZmZqVakEq8Eb38/WeHyPllxNOn0++s2q35fNK1fNKYct25KWVAWSCHXk4J8KcgAm0D CQ== Received: from aserp3030.oracle.com (aserp3030.oracle.com [141.146.126.71]) by aserp2120.oracle.com with ESMTP id 303yun9sb1-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 01 Apr 2020 18:39:18 +0000 Received: from pps.filterd (aserp3030.oracle.com [127.0.0.1]) by aserp3030.oracle.com (8.16.0.42/8.16.0.42) with SMTP id 031IdAYC046543; Wed, 1 Apr 2020 18:39:17 GMT Received: from aserv0122.oracle.com (aserv0122.oracle.com [141.146.126.236]) by aserp3030.oracle.com with ESMTP id 302g4u6pf8-1 (version=TLSv1.2 cipher=ECDHE-RSA-AES256-GCM-SHA384 bits=256 verify=OK); Wed, 01 Apr 2020 18:39:17 +0000 Received: from abhmp0003.oracle.com (abhmp0003.oracle.com [141.146.116.9]) by aserv0122.oracle.com (8.14.4/8.14.4) with ESMTP id 031IcWvZ002132; Wed, 1 Apr 2020 18:38:32 GMT Received: from monkey.oracle.com (/71.63.128.209) by default (Oracle Beehive Gateway v4.0) with ESMTP ; Wed, 01 Apr 2020 11:38:31 -0700 From: Mike Kravetz To: linux-mm@kvack.org, linux-kernel@vger.kernel.org, linux-arm-kernel@lists.infradead.org, linuxppc-dev@lists.ozlabs.org, linux-riscv@lists.infradead.org, linux-s390@vger.kernel.org, sparclinux@vger.kernel.org, linux-doc@vger.kernel.org Cc: Catalin Marinas , Will Deacon , Benjamin Herrenschmidt , Paul Mackerras , Paul Walmsley , Palmer Dabbelt , Albert Ou , Heiko Carstens , Vasily Gorbik , Christian Borntraeger , "David S . Miller" , Thomas Gleixner , Ingo Molnar , Dave Hansen , Jonathan Corbet , Longpeng , Christophe Leroy , Mina Almasry , Andrew Morton , Mike Kravetz Subject: [PATCH v2 1/4] hugetlbfs: add arch_hugetlb_valid_size Date: Wed, 1 Apr 2020 11:38:16 -0700 Message-Id: <20200401183819.20647-2-mike.kravetz@oracle.com> X-Mailer: git-send-email 2.25.1 In-Reply-To: <20200401183819.20647-1-mike.kravetz@oracle.com> References: <20200401183819.20647-1-mike.kravetz@oracle.com> MIME-Version: 1.0 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9578 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 adultscore=0 bulkscore=0 suspectscore=2 mlxscore=0 spamscore=0 malwarescore=0 mlxlogscore=999 phishscore=0 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004010151 X-Proofpoint-Virus-Version: vendor=nai engine=6000 definitions=9578 signatures=668685 X-Proofpoint-Spam-Details: rule=notspam policy=default score=0 phishscore=0 lowpriorityscore=0 malwarescore=0 adultscore=0 priorityscore=1501 mlxlogscore=999 bulkscore=0 suspectscore=2 mlxscore=0 spamscore=0 impostorscore=0 clxscore=1015 classifier=spam adjust=0 reason=mlx scancount=1 engine=8.12.0-2003020000 definitions=main-2004010150 Content-Transfer-Encoding: quoted-printable X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: The architecture independent routine hugetlb_default_setup sets up the default huge pages size. It has no way to verify if the passed value is valid, so it accepts it and attempts to validate at a later time. This requires undocumented cooperation between the arch specific and arch independent code. For architectures that support more than one huge page size, provide a routine arch_hugetlb_valid_size to validate a huge page size. hugetlb_default_setup can use this to validate passed values. arch_hugetlb_valid_size will also be used in a subsequent patch to move processing of the "hugepagesz=3D" in arch specific code to a common routine in arch independent code. Signed-off-by: Mike Kravetz --- arch/arm64/include/asm/hugetlb.h | 2 ++ arch/arm64/mm/hugetlbpage.c | 17 +++++++++++++---- arch/powerpc/include/asm/hugetlb.h | 3 +++ arch/powerpc/mm/hugetlbpage.c | 20 +++++++++++++------- arch/riscv/include/asm/hugetlb.h | 3 +++ arch/riscv/mm/hugetlbpage.c | 26 +++++++++++++++++--------- arch/s390/include/asm/hugetlb.h | 3 +++ arch/s390/mm/hugetlbpage.c | 16 ++++++++++++---- arch/sparc/include/asm/hugetlb.h | 3 +++ arch/sparc/mm/init_64.c | 24 ++++++++++++++++-------- arch/x86/include/asm/hugetlb.h | 5 +++++ arch/x86/mm/hugetlbpage.c | 17 +++++++++++++---- include/linux/hugetlb.h | 7 +++++++ mm/hugetlb.c | 15 ++++++++++++--- 14 files changed, 122 insertions(+), 39 deletions(-) diff --git a/arch/arm64/include/asm/hugetlb.h b/arch/arm64/include/asm/hu= getlb.h index 2eb6c234d594..81606223494f 100644 --- a/arch/arm64/include/asm/hugetlb.h +++ b/arch/arm64/include/asm/hugetlb.h @@ -59,6 +59,8 @@ extern void huge_pte_clear(struct mm_struct *mm, unsign= ed long addr, extern void set_huge_swap_pte_at(struct mm_struct *mm, unsigned long add= r, pte_t *ptep, pte_t pte, unsigned long sz); #define set_huge_swap_pte_at set_huge_swap_pte_at +bool __init arch_hugetlb_valid_size(unsigned long size); +#define arch_hugetlb_valid_size arch_hugetlb_valid_size =20 #include =20 diff --git a/arch/arm64/mm/hugetlbpage.c b/arch/arm64/mm/hugetlbpage.c index bbeb6a5a6ba6..069b96ee2aec 100644 --- a/arch/arm64/mm/hugetlbpage.c +++ b/arch/arm64/mm/hugetlbpage.c @@ -462,17 +462,26 @@ static int __init hugetlbpage_init(void) } arch_initcall(hugetlbpage_init); =20 -static __init int setup_hugepagesz(char *opt) +bool __init arch_hugetlb_valid_size(unsigned long size) { - unsigned long ps =3D memparse(opt, &opt); - - switch (ps) { + switch (size) { #ifdef CONFIG_ARM64_4K_PAGES case PUD_SIZE: #endif case CONT_PMD_SIZE: case PMD_SIZE: case CONT_PTE_SIZE: + return true; + } + + return false; +} + +static __init int setup_hugepagesz(char *opt) +{ + unsigned long ps =3D memparse(opt, &opt); + + if (arch_hugetlb_valid_size(ps)) { add_huge_page_size(ps); return 1; } diff --git a/arch/powerpc/include/asm/hugetlb.h b/arch/powerpc/include/as= m/hugetlb.h index bd6504c28c2f..19b453ee1431 100644 --- a/arch/powerpc/include/asm/hugetlb.h +++ b/arch/powerpc/include/asm/hugetlb.h @@ -64,6 +64,9 @@ static inline void arch_clear_hugepage_flags(struct pag= e *page) { } =20 +#define arch_hugetlb_valid_size arch_hugetlb_valid_size +bool __init arch_hugetlb_valid_size(unsigned long size); + #include =20 #else /* ! CONFIG_HUGETLB_PAGE */ diff --git a/arch/powerpc/mm/hugetlbpage.c b/arch/powerpc/mm/hugetlbpage.= c index 33b3461d91e8..de54d2a37830 100644 --- a/arch/powerpc/mm/hugetlbpage.c +++ b/arch/powerpc/mm/hugetlbpage.c @@ -558,7 +558,7 @@ unsigned long vma_mmu_pagesize(struct vm_area_struct = *vma) return vma_kernel_pagesize(vma); } =20 -static int __init add_huge_page_size(unsigned long long size) +bool __init arch_hugetlb_valid_size(unsigned long size) { int shift =3D __ffs(size); int mmu_psize; @@ -566,20 +566,26 @@ static int __init add_huge_page_size(unsigned long = long size) /* Check that it is a page size supported by the hardware and * that it fits within pagetable and slice limits. */ if (size <=3D PAGE_SIZE || !is_power_of_2(size)) - return -EINVAL; + return false; =20 mmu_psize =3D check_and_get_huge_psize(shift); if (mmu_psize < 0) - return -EINVAL; + return false; =20 BUG_ON(mmu_psize_defs[mmu_psize].shift !=3D shift); =20 - /* Return if huge page size has already been setup */ - if (size_to_hstate(size)) - return 0; + return true; +} =20 - hugetlb_add_hstate(shift - PAGE_SHIFT); +static int __init add_huge_page_size(unsigned long long size) +{ + int shift =3D __ffs(size); + + if (!arch_hugetlb_valid_size((unsigned long)size)) + return -EINVAL; =20 + if (!size_to_hstate(size)) + hugetlb_add_hstate(shift - PAGE_SHIFT); return 0; } =20 diff --git a/arch/riscv/include/asm/hugetlb.h b/arch/riscv/include/asm/hu= getlb.h index 728a5db66597..a6c414fa5b82 100644 --- a/arch/riscv/include/asm/hugetlb.h +++ b/arch/riscv/include/asm/hugetlb.h @@ -5,6 +5,9 @@ #include #include =20 +bool __init arch_hugetlb_valid_size(unsigned long size); +#define arch_hugetlb_valid_size arch_hugetlb_valid_size + static inline int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len) { diff --git a/arch/riscv/mm/hugetlbpage.c b/arch/riscv/mm/hugetlbpage.c index a6189ed36c5f..da1f516bc451 100644 --- a/arch/riscv/mm/hugetlbpage.c +++ b/arch/riscv/mm/hugetlbpage.c @@ -12,21 +12,29 @@ int pmd_huge(pmd_t pmd) return pmd_leaf(pmd); } =20 +bool __init arch_hugetlb_valid_size(unsigned long size) +{ + if (size =3D=3D HPAGE_SIZE) + return true; + else if (IS_ENABLED(CONFIG_64BIT) && size =3D=3D PUD_SIZE) + return true; + else + return false; +} + static __init int setup_hugepagesz(char *opt) { unsigned long ps =3D memparse(opt, &opt); =20 - if (ps =3D=3D HPAGE_SIZE) { - hugetlb_add_hstate(HPAGE_SHIFT - PAGE_SHIFT); - } else if (IS_ENABLED(CONFIG_64BIT) && ps =3D=3D PUD_SIZE) { - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); - } else { - hugetlb_bad_size(); - pr_err("hugepagesz: Unsupported page size %lu M\n", ps >> 20); - return 0; + if (arch_hugetlb_valid_size(ps)) { + hugetlb_add_hstate(ilog2(ps) - PAGE_SHIFT); + return 1; } =20 - return 1; + hugetlb_bad_size(); + pr_err("hugepagesz: Unsupported page size %lu M\n", ps >> 20); + return 0; + } __setup("hugepagesz=3D", setup_hugepagesz); =20 diff --git a/arch/s390/include/asm/hugetlb.h b/arch/s390/include/asm/huge= tlb.h index de8f0bf5f238..f49981c00e72 100644 --- a/arch/s390/include/asm/hugetlb.h +++ b/arch/s390/include/asm/hugetlb.h @@ -15,6 +15,9 @@ #define hugetlb_free_pgd_range free_pgd_range #define hugepages_supported() (MACHINE_HAS_EDAT1) =20 +bool __init arch_hugetlb_valid_size(unsigned long size); +#define arch_hugetlb_valid_size arch_hugetlb_valid_size + void set_huge_pte_at(struct mm_struct *mm, unsigned long addr, pte_t *ptep, pte_t pte); pte_t huge_ptep_get(pte_t *ptep); diff --git a/arch/s390/mm/hugetlbpage.c b/arch/s390/mm/hugetlbpage.c index f01daddcbc5e..ac25b207624c 100644 --- a/arch/s390/mm/hugetlbpage.c +++ b/arch/s390/mm/hugetlbpage.c @@ -251,16 +251,24 @@ follow_huge_pud(struct mm_struct *mm, unsigned long= address, return pud_page(*pud) + ((address & ~PUD_MASK) >> PAGE_SHIFT); } =20 +bool __init arch_hugetlb_valid_size(unsigned long size) +{ + if (MACHINE_HAS_EDAT1 && size =3D=3D PMD_SIZE) + return true; + else if (MACHINE_HAS_EDAT2 && size =3D=3D PUD_SIZE) + return true; + else + return false; +} + static __init int setup_hugepagesz(char *opt) { unsigned long size; char *string =3D opt; =20 size =3D memparse(opt, &opt); - if (MACHINE_HAS_EDAT1 && size =3D=3D PMD_SIZE) { - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); - } else if (MACHINE_HAS_EDAT2 && size =3D=3D PUD_SIZE) { - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); + if (arch_hugetlb_valid_size(size)) { + hugetlb_add_hstate(ilog2(size) - PAGE_SHIFT); } else { hugetlb_bad_size(); pr_err("hugepagesz=3D specifies an unsupported page size %s\n", diff --git a/arch/sparc/include/asm/hugetlb.h b/arch/sparc/include/asm/hu= getlb.h index 3963f80d1cb3..a88668b455d3 100644 --- a/arch/sparc/include/asm/hugetlb.h +++ b/arch/sparc/include/asm/hugetlb.h @@ -10,6 +10,9 @@ struct pud_huge_patch_entry { unsigned int insn; }; extern struct pud_huge_patch_entry __pud_huge_patch, __pud_huge_patch_en= d; + +bool __init arch_hugetlb_valid_size(unsigned long size); +#define arch_hugetlb_valid_size arch_hugetlb_valid_size #endif =20 #define __HAVE_ARCH_HUGE_SET_HUGE_PTE_AT diff --git a/arch/sparc/mm/init_64.c b/arch/sparc/mm/init_64.c index 1cf0d666dea3..2bfe8e22b706 100644 --- a/arch/sparc/mm/init_64.c +++ b/arch/sparc/mm/init_64.c @@ -360,16 +360,11 @@ static void __init pud_huge_patch(void) __asm__ __volatile__("flush %0" : : "r" (addr)); } =20 -static int __init setup_hugepagesz(char *string) +bool __init arch_hugetlb_valid_size(unsigned long size) { - unsigned long long hugepage_size; - unsigned int hugepage_shift; + unsigned int hugepage_shift =3D ilog2(size); unsigned short hv_pgsz_idx; unsigned int hv_pgsz_mask; - int rc =3D 0; - - hugepage_size =3D memparse(string, &string); - hugepage_shift =3D ilog2(hugepage_size); =20 switch (hugepage_shift) { case HPAGE_16GB_SHIFT: @@ -397,7 +392,20 @@ static int __init setup_hugepagesz(char *string) hv_pgsz_mask =3D 0; } =20 - if ((hv_pgsz_mask & cpu_pgsz_mask) =3D=3D 0U) { + if ((hv_pgsz_mask & cpu_pgsz_mask) =3D=3D 0U) + return false; + + return true; +} + +static int __init setup_hugepagesz(char *string) +{ + unsigned long long hugepage_size; + int rc =3D 0; + + hugepage_size =3D memparse(string, &string); + + if (!arch_hugetlb_valid_size((unsigned long)hugepage_size)) { hugetlb_bad_size(); pr_err("hugepagesz=3D%llu not supported by MMU.\n", hugepage_size); diff --git a/arch/x86/include/asm/hugetlb.h b/arch/x86/include/asm/hugetl= b.h index f65cfb48cfdd..53ae4df41433 100644 --- a/arch/x86/include/asm/hugetlb.h +++ b/arch/x86/include/asm/hugetlb.h @@ -7,6 +7,11 @@ =20 #define hugepages_supported() boot_cpu_has(X86_FEATURE_PSE) =20 +#ifdef CONFIG_X86_64 +bool __init arch_hugetlb_valid_size(unsigned long size); +#define arch_hugetlb_valid_size arch_hugetlb_valid_size +#endif + static inline int is_hugepage_only_range(struct mm_struct *mm, unsigned long addr, unsigned long len) { diff --git a/arch/x86/mm/hugetlbpage.c b/arch/x86/mm/hugetlbpage.c index 5bfd5aef5378..1c4372bfe782 100644 --- a/arch/x86/mm/hugetlbpage.c +++ b/arch/x86/mm/hugetlbpage.c @@ -181,13 +181,22 @@ hugetlb_get_unmapped_area(struct file *file, unsign= ed long addr, #endif /* CONFIG_HUGETLB_PAGE */ =20 #ifdef CONFIG_X86_64 +bool __init arch_hugetlb_valid_size(unsigned long size) +{ + if (size =3D=3D PMD_SIZE) + return true; + else if (size =3D=3D PUD_SIZE && boot_cpu_has(X86_FEATURE_GBPAGES)) + return true; + else + return false; +} + static __init int setup_hugepagesz(char *opt) { unsigned long ps =3D memparse(opt, &opt); - if (ps =3D=3D PMD_SIZE) { - hugetlb_add_hstate(PMD_SHIFT - PAGE_SHIFT); - } else if (ps =3D=3D PUD_SIZE && boot_cpu_has(X86_FEATURE_GBPAGES)) { - hugetlb_add_hstate(PUD_SHIFT - PAGE_SHIFT); + + if (arch_hugetlb_valid_size(ps)) { + hugetlb_add_hstate(ilog2(ps) - PAGE_SHIFT); } else { hugetlb_bad_size(); printk(KERN_ERR "hugepagesz: Unsupported page size %lu M\n", diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h index 2fc9bc91894e..962bb1e6682b 100644 --- a/include/linux/hugetlb.h +++ b/include/linux/hugetlb.h @@ -688,6 +688,13 @@ static inline spinlock_t *huge_pte_lockptr(struct hs= tate *h, return &mm->page_table_lock; } =20 +#ifndef arch_hugetlb_valid_size +static inline bool arch_hugetlb_valid_size(unsigned long size) +{ + return size =3D=3D HPAGE_SIZE; +} +#endif + #ifndef hugepages_supported /* * Some platform decide whether they support huge pages at boot diff --git a/mm/hugetlb.c b/mm/hugetlb.c index 38c3363b46e1..e9d9d179cf12 100644 --- a/mm/hugetlb.c +++ b/mm/hugetlb.c @@ -3324,12 +3324,21 @@ static int __init hugetlb_nrpages_setup(char *s) } __setup("hugepages=3D", hugetlb_nrpages_setup); =20 -static int __init hugetlb_default_setup(char *s) +static int __init default_hugepagesz_setup(char *s) { - default_hstate_size =3D memparse(s, &s); + unsigned long size; + + size =3D (unsigned long)memparse(s, NULL); + + if (!arch_hugetlb_valid_size(size)) { + pr_err("HugeTLB: unsupported default_hugepagesz %s\n", s); + return 0; + } + + default_hstate_size =3D size; return 1; } -__setup("default_hugepagesz=3D", hugetlb_default_setup); +__setup("default_hugepagesz=3D", default_hugepagesz_setup); =20 static unsigned int cpuset_mems_nr(unsigned int *array) { --=20 2.25.1