From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from mailgw.kylinos.cn (mailgw.kylinos.cn [124.126.103.232]) (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 39BD12FFF8D for ; Wed, 12 Aug 2026 06:44:44 +0000 (UTC) Authentication-Results: smtp.subspace.kernel.org; arc=none smtp.client-ip=124.126.103.232 ARC-Seal:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786517087; cv=none; b=aF0Bn0a5XQvzjoIw7vQsnm108P1yk9VTP+HY8Uq9VIrdncpgL7MRB3eAvqOUZrmXnf3XCpixj4j6kSr5BzLoBvD5TZ/fO/LTtWDL/2h+ZFtsjfjEBTOphg4iZB5IfiImZ+cRa5GLb3bESgfJINDARYG+JdUIyHzkilBD0r5BSUI= ARC-Message-Signature:i=1; a=rsa-sha256; d=subspace.kernel.org; s=arc-20240116; t=1786517087; c=relaxed/simple; bh=I9oTZbgTDczD/BV5r0FMrTe4Mbt+Ppfxb97siUJzQ/0=; h=Date:From:To:Cc:Subject:Message-ID:References:MIME-Version: Content-Type:Content-Disposition:In-Reply-To; b=QMbkkAz46aP1diVrlkvfZMia8ewrz+DY7LHWOLF8SO773TQKbASZNH0HWOohl3hdx6S8ae6D5lUjvC0/J8FVOBXkd2J3D2+Vawhx5r164RWaft6Ah9vN/G6LWmUNtqN/nARhUeTiTY//HUym5O9jAB30KNcisW/+H+0INDbV/lE= ARC-Authentication-Results:i=1; smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn; spf=pass smtp.mailfrom=kylinos.cn; arc=none smtp.client-ip=124.126.103.232 Authentication-Results: smtp.subspace.kernel.org; dmarc=none (p=none dis=none) header.from=kylinos.cn Authentication-Results: smtp.subspace.kernel.org; spf=pass smtp.mailfrom=kylinos.cn X-UUID: 456bcc9e961911f1aa26b74ffac11d73-20260812 X-CTIC-Tags: HR_CC_COUNT, HR_CC_DOMAIN_COUNT, HR_CC_NO_NAME, HR_CTE_MISS, HR_CTT_TXT HR_DATE_H, HR_DATE_WKD, HR_DATE_ZONE, HR_FROM_NAME, HR_SJ_DIGIT_LEN HR_SJ_LANG, HR_SJ_LEN, HR_SJ_LETTER, HR_SJ_NOR_SYM, HR_SJ_PHRASE HR_SJ_PHRASE_LEN, HR_SJ_PRE_RE, HR_SJ_WS, HR_TO_COUNT, HR_TO_DOMAIN_COUNT HR_TO_NAME, IP_UNTRUSTED, SRC_UNTRUSTED, IP_UNFAMILIAR, SRC_UNFAMILIAR DN_TRUSTED, SRC_TRUSTED, SA_TRUSTED, SA_EXISTED, SN_EXISTED SPF_NOPASS, DKIM_NOPASS, DMARC_NOPASS, CIE_BAD, CIE_GOOD_SPF CIE_UNKNOWN, GTI_FG_BS, GTI_C_CI, GTI_FG_IT, GTI_RG_INFO GTI_C_BU, AMN_GOOD, ABX_MISS_RDNS X-CID-P-RULE: Release_Ham X-CID-O-INFO: VERSION:1.3.12,REQID:37e11bf3-1a9c-4db9-9fdc-35547f909246,IP:10, URL:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION :release,TS:10 X-CID-INFO: VERSION:1.3.12,REQID:37e11bf3-1a9c-4db9-9fdc-35547f909246,IP:10,UR L:0,TC:0,Content:0,EDM:0,RT:0,SF:0,FILE:0,BULK:0,RULE:Release_Ham,ACTION:r elease,TS:10 X-CID-META: VersionHash:e7bac3a,CLOUDID:cefc1da37ade92827dbe03e95d4a7c84,BulkI D:2608121444354N6M416F,BulkQuantity:0,Recheck:0,SF:10|64|66|78|80|81|82|83 |102|127|136|841|850|865|898,TC:nil,Content:0|15|50,EDM:-3|-100,IP:-2,URL: 99|1,File:nil,RT:nil,Bulk:nil,QS:nil,BEC:nil,COL:0,OSI:0,OSA:0,AV:0,LES:1, SPR:NO,DKR:0,DKP:0,BRR:0,BRE:0,ARC:0 X-CID-BVR: 2,SSN|SDN X-CID-BAS: 2,SSN|SDN,0,_ X-CID-FACTOR: TF_CID_SPAM_SNR,TF_CID_SPAM_ULS X-CID-RHF: D41D8CD98F00B204E9800998ECF8427E X-UUID: 456bcc9e961911f1aa26b74ffac11d73-20260812 X-User: duanchenghao@kylinos.cn Received: from localhost [(106.37.134.166)] by mailgw.kylinos.cn (envelope-from ) (Generic MTA with TLSv1.3 TLS_AES_256_GCM_SHA384 256/256) with ESMTP id 1229026213; Wed, 12 Aug 2026 14:44:30 +0800 Date: Wed, 12 Aug 2026 14:44:28 +0800 From: Chenghao Duan To: Pratyush Yadav Cc: pasha.tatashin@soleen.com, rppt@kernel.org, graf@amazon.com, linux-kernel@vger.kernel.org, linux-mm@kvack.org, kexec@lists.infradead.org, jianghaoran@kylinos.cn Subject: Re: [PATCH v1 2/2] kho: unwind restored pages on kho_restore_vmalloc error Message-ID: <20260812064428.GA144642@chenghao-pc> References: <20260807075128.542806-1-duanchenghao@kylinos.cn> <20260807075128.542806-3-duanchenghao@kylinos.cn> <2vxzcxvo518j.fsf@kernel.org> Precedence: bulk X-Mailing-List: linux-kernel@vger.kernel.org List-Id: List-Subscribe: List-Unsubscribe: MIME-Version: 1.0 Content-Type: text/plain; charset=utf-8 Content-Disposition: inline In-Reply-To: <2vxzcxvo518j.fsf@kernel.org> On Tue, Aug 11, 2026 at 01:46:04PM +0200, Pratyush Yadav wrote: > On Fri, Aug 07 2026, Chenghao Duan wrote: > > > In kho_restore_vmalloc(), when kho_restore_pages() succeeds, the > > recovered pages are handed to the buddy allocator (via > > adjust_managed_page_count()). If any later step (e.g. > > __get_vm_area_node() or vmap_pages_range()) fails, the original error > > path only called kvfree(pages), leaking those folio pages. > > > > Fix by tracking how many folio groups have been restored with > > restored_idx. On any failure, use err_unwind_restored to walk > > restored_idx backwards and return each folio group to the buddy via > > __free_pages() before freeing the pages array. > > > > Signed-off-by: Chenghao Duan > > --- > > kernel/liveupdate/kexec_handover.c | 23 +++++++++++++++++------ > > 1 file changed, 17 insertions(+), 6 deletions(-) > > > > diff --git a/kernel/liveupdate/kexec_handover.c b/kernel/liveupdate/kexec_handover.c > > index ba03ff5baa9e..ed35405f59ab 100644 > > --- a/kernel/liveupdate/kexec_handover.c > > +++ b/kernel/liveupdate/kexec_handover.c > > @@ -1161,6 +1161,7 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) > > struct vm_struct *area; > > struct page **pages; > > unsigned int idx = 0; > > + unsigned int restored_idx = 0; > > int err; > > > > vm_flags = kho_flags_to_vmalloc(preservation->flags); > > @@ -1183,11 +1184,11 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) > > phys_addr_t phys = chunk->phys[i]; > > > > if (idx + contig_pages > total_pages) > > - goto err_free_pages_array; > > + goto err_unwind_restored; > > > > page = kho_restore_pages(phys, contig_pages); > > if (!page) > > - goto err_free_pages_array; > > + goto err_unwind_restored; > > > > for (int j = 0; j < contig_pages; j++) > > pages[idx++] = page + j; > > @@ -1195,13 +1196,14 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) > > > > page = kho_restore_pages(virt_to_phys(chunk), 1); > > if (!page) > > - goto err_free_pages_array; > > + goto err_unwind_restored; > > + restored_idx = idx; > > chunk = KHOSER_LOAD_PTR(chunk->hdr.next); > > __free_page(page); > > } > > > > if (idx != total_pages) > > - goto err_free_pages_array; > > + goto err_unwind_restored; > > > > area = __get_vm_area_node(total_pages * PAGE_SIZE, align, shift, > > vm_flags | VM_UNINITIALIZED, > > @@ -1209,7 +1211,7 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) > > NUMA_NO_NODE, GFP_KERNEL, > > __builtin_return_address(0)); > > if (!area) > > - goto err_free_pages_array; > > + goto err_unwind_restored; > > > > addr = (unsigned long)area->addr; > > size = get_vm_area_size(area); > > @@ -1231,7 +1233,16 @@ void *kho_restore_vmalloc(const struct kho_vmalloc *preservation) > > > > err_free_vm_area: > > free_vm_area(area); > > -err_free_pages_array: > > +err_unwind_restored: > > + /* > > + * Pages already restored via kho_restore_pages() have been given to > > + * the buddy allocator (via adjust_managed_page_count()). Return them > > + * to the buddy so that failure leaves the system in a clean state. > > + */ > > + while (restored_idx > 0) { > > + restored_idx -= contig_pages; > > + __free_pages(pages[restored_idx], order); > > + } > > This looks wrong. These are 0-order pages. You can't free them at order. Thanks for your review. I've looked into the preserve code. The order defaults to 0. When CONFIG_HAVE_ARCH_HUGE_VMALLOC is enabled and huge vmalloc allocation occurs (vm_flags & VM_ALLOW_HUGE_VMAP), order can be greater than 0. > > I sent a patch to do exactly this a while ago [0]. At the time it was > rejected with the below argument. > > Hm, I am not sure if KHO should be responsible for freeing the > restored pages. We don't know the content of those pages, and what > they are used for. They could be used by a hypervisor or a device. > Therefore, it may be better to keep them leaked, and let the caller > decide what to do next: i.e., boot into a maintenance mode, crash the > kernel, or allow the leak until the next reboot. Could you advise if there is an existing solution to handle this scenario in the current logic? As things stand, taking the error path results in leakage of buddy pages. Regards, Chenghao Duan > > Although thinking about this again, why would any device or hypervisor > use vmalloc buffers? They should only be used for metadata. So perhaps > we take another look at my patch? Pasha, what do you think? > > [0] https://lore.kernel.org/all/20251118181811.47336-1-pratyush@kernel.org/ > > > kvfree(pages); > > return NULL; > > } > > -- > Regards, > Pratyush Yadav