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 Received: from kanga.kvack.org (kanga.kvack.org [205.233.56.17]) by smtp.lore.kernel.org (Postfix) with ESMTP id 048A0C5B552 for ; Tue, 10 Jun 2025 10:16:43 +0000 (UTC) Received: by kanga.kvack.org (Postfix) id 8F9AE6B008A; Tue, 10 Jun 2025 06:16:42 -0400 (EDT) Received: by kanga.kvack.org (Postfix, from userid 40) id 8D0056B008C; Tue, 10 Jun 2025 06:16:42 -0400 (EDT) X-Delivered-To: int-list-linux-mm@kvack.org Received: by kanga.kvack.org (Postfix, from userid 63042) id 7E62E6B0092; Tue, 10 Jun 2025 06:16:42 -0400 (EDT) X-Delivered-To: linux-mm@kvack.org Received: from relay.hostedemail.com (smtprelay0015.hostedemail.com [216.40.44.15]) by kanga.kvack.org (Postfix) with ESMTP id 627986B008A for ; Tue, 10 Jun 2025 06:16:42 -0400 (EDT) Received: from smtpin14.hostedemail.com (a10.router.float.18 [10.200.18.1]) by unirelay10.hostedemail.com (Postfix) with ESMTP id D4B78C1974 for ; Tue, 10 Jun 2025 10:16:41 +0000 (UTC) X-FDA: 83539087002.14.7513D13 Received: from mail-ej1-f48.google.com (mail-ej1-f48.google.com [209.85.218.48]) by imf25.hostedemail.com (Postfix) with ESMTP id C1967A000C for ; Tue, 10 Jun 2025 10:16:39 +0000 (UTC) Authentication-Results: imf25.hostedemail.com; dkim=pass header.d=neon.tech header.s=google header.b=Z+VxFD7d; dmarc=pass (policy=reject) header.from=neon.tech; spf=pass (imf25.hostedemail.com: domain of sharnoff@neon.tech designates 209.85.218.48 as permitted sender) smtp.mailfrom=sharnoff@neon.tech ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=hostedemail.com; s=arc-20220608; t=1749550599; h=from:from:sender:reply-to:subject:subject:date:date: message-id:message-id:to:to:cc:cc:mime-version:mime-version: content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references:dkim-signature; bh=5TLMZnOwp1EufsUc3IBlAEgAbVTmb9HuOUhD3AV1YmY=; b=ipPt/XTnEeacoAuIG6ovrz+BQNhOD+PjmQxFwMevpucu4aXsddXMLc/kbxxd192BUEyldE OCiFpPh5khYCECGTIPO9d03boBoUFy8pbO6BrftHBRC4Dnl8Fvhfgd9ud9QmppMd7MKduK W/Gr+Xg8Rdtb+NdQAaSFdOjFDHAPzQg= ARC-Seal: i=1; s=arc-20220608; d=hostedemail.com; t=1749550599; a=rsa-sha256; cv=none; b=t7erWkS8HhWSpG2wqdlziaznBDwlYFEhMswGIcdQFQ1s+W2kV5YFwuTMKumUByNURPj4sm qYGFsaoDijyT6HDmyOlrlH0fPcMILKt6HXg7u2Z/vgC/wE7LqTj15VuQnHBEyoxI377poi bjmKwXeNQt1MZES0ETebR9OSkLRe1DY= ARC-Authentication-Results: i=1; imf25.hostedemail.com; dkim=pass header.d=neon.tech header.s=google header.b=Z+VxFD7d; dmarc=pass (policy=reject) header.from=neon.tech; spf=pass (imf25.hostedemail.com: domain of sharnoff@neon.tech designates 209.85.218.48 as permitted sender) smtp.mailfrom=sharnoff@neon.tech Received: by mail-ej1-f48.google.com with SMTP id a640c23a62f3a-ade30256175so700399466b.1 for ; Tue, 10 Jun 2025 03:16:39 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=neon.tech; s=google; t=1749550598; x=1750155398; darn=kvack.org; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:from:subject:user-agent:mime-version:date:message-id:from:to :cc:subject:date:message-id:reply-to; bh=5TLMZnOwp1EufsUc3IBlAEgAbVTmb9HuOUhD3AV1YmY=; b=Z+VxFD7dLYDk8/1rMve+iYkB3Fk9C+AEoEsCt7hFWH+qGS4FKRjHVH5hDUOHccgM3a 8bchtGHZ72i+aaoOeS9KfFBoBG/sFyIV5T4U1vM4LNHd21jKluEJy/YuF3A3i4RNdO/K EC8zB0Ju2AKYSdivNmXnEnOSw/BMBMXUZx7Fk= X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1749550598; x=1750155398; h=content-transfer-encoding:in-reply-to:content-language:references :cc:to:from:subject:user-agent:mime-version:date:message-id :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to; bh=5TLMZnOwp1EufsUc3IBlAEgAbVTmb9HuOUhD3AV1YmY=; b=ScQbHJ3ynSluLkNrFC218FGOzL3f96JIRDH6QOF15yv7yidG/AuZ8ILyXl/3b18xn8 yPZ480rEmFjaiTKRhEgm8vZ4GjB0XLwaERFFIa+B2ldEvhOPruQjmsvtRdk+AFxphnIS EEQ5q1eezrKQ9o5HWNX5Gn+LKpbvoNN7wsZMxk8zAgw0WEefE1UdOykgvIuBtUipxTC+ muwlOQw9v5Z6UhnjSZ3AjU7sBinFX1OkZL6PrXyFmLru8ZsHGqVLMUmvrl6yDts043Y0 R14/3flpfixk7t2B3vEdNruQamW0c5Kpg6TjCgsziPL7zwLkQOQJ/d5zDEJloFDMSPBS 7Cjg== X-Forwarded-Encrypted: i=1; AJvYcCVF/x2BRqjnic9ocu9jgJD9gKsdXiSB28/Pe44WIv7Qcx5VmYpvAtY+g0jvUdqiaerW6KRe78ClOw==@kvack.org X-Gm-Message-State: AOJu0Yw3XAMgtTQgYsLn6hgqgXkFNb5KwF0RE+Z4g94Zc/WKuwbk1HhY /5ENoqj60DC8cq4UR8OSKk0KJElde5hsbXfqOSzcuw54thGSOGUljiZ7yU5OQUBu4iU= X-Gm-Gg: ASbGncurnEFxFf+BLS8pV2R7xNGla9T7BwsdRTIXywAW/XkTQ5JBwpBski0UZ/FFEl6 jZzuD3FxUDF+3UALxg7Lt1mWiRrCpSG5RC2NTdF8WepAqsrFXHMVzdZnddGaL/r0i8nm7bClfVL dgLyr6YU51htRlgSEB+PudSH165i2xoZZ3RYkjz68SKpkk7Ynj1GM9BhmnzPZUR9K3UYZz5ow8z qpgjwwQ1d6ZEc2LI0jqT1IFEst4yRVgf2csqEhbnBaFKcNDSi2XKzSGFHIr00fw5DX5E0fYKVJS 1M6k3Q/JGJ1z1MFBrpClYUFhiPQnJcFK0VqsMblERE2nhhAQR/5xiPz2b6ScP+HCCA== X-Google-Smtp-Source: AGHT+IF3bXRwUOcNB/7Vgzzi7Oqw7d/+z7EkLbZ6h+MIcJik3RGx8NeiSc67WUrU/PAz4OZ9sYhWNw== X-Received: by 2002:a17:907:3e1e:b0:ade:4300:6c8f with SMTP id a640c23a62f3a-ade4300eb40mr1194776866b.57.1749550598026; Tue, 10 Jun 2025 03:16:38 -0700 (PDT) Received: from [192.168.86.142] ([84.65.228.220]) by smtp.gmail.com with ESMTPSA id a640c23a62f3a-ade1dc386f7sm686134066b.114.2025.06.10.03.16.36 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Tue, 10 Jun 2025 03:16:37 -0700 (PDT) Message-ID: Date: Tue, 10 Jun 2025 11:16:36 +0100 MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: [PATCH v3 1/2] x86/mm: Handle alloc failure in phys_*_init() From: Em Sharnoff To: linux-kernel@vger.kernel.org, x86@kernel.org, linux-mm@kvack.org Cc: Ingo Molnar , "H. Peter Anvin" , Dave Hansen , Andy Lutomirski , Peter Zijlstra , Thomas Gleixner , Borislav Petkov , "Edgecombe, Rick P" , Oleg Vasilev , Arthur Petukhovsky , Stefan Radig , Misha Sakhnov References: Content-Language: en-US In-Reply-To: Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 7bit X-Rspamd-Server: rspam10 X-Rspamd-Queue-Id: C1967A000C X-Stat-Signature: 61gf19dzf4g19mk3w86i4zzbg3bh6wma X-Rspam-User: X-HE-Tag: 1749550599-532241 X-HE-Meta: U2FsdGVkX1+JPpalig6OnpBkQRmEzWQOoq7LsCRN7fYxnGGXfL8oKhbGdyiwJoPMGYDUzIw/aZcEJ4+ja8tskrzjOxf5IDZRlWAiCqikkc50j6MBA0hr7dRDlHDe2VPUjUT/NrCl734XqZ2taJ+7UB4NUEYS5fnTA+IUbdkV4VhnHuozSU3gfAopvt4ugnFRTKMNPSfz/TCZwe73R7RMlqUU/F5I7yg52oFfGpsqY7E2McCc0Z9P1xzJ4Ak7ycOaREfFbT1+ilg2AODmvdXhNZsjA6lBxYyZd/ly1lluwPcadfIdh9Nrtv0wocvcDf1cqNVp2yY0gM1EFBMGKgiUkPgfMzAhJt2MVwLGP90y9GIA4vYnV48HBCne9esWrZthxzuNASXBB1+pExGvahKg2Lxih5Ty7/0Q+tHSw5Kt0KiIH7JUlAQPhlSUJkQlWYqC2R69sQd34Y7RV1a+y6hht5JcCT0ZaVHa4ynXV62vDxjk9dKt6mTY3bf2/5G+U7VZShKwq4QEBUyMWrOLMiEHvAY18sc2C5Fs/cB1DJbE4BFrb87bqBLIBkaPrSkaWC7KDukVPgTehIM+I0woMi1SpN3ubMtjHF27ANkxnkq7kKa26/17NHNyl72Qn0GF3rbObqhzPYhZtu/8yvQ3Nk0DNGedCLBRoRuIU4M2yhzg4YeLst2+4fMU6JABkgFkIR2fPHQUnBPW3OhqJeTWqL+w2hDw9Cnfh6U4A0L7dKjJb91WyFkE/Qh0Rz433uimBp8h3i1O56UAFPYaQ5p/c/CPBWxrTULA1cWktSejcW08U+TcfnwRKY5iCBEDufXNpYoGVzm+fsRm9SSPZVLDfCqfRjIpe/tbIMJfO8DILSh5f2hZJxcJSMUdvi/B/fkKT1CffH7brhMpJmHE3NSqpWgr0EtfgrjaGEy8Ewq/pLwKlgzvLPtw98qQadddgRPwWTRNNAntXyqsXHTOmwFp/11 C+XMuIOm +hcMw+q98n3xHdkZ706Ay6UT3UMQxD8mXyNTYiRZ1MtVLhjAWFMtVNfUwte5TkjVEvB3wrsrqlc1JWOkYyOB7Otb4xpFJfBby+i2Cj8QRpCUXkbA17Ldi3RMgqK6MT4JJXSapmR6jYiicaCbxa+VDarW3uIDdEclkK+OhbyNt+IMRs2BAPwcV3FNPpYZqy8iaNf9K1VJ694iHJrM/inZ1o1YDQRbuJvWnf43eqXPpGr4dPnAgGBqRiNEFt8lcSPA2rPl3SNerAAjV8JNvDt8W01ev9qleT7R2Yip/i6mFjX2SUeU5zR0tIDTEOzDQCPN5ifHGKBXJgehv++CeVGm3OCGs+2RZesEOtjYC6KVptF7xF/d7wY+IQg792yAxkoxG2K7abhsHxKHwkeZyFaaSRbH3d+8nKBVOjr4DSnd93MN1cyTfWoXHDqajbEptfQTvV4rw X-Bogosity: Ham, tests=bogofilter, spamicity=0.000000, version=1.2.4 Sender: owner-linux-mm@kvack.org Precedence: bulk X-Loop: owner-majordomo@kvack.org List-ID: List-Subscribe: List-Unsubscribe: During memory hotplug, allocation failures in phys_*_init() aren't handled, which results in a null pointer dereference, if they occur. To handle that, change phys_pud_init() and similar functions to return allocation errors via ERR_PTR() and check for that in arch_add_memory(). Signed-off-by: Em Sharnoff --- Changelog: - v2: switch from special-casing zero value to using ERR_PTR() - v3: Fix -Wint-conversion errors --- arch/x86/mm/init.c | 6 ++++- arch/x86/mm/init_64.c | 54 +++++++++++++++++++++++++++++++++++++++---- 2 files changed, 55 insertions(+), 5 deletions(-) diff --git a/arch/x86/mm/init.c b/arch/x86/mm/init.c index bfa444a7dbb0..a2665b6fe376 100644 --- a/arch/x86/mm/init.c +++ b/arch/x86/mm/init.c @@ -533,6 +533,7 @@ bool pfn_range_is_mapped(unsigned long start_pfn, unsigned long end_pfn) * Setup the direct mapping of the physical memory at PAGE_OFFSET. * This runs before bootmem is initialized and gets pages directly from * the physical memory. To access them they are temporarily mapped. + * Allocation errors are returned with ERR_PTR. */ unsigned long __ref init_memory_mapping(unsigned long start, unsigned long end, pgprot_t prot) @@ -547,10 +548,13 @@ unsigned long __ref init_memory_mapping(unsigned long start, memset(mr, 0, sizeof(mr)); nr_range = split_mem_range(mr, 0, start, end); - for (i = 0; i < nr_range; i++) + for (i = 0; i < nr_range; i++) { ret = kernel_physical_mapping_init(mr[i].start, mr[i].end, mr[i].page_size_mask, prot); + if (IS_ERR((void *)ret)) + return ret; + } add_pfn_range_mapped(start >> PAGE_SHIFT, ret >> PAGE_SHIFT); diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c index 7c4f6f591f2b..712006afcd6c 100644 --- a/arch/x86/mm/init_64.c +++ b/arch/x86/mm/init_64.c @@ -502,7 +502,8 @@ phys_pte_init(pte_t *pte_page, unsigned long paddr, unsigned long paddr_end, /* * Create PMD level page table mapping for physical addresses. The virtual * and physical address have to be aligned at this level. - * It returns the last physical address mapped. + * It returns the last physical address mapped. Allocation errors are + * returned with ERR_PTR. */ static unsigned long __meminit phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, @@ -572,7 +573,14 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, } pte = alloc_low_page(); + if (!pte) + return (unsigned long)ERR_PTR(-ENOMEM); paddr_last = phys_pte_init(pte, paddr, paddr_end, new_prot, init); + /* + * phys_{ppmd,pud,p4d}_init return allocation errors via ERR_PTR. + * phys_pte_init makes no allocations, so should not error. + */ + BUG_ON(IS_ERR((void *)paddr_last)); spin_lock(&init_mm.page_table_lock); pmd_populate_kernel_init(&init_mm, pmd, pte, init); @@ -586,7 +594,8 @@ phys_pmd_init(pmd_t *pmd_page, unsigned long paddr, unsigned long paddr_end, * Create PUD level page table mapping for physical addresses. The virtual * and physical address do not have to be aligned at this level. KASLR can * randomize virtual addresses up to this level. - * It returns the last physical address mapped. + * It returns the last physical address mapped. Allocation errors are + * returned with ERR_PTR. */ static unsigned long __meminit phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, @@ -623,6 +632,8 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, paddr_end, page_size_mask, prot, init); + if (IS_ERR((void *)paddr_last)) + return paddr_last; continue; } /* @@ -658,12 +669,22 @@ phys_pud_init(pud_t *pud_page, unsigned long paddr, unsigned long paddr_end, } pmd = alloc_low_page(); + if (!pmd) + return (unsigned long)ERR_PTR(-ENOMEM); paddr_last = phys_pmd_init(pmd, paddr, paddr_end, page_size_mask, prot, init); + /* + * We might have IS_ERR(paddr_last) if allocation failed, but we should + * still update pud before bailing, so that subsequent retries can pick + * up on progress (here and in phys_pmd_init) without leaking pmd. + */ spin_lock(&init_mm.page_table_lock); pud_populate_init(&init_mm, pud, pmd, init); spin_unlock(&init_mm.page_table_lock); + + if (IS_ERR((void *)paddr_last)) + return paddr_last; } update_page_count(PG_LEVEL_1G, pages); @@ -707,16 +728,26 @@ phys_p4d_init(p4d_t *p4d_page, unsigned long paddr, unsigned long paddr_end, pud = pud_offset(p4d, 0); paddr_last = phys_pud_init(pud, paddr, __pa(vaddr_end), page_size_mask, prot, init); + if (IS_ERR((void *)paddr_last)) + return paddr_last; continue; } pud = alloc_low_page(); + if (!pud) + return (unsigned long)ERR_PTR(-ENOMEM); paddr_last = phys_pud_init(pud, paddr, __pa(vaddr_end), page_size_mask, prot, init); spin_lock(&init_mm.page_table_lock); p4d_populate_init(&init_mm, p4d, pud, init); spin_unlock(&init_mm.page_table_lock); + + /* + * Bail only after updating p4d to keep progress from pud across retries. + */ + if (IS_ERR((void *)paddr_last)) + return paddr_last; } return paddr_last; @@ -748,10 +779,14 @@ __kernel_physical_mapping_init(unsigned long paddr_start, __pa(vaddr_end), page_size_mask, prot, init); + if (IS_ERR((void *)paddr_last)) + return paddr_last; continue; } p4d = alloc_low_page(); + if (!p4d) + return (unsigned long)ERR_PTR(-ENOMEM); paddr_last = phys_p4d_init(p4d, __pa(vaddr), __pa(vaddr_end), page_size_mask, prot, init); @@ -763,6 +798,13 @@ __kernel_physical_mapping_init(unsigned long paddr_start, (pud_t *) p4d, init); spin_unlock(&init_mm.page_table_lock); + + /* + * Bail only after updating pgd/p4d to keep progress from p4d across retries. + */ + if (IS_ERR((void *)paddr_last)) + return paddr_last; + pgd_changed = true; } @@ -777,7 +819,8 @@ __kernel_physical_mapping_init(unsigned long paddr_start, * Create page table mapping for the physical memory for specific physical * addresses. Note that it can only be used to populate non-present entries. * The virtual and physical addresses have to be aligned on PMD level - * down. It returns the last physical address mapped. + * down. It returns the last physical address mapped. Allocation errors are + * returned with ERR_PTR. */ unsigned long __meminit kernel_physical_mapping_init(unsigned long paddr_start, @@ -980,8 +1023,11 @@ int arch_add_memory(int nid, u64 start, u64 size, { unsigned long start_pfn = start >> PAGE_SHIFT; unsigned long nr_pages = size >> PAGE_SHIFT; + unsigned long ret = 0; - init_memory_mapping(start, start + size, params->pgprot); + ret = init_memory_mapping(start, start + size, params->pgprot); + if (IS_ERR((void *)ret)) + return (int)PTR_ERR((void *)ret); return add_pages(nid, start_pfn, nr_pages, params); } -- 2.39.5