From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mx0a-0031df01.pphosted.com (mx0a-0031df01.pphosted.com [205.220.168.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by smtp.subspace.kernel.org (Postfix) with ESMTPS id 75413337BAB for ; Fri, 19 Jun 2026 20:31:12 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=205.220.168.131 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781901073; cv=none; b=WWscpazWeKNuX4GFEgxMbBVCQey2mUyUHLRPQKQK5nZcmfdnyztqtu3CwPeburG8ZMVoZjzQPNID3y4aY/RYs4UEGkpmMkiPbYCIN8MMwnceVRgbTAnemTuKTvCTWOGyVINQQct0AXw1+Qh8VEqi/doLV7quUHGdFpOvTq2sweA= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1781901073; c=relaxed/simple; bh=zJCTzAWWl6SCphITl5wc0MMWpPiARcHaiJp61lMgWTk=; h=Message-ID:Date:MIME-Version:Subject:To:Cc:References:From: In-Reply-To:Content-Type; b=iC3eB/bHyREYLHi22WinnHd9Ibja7MR3zeJbFtSmVve9Ji62A0trCFamLuF7oqmOUgjFs8ySnZTfx/7A72FrL8FUiqiRP+J+P8gW4OrfSmtBwuBUembRE7Zoz6VMQ5gA0LL1wjJ0Ze9eri+WI7wcxSu1KzQ1ZYRtYmljHJdiL8Q= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com; spf=pass smtp.mailfrom=oss.qualcomm.com; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b=aMQRh5RY; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b=H1EtPDWz; arc=none smtp.client-ip=205.220.168.131 Authentication-Results: smtp.subspace.kernel.org; dmarc=pass (p=reject dis=none) header.from=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=oss.qualcomm.com Authentication-Results: smtp.subspace.kernel.org; dkim=pass (2048-bit key) header.d=qualcomm.com header.i=@qualcomm.com header.b="aMQRh5RY"; dkim=pass (2048-bit key) header.d=oss.qualcomm.com header.i=@oss.qualcomm.com header.b="H1EtPDWz" Received: from pps.filterd (m0279864.ppops.net [127.0.0.1]) by mx0a-0031df01.pphosted.com (8.18.1.11/8.18.1.11) with ESMTP id 65JHSjMD772235 for ; Fri, 19 Jun 2026 20:31:11 GMT DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=qualcomm.com; h= cc:content-transfer-encoding:content-type:date:from:in-reply-to :message-id:mime-version:references:subject:to; s=qcppdkim1; bh= BuBwEE2haUohTkvyqi25m3okwfP48tWf/B574SDKJzw=; b=aMQRh5RY+1m4PvyS +IZSwd27GAnobChJ98i6dlDOiIG4L0QruKgn3vCYXgo+yfeRvtnebQU4vFMnJLTy xShboJ7EKrZ8ooK6ljldp1rRsVACmFLU7vDzFITVrizvBnk4rgYrg8B3yh8QkO7h nF/LmyNOFV3gavmUwQCTN3uN0Ag2r+3gM2/JzCv+duxmGfP3kzT4GMe0Yey0CCto mRzuhNDN/u+qvPssX83+pKIVYZ3BthKvKMDw3IKYSgYsN53xUNZXrst2gY+nZRQ3 M0W6EuU08dDy2FTUhO9faCg7Kqj7/WcEI4Zk08JlieVKP0wl2ps519aOWNk/301S m999+w== Received: from mail-pg1-f199.google.com (mail-pg1-f199.google.com [209.85.215.199]) by mx0a-0031df01.pphosted.com (PPS) with ESMTPS id 4evy72jv6g-1 (version=TLSv1.3 cipher=TLS_AES_128_GCM_SHA256 bits=128 verify=NOT) for ; Fri, 19 Jun 2026 20:31:11 +0000 (GMT) Received: by mail-pg1-f199.google.com with SMTP id 41be03b00d2f7-c8aeb2c867fso1220029a12.3 for ; Fri, 19 Jun 2026 13:31:11 -0700 (PDT) DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=oss.qualcomm.com; s=google; t=1781901071; x=1782505871; darn=vger.kernel.org; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :from:to:cc:subject:date:message-id:reply-to; bh=BuBwEE2haUohTkvyqi25m3okwfP48tWf/B574SDKJzw=; b=H1EtPDWzXHr3+6X0pgmav3TQrZ8denIvGnVT55sfmZ6quxxVUfscODKCy321d9sHgS PWsDHeA01Xneg2Es0JgxGzSIbEMp3cbdCFqgKSdNkHBzFs0XrYXAyzSaqXIxWFQA4emM LD13a6TcC9Tnm61SYFWXiOJD7pp0hBqa/9KgKZ+Tdn9ajDgGc8vDFHraiIErvfD/KGdk /Lt+9N9lyFi0U/8rNFLcATJ26viyhTy+vu5qHuOZLFEdNpstVjcBu98kD6tDagNQMrfH cQilMymURWScy2FQgf7tizhvKzT0F79782x8j/n/2AiLhD2/8U8AX1RlWd1P8dxS6bIR PlNw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1781901071; x=1782505871; h=content-transfer-encoding:in-reply-to:from:content-language :references:cc:to:subject:user-agent:mime-version:date:message-id :x-gm-gg:x-gm-message-state:from:to:cc:subject:date:message-id :reply-to; bh=BuBwEE2haUohTkvyqi25m3okwfP48tWf/B574SDKJzw=; b=A1aCsTn2BMqWMGbWvKeciPqv2so30//HCYvM1zBOT131juSVFgx2qnEYZJ2trd6NRx sXE9gfmlJ5QY3JfhQHb1CTLCvcZeXj2jeftLPecdr7mSRtWMDG15q0JdBFTZXyWxuPKB 6WuCjekNvriQR3GALLOUuHZnHeR+VQudVVdC2RSJDadgTuZ4hQP0HxUWFdon4RV6T23b dZFUI3al6EM3Xaghqu2WQtiA/CGVO7M+QnWgoEwGvlcxggs6WVYlH1+6Rz/vgmGlhbO9 0JQcPzVtcHKBD8aKmXMvC3bCYusfiySJos0ITBQOwFFG5D9/40OiwAV37WIuW3ccp0lz wukw== X-Forwarded-Encrypted: i=1; AFNElJ9XtzliFx+Tsl196Qe4n2ksgoa8xA+eQt+CnPVdNWWZ5UXIYayozgQBFrh8XHNVmN9MyS3niwN6QcJy05s=@vger.kernel.org X-Gm-Message-State: AOJu0Ywvr0UUCQKMHpVCOR2itJVqZC9rRDLZRuxtbrAVOZl7zvh0sszx GL46dNY5zgkTMQMG+Y19a+Q7dQXbSBybG/QBz7C/OuahTv1O/TeVcWkLrGmn3lgdP7T8/fjNwn6 DC/lrX85Qf/oFnHZTvxq4JERGvcHcLTTibymo70h1JrbTzzKuPPE6CeIpnkbwKSl8pg4= X-Gm-Gg: AfdE7ckspJRgCuqj7EY/dcOZBRE9qevV+z6Cv9Ao2rVq5jUKGSFzdiAIUUvqpVJsGWB ZVMzSOIPsgBeUFUMvOALi+xPdwnui0ejC3UoQ8sbtMDc6f/mc/dexbvrno/HVymV6/UCwrTtiqs Des8VIQzsm/PZapYs584HftHplRR1YwVWSIPh05+VI39yTTJjwQG0saqo5DKx+idVRTYOT69vwk y6melzf0S891ZP82opMzksLP2lSrFMf2HrcZmKFdkp2DXN+6FihOsyIHiV1yeYdVea+IKaTh3W0 qYC7i2w7x9wlaK3N+75D8V0Y6MDWHLUPB9y9bv1tVTFNqjSKb7AldWr2YU+lx6QIkCyDs6hkzOY jLmB0RqjJSvxMNO/S6Z9ZOituXIWW4adQIloMx+59ww== X-Received: by 2002:a05:6a00:cc3:b0:82f:5051:f024 with SMTP id d2e1a72fcca58-84550866614mr5411688b3a.27.1781901070658; Fri, 19 Jun 2026 13:31:10 -0700 (PDT) X-Received: by 2002:a05:6a00:cc3:b0:82f:5051:f024 with SMTP id d2e1a72fcca58-84550866614mr5411649b3a.27.1781901069994; Fri, 19 Jun 2026 13:31:09 -0700 (PDT) Received: from [192.168.0.8] ([49.205.250.131]) by smtp.gmail.com with ESMTPSA id d2e1a72fcca58-84564d6c49fsm104395b3a.11.2026.06.19.13.31.05 (version=TLS1_3 cipher=TLS_AES_128_GCM_SHA256 bits=128/128); Fri, 19 Jun 2026 13:31:09 -0700 (PDT) Message-ID: <6982a194-fdc3-4cfe-a60f-1c73a083e7e0@oss.qualcomm.com> Date: Sat, 20 Jun 2026 02:01:04 +0530 Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 User-Agent: Mozilla Thunderbird Subject: Re: [PATCH] mm: page_ext: validate section in for_each_page_ext iterator To: Luiz Capitulino , "David Hildenbrand (Arm)" , Andrew Morton , Vlastimil Babka , Suren Baghdasaryan , Michal Hocko , Brendan Jackman , Johannes Weiner , Zi Yan Cc: kernel@oss.qualcomm.com, linux-mm@kvack.org, linux-kernel@vger.kernel.org References: <20260617-page_ext-v1-1-37ad802b1a38@oss.qualcomm.com> <1dbebf73-6c46-44e1-ac6a-f5ffa9849b37@kernel.org> <698e5cdc-8f1d-4984-bb54-a4b7979b4dc8@redhat.com> Content-Language: en-US From: Ketan Kishore In-Reply-To: <698e5cdc-8f1d-4984-bb54-a4b7979b4dc8@redhat.com> Content-Type: text/plain; charset=UTF-8; format=flowed Content-Transfer-Encoding: 8bit X-Proofpoint-Spam-Details-Enc: AW1haW4tMjYwNjE5MDE5NiBTYWx0ZWRfX9y93AI+aek2C U7fpCh0eZ+1CyRWiPgw67S2uvlFyXGFcG7zrMdbrHbQ+lir4k7OhQFqkrtXQk91kM8G4zfpPJD8 y9A5CgjP3cMJ/Xac/nyJg5oV2Nkyln44uUAFUyiVp90ShUC+KU/Qe+IABXt72Y9ZFZzE3QFQZ3r St/6CKJiuxb+wHgdhHf4dFV9jYnZSnXbGIhfbkwRUl2NRA7l7MTXsaGfGf1Xbjo9Bx1tQSvLnj0 JYe4erHlxFeqIqkUr+PvHfm79ohTIsE9vKJ5UvmDmtsRbbcm/lQgkC4CX2wFUTY/2VgdvvIZKCq D4xelmBvuKUpflMdWvBI+niP6cf6Fy7LRa4p34IVjLrFcxMn0G/8Zp3CJiPKYstYy6/HhPjWyYZ MKBSKDaWDrhGPdlehfNewhm0HyM+m4y8eVaX5bAUWMJzJ6e5IRK5CEkCb4Qrlm5fjxOOVDTP8D4 mGDEsanoPsdO+QszOBg== X-Proofpoint-Spam-Info: AW1haW4tMjYwNjE5MDE5NiBTYWx0ZWRfX39oH22ZVl8vR OiMJhMwkEQfspjOfJ1OgJftpehtLG3W7zulKm2Kj48AhdDjJzyeV6d330482EPQ5E1HNwK2+3h9 grWmV0B/iYOW0wsFHbi4c6pWiK0INeM= X-Authority-Analysis: v=2.4 cv=I75Vgtgg c=1 sm=1 tr=0 ts=6a35a70f cx=c_pps a=Oh5Dbbf/trHjhBongsHeRQ==:117 a=BL6/p84Y3ifFzq3ZkNxHwA==:17 a=IkcTkHD0fZMA:10 a=FelO9ux0wxsA:10 a=s4-Qcg_JpJYA:10 a=VkNPw1HP01LnGYTKEx00:22 a=u7WPNUs3qKkmUXheDGA7:22 a=DJpcGTmdVt4CTyJn9g5Z:22 a=EUspDBNiAAAA:8 a=9QaySs2r4CrtnCsAm2sA:9 a=3ZKOabzyN94A:10 a=QEXdDO2ut3YA:10 a=_Vgx9l1VpLgwpw_dHYaR:22 X-Proofpoint-ORIG-GUID: -juh28DwBrLXWe3C2RsNz5c5SmlTgiMB X-Proofpoint-GUID: -juh28DwBrLXWe3C2RsNz5c5SmlTgiMB X-Proofpoint-Virus-Version: vendor=baseguard engine=ICAP:2.0.293,Aquarius:18.0.1143,Hydra:6.1.125,FMLib:17.12.100.49 definitions=2026-06-19_04,2026-06-18_03,2025-10-01_01 X-Proofpoint-Spam-Details: rule=outbound_notspam policy=outbound score=0 lowpriorityscore=0 adultscore=0 impostorscore=0 phishscore=0 spamscore=0 clxscore=1015 priorityscore=1501 suspectscore=0 bulkscore=0 malwarescore=0 classifier=typeunknown authscore=0 authtc= authcc= route=outbound adjust=0 reason=mlx scancount=1 engine=8.22.0-2606150000 definitions=main-2606190196 On 6/19/2026 8:08 AM, Luiz Capitulino wrote: > On 2026-06-18 05:04, David Hildenbrand (Arm) wrote: >> On 6/17/26 17:09, Ketan wrote: >>> The page_ext iteration API do not validate if the PFN still >>> belongs to a valid section while advancing the iterator. >>> >>> When dynamically adding memory in hotplug path, it can lead >>> to a NULL pointer dereference during page_ext_lookup at the >>> boundary of the last valid section. >>> >>> [   14.555124][  T846] Call trace: >>> [   14.555125][  T846]  lookup_page_ext+0x6c/0x108 (P) >>> [   14.555127][  T846]  page_ext_lookup+0x30/0x3c >>> [   14.555129][  T846]   +0x11c/0x260 >>> [   14.571201][  T846]  __free_pages_ok+0x5e8/0x8e0 >>> [   14.571204][  T846]  __free_pages_core+0x78/0xf0 >>> [   14.571206][  T846]  generic_online_page+0x14/0x24 >>> [   14.597782][  T846]  online_pages+0x178/0x30c >>> [   14.597784][  T846]  memory_block_change_state+0x284/0x32c >>> [   14.597787][  T846]  memory_subsys_online+0x4c/0x64 >>> [   14.597789][  T846]  device_online+0x88/0xb0 >>> [   14.597791][  T846]  online_memory_block+0x30/0x40 >>> [   14.597793][  T846]  walk_memory_blocks+0xac/0xe8 >>> [   14.597794][  T846]  add_memory_resource+0x280/0x298 >>> [   14.656161][  T846]  add_memory+0x60/0x98 >> >> So, we do allocate the page_ext in memory_notify(MEM_GOING_ONLINE) -> ... >> page_ext_callback() -> online_page_ext(). >> >> Which makes sure that all page_ext is actually allocated (for the full >> section). >> >> So when we later end up in generic_online_page(), the page_ext should >> be there >> and the memory section should be valid. >> >> >> How can online_pages(), which onlines memory part of present memory >> sections, >> online (free) memory that suddenly does not belong to a present memory >> section? >> >> Something doesn't make sense here. > > Ketan, would you please share the full OOPs message and maybe tell us > how you reproduce this issue? > Sure Luiz, below is the full OOPs with the call stack. In one of our usecases, we try to add all the movable zone memory available to kernel after boot. At the boundary of last section being added, the iterator for_each_page_ext (which in turn calls lookup_page_ext) inside which the below fetched section is NULL for invalid pfn. "struct mem_section *section = __pfn_to_section(pfn); struct page_ext *page_ext = READ_ONCE(section->page_ext);" -> While accessing section for invalid PFN we get the below NULL pointer dereference. [   13.840511][  T846] Unable to handle kernel NULL pointer dereference at virtual address 0000000000000010 [   13.850253][  T846] Mem abort info: [   13.853859][  T846]   ESR = 0x0000000096000005 [   13.858441][  T846]   EC = 0x25: DABT (current EL), IL = 32 bits [   13.864642][  T846]   SET = 0, FnV = 0 [   13.868510][  T846]   EA = 0, S1PTW = 0 [   13.872472][  T846]   FSC = 0x05: level 1 translation fault [   13.878224][  T846] Data abort info: [   13.881914][  T846]   ISV = 0, ISS = 0x00000005, ISS2 = 0x00000000 [   13.888283][  T846]   CM = 0, WnR = 0, TnD = 0, TagAccess = 0 [   13.894211][  T846]   GCS = 0, Overlay = 0, DirtyBit = 0, Xs = 0 [   13.900398][  T846] user pgtable: 4k pages, 39-bit VAs, pgdp=000000089ff23000 [   13.907749][  T846] [0000000000000010] pgd=0000000000000000, p4d=0000000000000000, pud=0000000000000000 [   13.917687][  T846] Internal error: Oops: 0000000096000005 [#1]  SMP [   13.924220][  T846] Dumping ftrace buffer: [   13.928436][  T846]    (ftrace buffer empty) [   14.452210][  T846] CPU: 7 UID: 0 PID: 846 Comm: modprobe Tainted: G           OE       6.18.21-android17-4-maybe-dirty-debug #1 PREEMPT  df0e65d5b71bf0ce6ff80187ad4d31404755da65 [   14.468528][  T846] Tainted: [O]=OOT_MODULE, [E]=UNSIGNED_MODULE [   14.484959][  T846] pstate: 43400005 (nZcv daif +PAN -UAO +TCO +DIT -SSBS BTYPE=--) [   14.492820][  T846] pc : lookup_page_ext+0x6c/0x108 [   14.497840][  T846] lr : page_ext_lookup+0x30/0x3c [   14.502766][  T846] sp : ffffffc08d21b250 [   14.506887][  T846] x29: ffffffc08d21b250 x28: ffffffe2e901f080 x27: ffffffe2e9920000 [   14.514927][  T846] x26: 0000000000000400 x25: ffffff882701a380 x24: ffffffe2e8f28000 [   14.522972][  T846] x23: 0000000030000000 x22: 0000000000c00000 x21: eaf5b162e68bf47c [   14.531008][  T846] x20: 0000000000000000 x19: 0000000000c00000 x18: ffffffe2e8e4c380 [   14.539045][  T846] x17: 00000000c006287d x16: 00000000c006287d x15: 0000000073cc3b9a [   14.539047][  T846] x14: 000000007c6d34b7 x13: 00000000d0fa10f2 x12: ffffff882701b128 [   14.539048][  T846] x11: ffffffe2e93630a8 x10: 0000000000000011 x9 : 0000000000000003 [   14.539050][  T846] x8 : 0000000000000000 x7 : 0000000000000000 x6 : ffffffe2e68b78e4 [   14.539051][  T846] x5 : 0000000000000000 [   14.555122][  T846]  x4 : 0000000000000000 x3 : 0000000000000002 [   14.555123][  T846] x2 : 0000000000000000 x1 : ffffffe2e7f30cab x0 : fffffffeee000000 [   14.555124][  T846] Call trace: [   14.555125][  T846]  lookup_page_ext+0x6c/0x108 (P) [   14.555127][  T846]  page_ext_lookup+0x30/0x3c [   14.555129][  T846]  __reset_page_owner+0x11c/0x260 [   14.571201][  T846]  __free_pages_ok+0x5e8/0x8e0 [   14.571204][  T846]  __free_pages_core+0x78/0xf0 [   14.571206][  T846]  generic_online_page+0x14/0x24 [   14.597782][  T846]  online_pages+0x178/0x30c [   14.597784][  T846]  memory_block_change_state+0x284/0x32c [   14.597787][  T846]  memory_subsys_online+0x4c/0x64 [   14.597789][  T846]  device_online+0x88/0xb0 [   14.597791][  T846]  online_memory_block+0x30/0x40 [   14.597793][  T846]  walk_memory_blocks+0xac/0xe8 [   14.597794][  T846]  add_memory_resource+0x280/0x298 [   14.656161][  T846]  add_memory+0x60/0x98 As David already pointed out over this thread, "for_each_page_ext() does a "__page_ext = page_ext_iter_next(&__iter)" and the end." page_ext_iter_next tries to access the page_ext for an invalid pfn at the end. Thanks & Regards, Ketan >> >>> >>> Add a valid-section check before looking up the next page_ext >>> so the iterator stops cleanly at section boundaries. >>> >>> Fixes: 9039b9096ea2 ("mm: page_owner: use new iteration API") >> >> If the problem is real, we'd want to CC stable. >> >>> Signed-off-by: Ketan Kishore >>> --- >>>   mm/page_ext.c | 12 ++++++++++++ >>>   1 file changed, 12 insertions(+) >>> >>> diff --git a/mm/page_ext.c b/mm/page_ext.c >>> index e2e92bd27ebd..74067ea740fe 100644 >>> --- a/mm/page_ext.c >>> +++ b/mm/page_ext.c >>> @@ -253,6 +253,18 @@ static struct page_ext *lookup_page_ext(const >>> struct page *page) >>>   { >>>       unsigned long pfn = page_to_pfn(page); >>>       struct mem_section *section = __pfn_to_section(pfn); >>> + >>> +    /* >>> +     * section can be NULL when the page_ext iterator's for-loop >>> increment >>> +     * computes a PFN one step beyond the last registered section. This >>> +     * occurs because pfn_to_page() uses __nr_to_section() which >>> succeeds >>> +     * for unregistered sections that share a root array with >>> registered >>> +     * sections,while __pfn_to_section() returns NULL for them. >>> +     * >>> +     */ >>> +    if (!section) >>> +        return NULL; >>> + >>>       struct page_ext *page_ext = READ_ONCE(section->page_ext); >> >> In addition to what Zi says, which will end up as: >> >>     if (!section) >>         return NULL; >>     page_ext = READ_ONCE(section->page_ext); >> >> >> drop that comment, not required. And likely best to just add a >> unlikely(), >> because this doesn't usually happen. >> >