]> git.ipfire.org Git - thirdparty/kernel/stable.git/commitdiff
mm/hugetlb: check for unreasonable folio sizes when registering hstate
authorDavid Hildenbrand <david@redhat.com>
Mon, 1 Sep 2025 15:03:29 +0000 (17:03 +0200)
committerAndrew Morton <akpm@linux-foundation.org>
Sun, 21 Sep 2025 21:22:02 +0000 (14:22 -0700)
Let's check that no hstate that corresponds to an unreasonable folio size
is registered by an architecture.  If we were to succeed registering, we
could later try allocating an unsupported gigantic folio size.

Further, let's add a BUILD_BUG_ON() for checking that HUGETLB_PAGE_ORDER
is sane at build time.  As HUGETLB_PAGE_ORDER is dynamic on powerpc, we
have to use a BUILD_BUG_ON_INVALID() to make it compile.

No existing kernel configuration should be able to trigger this check:
either SPARSEMEM without SPARSEMEM_VMEMMAP cannot be configured or
gigantic folios will not exceed a memory section (the case on sparse).

Link: https://lkml.kernel.org/r/20250901150359.867252-9-david@redhat.com
Signed-off-by: David Hildenbrand <david@redhat.com>
Reviewed-by: Zi Yan <ziy@nvidia.com>
Reviewed-by: Lorenzo Stoakes <lorenzo.stoakes@oracle.com>
Reviewed-by: Liam R. Howlett <Liam.Howlett@oracle.com>
Signed-off-by: Andrew Morton <akpm@linux-foundation.org>
mm/hugetlb.c

index 1e777cc51ad0430e161f8f16d10f7a5cb8c60d3d..d3542e92a712e96d88cd66b6eba16c2aa6e4610a 100644 (file)
@@ -4657,6 +4657,7 @@ static int __init hugetlb_init(void)
 
        BUILD_BUG_ON(sizeof_field(struct page, private) * BITS_PER_BYTE <
                        __NR_HPAGEFLAGS);
+       BUILD_BUG_ON_INVALID(HUGETLB_PAGE_ORDER > MAX_FOLIO_ORDER);
 
        if (!hugepages_supported()) {
                if (hugetlb_max_hstate || default_hstate_max_huge_pages)
@@ -4740,6 +4741,7 @@ void __init hugetlb_add_hstate(unsigned int order)
        }
        BUG_ON(hugetlb_max_hstate >= HUGE_MAX_HSTATE);
        BUG_ON(order < order_base_2(__NR_USED_SUBPAGE));
+       WARN_ON(order > MAX_FOLIO_ORDER);
        h = &hstates[hugetlb_max_hstate++];
        __mutex_init(&h->resize_lock, "resize mutex", &h->resize_key);
        h->order = order;