From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357862; cv=none; d=zohomail.com; s=zohoarc; b=jPCWleOu5J+9CMW22nF8g6kPWWh28MkgHOWkkPs3Jmo4di5TeGmnDXnV7ePno7ennRFe50Ril0uUO0nDyhKJ2BJOoeZ76eiDQY0I9y/V92A0mrBgsBF9iUKSB+aSPLDoGV12ancJbqtt/iRSCNgKNRXU6bBIGxzWgCTvFp0ACws= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357862; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wimWBVOYQqwPaXI8zWtV5Ue4b9r9c1tb/eSNhf7mAu8=; b=XjOAJtqf4mJe3cFfSnsmZPkhL2BD3NEtyF2FSaQlQpNGUnLBRkkZwB76Wh9SQWm44ZQjIB5u0C5I9yfPuiShWjm1+hbYf4WCxca0cY9d5yR/l1OWOfErosNIGoLRIw6GZ/6xhPlVTYSc93AsScSUv8igoJsc70zsqSnGz5dhi84= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357862624462.8454833469631; Mon, 10 Aug 2026 03:31:02 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387325.1628587 (Exim 4.92) (envelope-from ) id 1wtNHF-00043N-4S; Mon, 10 Aug 2026 10:30:41 +0000 Received: by outflank-mailman (output) from mailman id 1387325.1628587; Mon, 10 Aug 2026 10:30:41 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHF-00042i-0W; Mon, 10 Aug 2026 10:30:41 +0000 Received: by outflank-mailman (input) for mailman id 1387325; Mon, 10 Aug 2026 10:30:40 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHD-000418-UB for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:40 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHD-00GuV3-Au for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:39 +0200 Received: from [10.42.69.5] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a84a-8faa-0a2a0a5109dd-0a2a4505b244-16 for ; Mon, 10 Aug 2026 12:30:39 +0200 Received: from [209.85.128.50] (helo=mail-wm1-f50.google.com) by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a84f-4cb1-0a2a45050019-d1558032e1c9-3 for ; Mon, 10 Aug 2026 12:30:39 +0200 Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-49554ebb87dso16345825e9.3 for ; Mon, 10 Aug 2026 03:30:39 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.37 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:38 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357839; x=1786962639; darn=lists.xenproject.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=wimWBVOYQqwPaXI8zWtV5Ue4b9r9c1tb/eSNhf7mAu8=; b=pMUY2/gLuvqcZpxqSH9bQjQUMiMRz7VNj44/wMATq5FDXfYlUUIHNtcIYMkFnioD7g aTT7jQdzjZTihTKOfEo5Pde+rm00UqxP/T6/VySpfQCWoX4K6Qzn2O9x2BZLzaqZC3LE o2GDwMlUqxmJDBYBGkLxOMhS67xdP3Yr92cBGltYdV30jY4wMiTrqd6RMwafWIpYmhgC QbCjAn1IrLBuL3Sj2Bl3pJGKvcZNsJvOuTenpekm0z+GLT2/eDyfRVEIgJFEvA6t0/+r l53C1HVlx9ekfr58cJ/+vf9Iwl386KtspUwcUzQ9UMYYbPRBhoLPT1gMo2ujAg2ZC0v4 YB+A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357839; x=1786962639; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=wimWBVOYQqwPaXI8zWtV5Ue4b9r9c1tb/eSNhf7mAu8=; b=OB+K3eIcuyxWNy5hXxSBPTa5HvZRO4xdTQKS0ZumNLvtq3H6LSdwywjghNP5TwinWm shTrgpYsiPBoFP5Yy+2uYh2pQnFJHFBrC4MgpULSflAPDnobXJNQr9CKykfyXTASr8qa +P3jzh0JBxrdMmwQQfFg6NWS1Gay+Dfui03gxNOONBL3kZzFpAzjIadPgS0+x7AM+t/P tZmJ/W5pW/ptP7+wuBIHvV02xU/vzs1w/thrAq1pDWwtY0WgZkafNTvhwPEwALl7cyPf oL4NdBgx7EJEXeppUuyhewiBCSoLsPZRPPIrWwL1cO8boF9ABuNfp1/1JJUV3zyNmyIs zVPQ== X-Gm-Message-State: AOJu0Yz80MEPM5A+eXTfuMOoSkluJ7x7I0HaSViyJSG6dPAhixzQiX7z oRAY0/UFQMVUYP8+kjitNrqb0RSQtPafWrrLVa1PZ7hxztYgKpbWoxgi7qAFjHP8RRs= X-Gm-Gg: AR+sD114K50KmHlnBQk48gKRilgm2Wm66uS171Rf1h2CNmYJa9PpVK/zYZliOswxEQ9 l/bYD8WRLmqVmSCNDDpuyMGWXCkJXXhukzMIoH40CNVCzXaY/AUAUVSVi/7CoF6o+0t9xSZHsFW g6qOf3N5HBsWWlqfLVFiTva2P991QUpWsdtfk7Fq6Pgsx1n2Mt6XPsgblGl9RMB7rt38/fsbEKr TkW7JEp/wFE3pzoWMwQCVUnM3xUXVwzhpd/5ozVe/rU68EFnbkNpqXBz3tLdSd9AZUGzAqe5i7e sW5c1J1PkbD9/kh5dh8br6dubNV7GepIL5cU815WYQbeFj3j53YyUlMbg/akOwksKc0UKVKDmrD DeKkXWxOjAAAtZzK3wMA1JH7uG5RVB6W8lX39f6xB9tx45RoUfGNMOYgeeLbcTWKmO7Glw1srKl 1eiNevzc/ozaUyKqlHSaWCPAVk5xkeMzbnoJp2M1Dwc3mU+uDEKTsb2qeexS9qTeFQs6HgNYGuy 9W6yeV7NTFqkzXwiAFsH1dRkFWF0VJ6QViN7ID+OgwYgRT/Jxza X-Received: by 2002:a05:600c:4715:b0:493:cefc:d113 with SMTP id 5b1f17b1804b1-4996195884bmr212355625e9.5.1786357838544; Mon, 10 Aug 2026 03:30:38 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross , Frediano Ziglio Subject: [PATCH v10 1/10] libs/call: cache up to 4 pages in hypercall bounce buffers Date: Mon, 10 Aug 2026 11:30:04 +0100 Message-ID: <20260810103018.54564-2-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-c201ff/1786357839-F74BC2A1-E42AB6FA/0/0 X-purgate-type: clean X-purgate-size: 5706 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357862973158500 From: Edwin T=C3=B6r=C3=B6k During migration there are a lot of mmap/munmap calls, because xc_get_pfn_type_batch() exceeds the default hypercall bounce buffer cache size, and needs to allocate every time it is called. munmap() is slow, especially in a PV Dom0 (takes an emulation fault), so is best avoided. Eventually it'd be good if the memory pool from xmalloc_tlsf.c was reused here, but for now make it handle the commonly encountered sizes (so far up to 4 pages). Signed-off-by: Edwin T=C3=B6r=C3=B6k Signed-off-by: Frediano Ziglio Reviewed-by: Anthony PERARD --- Changes since v2: - change prefix in subject. Changes since v4: - fix off-by-one bug. Changes since v5: - avoids potential buffer underflow if nr_pages is 0 calling cache_alloc. Changes since v6: - align changes made to cache_alloc to cache_free. Changes since v7: - use "unsigned int" instead of "unsigned". Changes since v8: - added Reviewed-by. --- tools/libs/call/buffer.c | 34 +++++++++++++++++++++++----------- tools/libs/call/core.c | 3 ++- tools/libs/call/private.h | 8 +++++--- 3 files changed, 30 insertions(+), 15 deletions(-) diff --git a/tools/libs/call/buffer.c b/tools/libs/call/buffer.c index 155e4f9d43..b7d00185c4 100644 --- a/tools/libs/call/buffer.c +++ b/tools/libs/call/buffer.c @@ -49,6 +49,9 @@ static void *cache_alloc(xencall_handle *xcall, size_t nr= _pages) { void *p =3D NULL; =20 + if ( nr_pages =3D=3D 0 ) + return NULL; + cache_lock(xcall); =20 xcall->buffer_total_allocations++; @@ -56,13 +59,13 @@ static void *cache_alloc(xencall_handle *xcall, size_t = nr_pages) if ( xcall->buffer_current_allocations > xcall->buffer_maximum_allocat= ions ) xcall->buffer_maximum_allocations =3D xcall->buffer_current_alloca= tions; =20 - if ( nr_pages > 1 ) + if ( nr_pages > ARRAY_SIZE(xcall->buffer_cache) ) { xcall->buffer_cache_toobig++; } - else if ( xcall->buffer_cache_nr > 0 ) + else if ( xcall->buffer_cache_nr[nr_pages-1] > 0 ) { - p =3D xcall->buffer_cache[--xcall->buffer_cache_nr]; + p =3D xcall->buffer_cache[nr_pages-1][--xcall->buffer_cache_nr[nr_= pages-1]]; xcall->buffer_cache_hits++; } else @@ -79,15 +82,18 @@ static int cache_free(xencall_handle *xcall, void *p, s= ize_t nr_pages) { int rc =3D 0; =20 + if ( nr_pages =3D=3D 0 ) + return 0; + cache_lock(xcall); =20 xcall->buffer_total_releases++; xcall->buffer_current_allocations--; =20 - if ( nr_pages =3D=3D 1 && - xcall->buffer_cache_nr < BUFFER_CACHE_SIZE ) + if ( nr_pages && nr_pages <=3D ARRAY_SIZE(xcall->buffer_cache) && + xcall->buffer_cache_nr[nr_pages-1] < BUFFER_CACHE_SIZE ) { - xcall->buffer_cache[xcall->buffer_cache_nr++] =3D p; + xcall->buffer_cache[nr_pages-1][xcall->buffer_cache_nr[nr_pages-1]= ++] =3D p; rc =3D 1; } =20 @@ -108,17 +114,23 @@ void buffer_release_cache(xencall_handle *xcall) DBGPRINTF("current allocations:%d maximum allocations:%d", xcall->buffer_current_allocations, xcall->buffer_maximum_allocations); - DBGPRINTF("cache current size:%d", - xcall->buffer_cache_nr); + for ( unsigned int i =3D 0; i < ARRAY_SIZE(xcall->buffer_cache_nr); ++= i ) + { + DBGPRINTF("cache current size[%u pages]:%d", i+1, + xcall->buffer_cache_nr[i]); + } DBGPRINTF("cache hits:%d misses:%d toobig:%d", xcall->buffer_cache_hits, xcall->buffer_cache_misses, xcall->buffer_cache_toobig); =20 - while ( xcall->buffer_cache_nr > 0 ) + for ( unsigned int i =3D 0; i < ARRAY_SIZE(xcall->buffer_cache_nr); ++= i ) { - p =3D xcall->buffer_cache[--xcall->buffer_cache_nr]; - osdep_free_pages(xcall, p, 1); + while ( xcall->buffer_cache_nr[i] > 0 ) + { + p =3D xcall->buffer_cache[i][--xcall->buffer_cache_nr[i]]; + osdep_free_pages(xcall, p, i + 1); + } } =20 cache_unlock(xcall); diff --git a/tools/libs/call/core.c b/tools/libs/call/core.c index 02c4f8e1ae..dd8877c1a0 100644 --- a/tools/libs/call/core.c +++ b/tools/libs/call/core.c @@ -14,6 +14,7 @@ */ =20 #include +#include =20 #include "private.h" =20 @@ -44,7 +45,7 @@ xencall_handle *xencall_open(xentoollog_logger *logger, u= nsigned open_flags) xentoolcore__register_active_handle(&xcall->tc_ah); =20 xcall->flags =3D open_flags; - xcall->buffer_cache_nr =3D 0; + memset(xcall->buffer_cache_nr, 0, sizeof(xcall->buffer_cache_nr)); =20 xcall->buffer_total_allocations =3D 0; xcall->buffer_total_releases =3D 0; diff --git a/tools/libs/call/private.h b/tools/libs/call/private.h index 9c3aa432ef..8e6a208975 100644 --- a/tools/libs/call/private.h +++ b/tools/libs/call/private.h @@ -31,13 +31,15 @@ struct xencall_handle { Xentoolcore__Active_Handle tc_ah; =20 /* - * A simple cache of unused, single page, hypercall buffers + * A simple cache of unused, small, hypercall buffers + * buffer_cache[i]'s size is (i+1) pages * * Protected by a global lock. */ #define BUFFER_CACHE_SIZE 4 - int buffer_cache_nr; - void *buffer_cache[BUFFER_CACHE_SIZE]; +#define BUFFER_CACHE_NRPAGES 4 + int buffer_cache_nr[BUFFER_CACHE_NRPAGES]; + void *buffer_cache[BUFFER_CACHE_NRPAGES][BUFFER_CACHE_SIZE]; =20 /* * Hypercall buffer statistics. All protected by the global --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357867; cv=none; d=zohomail.com; s=zohoarc; b=bMsbwZ5xUc/mYzV5yXS4/+BhkvSzykvwo/+m6AW83q/ViSrhp2nrLuV+wg4gUV18NeY4uD73XnCo6ag4+CHEEesrdZsRQ6AtJeOc16brNlnFc0sANSN0dUAuVu6sVtQljrMXFRoggXLbyjQvq91wBSHD9uBxLyE+7FsYnjskgkU= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357867; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=GVzljfbFKFoNV9C92LIEgW8vPbCFaLYksP7zU4eJtPg=; b=lhACXpQwBvCwR+uZAaC6OCR90J6YaOVKotLkHBZjTuRHWGnIPjJijKuxYCpmIEbl5rNfndBsQWf5Er+uD2ax2JuC2QdiKOXyIK9vColFHZBUe6IyJPJF/qgXTQidkSyXNcFdxsht1SzA0bqNwBZYIv45MQKt6hkpEjnilFok0cg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 178635786774617.199532805204967; Mon, 10 Aug 2026 03:31:07 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387326.1628600 (Exim 4.92) (envelope-from ) id 1wtNHH-0004R7-E0; Mon, 10 Aug 2026 10:30:43 +0000 Received: by outflank-mailman (output) from mailman id 1387326.1628600; Mon, 10 Aug 2026 10:30:43 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHH-0004R0-AT; Mon, 10 Aug 2026 10:30:43 +0000 Received: by outflank-mailman (input) for mailman id 1387326; Mon, 10 Aug 2026 10:30:42 +0000 Received: from mx.expurgate.net ([194.145.224.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHF-0004A8-UM for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:42 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHE-00AlTW-T7 for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:40 +0200 Received: from [10.42.69.11] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a84a-e002-0a2a0a5209dd-0a2a450bb4c2-14 for ; Mon, 10 Aug 2026 12:30:40 +0200 Received: from [209.85.128.49] (helo=mail-wm1-f49.google.com) by tlsNG-42698a.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a850-b7e8-0a2a450b0019-d1558031dcd9-3 for ; Mon, 10 Aug 2026 12:30:40 +0200 Received: by mail-wm1-f49.google.com with SMTP id 5b1f17b1804b1-4954afac04bso18664995e9.0 for ; Mon, 10 Aug 2026 03:30:40 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.38 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:39 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357840; x=1786962640; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=GVzljfbFKFoNV9C92LIEgW8vPbCFaLYksP7zU4eJtPg=; b=mAuUos2CXlYTXPWJltByqIPNA33B+CgqhMp2167Xx6dyFfepDXvO40fF5An+0q0o+E uz5ssDPs9wHWyjOEuw0W47iT063PE9BajXSY4saCCbn67KO0or2rvSbQJQ0/nmWvEtYu 29x5+3XxesexNMqS1Hlhrw6ivLT41PTv/ZYWqquuyz3xXN3ZyLfkkQCWmXHeqI+kOTuG UoUZB09yML3HC5v0LcswG8hslDVMAhhja4J9qEsXImnRQhvRN3U9c2gCCC/D6MpowiG3 3cVxCL2ngY/gBz5rlntqxpmxVJnQBOO9uPTrIbSIegc4g80J0B0oJPzZHdt6nsLYRAmy r1FQ== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357840; x=1786962640; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=GVzljfbFKFoNV9C92LIEgW8vPbCFaLYksP7zU4eJtPg=; b=nKglD52EDNS4oY59KtjyIiwDFYVjuHitrDfoS/imn8nWV6O6V1+nMEhU/EDEEj7ALm ZK0VAcOW/gq48pCS1ier5vzBWxBsPSctZp37ru4C4iPCS3O2VxCp8H8CtELny4Q9qleq cW2fC30yQfS1J9dpS7jw+g7QRlohlW85zU99FqrZdbRHrq5VJawzZHgueXg+h7KsvRN0 aqK7qGI3teKPN/IfGJDpLlnh5kwRe0EAJGr82jVvsh3WtBGhZku0YMwdRhHY6b3v1heq JCkZ3EUutgrlRbfTT6tLWIYDDGJlFf2hM7W1Adhtg3FUzQVkdXqP6dBJUMXcwORgomvY pTZQ== X-Gm-Message-State: AOJu0YyWDgjO99Ob7zCEhPbbyI3Pes52LgD7lnsGJYz6G+4rsiGGgHhQ MgM/74PG6m9z5E75hMKZgWdwDreLOwP0/DHa/ePEOlmG6JH4F971mVAVRpCgK6etzQg= X-Gm-Gg: AR+sD13RNGobMQJo3WwOBOMTB3HvYO7+pHv1fR3QB0TyrK6n6qDh+3UtqbSE4Jah4e5 qniKf7rnb248cqvTB8k7Bi2BvZseXROq/iDzLqEHfATrAKu4CQpLWJnAHcwLv6VWFR/WoWJThu9 /7uFcnYmjZ8k7fQKjpC43PJDXIDAvTK+1sjQPPS8JyFEjpSgR32+AD0E9uAetJxGXIxSnQIEcNj wvmnO1/aQ3CkTO6z/5r2mCB+RBvPskwF6fO4+hgRPxEV7dobfyVIIOWik9jfbDksyjKxM6RAXhO PaXFHoPz8Lhe69ZMN2z33uqoCr1p5db9OLp10A0d0+EXi8w+Ratoql/mdljKo8ubhIxZcZrR1GG /7fKfDYCKuAhr6nppLbjqdSQFZsVP4MoE7n2QyC+VFHckCwWKVw0cetiEm1Cv7Djagi714MigSy OCnC7hX7hQ/gJseYZ3U1mkp6akij6ahAibWoXFwPyLaX7l12WzXEfOEjVEEZ10bD4GI6zeTZh+k ZItuQPBeIcBz5mDVUrNkLD4c/9kfAfV2DHvkdIp X-Received: by 2002:a05:600c:3555:b0:499:521d:bff1 with SMTP id 5b1f17b1804b1-4996194e53emr251879455e9.2.1786357840167; Mon, 10 Aug 2026 03:30:40 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross Subject: [PATCH v10 2/10] libs/guest: move batch_pfns into a separate structure Date: Mon, 10 Aug 2026 11:30:05 +0100 Message-ID: <20260810103018.54564-3-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-42698a/1786357840-AB0DD9EA-63863286/0/0 X-purgate-type: clean X-purgate-size: 6125 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357868992158500 Content-Type: text/plain; charset="utf-8" Preparation for a followup patch "libs/guest: allocate various migration arrays just once". Signed-off-by: Frediano Ziglio Reviewed-by: Anthony PERARD --- Changes since v6: - split from "libs/guest: allocate various migration arrays just once". Changes since v7: - initialize "batch_pfns" on declaration. Changes since v8: - remove useless check; - added Reviewed-by. --- tools/libs/guest/xg_sr_common.h | 5 ++++- tools/libs/guest/xg_sr_save.c | 28 ++++++++++++++-------------- 2 files changed, 18 insertions(+), 15 deletions(-) diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_commo= n.h index f1573aefcb..7574c9f5b6 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -239,11 +239,14 @@ struct xc_sr_context =20 struct precopy_stats stats; =20 - xen_pfn_t *batch_pfns; unsigned int nr_batch_pfns; unsigned long *deferred_pages; unsigned long nr_deferred_pages; xc_hypercall_buffer_t dirty_bitmap_hbuf; + struct xc_sr_context_save_buffers + { + xen_pfn_t batch_pfns[MAX_BATCH_SIZE]; + } *buffers; } save; =20 struct /* Restore data. */ diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c index 84fdbe4140..22348db445 100644 --- a/tools/libs/guest/xg_sr_save.c +++ b/tools/libs/guest/xg_sr_save.c @@ -75,7 +75,7 @@ static int write_checkpoint_record(struct xc_sr_context *= ctx) =20 /* * Writes a batch of memory as a PAGE_DATA record into the stream. The ba= tch - * is constructed in ctx->save.batch_pfns. + * is constructed in ctx->save.buffers->batch_pfns. * * This function: * - gets the types for each pfn in the batch. @@ -95,6 +95,7 @@ static int write_batch(struct xc_sr_context *ctx) void *page, *orig_page; uint64_t *rec_pfns =3D NULL; struct iovec *iov =3D NULL; int iovcnt =3D 0; + xen_pfn_t *const batch_pfns =3D ctx->save.buffers->batch_pfns; struct { struct xc_sr_rhdr rec; struct xc_sr_rec_page_data_header page_data; @@ -110,6 +111,7 @@ static int write_batch(struct xc_sr_context *ctx) }; =20 assert(nr_pfns !=3D 0); + assert(nr_pfns <=3D MAX_BATCH_SIZE); =20 /* Mfns of the batch pfns. */ mfns =3D malloc(nr_pfns * sizeof(*mfns)); @@ -141,13 +143,12 @@ static int write_batch(struct xc_sr_context *ctx) =20 for ( i =3D 0; i < nr_pfns; ++i ) { - types[i] =3D mfns[i] =3D ctx->save.ops.pfn_to_gfn(ctx, - ctx->save.batch_pfns= [i]); + types[i] =3D mfns[i] =3D ctx->save.ops.pfn_to_gfn(ctx, batch_pfns[= i]); =20 /* Likely a ballooned page. */ if ( mfns[i] =3D=3D INVALID_MFN ) { - set_bit(ctx->save.batch_pfns[i], ctx->save.deferred_pages); + set_bit(batch_pfns[i], ctx->save.deferred_pages); ++ctx->save.nr_deferred_pages; } } @@ -193,7 +194,7 @@ static int write_batch(struct xc_sr_context *ctx) if ( errors[p] ) { ERROR("Mapping of pfn %#"PRIpfn" (mfn %#"PRIpfn") failed %= d", - ctx->save.batch_pfns[i], mfns[p], errors[p]); + batch_pfns[i], mfns[p], errors[p]); goto err; } =20 @@ -207,7 +208,7 @@ static int write_batch(struct xc_sr_context *ctx) { if ( rc =3D=3D -1 && errno =3D=3D EAGAIN ) { - set_bit(ctx->save.batch_pfns[i], ctx->save.deferred_pa= ges); + set_bit(batch_pfns[i], ctx->save.deferred_pages); ++ctx->save.nr_deferred_pages; types[i] =3D XEN_DOMCTL_PFINFO_XTAB; --nr_pages; @@ -235,7 +236,7 @@ static int write_batch(struct xc_sr_context *ctx) hdrs.rec.length +=3D nr_pages * PAGE_SIZE; =20 for ( i =3D 0; i < nr_pfns; ++i ) - rec_pfns[i] =3D ((uint64_t)(types[i]) << 32) | ctx->save.batch_pfn= s[i]; + rec_pfns[i] =3D ((uint64_t)(types[i]) << 32) | batch_pfns[i]; =20 if ( writev_exact(ctx->fd, iov, iovcnt) ) { @@ -274,9 +275,9 @@ static int flush_batch(struct xc_sr_context *ctx) =20 if ( !rc ) { - VALGRIND_MAKE_MEM_UNDEFINED(ctx->save.batch_pfns, + VALGRIND_MAKE_MEM_UNDEFINED(ctx->save.buffers->batch_pfns, MAX_BATCH_SIZE * - sizeof(*ctx->save.batch_pfns)); + sizeof(*ctx->save.buffers->batch_pfns)= ); } =20 return rc; @@ -293,7 +294,7 @@ static int add_to_batch(struct xc_sr_context *ctx, xen_= pfn_t pfn) rc =3D flush_batch(ctx); =20 if ( rc =3D=3D 0 ) - ctx->save.batch_pfns[ctx->save.nr_batch_pfns++] =3D pfn; + ctx->save.buffers->batch_pfns[ctx->save.nr_batch_pfns++] =3D pfn; =20 return rc; } @@ -784,11 +785,10 @@ static int setup(struct xc_sr_context *ctx) =20 dirty_bitmap =3D xc_hypercall_buffer_alloc_pages( xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size))); - ctx->save.batch_pfns =3D malloc(MAX_BATCH_SIZE * - sizeof(*ctx->save.batch_pfns)); ctx->save.deferred_pages =3D bitmap_alloc(ctx->save.p2m_size); + ctx->save.buffers =3D calloc(1, sizeof(*ctx->save.buffers)); =20 - if ( !ctx->save.batch_pfns || !dirty_bitmap || !ctx->save.deferred_pag= es ) + if ( !ctx->save.buffers || !dirty_bitmap || !ctx->save.deferred_pages ) { ERROR("Unable to allocate memory for dirty bitmaps, batch pfns and" " deferred pages"); @@ -819,7 +819,7 @@ static void cleanup(struct xc_sr_context *ctx) xc_hypercall_buffer_free_pages(xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size)= )); free(ctx->save.deferred_pages); - free(ctx->save.batch_pfns); + free(ctx->save.buffers); } =20 /* --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357861; cv=none; d=zohomail.com; s=zohoarc; b=YGVtQmY9c8ouEaV4Vx/MXIB16847+aZ4WBxxyGs3NwFo7Z4Sxwh6S+zKUw0p7qU9XMtH4xj5Ar8bloOOdAK6aT7ae49R82k61h3bq4HSNWL001v1xcmNXzbP8J7KAlZwNYe34pyR3aw5c+Ibjtj7aAxlrEeengoTqGcqWz5IbHo= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357861; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=2NxxLpvMxvCVNIhMLzqk93Yy2TTgs6s75lOWPEK4aL8=; b=MJTizT6QN0MtKx8eEPqvgL/D6vM/+Ebr7o7SQBE0QOws8JaEVxUSQ566mZuwKK0RyhYUyufnBkwQgRmEwjLPQcUT9/vJdXAWhD8i2G/eZ1X5w+cRF14qYpj81yqJCc5unFVdvMFamoJDd3V51nsGhC+c9062SjNftD2bwiCOfng= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357861558151.60278393858312; Mon, 10 Aug 2026 03:31:01 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387327.1628609 (Exim 4.92) (envelope-from ) id 1wtNHI-0004eP-LO; Mon, 10 Aug 2026 10:30:44 +0000 Received: by outflank-mailman (output) from mailman id 1387327.1628609; Mon, 10 Aug 2026 10:30:44 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHI-0004eF-H9; Mon, 10 Aug 2026 10:30:44 +0000 Received: by outflank-mailman (input) for mailman id 1387327; Mon, 10 Aug 2026 10:30:43 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHH-0004Qx-Cx for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:43 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHG-000B9X-Pv for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:42 +0200 Received: from [10.42.69.12] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a84d-2eae-0a2a0a5409dd-0a2a450ce5b4-16 for ; Mon, 10 Aug 2026 12:30:42 +0200 Received: from [209.85.128.47] (helo=mail-wm1-f47.google.com) by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a852-f479-0a2a450c0019-d155802fe454-3 for ; Mon, 10 Aug 2026 12:30:42 +0200 Received: by mail-wm1-f47.google.com with SMTP id 5b1f17b1804b1-4953de5be0aso12486915e9.0 for ; Mon, 10 Aug 2026 03:30:42 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.40 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:41 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357842; x=1786962642; darn=lists.xenproject.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=2NxxLpvMxvCVNIhMLzqk93Yy2TTgs6s75lOWPEK4aL8=; b=WWMY34C84Gr2gIQEaxu6lLq5DNlTNwYhWCjGo99tLHoTTAvvrEBhKdpXVAbhAER/dI xShAcUzSH6rwIcYm8/jy0ws8yXx3PHzxsdqcnLu9p6Rb0sJl9/ZlsXwRzaKKOKdODe/4 J9uRIaqeGCwJM8sbY+y7+si3q4684NniBbD+rI5k567JdZnhd3bEkF7Xa6ghzFaLtKCQ tT8WhcB1XQlMhrssCb9KlpBt6P/u9vm3nYM1M7e5wpiSZcZaA4KfkceT1D0cUwKUBsQX 81rDHFTEYpQ5FXn2siLlCQUWryUYDOpzVtczDUlX70JZsJFUW0HTuq10BSELoc7RQsdS 8cuw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357842; x=1786962642; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=2NxxLpvMxvCVNIhMLzqk93Yy2TTgs6s75lOWPEK4aL8=; b=U7Ob54e4udQPEf4hbQRTlSHgq9WxFYvsq03m0qBkGVFVETVl4Ivo/8qhTQOA6/iVNn NXsuhZD9lxC4+mojFx+Ex/s+nsuYPMBSK2cIYtSWQfEwJN7ZG0V974NK0HIhQzqev7HI nzQ4AtzUAuHYamubwQiBHJZ5M32zL30vy8ADHht9NxRM5l8M5Jb1ghr1YWbSK4e7xkjL CyFqYVIAMIk+wwomy3235oUGmUQKKU9+XZSwTtHx6yjis9MdHFc8/g/4SBosJG0HE4/K 2OG0/PfZjjfr0b7y5DX1ptWw0WJqBPpMw0a0iEttFYkzDDu1YnkPBljW9hXi2EMRr/+k 3MPQ== X-Gm-Message-State: AOJu0YzhzZyR7f75N2MndHdI5Ud08seJEGcnNv9H1zjFOj4tqTPU5QR/ 4b3juZr/SJiP6s/I8wP2KYGCXshnWLGKPbmhIHBddunDTr6ripkibmUxaNtPtC5RRwg= X-Gm-Gg: AR+sD13xEAgsLrqQ2r8yol4nTt/olGWo8B0mM7KXqF5WR1W9ONmPHWLJSS/8lMXVmlF Ptae/Ae/9/Dn2P/t/hIwydTf0VCpyq/PZCF2wPRVMA9x6es2bVLSv1n5mQtIa2yp8bXM2nfzCSG LKmkrIjEJ/b0y+0qWnnT+A3xtrnc5loBoeUHOOhIrj+Mp8SUpHNHjvfC8Dqh+SnkVoOXCCOXLjO XE2/qbTHDt3g8u9oJm42wqzV4oU/rP0AN14GWC2XzNY9OiUwSSVONBEDSo1neeOGK3HioC/odcx 1RCHpCsVLkTbOspK+EHsIF+Q4ViSdVGYhfr9YF53cmIEVCOsCwLbF0f21vxn1vuzwMGFgs6eVMA FnJDinlqHbKshAYE2j5Xo5WKB01LxSV2/+SBPfK1wscaGbQmJqgx2Jv8ep/0na14bWRcU8AogS3 GpKFk6mFUZ7IOIRoqNLuk2HrB482qESPoXKaaFd2wt+CsViwCHMhM1ZcR5jF+iBUWgtHJr5e9zK bLzcwvdlDH6l/ICD0H5jNKheqV97FpGEM+P0aPd X-Received: by 2002:a05:600c:4fcb:b0:495:5890:8f6c with SMTP id 5b1f17b1804b1-4995e084875mr253273375e9.7.1786357841888; Mon, 10 Aug 2026 03:30:41 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross , Frediano Ziglio Subject: [PATCH v10 3/10] libs/guest: allocate various migration arrays just once Date: Mon, 10 Aug 2026 11:30:06 +0100 Message-ID: <20260810103018.54564-4-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-d25034/1786357842-034D7A5B-FE0536AF/0/0 X-purgate-type: clean X-purgate-size: 4898 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357862975158501 From: Edwin T=C3=B6r=C3=B6k Allocate these array just once at the start of migration, using the maximum batch size, and free them at the end. Signed-off-by: Edwin T=C3=B6r=C3=B6k Signed-off-by: Frediano Ziglio Reviewed-by: Anthony PERARD --- Changes since v2: - change prefix in subject. Changes since v3: - fix comment style Changes since v4: - change order of fields in structure. Changes since v6: - split preparation commit. Changes since v8: - remove useless memset; - initialize variables while declaring them. Changes since v9: - added Reviewed-by. --- tools/libs/guest/xg_sr_common.h | 6 +++++ tools/libs/guest/xg_sr_save.c | 45 ++++++++++++--------------------- 2 files changed, 22 insertions(+), 29 deletions(-) diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_commo= n.h index 7574c9f5b6..c07c6db59e 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -246,6 +246,12 @@ struct xc_sr_context struct xc_sr_context_save_buffers { xen_pfn_t batch_pfns[MAX_BATCH_SIZE]; + xen_pfn_t mfns[MAX_BATCH_SIZE]; + xen_pfn_t types[MAX_BATCH_SIZE]; + void *local_pages[MAX_BATCH_SIZE]; + struct iovec iov[MAX_BATCH_SIZE + 2]; /* Headers + data. */ + uint64_t rec_pfns[MAX_BATCH_SIZE]; + int errors[MAX_BATCH_SIZE]; } *buffers; } save; =20 diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c index 22348db445..6a77e33a47 100644 --- a/tools/libs/guest/xg_sr_save.c +++ b/tools/libs/guest/xg_sr_save.c @@ -86,15 +86,12 @@ static int write_checkpoint_record(struct xc_sr_context= *ctx) static int write_batch(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; - xen_pfn_t *mfns =3D NULL, *types =3D NULL; void *guest_mapping =3D NULL; - void **local_pages =3D NULL; - int *errors =3D NULL, rc =3D -1; + int rc =3D -1; unsigned int i, p, nr_pages =3D 0, nr_pages_mapped =3D 0; unsigned int nr_pfns =3D ctx->save.nr_batch_pfns; void *page, *orig_page; - uint64_t *rec_pfns =3D NULL; - struct iovec *iov =3D NULL; int iovcnt =3D 0; + int iovcnt =3D 0; xen_pfn_t *const batch_pfns =3D ctx->save.buffers->batch_pfns; struct { struct xc_sr_rhdr rec; @@ -110,28 +107,21 @@ static int write_batch(struct xc_sr_context *ctx) }, }; =20 - assert(nr_pfns !=3D 0); - assert(nr_pfns <=3D MAX_BATCH_SIZE); - /* Mfns of the batch pfns. */ - mfns =3D malloc(nr_pfns * sizeof(*mfns)); + xen_pfn_t *const mfns =3D ctx->save.buffers->mfns; /* Types of the batch pfns. */ - types =3D malloc(nr_pfns * sizeof(*types)); + xen_pfn_t *const types =3D ctx->save.buffers->types; /* Errors from attempting to map the gfns. */ - errors =3D malloc(nr_pfns * sizeof(*errors)); + int *const errors =3D ctx->save.buffers->errors; /* Pointers to locally allocated pages. Need freeing. */ - local_pages =3D calloc(nr_pfns, sizeof(*local_pages)); + void **const local_pages =3D ctx->save.buffers->local_pages; /* iovec[] for writev(). */ - iov =3D malloc((nr_pfns + 2) * sizeof(*iov)); + struct iovec *const iov =3D ctx->save.buffers->iov; /* page_data record PFNs list */ - rec_pfns =3D malloc(nr_pfns * sizeof(*rec_pfns)); + uint64_t *const rec_pfns =3D ctx->save.buffers->rec_pfns; =20 - if ( !mfns || !types || !errors || !local_pages || !iov || !rec_pfns ) - { - ERROR("Unable to allocate arrays for a batch of %u pages", - nr_pfns); - goto err; - } + assert(nr_pfns !=3D 0); + assert(nr_pfns <=3D MAX_BATCH_SIZE); =20 iov[0].iov_base =3D &hdrs; iov[0].iov_len =3D sizeof(hdrs); @@ -249,14 +239,11 @@ static int write_batch(struct xc_sr_context *ctx) err: if ( guest_mapping ) xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped); - for ( i =3D 0; local_pages && i < nr_pfns; ++i ) + for ( i =3D 0; i < nr_pfns; ++i ) + { free(local_pages[i]); - free(rec_pfns); - free(iov); - free(local_pages); - free(errors); - free(types); - free(mfns); + local_pages[i] =3D NULL; + } =20 return rc; } @@ -790,8 +777,8 @@ static int setup(struct xc_sr_context *ctx) =20 if ( !ctx->save.buffers || !dirty_bitmap || !ctx->save.deferred_pages ) { - ERROR("Unable to allocate memory for dirty bitmaps, batch pfns and" - " deferred pages"); + ERROR("Unable to allocate memory for dirty bitmaps, deferred pages" + " and various batch buffers"); rc =3D -1; errno =3D ENOMEM; goto err; --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357868; cv=none; d=zohomail.com; s=zohoarc; b=Np1aiv90SdEyYOXmHlzkOvUu4A5Vg//Jiydfly3D0xeHG7cjyXPhytdZoeHz+TD1L2YtaDpyX+sIxYn58yrRNoi5CKrITTACJvC60MutsfolCbYo4WIMQWqYVukD6Z2bgp3XGU6gjBx7ydMi4MI1xc1vVu29fjHqLVql2ioMg5s= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357868; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=mmYKOwc9TBhHBw9HKQnv11v7wtvX4hGi6xT3sze3LxM=; b=YE2ctsrDAuiGijrTFh13eo5TesZpP99JTusJ3QEDhLsqFWsO1d7b4f1VjW3QhX21/HMZOUc3oEmvGQ9e1UPaPZxiD1aPDO7Pti495vSsxQmjLboi3t3KsVLQaHudsUPJmNdKPUUkga+ZKh/5G5wj2oGI6vXMDYdJhRvBF0sG23U= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 178635786859589.23694222194149; Mon, 10 Aug 2026 03:31:08 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387328.1628618 (Exim 4.92) (envelope-from ) id 1wtNHK-0004tl-4h; Mon, 10 Aug 2026 10:30:46 +0000 Received: by outflank-mailman (output) from mailman id 1387328.1628618; Mon, 10 Aug 2026 10:30:46 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHJ-0004tc-W6; Mon, 10 Aug 2026 10:30:45 +0000 Received: by outflank-mailman (input) for mailman id 1387328; Mon, 10 Aug 2026 10:30:45 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHJ-0004ir-4M for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:45 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHI-00Dyin-HR for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:44 +0200 Received: from [10.42.69.4] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a842-bab6-0a2a0a5309dd-0a2a4504c9d8-22 for ; Mon, 10 Aug 2026 12:30:44 +0200 Received: from [209.85.128.45] (helo=mail-wm1-f45.google.com) by tlsNG-ebf023.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a854-b57f-0a2a45040019-d155802dd551-3 for ; Mon, 10 Aug 2026 12:30:44 +0200 Received: by mail-wm1-f45.google.com with SMTP id 5b1f17b1804b1-490cf322ed0so10862685e9.1 for ; Mon, 10 Aug 2026 03:30:44 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.41 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:42 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357843; x=1786962643; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=mmYKOwc9TBhHBw9HKQnv11v7wtvX4hGi6xT3sze3LxM=; b=c9eyfgznDHwu2KFRkAc50rBNR8rftgT1J23Rmqp97Z0WRxm+RhDwY4K+l+l8xrh0KU 3wAJTBHeSYDR7lbdOzXKEp6kc+MwZ9Cb8pzvqL2wGJHafopwqyHAPJO4xg+pXlIJsubl oLYNOt8Z7IqNqU5ieODubmMRUCgAI5uNHGHRIvtseOfAKVlV3K0lQcXiApzVQ2mbTRz5 fPAoQKxB+bLAQmTX05YupoK1dBAi8VEAcnTI1MmixNtHEdq+7x6dLdNCrkotcQP8zt0x d0/Zgqs4nOSnjYTA3dLDd3h5taJN31VvraEpvYvqycakpQKwmO+D+vOmgJb/7OitpQez /G4Q== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357843; x=1786962643; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=mmYKOwc9TBhHBw9HKQnv11v7wtvX4hGi6xT3sze3LxM=; b=eQbLOBpe3qmqiK840BMANpP87LpQOxDhANMOP79RDNOW888qcBWGPD0WtmqYgeyhqU VtkkpqRmY8f/PrHgHyXUG0ixgi61TJC1JtjKH4uDCby8/POaNjrytJPnT31s0vh0OQmv x4aovnk620OtPQi35dVIIbHIFq7AMluEs2RcRWHJKycjKKy7AzTLP490QZPxgbW2Z0YE Gnt2xATrLl3hM5ieB1qBKCMGlZ2r31xW7OdGQACmF4fxdm106a4Sd3M4xIinmlM05Es8 MbuheIvHOSPIEqdLeSUE1gfMM/qwrKJ38h8wcsoSfhKE4VdIZeyI4LD5sEFIfpId6cML Fi2Q== X-Gm-Message-State: AOJu0YwazFJExIbwzBquVb/tz0lWRsommcT/GEouq4yGbYbH7FkBkCjt Fap1xZPvHdRf+jBQIBmmd5rW8CRh/SsgfqfPA/rNGLofCSaRqDHNjB53IOZfkt/94c0= X-Gm-Gg: AR+sD12WBUM0fMkuAJQxxc27YUthk2n0YcsD+ozU5BEMLrwThQOm8bjUV9ctpvKOmQx xUKp76U7IKcH+Ly5OOtyLaTg3NOAk5qDR7Vj6LPBUHt4PKTxe9liJzXSAC9W0G4rOvh67NoV0u7 nMxQP6dohXPMrn1MQYs5qhJ0BRtDDOZxG2Au45OL4Xbk20WrvHD2i2ZJ2U5o013F4Bj/WQDvVNS rse0152W5JHykR2OuhlYNZ7qC+QtJyV/TETbkN4ETMLu/W4wlKIP2RFNDaU9TAroDRGKd4pI7Ua F7uQ+4meHclH+H4vzCLdodelCwPi0U6W7ToUetJGz2DmphxH0RzLUYxG7Qs/1/fjXvUlgCftJgT ks007RO3ufT3uyWv8OvIJnwo5/1v3420Ku8k+x7J48+6FR8LTZUo+++SKFTfa0LRixSypYV3Aq+ gT1fGT+VXt1HTfu4EqzilXArKql1+FYnu0JY0/SN8RkQ7SZqE8+6TyYbPJgHIAjp/JTJa4z03si VmnmKUr37H4T54m1G9NTcGkwOfnPRroruRaxs6v X-Received: by 2002:a05:600c:6298:b0:495:503f:cf9a with SMTP id 5b1f17b1804b1-499619839d6mr196524995e9.9.1786357843492; Mon, 10 Aug 2026 03:30:43 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross Subject: [PATCH v10 4/10] libs/guest: use Valgrind or sanitizers to detect various buffer overflows Date: Mon, 10 Aug 2026 11:30:07 +0100 Message-ID: <20260810103018.54564-5-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-ebf023/1786357844-C0EDEB50-0D7D9B2F/0/0 X-purgate-type: clean X-purgate-size: 7329 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357869038158500 Content-Type: text/plain; charset="utf-8" Previously this was done as buffers were allocated separately. Signed-off-by: Frediano Ziglio --- Changes since v9: - add support for sanitizers also; - remove some unneeded check buffers. --- tools/config.h.in | 6 ++++ tools/configure | 12 +++++++ tools/configure.ac | 3 +- tools/libs/ctrl/xc_private.h | 61 +++++++++++++++++++++++++++++++-- tools/libs/guest/xg_sr_common.h | 6 ++++ tools/libs/guest/xg_sr_save.c | 11 ++++++ 6 files changed, 96 insertions(+), 3 deletions(-) diff --git a/tools/config.h.in b/tools/config.h.in index ed0042018d..d51816453b 100644 --- a/tools/config.h.in +++ b/tools/config.h.in @@ -48,6 +48,12 @@ /* ROMBIOS enabled */ #undef HAVE_ROMBIOS =20 +/* Define to 1 if you have the header file. */ +#undef HAVE_SANITIZER_ASAN_INTERFACE_H + +/* Define to 1 if you have the header file. */ +#undef HAVE_SANITIZER_MSAN_INTERFACE_H + /* Define to 1 if you have the header file. */ #undef HAVE_STDINT_H =20 diff --git a/tools/configure b/tools/configure index cd989925ed..94e630665f 100755 --- a/tools/configure +++ b/tools/configure @@ -10203,6 +10203,18 @@ then : printf "%s\n" "#define HAVE_UTMP_H 1" >>confdefs.h =20 fi +ac_fn_c_check_header_compile "$LINENO" "sanitizer/asan_interface.h" "ac_cv= _header_sanitizer_asan_interface_h" "$ac_includes_default" +if test "x$ac_cv_header_sanitizer_asan_interface_h" =3D xyes +then : + printf "%s\n" "#define HAVE_SANITIZER_ASAN_INTERFACE_H 1" >>confdefs.h + +fi +ac_fn_c_check_header_compile "$LINENO" "sanitizer/msan_interface.h" "ac_cv= _header_sanitizer_msan_interface_h" "$ac_includes_default" +if test "x$ac_cv_header_sanitizer_msan_interface_h" =3D xyes +then : + printf "%s\n" "#define HAVE_SANITIZER_MSAN_INTERFACE_H 1" >>confdefs.h + +fi =20 =20 # Check for libnl3 >=3D3.2.8. If present enable remus network buffering. diff --git a/tools/configure.ac b/tools/configure.ac index 74b9f56025..5346ff6129 100644 --- a/tools/configure.ac +++ b/tools/configure.ac @@ -454,7 +454,8 @@ AC_CHECK_DECLS([fdt_property_u32],,,[#include ]) esac =20 # Checks for header files. -AC_CHECK_HEADERS([yajl/yajl_version.h sys/eventfd.h valgrind/memcheck.h ut= mp.h]) +AC_CHECK_HEADERS([yajl/yajl_version.h sys/eventfd.h valgrind/memcheck.h \ + utmp.h sanitizer/asan_interface.h sanitizer/msan_interfa= ce.h]) =20 # Check for libnl3 >=3D3.2.8. If present enable remus network buffering. PKG_CHECK_MODULES(LIBNL3, [libnl-3.0 >=3D 3.2.8 libnl-route-3.0 >=3D 3.2.8= ], diff --git a/tools/libs/ctrl/xc_private.h b/tools/libs/ctrl/xc_private.h index 8a325c17b0..7803192599 100644 --- a/tools/libs/ctrl/xc_private.h +++ b/tools/libs/ctrl/xc_private.h @@ -42,13 +42,70 @@ =20 #include =20 -#if defined(HAVE_VALGRIND_MEMCHECK_H) && !defined(NDEBUG) && !defined(__MI= NIOS__) +#undef XEN_USE_MEM_NOACCESS +#if !defined(NDEBUG) && !defined(__MINIOS__) + +#if !defined(__has_feature) +#define __has_feature(x) 0 +#endif + +#if defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \ + (__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)) +#include +#define XEN_USE_MEM_NOACCESS 1 +#elif defined(HAVE_SANITIZER_MSAN_INTERFACE_H) && \ + __has_feature(memory_sanitizer) +#include +#define XEN_USE_MEM_NOACCESS 1 +#endif +#if defined(HAVE_VALGRIND_MEMCHECK_H) /* Compile in Valgrind client requests? */ #include -#else +#define XEN_USE_MEM_NOACCESS 1 +#endif + +#endif + +#if !defined(HAVE_VALGRIND_MEMCHECK_H) || defined(NDEBUG) || defined(__MIN= IOS__) #define VALGRIND_MAKE_MEM_UNDEFINED(addr, len) /* addr, len */ #endif =20 +#if defined(XEN_USE_MEM_NOACCESS) +#define MEM_NOACCESS_BUFFER(name, size) uint8_t name[size]; +#if defined(HAVE_VALGRIND_MEMCHECK_H) +#define MEM_NOACCESS_INIT_VALGRIND(field) \ + VALGRIND_MAKE_MEM_NOACCESS(field, sizeof(field)) +#else +#define MEM_NOACCESS_INIT_VALGRIND(field) +#endif +#if defined(HAVE_SANITIZER_ASAN_INTERFACE_H) && \ + (__has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)) +#define MEM_NOACCESS_INIT_SANITIZER(field) \ + ASAN_POISON_MEMORY_REGION(field, sizeof(field)) +#else +#define MEM_NOACCESS_INIT_SANITIZER(field) +#endif +#if defined(HAVE_SANITIZER_MSAN_INTERFACE_H) && \ + __has_feature(memory_sanitizer) +#define MEM_UNDEFINED_INIT_SANITIZER(field) \ + __msan_poison(field, sizeof(field)) +#else +#define MEM_UNDEFINED_INIT_SANITIZER(field) +#endif +#define MEM_NOACCESS_INIT(field) do { \ + MEM_NOACCESS_INIT_VALGRIND(field); \ + MEM_NOACCESS_INIT_SANITIZER(field); \ +} while(0) +#define MEM_UNDEFINED_INIT(field) do { \ + VALGRIND_MAKE_MEM_UNDEFINED(field, sizeof(field)); \ + MEM_UNDEFINED_INIT_SANITIZER(field); \ +} while(0) +#else +#define MEM_NOACCESS_BUFFER(name, size) +#define MEM_NOACCESS_INIT(field) do {} while(0) +#define MEM_UNDEFINED_INIT(field) do {} while(0) +#endif + #if defined(__MINIOS__) /* * MiniOS's libc doesn't know about sys/uio.h or writev(). diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_commo= n.h index c07c6db59e..020b1a5272 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -246,11 +246,17 @@ struct xc_sr_context struct xc_sr_context_save_buffers { xen_pfn_t batch_pfns[MAX_BATCH_SIZE]; + MEM_NOACCESS_BUFFER(na0, 64); xen_pfn_t mfns[MAX_BATCH_SIZE]; + MEM_NOACCESS_BUFFER(na1, 64); xen_pfn_t types[MAX_BATCH_SIZE]; + MEM_NOACCESS_BUFFER(na2, 64); void *local_pages[MAX_BATCH_SIZE]; + MEM_NOACCESS_BUFFER(na3, 64); struct iovec iov[MAX_BATCH_SIZE + 2]; /* Headers + data. */ + MEM_NOACCESS_BUFFER(na4, 64); uint64_t rec_pfns[MAX_BATCH_SIZE]; + MEM_NOACCESS_BUFFER(na5, 64); int errors[MAX_BATCH_SIZE]; } *buffers; } save; diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c index 6a77e33a47..96d7e9e2f8 100644 --- a/tools/libs/guest/xg_sr_save.c +++ b/tools/libs/guest/xg_sr_save.c @@ -123,6 +123,11 @@ static int write_batch(struct xc_sr_context *ctx) assert(nr_pfns !=3D 0); assert(nr_pfns <=3D MAX_BATCH_SIZE); =20 + MEM_UNDEFINED_INIT(ctx->save.buffers->mfns); + MEM_UNDEFINED_INIT(ctx->save.buffers->types); + MEM_UNDEFINED_INIT(ctx->save.buffers->iov); + MEM_UNDEFINED_INIT(ctx->save.buffers->rec_pfns); + iov[0].iov_base =3D &hdrs; iov[0].iov_len =3D sizeof(hdrs); =20 @@ -783,6 +788,12 @@ static int setup(struct xc_sr_context *ctx) errno =3D ENOMEM; goto err; } + MEM_NOACCESS_INIT(ctx->save.buffers->na0); + MEM_NOACCESS_INIT(ctx->save.buffers->na1); + MEM_NOACCESS_INIT(ctx->save.buffers->na2); + MEM_NOACCESS_INIT(ctx->save.buffers->na3); + MEM_NOACCESS_INIT(ctx->save.buffers->na4); + MEM_NOACCESS_INIT(ctx->save.buffers->na5); =20 rc =3D 0; =20 --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357868; cv=none; d=zohomail.com; s=zohoarc; b=fjFEuXlVSTkyrAC0C4sTmB+PQoNRBY305jfnR19Vna7fFAZtEkFnIVgGgjJ9H3MxsH/LN0f0ZUJsMwx44XyxHb5MBeej+M+mMRLbUOISiak545gKEkIgwkIUgCowoCL45VJW1Y1ryZN4SLd2svLVdT3oSNQ9xrYZulQ32o/vMGk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357868; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=DkECl6LDMDGOPn0+PvCj6l9ySrP1BztPa+S0NKPl8lo=; b=HVRSTHylNpz9bLBobGP5zBS+u35mTNkK82UuW8QG5n6JTisihQm2Gcvf4yH9Bu6P0C/ZvMUoeEyDmmJ1C33cn/FT+84+T1OzaVPijWk12m59lZEAxge8e2jluyKptTYJrMRC6X/WKSpcCl97it5EFQ6/+BNmn5jnCCExRGSGNvg= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357868806253.2140860449855; Mon, 10 Aug 2026 03:31:08 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387329.1628627 (Exim 4.92) (envelope-from ) id 1wtNHL-00058Z-CE; Mon, 10 Aug 2026 10:30:47 +0000 Received: by outflank-mailman (output) from mailman id 1387329.1628627; Mon, 10 Aug 2026 10:30:47 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHL-00058O-8P; Mon, 10 Aug 2026 10:30:47 +0000 Received: by outflank-mailman (input) for mailman id 1387329; Mon, 10 Aug 2026 10:30:46 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHJ-0004t8-UU for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:46 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHJ-000B9X-Ay for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:45 +0200 Received: from [10.42.69.9] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a854-2eae-0a2a0a5409dd-0a2a4509bf7e-10 for ; Mon, 10 Aug 2026 12:30:45 +0200 Received: from [209.85.128.46] (helo=mail-wm1-f46.google.com) by tlsNG-bad1c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a855-be1a-0a2a45090019-d155802ec06a-3 for ; Mon, 10 Aug 2026 12:30:45 +0200 Received: by mail-wm1-f46.google.com with SMTP id 5b1f17b1804b1-4996f1ee4a4so6106325e9.2 for ; Mon, 10 Aug 2026 03:30:45 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.43 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:44 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357845; x=1786962645; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=DkECl6LDMDGOPn0+PvCj6l9ySrP1BztPa+S0NKPl8lo=; b=XK4ZZmLdPIeRTaxO29DQeKvE5Yq9F2kKDoE/51xEgGvfJCOhc3VQTU2SsUf693ssh3 LWKzwQ5/ARqHDrv/6JIt2VFglMMitk6P6GACT3nmFz/NHxrI0UWpWTmJm9uxF9d7TfqQ H+7EvhagApP6OKFXWJNOP0dxpmXNU8Y6XP09b/6QkKzfI5eks1x+2MQxJCJLpJCIFygF saU1GAgFTaq9QBfcL202wcg6/4Vf85nXDw/zcr7OnmMFHnz/lyazsqyUs5mQlAJTq400 BQP1lz8bjADlFNOsIJ9rfBAhLa8csd3VFRpNrzbyEi09/7+dSBMfH4q5wXFoRImD9rni jXwA== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357845; x=1786962645; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=DkECl6LDMDGOPn0+PvCj6l9ySrP1BztPa+S0NKPl8lo=; b=smh4Dds/2tE2EFxDV9SxuowfUvow7zxwImZh+/EEkEpEhKggFxYPysMUsvcBWWHMy1 APpvwp8LiGE10ECBlM+9l9S4LctnaoUCuVN4EYyYP4zHnTbRbOEV0T44MWPnd1bSMrNp B11GDHqss8FeIY4Gtgh/CVyQy7cVob8yez0c+a4MYMhreCi1ly5eiYdNXxwkZgND691k pIaHahjd/VbKXUgGw6DJKaoF87p1W816zotfn2oTSjKr+y8IqpLLg+h909P76lFiF8rA UOiFXPHcqWwfQt/Tyn26CAr7S2IzdH39cw6TZe6BW1ErIfOR3r73swobpHOAxRoytvVn srwA== X-Gm-Message-State: AOJu0YyIRu+n3IiHtAB6wzM5Q4OsziYbEoM14VLijSYUw5PZMO3tGsLJ v3zEJLFalBn05ZluDnb2LK6lDXM9GxzcWIVJoWz8S/sQ2ezrj4K+w4FiDcSC0RpWqXk= X-Gm-Gg: AR+sD10bp/jD1AEj8oWHDVxrLEyn8C8E7QjgnZcAP/Qlxg/UwaInUKk+ekX4r9emFuK s9awuR06gsyyAeTg2Frm/Nkkr9GU32ZaLlimqDyGmtDMnsfkGRhdmvdY8oWkutBz0tMvG9GtAsH W0GLsc8kNf4tuXGYfriZjU0/ivXLrIia48zfz7gMvlu6lcns9Ha1pWB3QJPRDZbZWd887ZWk1IB 0UI1tpVBuvqR6MUeCuCn7GlN63N9q/7AO995krbgT1ufC8yRo4dB9w8uVk1Phd5QQcEMkDSNmN4 KiR3fcXXRF4R9o0kjTjLy5Qgqv1dp02q0Sb2BhXUi6IRE7n3yvVL+CpPdcCymVl4UWpekCskFEA RFq58/cP4ZDfn5GZgwhrIxNTZkzLfKz1zHsBtyCqtUgIJGXTZBPVHAl5UC1t2UsQRUpDDTBZYrY Nuvuj7u+W69lFUfl76NGsxV+ZRVEHM8qzGcoLZsZG4zCoOQ1uU5bbiiyiAKFD8ahscBTph07FMe 1UaYkytL4EG3EMv+koplDndrTaMPMpfxfYXqmRm X-Received: by 2002:a05:600c:3b93:b0:495:6a50:3fb8 with SMTP id 5b1f17b1804b1-499727417c7mr9643525e9.1.1786357844497; Mon, 10 Aug 2026 03:30:44 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross Subject: [PATCH v10 5/10] libs/guest: add xg_foreignmemory_copy_{from,to} Date: Mon, 10 Aug 2026 11:30:08 +0100 Message-ID: <20260810103018.54564-6-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-bad1c0/1786357845-3A8D9034-D08973B3/0/0 X-purgate-type: clean X-purgate-size: 4001 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357868993158500 Content-Type: text/plain; charset="utf-8" This change prepare code to use a new "foreign copy" hypercall. The new hypercall will copy memory from/to a foreign domain. The new hypercall can be emulated with a sequence of: - map foreign memory; - copy memory; - unmap foreign memory. The reason to introduce the emulation first is that you can refactor on the emulation without having to introduce the new hypercall. Introducing the hypercall first would make testing more complicated as bugs on the hypercall have to be taken into account and considered. Also it is easier that way to enable or disable new code. For instance you want to test for performance regression (in this case the code emulated should not perform worse). Signed-off-by: Frediano Ziglio --- Changes since v5: - Do not overwrite errno if xenforeignmemory_map fails. Changes since v6: - improve commit message, explain order and changes. --- tools/libs/guest/xg_sr_common.c | 57 +++++++++++++++++++++++++++++++++ tools/libs/guest/xg_sr_common.h | 8 +++++ 2 files changed, 65 insertions(+) diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_commo= n.c index 9b2782b5cf..90da21c35f 100644 --- a/tools/libs/guest/xg_sr_common.c +++ b/tools/libs/guest/xg_sr_common.c @@ -156,6 +156,63 @@ static void __attribute__((unused)) build_assertions(v= oid) BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params) !=3D 8); } =20 +enum { + foreigncopy_from, + foreigncopy_to +}; + +static int xg_foreignmemory_copy(xc_interface *xch, domid_t domid, + int dir, size_t nr_pages, void *buffer, + const xen_pfn_t foreign_pfns[nr_pages]) +{ + if ( nr_pages =3D=3D 0 ) + return 0; + + if ( !buffer || !foreign_pfns ) + { + errno =3D EINVAL; + return -1; + } + + int err[nr_pages]; + const int prot =3D (dir =3D=3D foreigncopy_from) ? PROT_READ : PROT_RE= AD|PROT_WRITE; + + void *p =3D xenforeignmemory_map(xch->fmem, domid, prot, nr_pages, for= eign_pfns, err); + if ( !p ) + return -1; + + for ( size_t n =3D 0; n < nr_pages; ++n ) + if ( err[n] ) + { + xenforeignmemory_unmap(xch->fmem, p, nr_pages); + errno =3D -err[n]; + return -1; + } + + if ( dir =3D=3D foreigncopy_from ) + memcpy(buffer, p, nr_pages * XC_PAGE_SIZE); + else + memcpy(p, buffer, nr_pages * XC_PAGE_SIZE); + + return xenforeignmemory_unmap(xch->fmem, p, nr_pages); +} + +int xg_foreignmemory_copy_from(xc_interface *xch, domid_t dom, + size_t nr_pages, void *dest, + const xen_pfn_t source[nr_pages]) +{ + return xg_foreignmemory_copy(xch, dom, foreigncopy_from, + nr_pages, dest, source); +} + +int xg_foreignmemory_copy_to(xc_interface *xch, domid_t dom, + size_t nr_pages, const xen_pfn_t dest[nr_page= s], + const void *source) +{ + return xg_foreignmemory_copy(xch, dom, foreigncopy_to, + nr_pages, (void *) source, dest); +} + /* * Local variables: * mode: C diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_commo= n.h index 020b1a5272..50f235ba87 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -556,6 +556,14 @@ static inline bool page_type_has_stream_data(uint32_t = type) } } =20 +int xg_foreignmemory_copy_from(xc_interface *xch, domid_t dom, + size_t nr_pages, void *dest, + const xen_pfn_t source[nr_pages]); + +int xg_foreignmemory_copy_to(xc_interface *xch, domid_t dom, + size_t nr_pages, const xen_pfn_t dest[nr_page= s], + const void *source); + #endif /* * Local variables: --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357883; cv=none; d=zohomail.com; s=zohoarc; b=LTF0ajOaclw3HfeXwDR33UV8k+gMC/AOuxCuu5TAC6GQS7gA6dfedw94YSs5fN9WBsHt2IL19NMNjsZBFcrJf6iDEahIJS+ZapnaO+PV2ec20qJvwlCmuoXHmVWQaBRha1/kRPxih29UqUzmR5sz6SyQ7kzZH6sCu1y0ppfSLDk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357883; h=Content-Type:Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=noFi4Nk2/RkhWge/ysH4KvzMVBLDNZGcIPZ/3WMBXro=; b=FYOccp/H5oeT/4pH9cIuB+zVXNEAVo5aKskhIM2A85Y4exiXe/oIFKLLNXBrDe/SFqt5iHR93iHUxTu0ilnS23PRPnThUtXd59oyMdQ0LgqflH2PTISAxNHu1b6dmyefEsVVrxa3MqcSJhFF5uTH4nXRyt9eqg5p1SEkkwNk0Pc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357883783413.3711168466501; Mon, 10 Aug 2026 03:31:23 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387330.1628636 (Exim 4.92) (envelope-from ) id 1wtNHM-0005Nb-Jb; Mon, 10 Aug 2026 10:30:48 +0000 Received: by outflank-mailman (output) from mailman id 1387330.1628636; Mon, 10 Aug 2026 10:30:48 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHM-0005NI-FW; Mon, 10 Aug 2026 10:30:48 +0000 Received: by outflank-mailman (input) for mailman id 1387330; Mon, 10 Aug 2026 10:30:47 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHL-00056B-5W for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:47 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHK-00Dyin-IZ for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:46 +0200 Received: from [10.42.69.7] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a854-bab6-0a2a0a5309dd-0a2a450799ec-8 for ; Mon, 10 Aug 2026 12:30:46 +0200 Received: from [209.85.128.51] (helo=mail-wm1-f51.google.com) by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a856-b4ea-0a2a45070019-d1558033dd86-3 for ; Mon, 10 Aug 2026 12:30:46 +0200 Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-49802c418b5so16277125e9.1 for ; Mon, 10 Aug 2026 03:30:46 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.44 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:45 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:Content-Type:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357846; x=1786962646; darn=lists.xenproject.org; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:from:to:cc:subject :date:message-id:reply-to:content-type; bh=noFi4Nk2/RkhWge/ysH4KvzMVBLDNZGcIPZ/3WMBXro=; b=Imf5WD3OT3FoiLQZlFAhUwHzfItTrfwcC805OQe8ZgUajU6edQ48oxW1Fp/lfVgGfK qweM9sP1zGrsbgXTalSCme7QTKxTV0IcW0HIHzupvYTAZAQOPq8ikTOPLYM+J6AusguP U+1dN7vFfDumlHhVs8RwAaZc++wxf2V0Y0YQ11RtZjFvId3XePbwPn2sMebNOYXZlkD7 NBepaUPBSB721VMjuGJL+V1u7ZuHTg0QVXqjfLJt6EmCpqt8FkX4N3XPOa4JyOagawoq psE6/XJzxu+dXGJzy8CN2VX79RLp+QIKi0fNncf6WBcxTZiD7T5uqt2mMNk5UTwBFWFD UbGw== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357846; x=1786962646; h=content-transfer-encoding:content-type:mime-version:references :in-reply-to:message-id:date:subject:cc:to:from:x-gm-gg :x-gm-message-state:from:to:cc:subject:date:message-id:reply-to :content-type; bh=noFi4Nk2/RkhWge/ysH4KvzMVBLDNZGcIPZ/3WMBXro=; b=bfL7TnJxG2kVKz+iUOkJkJG5IXuXG6lwoL+YhCgQLefxQASALSLUxEZQy3oIxRelRq u7dop67zjyem7dsc/FqvYdwUOP/hP4JjxsFU1WbPJeOBjIAg/xXyREcURSx+FP6SuCg+ 8rg4FJAC66JPrjRVGsIEshY8YeTwaPA/VLY2Z2nROqz6CTCx/9CMwYGLH/AaJ84ASV0K 44w1T1oDCZLqKLELYwJ7UY6qOWuz59bNDz1V64u8IILKFtNWSCfXisetZGNYHoHrAziH AdcY7avMvoD8BnUT18bxvIZOXGBuTKENLXAMOWnYWR5W4uKXzZiVTLXUdSpfqQwvClGA tKxw== X-Gm-Message-State: AOJu0Yx19SGQ/cWTb7+JmUyMs49hgk34uzecIY8k3CPdzwJlcTrJOFiQ 3u8QJDHnB/V01y8Gp9JAWQC121qlynJ7y1CpHB5RkSzI/1lEVc9VZq8w8Z/h1hBvrlI= X-Gm-Gg: AR+sD12WeVVYwl5ZtZG/KZif3EoxcPUp/Owu9vs1dmpdEEmg9ef57g7wH0sKIRaIxCG Ua4mFNUQ1zY+iZ/AAipP+op/DlIZAzmh+itZlF7xfi1ZtrM9jV5HfLGacmt5DioTNap3K3aTSsZ VgjvRPzlKMgrqo+PZGt+X7BSlLf0O2jk+AM5TLQTAz2zq2PuGya8L4SqqpmYk7suBPQc51fHM5X aUbJFBLXBmNrNr/KGTvur21ymH7nRElsQIANCdZn/RMJwEjqcUaHntLKPot39bTkY2KdRL4Kf9+ e345jt/LYg9xAVfYZ508IyYn9qOh2aoeiySI9g0YFVhjuV3H0kGWQyOlYfb+BpRkZzo5DQbIEI+ KKZ4o7btN7r19HCsA01qZ12PdzpKVSBK3na8AAKOdh5vfqaYWwLbBNdchUgFSGgs/6VXVlI7g0A C+3WfTe45Zf2M5O06AzoSyyRCt6ctlc5HkSWy+8FoLDINdtEL7KudvswVy/ODa/IYTYDSmvUKIY AH9ilWkwM4auEZqcvqGvVoNdODgUcQQPySX4HoV X-Received: by 2002:a05:600c:1391:b0:499:4dca:aa4 with SMTP id 5b1f17b1804b1-4996194deb6mr204011195e9.4.1786357845569; Mon, 10 Aug 2026 03:30:45 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: =?UTF-8?q?Edwin=20T=C3=B6r=C3=B6k?= , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross , Frediano Ziglio Subject: [PATCH v10 6/10] libs/guest: use foreign copy API during migration Date: Mon, 10 Aug 2026 11:30:09 +0100 Message-ID: <20260810103018.54564-7-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-ef75cf/1786357846-378D1AE4-808F9804/0/0 X-purgate-type: clean X-purgate-size: 13400 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357885313158500 From: Edwin T=C3=B6r=C3=B6k Use foreign code emulation code provided by previous commit to prepare to use new hypercall. This to make sure there are no regression in both functionality and performance. In particular tested: - HVM VM; - PV VM; - verification code. Migration times did not change. Signed-off-by: Edwin T=C3=B6r=C3=B6k Signed-off-by: Frediano Ziglio --- Changes since v6: - merge with "finalize PoC" to remove the PoC; - remove statistics, old and not clear at all how they were made; - describe tests made. --- tools/libs/guest/xg_sr_common.h | 4 +- tools/libs/guest/xg_sr_restore.c | 78 +++++++++++++++++--------------- tools/libs/guest/xg_sr_save.c | 62 +++++++++++-------------- 3 files changed, 71 insertions(+), 73 deletions(-) diff --git a/tools/libs/guest/xg_sr_common.h b/tools/libs/guest/xg_sr_commo= n.h index 50f235ba87..ec3435790a 100644 --- a/tools/libs/guest/xg_sr_common.h +++ b/tools/libs/guest/xg_sr_common.h @@ -243,6 +243,7 @@ struct xc_sr_context unsigned long *deferred_pages; unsigned long nr_deferred_pages; xc_hypercall_buffer_t dirty_bitmap_hbuf; + xc_hypercall_buffer_t dest_buf; struct xc_sr_context_save_buffers { xen_pfn_t batch_pfns[MAX_BATCH_SIZE]; @@ -256,8 +257,6 @@ struct xc_sr_context struct iovec iov[MAX_BATCH_SIZE + 2]; /* Headers + data. */ MEM_NOACCESS_BUFFER(na4, 64); uint64_t rec_pfns[MAX_BATCH_SIZE]; - MEM_NOACCESS_BUFFER(na5, 64); - int errors[MAX_BATCH_SIZE]; } *buffers; } save; =20 @@ -269,6 +268,7 @@ struct xc_sr_context int send_back_fd; unsigned long p2m_size; xc_hypercall_buffer_t dirty_bitmap_hbuf; + xc_hypercall_buffer_t verify_buf; =20 /* From Image Header. */ uint32_t format_version; diff --git a/tools/libs/guest/xg_sr_restore.c b/tools/libs/guest/xg_sr_rest= ore.c index 458eaa5992..af97f3d466 100644 --- a/tools/libs/guest/xg_sr_restore.c +++ b/tools/libs/guest/xg_sr_restore.c @@ -257,16 +257,15 @@ static int process_page_data(struct xc_sr_context *ct= x, unsigned int count, { xc_interface *xch =3D ctx->xch; xen_pfn_t *mfns =3D malloc(count * sizeof(*mfns)); - int *map_errs =3D malloc(count * sizeof(*map_errs)); int rc; - void *mapping =3D NULL, *guest_page =3D NULL; unsigned int nr_pages =3D 0; + void *const source =3D page_data; =20 - if ( !mfns || !map_errs ) + if ( !mfns ) { rc =3D -1; ERROR("Failed to allocate %zu bytes to process page data", - count * (sizeof(*mfns) + sizeof(*map_errs))); + count * sizeof(*mfns)); goto err; } =20 @@ -294,27 +293,8 @@ static int process_page_data(struct xc_sr_context *ctx= , unsigned int count, if ( nr_pages =3D=3D 0 ) goto done; =20 - mapping =3D guest_page =3D xenforeignmemory_map( - xch->fmem, ctx->domid, PROT_READ | PROT_WRITE, - nr_pages, mfns, map_errs); - if ( !mapping ) - { - rc =3D -1; - PERROR("Unable to map %u mfns for %u pages of data", - nr_pages, count); - goto err; - } - for ( unsigned int i =3D 0; i < nr_pages; ++i ) { - if ( map_errs[i] ) - { - rc =3D -1; - ERROR("Mapping pfn %#"PRIpfn" (mfn %#"PRIpfn", type %#"PRIx32"= ) failed with %d", - pfns[i], mfns[i], types[i], map_errs[i]); - goto err; - } - /* Undo page normalisation done by the saver. */ rc =3D ctx->restore.ops.localise_page(ctx, types[i], page_data); if ( rc ) @@ -324,31 +304,41 @@ static int process_page_data(struct xc_sr_context *ct= x, unsigned int count, goto err; } =20 - if ( ctx->restore.verify ) + page_data +=3D PAGE_SIZE; + } + if ( !ctx->restore.verify ) + { + rc =3D xg_foreignmemory_copy_to(xch, ctx->domid, nr_pages, mfns, s= ource); + if ( rc < 0 ) + goto err; + } + else + { + DECLARE_HYPERCALL_BUFFER_SHADOW(uint8_t, verify_buf, + &ctx->restore.verify_buf); + void *guest_page =3D verify_buf; + + rc =3D xg_foreignmemory_copy_from(xch, ctx->domid, nr_pages, verif= y_buf, mfns); + if ( rc < 0 ) + goto err; + + page_data =3D source; + for ( unsigned int i =3D 0; i < nr_pages; ++i ) { /* Verify mode - compare incoming data to what we already have= . */ if ( memcmp(guest_page, page_data, PAGE_SIZE) ) ERROR("verify pfn %#"PRIpfn" failed (type %#"PRIx32")", pfns[i], types[i] >> XEN_DOMCTL_PFINFO_LTAB_SHIFT); - } - else - { - /* Regular mode - copy incoming data into place. */ - memcpy(guest_page, page_data, PAGE_SIZE); - } =20 - guest_page +=3D PAGE_SIZE; - page_data +=3D PAGE_SIZE; + guest_page +=3D PAGE_SIZE; + page_data +=3D PAGE_SIZE; + } } =20 done: rc =3D 0; =20 err: - if ( mapping ) - xenforeignmemory_unmap(xch->fmem, mapping, nr_pages); - - free(map_errs); free(mfns); =20 return rc; @@ -738,6 +728,18 @@ static int setup(struct xc_sr_context *ctx) int rc; DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, &ctx->restore.dirty_bitmap_hbuf); + DECLARE_HYPERCALL_BUFFER_SHADOW(uint8_t, verify_buf, + &ctx->restore.verify_buf); + + verify_buf =3D xc_hypercall_buffer_alloc_pages( + xch, verify_buf, MAX_BATCH_SIZE); + + if ( !verify_buf ) + { + ERROR("Unable to allocate memory for test buffer"); + rc =3D -1; + goto err; + } =20 if ( ctx->stream_type =3D=3D XC_STREAM_COLO ) { @@ -786,6 +788,8 @@ static void cleanup(struct xc_sr_context *ctx) unsigned int i; DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, &ctx->restore.dirty_bitmap_hbuf); + DECLARE_HYPERCALL_BUFFER_SHADOW(uint8_t, verify_buf, + &ctx->restore.verify_buf); =20 for ( i =3D 0; i < ctx->restore.buffered_rec_num; i++ ) free(ctx->restore.buffered_records[i].data); @@ -794,6 +798,8 @@ static void cleanup(struct xc_sr_context *ctx) xc_hypercall_buffer_free_pages( xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->restore.p2m_size))= ); =20 + xc_hypercall_buffer_free_pages(xch, verify_buf, MAX_BATCH_SIZE); + free(ctx->restore.buffered_records); free(ctx->restore.populated_pfns); =20 diff --git a/tools/libs/guest/xg_sr_save.c b/tools/libs/guest/xg_sr_save.c index 96d7e9e2f8..6b381f0219 100644 --- a/tools/libs/guest/xg_sr_save.c +++ b/tools/libs/guest/xg_sr_save.c @@ -86,11 +86,9 @@ static int write_checkpoint_record(struct xc_sr_context = *ctx) static int write_batch(struct xc_sr_context *ctx) { xc_interface *xch =3D ctx->xch; - void *guest_mapping =3D NULL; int rc =3D -1; - unsigned int i, p, nr_pages =3D 0, nr_pages_mapped =3D 0; + unsigned int i, nr_pages =3D 0; unsigned int nr_pfns =3D ctx->save.nr_batch_pfns; - void *page, *orig_page; int iovcnt =3D 0; xen_pfn_t *const batch_pfns =3D ctx->save.buffers->batch_pfns; struct { @@ -111,8 +109,6 @@ static int write_batch(struct xc_sr_context *ctx) xen_pfn_t *const mfns =3D ctx->save.buffers->mfns; /* Types of the batch pfns. */ xen_pfn_t *const types =3D ctx->save.buffers->types; - /* Errors from attempting to map the gfns. */ - int *const errors =3D ctx->save.buffers->errors; /* Pointers to locally allocated pages. Need freeing. */ void **const local_pages =3D ctx->save.buffers->local_pages; /* iovec[] for writev(). */ @@ -170,30 +166,26 @@ static int write_batch(struct xc_sr_context *ctx) mfns[nr_pages++] =3D mfns[i]; } =20 - if ( nr_pages > 0 ) + if ( nr_pages ) { - guest_mapping =3D xenforeignmemory_map( - xch->fmem, ctx->domid, PROT_READ, nr_pages, mfns, errors); - if ( !guest_mapping ) + DECLARE_HYPERCALL_BUFFER_SHADOW(uint8_t, dest_buf, + &ctx->save.dest_buf); + + rc =3D xg_foreignmemory_copy_from(xch, ctx->domid, nr_pages, dest_= buf, mfns); + if ( rc < 0 ) { - PERROR("Failed to map guest pages"); + ERROR("xg_foreignmemory_copy_from failed"); goto err; } - nr_pages_mapped =3D nr_pages; =20 - for ( i =3D 0, p =3D 0; i < nr_pfns; ++i ) + for ( unsigned int i =3D 0, p =3D 0; i < nr_pfns; ++i ) { + void *page, *orig_page; + if ( !page_type_has_stream_data(types[i]) ) continue; =20 - if ( errors[p] ) - { - ERROR("Mapping of pfn %#"PRIpfn" (mfn %#"PRIpfn") failed %= d", - batch_pfns[i], mfns[p], errors[p]); - goto err; - } - - orig_page =3D page =3D guest_mapping + (p * PAGE_SIZE); + orig_page =3D page =3D dest_buf + (p * PAGE_SIZE); rc =3D ctx->save.ops.normalise_page(ctx, types[i], &page); =20 if ( orig_page !=3D page ) @@ -201,15 +193,13 @@ static int write_batch(struct xc_sr_context *ctx) =20 if ( rc ) { - if ( rc =3D=3D -1 && errno =3D=3D EAGAIN ) - { - set_bit(batch_pfns[i], ctx->save.deferred_pages); - ++ctx->save.nr_deferred_pages; - types[i] =3D XEN_DOMCTL_PFINFO_XTAB; - --nr_pages; - } - else + if ( rc !=3D -1 || errno !=3D EAGAIN ) goto err; + + set_bit(batch_pfns[i], ctx->save.deferred_pages); + ++ctx->save.nr_deferred_pages; + types[i] =3D XEN_DOMCTL_PFINFO_XTAB; + --nr_pages; } else if ( iov[iovcnt - 1].iov_base + iov[iovcnt - 1].iov_len != =3D page ) @@ -222,8 +212,6 @@ static int write_batch(struct xc_sr_context *ctx) { iov[iovcnt - 1].iov_len +=3D PAGE_SIZE; } - - rc =3D -1; ++p; } } @@ -236,14 +224,13 @@ static int write_batch(struct xc_sr_context *ctx) if ( writev_exact(ctx->fd, iov, iovcnt) ) { PERROR("Failed to write page data to stream"); + rc =3D -1; goto err; } =20 rc =3D ctx->save.nr_batch_pfns =3D 0; =20 err: - if ( guest_mapping ) - xenforeignmemory_unmap(xch->fmem, guest_mapping, nr_pages_mapped); for ( i =3D 0; i < nr_pfns; ++i ) { free(local_pages[i]); @@ -770,17 +757,21 @@ static int setup(struct xc_sr_context *ctx) int rc; DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, &ctx->save.dirty_bitmap_hbuf); + DECLARE_HYPERCALL_BUFFER_SHADOW(uint8_t, dest_buf, + &ctx->save.dest_buf); =20 rc =3D ctx->save.ops.setup(ctx); if ( rc ) goto err; =20 + dest_buf =3D xc_hypercall_buffer_alloc_pages( + xch, dest_buf, MAX_BATCH_SIZE); dirty_bitmap =3D xc_hypercall_buffer_alloc_pages( xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size))); ctx->save.deferred_pages =3D bitmap_alloc(ctx->save.p2m_size); ctx->save.buffers =3D calloc(1, sizeof(*ctx->save.buffers)); =20 - if ( !ctx->save.buffers || !dirty_bitmap || !ctx->save.deferred_pages ) + if ( !ctx->save.buffers || !dirty_bitmap || !ctx->save.deferred_pages = || !dest_buf ) { ERROR("Unable to allocate memory for dirty bitmaps, deferred pages" " and various batch buffers"); @@ -793,7 +784,6 @@ static int setup(struct xc_sr_context *ctx) MEM_NOACCESS_INIT(ctx->save.buffers->na2); MEM_NOACCESS_INIT(ctx->save.buffers->na3); MEM_NOACCESS_INIT(ctx->save.buffers->na4); - MEM_NOACCESS_INIT(ctx->save.buffers->na5); =20 rc =3D 0; =20 @@ -806,7 +796,8 @@ static void cleanup(struct xc_sr_context *ctx) xc_interface *xch =3D ctx->xch; DECLARE_HYPERCALL_BUFFER_SHADOW(unsigned long, dirty_bitmap, &ctx->save.dirty_bitmap_hbuf); - + DECLARE_HYPERCALL_BUFFER_SHADOW(uint8_t, dest_buf, + &ctx->save.dest_buf); =20 xc_shadow_control(xch, ctx->domid, XEN_DOMCTL_SHADOW_OP_OFF, NULL, 0); @@ -816,6 +807,7 @@ static void cleanup(struct xc_sr_context *ctx) =20 xc_hypercall_buffer_free_pages(xch, dirty_bitmap, NRPAGES(bitmap_size(ctx->save.p2m_size)= )); + xc_hypercall_buffer_free_pages(xch, dest_buf, MAX_BATCH_SIZE); free(ctx->save.deferred_pages); free(ctx->save.buffers); } --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357870; cv=none; d=zohomail.com; s=zohoarc; b=AABuy++bjKYHzngOjV/S3BSmBvnYFzQ07+Q9p/RgWql2kmYoMJxX21LXXJXHQVuqtarNmr+TvFap7slYIbHhnsWCswskShl3izcUZ1ZBO6YrrvMTZTPhZvvIYvh/ajgKz1mJ8+JrvPGUeEWJULONqle/ekCMD9/Lqa84SnvDuW4= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357870; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=qkv0EX1DlL9MRRhP+Wk/CTJgzWiZHG9SS1IgseXcsTo=; b=H+276P8kJx//J+tmrOt6Ko24iEQbMhm1MUYe2l3x/oG5eih8s8lpqXuCmklOtlg5EC+o9ryclHLgjRMdySzOhb0uoN43Ln89YNwspp1cthmQqnclkApJ/c9KqBaCA1BHPzLTVftnad2AKYJtrkfUWBl2+vnIhKLTbbH+6zsrV7c= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357870038905.1830244187914; Mon, 10 Aug 2026 03:31:10 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387331.1628645 (Exim 4.92) (envelope-from ) id 1wtNHN-0005di-Vt; Mon, 10 Aug 2026 10:30:49 +0000 Received: by outflank-mailman (output) from mailman id 1387331.1628645; Mon, 10 Aug 2026 10:30:49 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHN-0005dR-Si; Mon, 10 Aug 2026 10:30:49 +0000 Received: by outflank-mailman (input) for mailman id 1387331; Mon, 10 Aug 2026 10:30:48 +0000 Received: from mx.expurgate.net ([194.145.224.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHM-0005NJ-LC for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:48 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHM-00AlYD-1S for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:48 +0200 Received: from [10.42.69.3] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a84f-e002-0a2a0a5209dd-0a2a450394e8-34 for ; Mon, 10 Aug 2026 12:30:48 +0200 Received: from [209.85.128.51] (helo=mail-wm1-f51.google.com) by tlsNG-33051d.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a857-fae8-0a2a45030019-d1558033b954-3 for ; Mon, 10 Aug 2026 12:30:47 +0200 Received: by mail-wm1-f51.google.com with SMTP id 5b1f17b1804b1-4954a2e73a9so10218785e9.3 for ; Mon, 10 Aug 2026 03:30:47 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.45 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:46 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357847; x=1786962647; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=qkv0EX1DlL9MRRhP+Wk/CTJgzWiZHG9SS1IgseXcsTo=; b=dssgC8bYdRsy1rv6mnHpmk95qopnTHYfBG03RycozOpT7Xmo8dQHhxB4Sl82MMD8Ky SL7nAtNBYvO64eJ8Wt1qRqhU5ylZ/0T9PIM5ZVbIe0qPqRVbfHUqhKxncYSJRrNaihlo 9v3m550Ved+iR0qBsQwToFNObsJ2CDpgnY/2X2a9hRmv05Omh6rTU4ymTtMGwU1nGMwz ylLreFa3surfadgv7cEnSYpIXW5p14mpny2mXs1DodIOw71itLZgmVidYsN+fM2s37K/ L/ACBDLCjUKnZFA4MKbauic9HfS9fKKO0j3uGCRlAXRRdgtQCJwHTEQi7Sa276EHiyqk dQSg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357847; x=1786962647; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=qkv0EX1DlL9MRRhP+Wk/CTJgzWiZHG9SS1IgseXcsTo=; b=dUjd7OW6kr4BH7uGzI12euWAKiRyleMJxRQlElE1/X9oFlnevP7pkjKzn/b6UohWY+ kREO8Tk39mH2zuwsn23LahkgcEE3XxUn2pJ3abjM2rmJxhaoBK49wkJXNNj8/UOeEMtT BvRUA16pxopJePk5Tf0udlLubNxl/EPay75/QeY2rTuKusdsTV61KG6Dq70/MNh1k7r3 2qCt7VHkjQqbSbjv67MqFTW9UrnC/XehxXlIgmqy8n/3tK+t9EFyjl0hJhucU/+9dZJ8 XTuSE928tNz+VfvXaIyJUGUB3AJ8l72iLFik6bTmjjM2fSIoII6N8U1Hqwiqxr4739Ua zTwg== X-Gm-Message-State: AOJu0Yxbfd396HTgZ9Dei6HV0dGyxCccFE0393rBFMqGnlzB+FsOiDCG yMyYJSfZIetHeNkT2NSyIeUmTy9dcAHmikh437yZXjlN4lU2qaDvLiVeQeqQ2T46Mig= X-Gm-Gg: AR+sD10RbCtaaPoqbfSabvQh9WZMXwhuYE0KepEB/FZ+LWAIO8Sxl8ZJrcRBiVM1upM WhUN2jP0Y9jsAxbV7KbFpTZVSr9JUwsVUm5ag6wwTmF8DGWO9xuYPQOfJMVzLKbPEcFKin72s1j sT2uKMD78B0rc0mCAzHDtyi3/Et+K4pe/w41DJduCq13EayJ3CKXwDwJijPLhEsqdOKWtJNl1dZ aZxtTjox4zWeJOQAx5+G+GRYtzLEtYMswz8p1l2T3foSdy2tTtznrFTGjyDlyQISsiUCaln1TEo 4vdxEFFYNd+g4ORzafx/5SRPkvieQtmxMA2cX49I4yIAbY+FwGUChZ7Xiez/ysRv0b3EaDzyW9o W8lRZ6vNnEWAWqHXGkphlYcBb3piQzhzo4dUVvKRSBurOM+Iks6UpcbTKXBDH2yXSeYEkjjLxWS WtOlZo5YvIynE4h6JrCKx2g1J0BtfsZpTojVcuDjc9dDQkGj+bzTvb7VkRPHl7XggVuuARmrabz dia0edVq2QMvMcHedzLF+t6VT4iFMUMGwkeH/P5 X-Received: by 2002:a05:600c:1553:b0:495:5045:39e6 with SMTP id 5b1f17b1804b1-4994e7d3080mr453921205e9.17.1786357847166; Mon, 10 Aug 2026 03:30:47 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross , "Daniel P . Smith" Subject: [PATCH v10 7/10] xen: implement new foreign copy hypercall Date: Mon, 10 Aug 2026 11:30:10 +0100 Message-ID: <20260810103018.54564-8-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-33051d/1786357847-74C884E9-DCD50404/0/0 X-purgate-type: clean X-purgate-size: 10676 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357871112158500 Content-Type: text/plain; charset="utf-8" Add a sub hypercall to __HYPERVISOR_memory_op to allow to read/write memory from/to a foreign domain. Extending MMUEXT_COPY_PAGE seems better on first sight but considering that MMUEXT is meant for PV only and trying to change that sub-op this solution is better. Signed-off-by: Frediano Ziglio --- Changes since v4: - Fix typo in comment. Changes since v5: - update xen_foreigncopy structure comments; - move check for no frames after checking the domain; - use mnemonic instead of 1U; - fix page type checks; - do not overwrite error copying back structure; - latch MFN value; - improved commit message. Changes since v6: - check permissions before nr_frames; - different flag for read or write; - print error as negative for coherence; - update some comments; - different page types for different architectures. Changes since v9: - page permission checks like MMU_UPDATE; - new XSM settings; - do not restrict domain; - different explanation why HVM guests are not supported. --- xen/common/memory.c | 149 ++++++++++++++++++++++++++++++++++++ xen/include/public/memory.h | 45 ++++++++++- xen/include/xsm/dummy.h | 14 ++++ xen/include/xsm/hooks.h | 2 + xen/xsm/flask/hooks.c | 10 +++ 5 files changed, 219 insertions(+), 1 deletion(-) diff --git a/xen/common/memory.c b/xen/common/memory.c index 9443e35a7f..29a70d99b1 100644 --- a/xen/common/memory.c +++ b/xen/common/memory.c @@ -1548,6 +1548,141 @@ static int acquire_resource( return rc; } =20 +/* + * The "noinline" qualifier avoids the compiler to create a large function + * consuming quite a lot of stack. + */ +static int noinline mem_foreigncopy( + XEN_GUEST_HANDLE_PARAM(xen_foreigncopy_t) arg) +{ + struct domain *d, *const currd =3D current->domain; + xen_foreigncopy_t copy; + int rc, direction; + + if ( copy_from_guest(©, arg, 1) ) + return -EFAULT; + + if ( copy.flags & ~XENMEM_foreigncopy_direction ) + return -EINVAL; + + direction =3D copy.flags & XENMEM_foreigncopy_direction; + + d =3D rcu_lock_domain_by_any_id(copy.domid); + if ( !d ) + return -ESRCH; + + /* + * Check we are allowed to map and access these foreign pages. + */ + if ( direction =3D=3D XENMEM_foreigncopy_from ) + rc =3D xsm_foreigncopy_from(XSM_TARGET, currd, d); + else + rc =3D xsm_foreigncopy_to(XSM_TARGET, currd, d); + if ( rc ) + goto out; + + while ( copy.nr_frames ) + { + /* + * Arbitrary size. Not too much stack space, and a reasonable str= ide + * for continuation checks. + */ + xen_pfn_t gfn_list[32]; + unsigned int todo =3D MIN(ARRAY_SIZE(gfn_list), copy.nr_frames); + + rc =3D -EFAULT; + if ( copy_from_guest(gfn_list, copy.frame_list, todo) ) + goto out; + + for ( unsigned int i =3D 0; i < todo; i++ ) + { + struct page_info *foreign_page; + mfn_t foreign_mfn; + void *foreign; + p2m_type_t p2mt; + p2m_query_t q =3D (direction =3D=3D XENMEM_foreigncopy_to) ? + P2M_ALLOC | P2M_UNSHARE : P2M_ALLOC; + + foreign_page =3D get_page_from_gfn(d, gfn_list[i], &p2mt, q); + + if ( unlikely(p2m_is_paged(p2mt)) ) + { + if ( foreign_page ) + put_page(foreign_page); + p2m_mem_paging_populate(d, _gfn(gfn_list[i])); + p2mt =3D p2m_ram_paging_in; + foreign_page =3D NULL; + } + + if ( unlikely(!foreign_page) ) + { + rc =3D -ENOENT; + if ( p2mt !=3D p2m_ram_paging_in ) + { + gdprintk(XENLOG_WARNING, + "Error accessing foreign gfn %" PRI_gfn "\n", + gfn_list[i]); + rc =3D -EINVAL; + } + copy.nr_frames -=3D i; + guest_handle_add_offset(copy.frame_list, i); + goto out; + } + + foreign_mfn =3D page_to_mfn(foreign_page); + + /* A page is dirtied when it's being copied to. */ + if ( direction =3D=3D XENMEM_foreigncopy_to ) + paging_mark_dirty(d, foreign_mfn); + + foreign =3D map_domain_page(foreign_mfn); + if ( direction =3D=3D XENMEM_foreigncopy_from ) + rc =3D copy_to_guest(copy.buffer, foreign, PAGE_SIZE); + else + rc =3D copy_from_guest(foreign, copy.buffer, PAGE_SIZE); + unmap_domain_page(foreign); + put_page(foreign_page); + + if ( unlikely(rc) ) + { + gdprintk(XENLOG_WARNING, + "Error %d copying gfn %" PRI_gfn "\n", + rc, gfn_list[i]); + copy.nr_frames -=3D i; + guest_handle_add_offset(copy.frame_list, i); + goto out; + } + + guest_handle_add_offset(copy.buffer, PAGE_SIZE); + } + + copy.nr_frames -=3D todo; + guest_handle_add_offset(copy.frame_list, todo); + + if ( copy.nr_frames && hypercall_preempt_check() ) + { + rc =3D hypercall_create_continuation( + __HYPERVISOR_memory_op, "lh", XENMEM_foreigncopy, arg); + goto out; + } + } + + rc =3D 0; + + out: + rcu_unlock_domain(d); + + /* + * Update in all cases, it allows the caller to know how many + * frames were successfully copied and the continuation to + * continue correctly. + */ + if ( __copy_to_guest(arg, ©, 1) && rc >=3D 0 ) + rc =3D -EFAULT; + + return rc; +} + long do_memory_op(unsigned long cmd, XEN_GUEST_HANDLE_PARAM(void) arg) { struct domain *d, *curr_d =3D current->domain; @@ -2027,6 +2162,20 @@ long do_memory_op(unsigned long cmd, XEN_GUEST_HANDL= E_PARAM(void) arg) start_extent); break; =20 + case XENMEM_foreigncopy: + /* + * Instead of using "start_extent" for the continuation, we update + * the xen_foreigncopy structure back, so we are not constrained by + * MEMOP_EXTENT_SHIFT. + * We copy it back also to tell the caller where the copy stopped + * (either for error or because all frames were copied). + */ + if ( unlikely(start_extent) ) + return -EINVAL; + + rc =3D mem_foreigncopy(guest_handle_cast(arg, xen_foreigncopy_t)); + break; + default: rc =3D arch_memory_op(cmd, arg); break; diff --git a/xen/include/public/memory.h b/xen/include/public/memory.h index bd9fc37b52..66bd2a6c42 100644 --- a/xen/include/public/memory.h +++ b/xen/include/public/memory.h @@ -740,7 +740,50 @@ struct xen_vnuma_topology_info { typedef struct xen_vnuma_topology_info xen_vnuma_topology_info_t; DEFINE_XEN_GUEST_HANDLE(xen_vnuma_topology_info_t); =20 -/* Next available subop number is 29 */ +/* + * Copy memory from/to a given domain. + * This calls is meant to replace expensive operations during migration wh= ich + * are only supported for PV guests. + */ +#define XENMEM_foreigncopy 29 +struct xen_foreigncopy { + /* IN - The domain whose memory is to be copied. */ + domid_t domid; + + /* IN - Flags. */ +#define XENMEM_foreigncopy_from 0 +#define XENMEM_foreigncopy_to 1 +#define XENMEM_foreigncopy_direction 1 + uint16_t flags; + + /* + * IN/OUT + * + * As an IN parameter number of frames of the domain to be copied. + * On output updated number of frames left (0 if success). + */ + uint32_t nr_frames; + + /* + * IN/OUT + * + * Frames to be copied. + * On output updated to point to the first frame unhandled, if any. + */ + XEN_GUEST_HANDLE(xen_pfn_t) frame_list; + + /* + * IN/OUT + * + * Guest buffer to read/write from. + * On output updated to point to the first page pointer unhandled. + */ + XEN_GUEST_HANDLE(uint8) buffer; +}; +typedef struct xen_foreigncopy xen_foreigncopy_t; +DEFINE_XEN_GUEST_HANDLE(xen_foreigncopy_t); + +/* Next available subop number is 30 */ =20 #endif /* __XEN_PUBLIC_MEMORY_H__ */ =20 diff --git a/xen/include/xsm/dummy.h b/xen/include/xsm/dummy.h index 131631cb27..dcdb7f5396 100644 --- a/xen/include/xsm/dummy.h +++ b/xen/include/xsm/dummy.h @@ -569,6 +569,20 @@ static XSM_INLINE int cf_check xsm_map_gmfn_foreign( return xsm_default_action(action, d, t); } =20 +static XSM_INLINE int cf_check xsm_foreigncopy_from( + XSM_DEFAULT_ARG struct domain *d, struct domain *t) +{ + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d, t); +} + +static XSM_INLINE int cf_check xsm_foreigncopy_to( + XSM_DEFAULT_ARG struct domain *d, struct domain *t) +{ + XSM_ASSERT_ACTION(XSM_TARGET); + return xsm_default_action(action, d, t); +} + #ifdef CONFIG_HVM =20 static XSM_INLINE int cf_check xsm_hvm_param( diff --git a/xen/include/xsm/hooks.h b/xen/include/xsm/hooks.h index 5bdb23f26d..63e2831d31 100644 --- a/xen/include/xsm/hooks.h +++ b/xen/include/xsm/hooks.h @@ -58,6 +58,8 @@ XSM_HOOK(int, add_to_physmap, struct domain *, struct dom= ain *) XSM_HOOK(int, remove_from_physmap, struct domain *, struct domain *) XSM_HOOK(int, map_gmfn_foreign, struct domain *, struct domain *) XSM_HOOK(int, claim_pages, struct domain *) +XSM_HOOK(int, foreigncopy_from, struct domain *, struct domain *); +XSM_HOOK(int, foreigncopy_to, struct domain *, struct domain *); =20 XSM_HOOK(int, console_io, struct domain *, int) =20 diff --git a/xen/xsm/flask/hooks.c b/xen/xsm/flask/hooks.c index 3cfdf6bf08..281800e176 100644 --- a/xen/xsm/flask/hooks.c +++ b/xen/xsm/flask/hooks.c @@ -1368,6 +1368,16 @@ static int cf_check flask_map_gmfn_foreign(struct do= main *d, struct domain *t) return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WR= ITE); } =20 +static int cf_check flask_foreigncopy_from(struct domain *d, struct domain= *t) +{ + return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ); +} + +static int cf_check flask_foreigncopy_to(struct domain *d, struct domain *= t) +{ + return domain_has_perm(d, t, SECCLASS_MMU, MMU__MAP_READ | MMU__MAP_WR= ITE); +} + #ifdef CONFIG_HVM =20 static int cf_check flask_hvm_param(struct domain *d, unsigned long op) --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357877; cv=none; d=zohomail.com; s=zohoarc; b=K1CcyMVvBR4/wmQgWdrpkwY7Dvs/Pb5k7opPTKaDWIA5mOczYEUoU/oglgem+870L4E070Kq9saP8zoMy2lPSe6NmAIkE9haeJevsvSUJgAhxRfolfKCzoGqFcV2f4NkKOFeCl6fAqmsfFFgKd7f9KJx5TEdut9b6OvdG2Bc9us= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357877; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=3+Xmp4HOhS3Pe3sNnwkV9Nev075F3jzmTYNfYLmJyJ8=; b=IouUvtpv/LJphU9biI0S20mHIFaKxY3Nu6O0RBqwrZBTAp03OSTkCdWuBtvQFGVori9g6eaw0swKfPc3XMgPlTDhqc9i6meYjkuhYf69vVdMpC9CUws1bhoZ7VjvC37gTzndynv83ru6wtNx0RnHOXf7XQyJ04dffkNsm48o4Us= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357877069843.014528168913; Mon, 10 Aug 2026 03:31:17 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387332.1628653 (Exim 4.92) (envelope-from ) id 1wtNHQ-0005wj-BT; Mon, 10 Aug 2026 10:30:52 +0000 Received: by outflank-mailman (output) from mailman id 1387332.1628653; Mon, 10 Aug 2026 10:30:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHQ-0005wW-7O; Mon, 10 Aug 2026 10:30:52 +0000 Received: by outflank-mailman (input) for mailman id 1387332; Mon, 10 Aug 2026 10:30:50 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHO-0005mI-Re for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:50 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHO-00Dyin-8C for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:50 +0200 Received: from [10.42.69.7] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a854-bab6-0a2a0a5309dd-0a2a450799ec-14 for ; Mon, 10 Aug 2026 12:30:50 +0200 Received: from [209.85.128.53] (helo=mail-wm1-f53.google.com) by tlsNG-ef75cf.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a85a-b4ea-0a2a45070019-d1558035a911-3 for ; Mon, 10 Aug 2026 12:30:50 +0200 Received: by mail-wm1-f53.google.com with SMTP id 5b1f17b1804b1-4954a9e8490so22911205e9.1 for ; Mon, 10 Aug 2026 03:30:50 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.47 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:47 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357849; x=1786962649; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=3+Xmp4HOhS3Pe3sNnwkV9Nev075F3jzmTYNfYLmJyJ8=; b=gtDSvt3XLEF0+lvQmQpagPOxD+0HfyCi9SY4SgOtI34Q71fF520A50KI3R6asKiy7o EcYlQ3rf4vzvzkchvPC01UnKK++WMHlUXH5OH706GiBiqvJmi+8U6zknAp+RHmOuY0Tm Hdp4ppYkczqspONQlul4iFdjhg/pVXFFOo/CPqeM5m/7HBN2E8w5pSC17iPxKzAgZ25S uOKOV4HqmTJFIXMyJVIfJgSyvCcNZ4r+OpQMO9LMWYVp1FgrISAx7+4gLTMyaTZqnoay hAkRBTQPbtx2qHVGzVMwATUKSGA7uhSiwtjyvijDYIQCm9+fuL6BKjsmeJ/nvGY5rMYo icZg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357849; x=1786962649; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=3+Xmp4HOhS3Pe3sNnwkV9Nev075F3jzmTYNfYLmJyJ8=; b=nNMea2ZxnrskLsVM7ZtZTuExUNL9p7rztECnxYx/Jyh9bjzpg5GpAPiPipHYJ/Qpik EMZ3yoAbdHImBimhP0g8Hc5mlCUW5vkXbLUij9OSBdgsf4riDudsERx6HrqpejkAqFDF iv7X3xzGZJ50P5crPIcj1xzbh/MvcsOPtIk6QJL9u5kEaVM/fN6EWlj0BQSBOOKBDUte fk+vMm3m7Tm0engIlvzKElhTuWl1ITEiKfzw7j0YabFyH6JTadG0mlf7C70IC4D5fFnd brNLTg3s76yB8zvmRP7qA0RHIf8TjXNPQiWKcS7duVSCGH/11Ux1qruDJ8/yMfcG+qRk 9Zdw== X-Gm-Message-State: AOJu0YyhS9Da4dMD8o5+/DCwl3AeCosrtOZm0jGpyyVd74k48sUEVIBm Pfbcaps3+vtKSJSk4oK1i7D8WHeRBM7YInfadNtMttnFqAys1LWEhCv546Wn0ljjjFs= X-Gm-Gg: AR+sD11E9+7ILZ58VGN/7jJlVXLWJNpaGETrhUnec912ha4u18E6sqbVHs5zAhEYzsB TM1YunT6CHuk1seD3h+az2jpbweExOvp2Ui0X6UMWw47+GAdIMTfyYdESfF4FSXZ3TXxEsDfdGz msitmMpjZVoatZYA6WCr0EWYmXTreM55GGnx4sqRv89hxakWY5/0edBZ687FOXHi04TkUqWD1CN U3xFJ8OgmR9NlHmDZc98w92yo0oBvxNnj14n3w8f67SDBCra55FaiyEWyFtPpMT3f7JYjqcpBLs cJgIcOy6CoWtr6gj/WWBAY35lKSWhimmbXi3vRjanX/JovtP2p/yFdDQCNl/jD6Bfhkx3llsLBc q1YDmTlUsgQVDGXaGTb9tu41AByUxiybfpJ0+68mHoZoCRhKNHwxAG4hqK7drROyrtJ/0Oc12Ut 8MGGOiG7MofJyEwlmspeDEyxIQv7mfXQw4r26RdhNOuVjy+MOE7MLeCr4P3ba6yF7u27Pcp1VAy YVnfjMOzSG1VJaixXneYAEIWJZPJT1nFaLOoVFm X-Received: by 2002:a05:600c:3154:b0:495:3bc6:d381 with SMTP id 5b1f17b1804b1-49962453c45mr201315725e9.2.1786357848475; Mon, 10 Aug 2026 03:30:48 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross Subject: [PATCH v10 8/10] privcmd: Add definition for new Linux privcmd to access new Xen hypercall Date: Mon, 10 Aug 2026 11:30:11 +0100 Message-ID: <20260810103018.54564-9-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-ef75cf/1786357850-374D3AE4-0A5726EE/0/0 X-purgate-type: clean X-purgate-size: 1401 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357879072158500 Content-Type: text/plain; charset="utf-8" Userspace should use new ioctl to access new hypercall. Signed-off-by: Frediano Ziglio --- Changes since v4: - update comment. --- tools/include/xen-sys/Linux/privcmd.h | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/tools/include/xen-sys/Linux/privcmd.h b/tools/include/xen-sys/= Linux/privcmd.h index 607dfa2287..7a3c41308b 100644 --- a/tools/include/xen-sys/Linux/privcmd.h +++ b/tools/include/xen-sys/Linux/privcmd.h @@ -100,6 +100,14 @@ typedef struct privcmd_pcidev_get_gsi { __u32 gsi; } privcmd_pcidev_get_gsi_t; =20 +typedef struct privcmd_foreigncopy { + domid_t dom; /* Foreign domain. */ + __u16 dir; /* Direction, 0 from, 1 to. */ + __u32 num; /* Number of pages to copy. */ + const xen_pfn_t __user *pfns; /* Array of pfns. */ + void __user *buffer; /* Buffer to copy to/from. */ +} privcmd_foreigncopy_t; + /* * @cmd: IOCTL_PRIVCMD_HYPERCALL * @arg: &privcmd_hypercall_t @@ -121,6 +129,8 @@ typedef struct privcmd_pcidev_get_gsi { _IOC(_IOC_NONE, 'P', 7, sizeof(privcmd_mmap_resource_t)) #define IOCTL_PRIVCMD_PCIDEV_GET_GSI \ _IOC(_IOC_NONE, 'P', 10, sizeof(privcmd_pcidev_get_gsi_t)) +#define IOCTL_PRIVCMD_FOREIGNCOPY \ + _IOWR('P', 11, privcmd_foreigncopy_t) #define IOCTL_PRIVCMD_UNIMPLEMENTED \ _IOC(_IOC_NONE, 'P', 0xFF, 0) =20 --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357870; cv=none; d=zohomail.com; s=zohoarc; b=TygR5TBqi+i4iD2bjIXd+AL9qrQ/nNGv2vBFnicgCRunmnDg030zwKAZoDI68ViMBzQzPbvJ9MnXWhzUL9K3GYsAGmIybrELd5hfUTTEepa1XMbdcmGoyq1Eg9ZKdxi2qSkGzF1YkhZgjQSL6d4CKJORv4mdFjbyuwGD5YPGqeI= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357870; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=kAXV9ixt1kgi3GnwQ2iOZUoRsAZqt/4+AFDCaE6CjSg=; b=l1TfVuWz/Rheoat+/jqt2PtdugrkluINRVZq1UosozQbo4VKGfDBKEBGUMq0rg0Rm7EvTuISgYhku0wxUHmE81dnfnjGdGSPvWZ4X4T/zWTFK1tJcWBswGio1xBfh/KUC3UGQdqYKwt1Bu1KV7LEyavIcIagHAmdUEBYt874R4E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357870452924.6878417386068; Mon, 10 Aug 2026 03:31:10 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387334.1628660 (Exim 4.92) (envelope-from ) id 1wtNHQ-0005zd-S1; Mon, 10 Aug 2026 10:30:52 +0000 Received: by outflank-mailman (output) from mailman id 1387334.1628660; Mon, 10 Aug 2026 10:30:52 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHQ-0005yb-GH; Mon, 10 Aug 2026 10:30:52 +0000 Received: by outflank-mailman (input) for mailman id 1387334; Mon, 10 Aug 2026 10:30:51 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHP-0005rk-Bq for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:51 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHO-00Dyin-Oq for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:50 +0200 Received: from [10.42.69.12] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a85a-bab6-0a2a0a5309dd-0a2a450ce3f8-0 for ; Mon, 10 Aug 2026 12:30:50 +0200 Received: from [209.85.128.50] (helo=mail-wm1-f50.google.com) by tlsNG-d25034.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a85a-f479-0a2a450c0019-d1558032ad5d-3 for ; Mon, 10 Aug 2026 12:30:50 +0200 Received: by mail-wm1-f50.google.com with SMTP id 5b1f17b1804b1-49558ce01afso13250535e9.1 for ; Mon, 10 Aug 2026 03:30:50 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.48 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:49 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357850; x=1786962650; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=kAXV9ixt1kgi3GnwQ2iOZUoRsAZqt/4+AFDCaE6CjSg=; b=P5iCpsfNaVH88Si13CsIDlLOFZztr6wXx6/QCdl1ZFuI4R/OZccH+ZMMxp5OAFoS2/ IQsUMSmvlVryFWImXqacDwF/dXwMabeeRyrSsqyRmyCaDxSgT2MRpkerCM/tdLkE3bA4 pHO693NJptx9bwrdUmbznIh8L0PrUL0nGGGYF+9zfCA9+SlcohYv5LiDaZ3X/8JTG5k4 lPl4aplLUymxPbI55R8UpTejLhm2ybPnjL7xF8QJCkWygt9ZcVVOQgarR6ELVijkoort mS8oyYbSqkhIhhgT0Fn35QTFIiy6Bma7f8pmcOUcrTHtKkdSSxZggFwjpaMC1ieAxNqC pe/A== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357850; x=1786962650; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=kAXV9ixt1kgi3GnwQ2iOZUoRsAZqt/4+AFDCaE6CjSg=; b=rY/hK24RFYvWKtj+nJpwj03KxQepQ0sGNqDpP6PnG2hHUWHMazsQ3VXQ+WLGybocg7 oxIC3p7LD41aiEU/+mzNqI30WPF0riSlXcsgevmDYo6jsGF3EmPCIJkSfL6SV3Mg9YSy k8gXbsS2yMGJX8v4OGr909Q9mQG52Zx9uYCdme6ONg7Yy5O5PW+N+DCQpNYp7KnQPcHB z8MQlwrQNYtvU+STulPuJurlhP72Ahlhg/4xNyxiTzJ7tzSBRJajXxTz+QLC7BR5wk6X wysYMoeHEM2x3PLsPWXdAYdIHc37ZFmFxBjp1G2rE3tUwH/lN76BrnC+gm1EoMzI8ifc Fnmw== X-Gm-Message-State: AOJu0YzncX2+NPhg9m9OZTiQgTtN53M6hpXdS0fmTUkOCQ7h43ioOg5W YzQjJpHOg7z9gB4eUsop3w4HUtkqwfXbLQCpLEmbyfKCKlZLd23Cetew9PFZSal2T6s= X-Gm-Gg: AR+sD11ZoQpDWYJWdZduz8EPTTu2UDEv+8gGN6W3lT3OZLoGxmLGxIqtzLTuPqzTumh G8x4ISKAgJLt0Sz/WiA55jMZS5pUdnvoRDFgHoy5RKuzHPD7f2ay0VkTJA07sgi3+FDGch8wK2N +CinvDQ2iLAA4CgqFt9pZoSxabkrAmU0kUeHQ743AvGZySd/t+gPgQgPufO+/0Ub0ddKgIcrFsC GiORVZfh1uP5Ap9mdN5rNCIzrwfuYwPVn7j54wE8dO9v/j+5TKWOwo9jZzzqsGpRpTs313sX1P/ osto5luJSZWm+0/B3vqJPn2Z39PqIXWUKwTeIsfn6U8S0lde8jUO/kz7T6E9JRzyCI9QjbH773p fepH99Yx93OIwHAKwBTSC+tMRSohwMM67SEogEGkRWgvmswSk0OszqtRoKo1T8Hw1wkBBp11v7e rCZa+7L0VNk1NTkD5hUXWRgFla0Wo8Gt/k3KT913+QL5q3Q1k21QYX7TLOYZzOT06RqcXfkCuuU VUv4VheoKXoxPdPBeyQpRKk4auOfKPdtJdIbbBD X-Received: by 2002:a05:600c:35c8:b0:499:593b:a15b with SMTP id 5b1f17b1804b1-499593ba192mr395987645e9.1.1786357850038; Mon, 10 Aug 2026 03:30:50 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross Subject: [PATCH v10 9/10] libs/guest: use new hypercall if available Date: Mon, 10 Aug 2026 11:30:12 +0100 Message-ID: <20260810103018.54564-10-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-d25034/1786357850-51D34A5B-337B1D1C/0/0 X-purgate-type: clean X-purgate-size: 4281 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357871019158500 Content-Type: text/plain; charset="utf-8" Use new hypercall if available, otherwise fall back to map+copy+unmap sequence. I took some statistics while migrating some machines instrumenting the code to use new and old code and doing it 5 times in a row for each and the raw operation takes at least 4 (from) or 5 (to) times less. Specifically for a test done with a machine with Intel Xeon Sapphire Rapids CPUs and migrating a Windows 10 machine with 12 GB of RAM the ratios were: - 4.9 times faster copying from guest to dom0; - 5.3 times faster copying to guest from dom0. The test was repeated multiple times resulting consistent in all rans. Signed-off-by: Frediano Ziglio --- Changes since v4: - use int8_t instead of char for signed type. Changes since v6: - add some statistics. Changes since v9: - fixed a pointer initialization. --- tools/libs/guest/xg_sr_common.c | 47 ++++++++++++++++++++++++++------- 1 file changed, 38 insertions(+), 9 deletions(-) diff --git a/tools/libs/guest/xg_sr_common.c b/tools/libs/guest/xg_sr_commo= n.c index 90da21c35f..ce5026c707 100644 --- a/tools/libs/guest/xg_sr_common.c +++ b/tools/libs/guest/xg_sr_common.c @@ -156,11 +156,6 @@ static void __attribute__((unused)) build_assertions(v= oid) BUILD_BUG_ON(sizeof(struct xc_sr_rec_hvm_params) !=3D 8); } =20 -enum { - foreigncopy_from, - foreigncopy_to -}; - static int xg_foreignmemory_copy(xc_interface *xch, domid_t domid, int dir, size_t nr_pages, void *buffer, const xen_pfn_t foreign_pfns[nr_pages]) @@ -174,8 +169,42 @@ static int xg_foreignmemory_copy(xc_interface *xch, do= mid_t domid, return -1; } =20 + /* + * If foreign copy is supported, -1 not initialized, 0 not supported, + * 1 supported. + */ + static int8_t foreign_copy_supported =3D -1; + + if ( foreign_copy_supported ) + { + int rc; + privcmd_foreigncopy_t copy =3D { + .dom =3D domid, + .dir =3D dir, + .num =3D nr_pages, + .buffer =3D buffer, + }; + DECLARE_HYPERCALL_BOUNCE_IN(foreign_pfns, nr_pages * sizeof(xen_pf= n_t)); + + if ( xc_hypercall_bounce_pre(xch, foreign_pfns) ) + return -1; + + copy.pfns =3D (xen_pfn_t *)HYPERCALL_BUFFER_AS_ARG(foreign_pfns); + + rc =3D ioctl(xencall_fd(xch->xcall), IOCTL_PRIVCMD_FOREIGNCOPY, &c= opy); + if ( foreign_copy_supported < 0 ) + foreign_copy_supported =3D + (!rc || (errno !=3D ENOTTY && errno !=3D ENOSYS)); + + xc_hypercall_bounce_post(xch, foreign_pfns); + + if ( foreign_copy_supported ) + return rc; + } + + /* Fallback, emulate. */ int err[nr_pages]; - const int prot =3D (dir =3D=3D foreigncopy_from) ? PROT_READ : PROT_RE= AD|PROT_WRITE; + const int prot =3D (dir =3D=3D XENMEM_foreigncopy_from) ? PROT_READ : = PROT_READ|PROT_WRITE; =20 void *p =3D xenforeignmemory_map(xch->fmem, domid, prot, nr_pages, for= eign_pfns, err); if ( !p ) @@ -189,7 +218,7 @@ static int xg_foreignmemory_copy(xc_interface *xch, dom= id_t domid, return -1; } =20 - if ( dir =3D=3D foreigncopy_from ) + if ( dir =3D=3D XENMEM_foreigncopy_from ) memcpy(buffer, p, nr_pages * XC_PAGE_SIZE); else memcpy(p, buffer, nr_pages * XC_PAGE_SIZE); @@ -201,7 +230,7 @@ int xg_foreignmemory_copy_from(xc_interface *xch, domid= _t dom, size_t nr_pages, void *dest, const xen_pfn_t source[nr_pages]) { - return xg_foreignmemory_copy(xch, dom, foreigncopy_from, + return xg_foreignmemory_copy(xch, dom, XENMEM_foreigncopy_from, nr_pages, dest, source); } =20 @@ -209,7 +238,7 @@ int xg_foreignmemory_copy_to(xc_interface *xch, domid_t= dom, size_t nr_pages, const xen_pfn_t dest[nr_page= s], const void *source) { - return xg_foreignmemory_copy(xch, dom, foreigncopy_to, + return xg_foreignmemory_copy(xch, dom, XENMEM_foreigncopy_to, nr_pages, (void *) source, dest); } =20 --=20 2.43.0 From nobody Thu Aug 13 09:21:37 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=gmail.com ARC-Seal: i=1; a=rsa-sha256; t=1786357879; cv=none; d=zohomail.com; s=zohoarc; b=VcopbxbDObKw/pmOyNgvmu5ByyPhzyU5rzZQwrjqVN4RCQffkioZ4maUgU1t06ABz9ptFX/Dximr7rVYkeqlzV2K+QZFztDQVQ99aBKMra0v9aspItE8AJV2eGFH6Ajg0y4UcG49U0at9VDrhauMCooPOTfRrNHrJOFWaOHod2o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1786357879; h=Content-Transfer-Encoding:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=UVOrYo9kwDL27bIBgSRi6l0uRZVsLr0xOhtweF06SqI=; b=SuSiXeqH1YQuUHQHBkLJeivOqYvDmRItCyZoZowwNAoaQO9jkcmLmpqksS2l3W729UsQOg/5fNfK+x1/pFxZ2L3brFVLDzEfhFYFgcRdbB4NAKJahVUVTufsVa1/nYfGeY3HGcBrhMrZWWSvtFBtOQhndZIsLWp+4LcDuUJNuj4= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1786357879713606.0969790871716; Mon, 10 Aug 2026 03:31:19 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1387336.1628668 (Exim 4.92) (envelope-from ) id 1wtNHS-0006LE-8S; Mon, 10 Aug 2026 10:30:54 +0000 Received: by outflank-mailman (output) from mailman id 1387336.1628668; Mon, 10 Aug 2026 10:30:54 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHS-0006Jf-1g; Mon, 10 Aug 2026 10:30:54 +0000 Received: by outflank-mailman (input) for mailman id 1387336; Mon, 10 Aug 2026 10:30:53 +0000 Received: from mx.expurgate.net ([195.190.135.10]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1wtNHQ-0005zg-Q5 for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 10:30:52 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1wtNHQ-000BDZ-6F for xen-devel@lists.xenproject.org; Mon, 10 Aug 2026 12:30:52 +0200 Received: from [10.42.69.9] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a79a854-2eae-0a2a0a5409dd-0a2a4509bf7e-46 for ; Mon, 10 Aug 2026 12:30:52 +0200 Received: from [209.85.128.41] (helo=mail-wm1-f41.google.com) by tlsNG-bad1c0.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a79a85c-be1a-0a2a45090019-d1558029d1c2-3 for ; Mon, 10 Aug 2026 12:30:52 +0200 Received: by mail-wm1-f41.google.com with SMTP id 5b1f17b1804b1-4995b0343c1so14895985e9.3 for ; Mon, 10 Aug 2026 03:30:52 -0700 (PDT) Received: from localhost.localdomain ([31.111.172.30]) by smtp.gmail.com with ESMTPSA id 5b1f17b1804b1-4995bb8b668sm218478455e9.0.2026.08.10.03.30.50 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Mon, 10 Aug 2026 03:30:51 -0700 (PDT) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=20251104 header.d=gmail.com header.i="@gmail.com" header.h="Content-Transfer-Encoding:MIME-Version:References:In-Reply-To:Message-ID:Date:Subject:Cc:To:From" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=gmail.com; s=20251104; t=1786357851; x=1786962651; darn=lists.xenproject.org; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:from:to:cc:subject:date :message-id:reply-to:content-type; bh=UVOrYo9kwDL27bIBgSRi6l0uRZVsLr0xOhtweF06SqI=; b=OFQuNM/CI3Ms3ghElvx6gHV113l9f8rJdEPvrkjHSnPr/Fl7VuGVd6HOrhKZpudEKU VsgqdHY0flt9zyRLmzpU3zwUbLIFBp9EZbBad5flLsliatOf50DNxMxyg677h6eo1y3u 3eBdyqtLeFbwqQaoXR1QI0rPH2jiTj5M6CFsCINN7apxor5ivpAXUffe9YK9aD8NLkez I1BlKtfemqzeT86jBU74TXh14bntZGjYqziICDDf/UWuHWRPYFG8+aEpjLVEbE1SrmL6 1ffu1VoSwkJqfXG18P0PtsNvUfbf4A7gbAFSR9KbqHaGp6IbHlzS4FdknKZcrzh9cqRK H2fg== X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20251104; t=1786357851; x=1786962651; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-gg:x-gm-message-state:from :to:cc:subject:date:message-id:reply-to:content-type; bh=UVOrYo9kwDL27bIBgSRi6l0uRZVsLr0xOhtweF06SqI=; b=qbYnE6xRPVHuZ0s8uCRbR6NBYLuLocC1ujczkNtCKV8hdSu1hh3zzqgVNvG7QA1LUx 3RCbQdjx0Aq9YF18MXMvRSnhst9c2OVM+I213AlWA1wIIUIxRWyw37lHPwrdg7KQKlQv T6O79/1xDX1l2b9Dmtvp24yOQtHUj2G3qGF596SEeo8cXV9P0tdWSfPUqUayfldq15nx ljxl/RBwUDUkmSBFd3Pl4B/D1+ywUJMuZ/YMYKF8QdO95W+qrcAa2MqNDf3ClD6UF5as BDeBabtQT0bB9LT/4VrddCly6NZkcgu/sqozD6TVWWQcWwNovyxbz0XCrdtEBctI9147 SpXw== X-Gm-Message-State: AOJu0YzUxup0D13r3gziyWX8EzSqjidParyWHBB24FpMtibY8S030vGI e1vn9bgyQOgMSux978Stui3mtbvqCAFMbpwQHB9N1fCz9UXKl5DIo7dIEcBnLe6kWVk= X-Gm-Gg: AR+sD12cUWJyexX2URDj4+cUh5U9q2py+t52F6gRZjy3syVxB00j1zvGu1dFvljZWfI jNS8D3nX/Hw26AoBjLHPyfqreAiGOHsj8iGVlk5y8bTkHCw2mvzC1xIczWi4hdwMD3ybxqrVf4j nsfzynpIQUWCJ0QD3Y0RaAG2RSu+IRIVJK9okYT0HyCuPfVFpVM0Gs4B0Zbnpltr+BHMZjfdNEe LKKLL8ZbVjfFzef+8s8dH6usgZmDt1TMsFKyVsvWXuHt4v3c9XSTQuEdaUECy/8kYtXN99HlHBs /rskhkG98SRMFfLTmvpQpz2XfBstRgGAN4VYFISTVYlrZez1tdmjk8hTkIKRVWIiEzBOkg5ep1w c9soKxsffV/4+ixIczmR4R3JhA3g0UGYImo/JkAmZ/P6pNoAbRmOR9TA38PlL4rsmcFw16bm1+x Fz3i5OosHXGPfMQPsXEYL1D/AZDeYLv1COiZeSDN0NA58W54gXeYgwSB5skyIhUOVWkz5+jESN+ pFjPc4pGWyBRIrsoP2BTjOBiU35Vy4mAneEVCkm X-Received: by 2002:a05:600c:4f45:b0:493:c47f:3c55 with SMTP id 5b1f17b1804b1-49972764ed2mr11520785e9.5.1786357851500; Mon, 10 Aug 2026 03:30:51 -0700 (PDT) From: Frediano Ziglio X-Google-Original-From: Frediano Ziglio To: xen-devel@lists.xenproject.org Cc: Frediano Ziglio , Jan Beulich , Andrew Cooper , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Teddy Astie , Anthony PERARD , Juergen Gross Subject: [PATCH Linux v6 10/10] xen/privcmd: Add new ABI to allow copying foreign memory Date: Mon, 10 Aug 2026 11:30:13 +0100 Message-ID: <20260810103018.54564-11-frediano.ziglio@citrix.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20260810103018.54564-1-frediano.ziglio@citrix.com> References: <20260810103018.54564-1-frediano.ziglio@citrix.com> MIME-Version: 1.0 Content-Transfer-Encoding: quoted-printable X-purgate-ID: tlsNG-bad1c0/1786357852-BCAC8034-8D57BA6A/0/0 X-purgate-type: clean X-purgate-size: 6569 X-ZohoMail-DKIM: pass (identity @gmail.com) X-ZM-MESSAGEID: 1786357881165158500 Content-Type: text/plain; charset="utf-8" This new ABI allows to copy foreign domain memory to/from a buffer. This avoids having to map/copy/unmap foreign memory which is expensive. This operation is done particularly when migrating VMs. Signed-off-by: Frediano Ziglio -- Changes since v4: - fix wrong assign; - use set_xen_guest_handle to set handle; - wrap slow hypercall with xen_preemptible_hcall_{begin,end}; - use _IOWR for ioctl code to be more specific; - use __copy_to_user if buffer already checked. Changes since v6: - compatibility ARM/x86. --- arch/x86/include/asm/xen/interface.h | 3 ++ drivers/xen/privcmd.c | 49 ++++++++++++++++++++++++++++ include/uapi/xen/privcmd.h | 10 ++++++ include/xen/arm/interface.h | 2 ++ include/xen/interface/memory.h | 37 +++++++++++++++++++++ 5 files changed, 101 insertions(+) diff --git a/arch/x86/include/asm/xen/interface.h b/arch/x86/include/asm/xe= n/interface.h index a078a2b0f032..fc76fac8fb16 100644 --- a/arch/x86/include/asm/xen/interface.h +++ b/arch/x86/include/asm/xen/interface.h @@ -59,6 +59,7 @@ #elif defined(__x86_64__) #define set_xen_guest_handle(hnd, val) do { (hnd).p =3D val; } while (0) #endif +#define get_xen_guest_handle(hnd) ((hnd).p) #else #if defined(__i386__) #define set_xen_guest_handle(hnd, val) \ @@ -70,6 +71,7 @@ #elif defined(__x86_64__) #define set_xen_guest_handle(hnd, val) do { (hnd) =3D val; } while (0) #endif +#define get_xen_guest_handle(hnd) (hnd) #endif =20 #ifndef __ASSEMBLER__ @@ -91,6 +93,7 @@ DEFINE_GUEST_HANDLE(int); DEFINE_GUEST_HANDLE(void); DEFINE_GUEST_HANDLE(uint64_t); DEFINE_GUEST_HANDLE(uint32_t); +DEFINE_GUEST_HANDLE(uint8_t); DEFINE_GUEST_HANDLE(xen_pfn_t); DEFINE_GUEST_HANDLE(xen_ulong_t); #endif diff --git a/drivers/xen/privcmd.c b/drivers/xen/privcmd.c index 725a49a0eee7..55364801ba2e 100644 --- a/drivers/xen/privcmd.c +++ b/drivers/xen/privcmd.c @@ -1522,6 +1522,51 @@ static inline void privcmd_ioeventfd_exit(void) } #endif /* CONFIG_XEN_PRIVCMD_EVENTFD */ =20 +static long privcmd_ioctl_foreigncopy( + struct file *file, void __user *udata) +{ + const struct privcmd_data *const data =3D file->private_data; + long ret; + struct privcmd_foreigncopy copy; + struct xen_foreigncopy xcopy; + + if (copy_from_user(©, udata, sizeof(copy))) + return -EFAULT; + if (copy.dir & ~1u) + return -EINVAL; + if (copy.num >=3D U32_MAX >> PAGE_SHIFT) + return -EINVAL; + if (!access_ok(copy.pfns, copy.num * sizeof(*copy.pfns))) + return -EFAULT; + if (!access_ok(copy.buffer, copy.num << PAGE_SHIFT)) + return -EFAULT; + + /* If restriction is in place, check the domid matches */ + if (data->domid !=3D DOMID_INVALID && data->domid !=3D copy.dom) + return -EPERM; + + xcopy.domid =3D copy.dom; + xcopy.flags =3D copy.dir; + xcopy.nr_frames =3D copy.num; + set_xen_guest_handle(xcopy.frame_list, (__force xen_pfn_t *)copy.pfns); + set_xen_guest_handle(xcopy.buffer, (__force uint8_t *)copy.buffer); + + xen_preemptible_hcall_begin(); + ret =3D HYPERVISOR_memory_op(XENMEM_foreigncopy, &xcopy); + xen_preemptible_hcall_end(); + + /* copy values back in case of error */ + if (ret) { + copy.num =3D xcopy.nr_frames; + copy.pfns =3D get_xen_guest_handle(xcopy.frame_list); + copy.buffer =3D get_xen_guest_handle(xcopy.buffer); + if (__copy_to_user(udata, ©, sizeof(copy))) + ret =3D -EFAULT; + } + + return ret; +} + static long privcmd_ioctl(struct file *file, unsigned int cmd, unsigned long data) { @@ -1569,6 +1614,10 @@ static long privcmd_ioctl(struct file *file, ret =3D privcmd_ioctl_pcidev_get_gsi(file, udata); break; =20 + case IOCTL_PRIVCMD_FOREIGNCOPY: + ret =3D privcmd_ioctl_foreigncopy(file, udata); + break; + default: break; } diff --git a/include/uapi/xen/privcmd.h b/include/uapi/xen/privcmd.h index 8e2c8fd44764..993b501e35bf 100644 --- a/include/uapi/xen/privcmd.h +++ b/include/uapi/xen/privcmd.h @@ -131,6 +131,14 @@ struct privcmd_pcidev_get_gsi { __u32 gsi; }; =20 +struct privcmd_foreigncopy { + domid_t dom; /* foreign domain */ + __u16 dir; /* direction, 0 from, 1 to */ + __u32 num; /* number of pages to copy */ + const xen_pfn_t __user *pfns; /* array of pfns */ + void __user *buffer; /* buffer to copy to/from */ +}; + /* * @cmd: IOCTL_PRIVCMD_HYPERCALL * @arg: &privcmd_hypercall_t @@ -164,5 +172,7 @@ struct privcmd_pcidev_get_gsi { _IOW('P', 9, struct privcmd_ioeventfd) #define IOCTL_PRIVCMD_PCIDEV_GET_GSI \ _IOC(_IOC_NONE, 'P', 10, sizeof(struct privcmd_pcidev_get_gsi)) +#define IOCTL_PRIVCMD_FOREIGNCOPY \ + _IOWR('P', 11, struct privcmd_foreigncopy) =20 #endif /* __LINUX_PUBLIC_PRIVCMD_H__ */ diff --git a/include/xen/arm/interface.h b/include/xen/arm/interface.h index 61360b89da40..20ee1ed44436 100644 --- a/include/xen/arm/interface.h +++ b/include/xen/arm/interface.h @@ -27,6 +27,7 @@ *(uint64_t *)&(hnd) =3D 0; \ (hnd).p =3D val; \ } while (0) +#define get_xen_guest_handle(hnd) ((hnd).p) =20 #define __HYPERVISOR_platform_op_raw __HYPERVISOR_platform_op =20 @@ -53,6 +54,7 @@ DEFINE_GUEST_HANDLE(int); DEFINE_GUEST_HANDLE(void); DEFINE_GUEST_HANDLE(uint64_t); DEFINE_GUEST_HANDLE(uint32_t); +DEFINE_GUEST_HANDLE(uint8_t); DEFINE_GUEST_HANDLE(xen_pfn_t); DEFINE_GUEST_HANDLE(xen_ulong_t); =20 diff --git a/include/xen/interface/memory.h b/include/xen/interface/memory.h index 1a371a825c55..5981402fccde 100644 --- a/include/xen/interface/memory.h +++ b/include/xen/interface/memory.h @@ -325,4 +325,41 @@ struct xen_mem_acquire_resource { }; DEFINE_GUEST_HANDLE_STRUCT(xen_mem_acquire_resource); =20 +/* + * Copy memory from/to a given domain. + */ +#define XENMEM_foreigncopy 29 +struct xen_foreigncopy { + /* IN - The domain whose resource is to be copied */ + domid_t domid; + + /* IN - Flags */ +#define XENMEM_foreigncopy_from 0 +#define XENMEM_foreigncopy_to 1 +#define XENMEM_foreigncopy_direction 1 + uint16_t flags; + + /* + * IN + * + * As an IN parameter number of frames of the domain to be copied. + */ + uint32_t nr_frames; + + /* + * IN + * + * Frames to be copied. + */ + GUEST_HANDLE(xen_pfn_t) frame_list; + + /* + * IN/OUT + * + * Userspace buffer to read/write from. + */ + GUEST_HANDLE(uint8_t) buffer; +}; +DEFINE_GUEST_HANDLE_STRUCT(xen_foreigncopy); + #endif /* __XEN_PUBLIC_MEMORY_H__ */ --=20 2.54.0