From nobody Sun Dec 14 08:04:37 2025 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) client-ip=8.43.85.245; envelope-from=devel-bounces@lists.libvirt.org; helo=lists.libvirt.org; Authentication-Results: mx.zohomail.com; dkim=fail; spf=pass (zohomail.com: domain of lists.libvirt.org designates 8.43.85.245 as permitted sender) smtp.mailfrom=devel-bounces@lists.libvirt.org; arc=fail (BodyHash is different from the expected one); dmarc=pass(p=reject dis=none) header.from=lists.libvirt.org Return-Path: Received: from lists.libvirt.org (lists.libvirt.org [8.43.85.245]) by mx.zohomail.com with SMTPS id 174734150213444.76132334822955; Thu, 15 May 2025 13:38:22 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id 1C4C4142F; Thu, 15 May 2025 16:38:21 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id B381313CE; Thu, 15 May 2025 16:37:26 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id BF47112ED; Thu, 15 May 2025 16:37:21 -0400 (EDT) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2066.outbound.protection.outlook.com [40.107.236.66]) (using TLSv1.2 with cipher ECDHE-RSA-AES128-GCM-SHA256 (128/128 bits)) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 550B21489 for ; Thu, 15 May 2025 16:37:06 -0400 (EDT) Received: from SN7PR12MB6838.namprd12.prod.outlook.com (2603:10b6:806:266::18) by SJ2PR12MB8135.namprd12.prod.outlook.com (2603:10b6:a03:4f3::13) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.8722.32; Thu, 15 May 2025 20:37:01 +0000 Received: from SN7PR12MB6838.namprd12.prod.outlook.com ([fe80::529d:478:bc5d:b400]) by SN7PR12MB6838.namprd12.prod.outlook.com ([fe80::529d:478:bc5d:b400%3]) with mapi id 15.20.8722.027; Thu, 15 May 2025 20:37:01 +0000 X-Spam-Checker-Version: SpamAssassin 3.4.4 (2020-01-24) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_INVALID,DKIM_SIGNED, FORGED_SPF_HELO,MAILING_LIST_MULTI,RCVD_IN_DNSWL_NONE, RCVD_IN_MSPIKE_H2,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_HELO_PASS autolearn=no autolearn_force=no version=3.4.4 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Kkuqcqd3zrn3Y8OCg7i7nh/jVjuFiSlHIodCngybI+egnYPmyEsDAx9IRcMMuuBb5rro9jybnuSO6+dS07E4p8n8/W6djq2aEiDsesU0jYgwKuB9uFeI1ZC4FtBhqjjwprxsFMUf/RAxWJYhf+CPZGjsmsmZS/dlaoP/fYYIodjBTnOXHHNdKBhv/uvIvoAzQwrVcR78T3d2PdwYNgclV+8r7r2UW5Gdc3+QLa0+oQb14yy7Ph2mppsytPxzv2Kfk9upG0OW0m2gNdYFLKvUBa81/OKo9Rx66db8nOnVDSJ0Qi6QxiwzsnASyriPHXaWAPhf6hAcZlmswNzOLR/XGA== ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=microsoft.com; s=arcselector10001; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-AntiSpam-MessageData-ChunkCount:X-MS-Exchange-AntiSpam-MessageData-0:X-MS-Exchange-AntiSpam-MessageData-1; bh=pFnlBaevaT35+Pc5EN7v4vLyqgiU6RvmU0xYQNypsx0=; b=QX+bS8KJRcVplI5olAA5ByUw4Ji2laP37Uztu9DsScQFNhT6nKi4V64PhtNeZqclChm+oK33xZJnrFOFsDTZiTAxxIEVNTHdK8V+kuG/FfSGIIpY4yiNqkhMGuHIBH7wODgm4RZ5b2FWyEyxP2ePtoDk5uspN/AJgGAZl2AVgh773PLX66BVHtA41+/BGiJWtr/c+LK2RJhbGn97DhPkHflQbG3nCQ1vC7yfWnMAO7pEtXz155F82AyVc1MGDqxrz7iXPGfbIdQZyoyqqGX6w+hlTdK8ncWMSuV2+VRJm0JLVz1FWd4VjVcRekrQxCVgi9M02wg4al17TwwDknOfJA== ARC-Authentication-Results: i=1; mx.microsoft.com 1; spf=pass smtp.mailfrom=nvidia.com; dmarc=pass action=none header.from=nvidia.com; dkim=pass header.d=nvidia.com; arc=none DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=Nvidia.com; s=selector2; h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck; bh=pFnlBaevaT35+Pc5EN7v4vLyqgiU6RvmU0xYQNypsx0=; b=UiizYWjHjZlxP9RWvUbklNMO40CZC5n0GV5KiU9E3eqYRoSfEjTAGeeaKhXpq3Hq3tTd0qxVawGaLF4igC3gG3FTuyJOFRK9x9cOGXqBTcZAKEOYT4xs43uWwGqtrIiv3qRjF2v2kLfwV0fkyb6+GFH5R7f+mZfuR8MgmQh/xlgnp47+nnz/s1gLMB3Eh959nh3orasEGGtFej6lZ+q2uaCsIIgKFVrHuRG/NAiGv3TRrQpp3fZnvIYtgUFRhsBmaPiLNLkPVJX5ajmxPy/Uj7GsMw93lu9mTUCcyqdgr3O+BdSXmBnyroEoNiCgln7r2DMw9qHj4+lGX+iFdlZ6Gg== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; To: devel@lists.libvirt.org Subject: [RFC PATCH 2/5] conf: Add an iommufd member struct to virDomainIOMMUDef Date: Thu, 15 May 2025 13:36:40 -0700 Message-ID: <20250515203643.21109-3-nathanc@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250515203643.21109-1-nathanc@nvidia.com> References: <20250515203643.21109-1-nathanc@nvidia.com> X-ClientProxiedBy: SJ0P220CA0025.NAMP220.PROD.OUTLOOK.COM (2603:10b6:a03:41b::16) To SN7PR12MB6838.namprd12.prod.outlook.com (2603:10b6:806:266::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN7PR12MB6838:EE_|SJ2PR12MB8135:EE_ X-MS-Office365-Filtering-Correlation-Id: 7000a825-5c15-462b-b94f-08dd93f03f0d X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|1800799024|366016; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?QhjCfMf/eU7CeF0I07AbnN2vaHq3mX3NlwsFwjBikG4R8lpXIrwcRF9xR6c8?= =?us-ascii?Q?UnnJzzaeF2eKinXGhkDeGllRgonuVLQyjReWt1GthNUws80HF6r3THRQZMb1?= =?us-ascii?Q?6SUKmFM/hMNCUcufR+XOMRoSukyI54kGk6WC9PfT4k0pr3YPyktCS68keK7P?= =?us-ascii?Q?N/toimbSV2wpRTx+RKeyMruZkcRaHYaGqNF+ZHrU6Aeu8kxr4zDKLcXBWjXE?= =?us-ascii?Q?m0J0SEfvQ2cdc4aO4acHeYwn1NJMyPkLc5IB2c00Om7BppR6UdUT7fmZuaU8?= =?us-ascii?Q?kZIRwh+w3lkQyOpR1pVG86AyahRiu7OjSrF3ta5kBVETywYftOj4bHwzP97L?= =?us-ascii?Q?YjZ763PQxjSlx632eIj9nJ9gGXWgxbxwXVKmJku+dWvDuxcJBWkGcdUb2XGE?= =?us-ascii?Q?dkeXj/tPZeelIBooQuEO+RXi+eGagkk57AWyPOTgndFQSUdXFxV+JG6d948/?= =?us-ascii?Q?Kp7zL1SsT+epuWJaE2owG+I78WPkHY7wEppsJyeY6RpiGnrF6vpp/JoDx9RN?= =?us-ascii?Q?m/qEscmEg7Dh+4fluzT93tuU8mwm8NaafctFwrFW4HU0/SBqRGjxG0mHDNlf?= =?us-ascii?Q?juou5wGntRANXoUtt60FvTtumqmNAG96xm1CTMmFwVrGyvhraJvUSKTtGxL5?= =?us-ascii?Q?oZwjWChZVP/kd6BSqNXGbynEw/Lk9MW36mAwHSOKGrm25NVPaMaHqjGiO3JZ?= =?us-ascii?Q?CfGQzswEhMurK2oN42jXjZlfBkw2+Hj8FTdpzCmS9XIfxo8HObmnsHBXou5C?= =?us-ascii?Q?zjLiPezht+kTfB/hGCESn1X2SlNhnbww7oIkzYo1V0zHMWl+ucUURW3OHe/u?= =?us-ascii?Q?mqdxcia17HRtmX/xxdOBWnOJoun4xNpnvAjiQ1qHehNRCU2B8Cp9S2BbX3KG?= =?us-ascii?Q?zuAK+FcFSlYt85bpxGlHziQs5v9Q9+P4sHYEJjSMA9sAydnFDeix20G+pE9M?= =?us-ascii?Q?EXaAzqXJLBf/V6qVQNYWJT2zEMNXJaTeeM71izQDFLR9Jz+3PaQnub4mxuZ5?= =?us-ascii?Q?F+6j/JOeI9UULqKHpS7bKFgAmvrPE935mSjylF73gXt+C07JV0AQ4Jc/rXJI?= =?us-ascii?Q?ZH/4HJ1n+wiSVuAV4T3Ti5Ui2wik8FP4b+Oj4s+ZN6IHpya1YlMuk6+9EqBo?= =?us-ascii?Q?GGAa8f6RsiSNZ3oxGCV4UKHXCNmWpeHPGqJ6iqOPuttaxKxFYUmgmZBCd+jv?= =?us-ascii?Q?qMdUN5r+wGcjsyoeyvNmS1PqN6MG/GCpbhhs5msppuCT58Uuo2+0s/6OW6iy?= =?us-ascii?Q?RlwsXq2UhqcgsEVVFpzLEgBCzOl4o99d+3KyoRQQvAnCtOXfX7IrbQAMo/QT?= =?us-ascii?Q?XE414qp74wY9rOTb1wzLdRcEifhWHPaGkghdowYTqDsCa0114aOO3E4fXVqq?= =?us-ascii?Q?JAmLFgxB0Oj8MzHwBfNArtihKCgR97i20oWXPZ6LQYtyeBVX7EJF60Ck1Irr?= =?us-ascii?Q?SxKnDlH2Mz8=3D?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SN7PR12MB6838.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(1800799024)(366016);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?Epmuo/yUlf6sMlt82CuF4wUXHBntMVyvdxwycgekdg7nQ2LdaCXxF0x9Iumb?= =?us-ascii?Q?OzLUVPQRYdrurKqpxW8P41IokfgjgcGHKuCMGP9RKx4TkNhAByDJlCEd4LNV?= =?us-ascii?Q?EZPqJwtuURBFABPNdFqp57LJEOiiNBrc2a2YABhJcVBuNxSQAdW+S6HqCbo9?= =?us-ascii?Q?kzPID9C6wcG2KE7hp55F9hjXDAf14H5iAXdfHg7bLUmBGnjHYUfL3P6pV9Cj?= =?us-ascii?Q?3vIHnYltylmb+u3C9iATPMmztf8+WfSZZTaNwLCVIT/iZpxmoqsR8Vu6tuA/?= =?us-ascii?Q?isi+qXDc4RxILoJM2IV8z+fMK438N2nFOKmjbnfGFQJEpMwSRk1mj6+Dvg9/?= =?us-ascii?Q?0LkybWAxVtC/MxkGad/iowLHOi2vmnAeL5wcg67zQQAh9l3aZOvc+BPDltjH?= =?us-ascii?Q?Fy/ic7uwNzTfQ343gBHACJ2XDLG7y0EwIq/xIpc4bvyO68d+svkftGnL7kV9?= =?us-ascii?Q?8Ue9POMH7L6++qPMI7oEAUKTFCk6PK0yn4TzuQy9afd2sInTkGIYdpoQ3Yck?= =?us-ascii?Q?tQ+CwNOn+cNo3Rkpeq3bopYQCyoFzGvK7NeBKpc7dftQMW/KuXvWzIzdQivw?= =?us-ascii?Q?KPG2Zvb5qYWPNglddPcMEpcucH0bBSAb213WI88shwyFQK2C4Cs8Rem4iJCJ?= =?us-ascii?Q?0LLD4ReR3Didh5kMOSHN1lbIa650PqbHpbIPx7RYXxFNdbGdxsaGEqBntpo2?= =?us-ascii?Q?HHvSnXdXt7ddQn75sZijKDFxjNr2ozqb91z032siyc6Yj4+tNGFxMXlstXkh?= =?us-ascii?Q?GmMlZlQU8jxZu0jZjigYKWo5CVdgsa4amMdVqTnARHKNe53andcz2lt7VRuC?= =?us-ascii?Q?Bu3U2HGykuEcGuyBrQVXCoiaGsCrQCDFBDI3MJyzl6A4FPSBZTB1OISGuYOd?= =?us-ascii?Q?/ya31qBn+Br8iISJBMW2W+qyfuFm7/eU24R8n1GLTTONMHZScwaKZRpCVUST?= =?us-ascii?Q?Wd0vwDJ9+/K68GK3+Qd2MFXGoGcUGY019PLw/myvgOHHrhPUWkX2tym9l7eS?= =?us-ascii?Q?G0J5R1K389i3shXNTeKLBC2PSchkfHpTes6rjHI5IQG6M5dKYNAIswKwzB6I?= =?us-ascii?Q?t5LYGa1eb0wVk/6sZija5FKZJ5gRTN1nqGPawQ+o0E6vekJdEsnaWROM8HZ9?= =?us-ascii?Q?/+7wNPNEtfyLblGXpDF0R8rNngYzj4YaNZCby/6IolFVeZgdcOL634yVGTLV?= =?us-ascii?Q?dOL1iylDMz93RF0BF7EY6VJYf18UI4IKIbboMh3pmoMhgAQSM3EKRwisbrK4?= =?us-ascii?Q?TMhtJiYUcNbVttr4lcHUUhyalM476f5bR2qadFP/thDD+d+8SIjt7NEMxMNl?= =?us-ascii?Q?pDe0TOXnHlhlO066STj8Rh+JsGlYZ1kQ64vlAk0QN5e3Edna+t28/f2LHbX/?= =?us-ascii?Q?eFk7j4JENwHSqBPobgramPhr4KR7hW8uKe9ltgF+y8zQhx3pVJlI5hPoL3Pb?= =?us-ascii?Q?A5B8lsSufaLeNv4IdpJMn0c5AQY3gh87Cf8gGPt25wgK57a5XdnFmZXHP3kg?= =?us-ascii?Q?p+1+cXDC6i/B6v5FMGV15YIMLyHF2trrqT/wx/VeKTsXKq2TGwKfHUoMZbN9?= =?us-ascii?Q?vvcxuC/Eoub+2OghAUBJIQhlaPJXdplQaLXxZYJ7?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7000a825-5c15-462b-b94f-08dd93f03f0d X-MS-Exchange-CrossTenant-AuthSource: SN7PR12MB6838.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 May 2025 20:37:01.7297 (UTC) X-MS-Exchange-CrossTenant-FromEntityHeader: Hosted X-MS-Exchange-CrossTenant-Id: 43083d15-7273-40c1-b7db-39efd9ccc17a X-MS-Exchange-CrossTenant-MailboxType: HOSTED X-MS-Exchange-CrossTenant-UserPrincipalName: RhaozQzPtByhglth62wiSvHLUwUlXKS5km0aBIPh8NUTAzKOg7sVPc4/E8f42xr6L1LEsUjrfOBNqqaYAKcbLw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SJ2PR12MB8135 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: 24B5RO7G5CSLWLEKODN54VRLCSWDXBME X-Message-ID-Hash: 24B5RO7G5CSLWLEKODN54VRLCSWDXBME X-MailFrom: nathanc@nvidia.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; emergency; loop; banned-address; member-moderation; header-match-config-1; header-match-config-2; header-match-config-3; header-match-devel.lists.libvirt.org-0; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; suspicious-header CC: shameerali.kolothum.thodi@huawei.com, nicolinc@nvidia.com, Nathan Chen X-Mailman-Version: 3.2.2 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Post: List-Subscribe: List-Unsubscribe: From: Nathan Chen via Devel Reply-To: Nathan Chen X-ZohoMail-DKIM: fail (Header signature does not verify) X-ZM-MESSAGEID: 1747341503556116600 Content-Type: text/plain; charset="utf-8" Add support for an "iommufd" virDomainIOMMUDef member that will be translated to a qemu "-object iommufd" command line argument. This iommufd struct has an "id" member to specify the iommufd object id that can be associated with a passthrough device, and an "fd" member to specify the fd for externally opening the /dev/iommu and VFIO cdev by a management layer. Signed-off-by: Nathan Chen --- src/conf/domain_conf.c | 108 +++++++++++++++++++++++++++++- src/conf/domain_conf.h | 8 +++ src/conf/domain_validate.c | 44 +++++++++++- src/conf/schemas/domaincommon.rng | 14 ++++ src/conf/virconftypes.h | 2 + src/qemu/qemu_command.c | 13 ++++ 6 files changed, 186 insertions(+), 3 deletions(-) diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c index c8d481eb5c..9330c47b7a 100644 --- a/src/conf/domain_conf.c +++ b/src/conf/domain_conf.c @@ -2814,6 +2814,9 @@ virDomainIOMMUDefFree(virDomainIOMMUDef *iommu) if (!iommu) return; =20 + if (iommu->iommufd) + virDomainIommufdDefFree(iommu->iommufd); + virDomainDeviceInfoClear(&iommu->info); g_free(iommu); } @@ -14292,6 +14295,54 @@ virDomainMemoryDefParseXML(virDomainXMLOption *xml= opt, } =20 =20 +void virDomainIommufdDefFree(virDomainIommufdDef *def) +{ + if (!def) + return; + + g_free(def->id); + + g_free(def->fd); + + g_free(def); +} + + +static virDomainIommufdDef * +virDomainIommufdParseXML(xmlNodePtr node, + xmlXPathContextPtr ctxt) +{ + virDomainIommufdDef *def; + g_autofree char *iommufdId =3D NULL; + g_autofree char *iommufdFd =3D NULL; + VIR_XPATH_NODE_AUTORESTORE(ctxt) + + ctxt->node =3D node; + + def =3D g_new0(virDomainIommufdDef, 1); + + if (!(iommufdId =3D virXPathString("string(./id)", ctxt))) + goto error; + + def->id =3D g_strdup(iommufdId); + + iommufdFd =3D virXPathString("string(./fd)", ctxt); + + def->fd =3D g_strdup(iommufdFd); + + if (!def->id) + goto error; + + if (iommufdFd && !def->fd) + goto error; + + return def; + error: + virDomainIommufdDefFree(def); + return NULL; +} + + static virDomainIOMMUDef * virDomainIOMMUDefParseXML(virDomainXMLOption *xmlopt, xmlNodePtr node, @@ -14299,7 +14350,7 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlop= t, unsigned int flags) { VIR_XPATH_NODE_AUTORESTORE(ctxt) - xmlNodePtr driver; + xmlNodePtr driver, iommufd; g_autoptr(virDomainIOMMUDef) iommu =3D NULL; =20 ctxt->node =3D node; @@ -14336,6 +14387,11 @@ virDomainIOMMUDefParseXML(virDomainXMLOption *xmlo= pt, return NULL; } =20 + if ((iommufd =3D virXPathNode("./iommufd", ctxt))) { + if (!(iommu->iommufd =3D virDomainIommufdParseXML(iommufd, ctxt))) + return NULL; + } + if (virDomainDeviceInfoParseXML(xmlopt, node, ctxt, &iommu->info, flags) < 0) return NULL; @@ -16384,6 +16440,25 @@ virDomainIOMMUDefEquals(const virDomainIOMMUDef *a, a->dma_translation !=3D b->dma_translation) return false; =20 + if (a->iommufd && b->iommufd) { + if (a->iommufd->id && b->iommufd->id) { + if (STRNEQ(a->iommufd->id, b->iommufd->id)) + return false; + } else if ((a->iommufd->id && !b->iommufd->id) || + (!a->iommufd->id && b->iommufd->id)) { + return false; + } + if (a->iommufd->fd && b->iommufd->fd) { + if (STRNEQ(a->iommufd->fd, b->iommufd->fd)) + return false; + } else if ((a->iommufd->fd && !b->iommufd->fd) || + (!a->iommufd->fd && b->iommufd->fd)) { + return false; + } + } else { + return false; + } + switch (a->info.type) { case VIR_DOMAIN_DEVICE_ADDRESS_TYPE_PCI: if (a->info.addr.pci.domain !=3D b->info.addr.pci.domain || @@ -22078,6 +22153,27 @@ virDomainIOMMUDefCheckABIStability(virDomainIOMMUD= ef *src, virTristateSwitchTypeToString(src->dma_translation)= ); return false; } + if (src->iommufd && dst->iommufd) { + if (STRNEQ(src->iommufd->id, dst->iommufd->id)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device iommufd id '%1$s'= does not match source '%2$s'"), + dst->iommufd->id, + src->iommufd->id); + return false; + } + if (STRNEQ(src->iommufd->fd, dst->iommufd->fd)) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("Target domain IOMMU device iommufd fd '%1$s'= does not match source '%2$s'"), + dst->iommufd->fd, + src->iommufd->fd); + return false; + } + } else if ((src->iommufd && !dst->iommufd) || + (!src->iommufd && dst->iommufd)) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("Target domain IOMMU device iommufd does not matc= h source")); + return false; + } =20 return virDomainDeviceInfoCheckABIStability(&src->info, &dst->info); } @@ -28310,6 +28406,16 @@ virDomainIOMMUDefFormat(virBuffer *buf, =20 virXMLFormatElement(&childBuf, "driver", &driverAttrBuf, NULL); =20 + if (iommu->iommufd) { + virBufferAddLit(&childBuf, "\n"); + virBufferAdjustIndent(&childBuf, 2); + virBufferAsprintf(&childBuf, "%s\n", iommu->iommufd->id); + if (iommu->iommufd->fd) + virBufferAsprintf(&childBuf, "%s\n", iommu->iommufd->= fd); + virBufferAdjustIndent(&childBuf, -2); + virBufferAddLit(&childBuf, "\n"); + } + virDomainDeviceInfoFormat(&childBuf, &iommu->info, 0); =20 virBufferAsprintf(&attrBuf, " model=3D'%s'", diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h index 75568ff50a..ce447e9823 100644 --- a/src/conf/domain_conf.h +++ b/src/conf/domain_conf.h @@ -3010,6 +3010,11 @@ typedef enum { VIR_DOMAIN_IOMMU_MODEL_LAST } virDomainIOMMUModel; =20 +struct _virDomainIommufdDef { + char *id; + char *fd; +}; + struct _virDomainIOMMUDef { virDomainIOMMUModel model; virTristateSwitch intremap; @@ -3017,6 +3022,8 @@ struct _virDomainIOMMUDef { virTristateSwitch eim; virTristateSwitch iotlb; unsigned int aw_bits; + virDomainIommufdDef *iommufd; + virDomainDeviceInfo info; virTristateSwitch dma_translation; }; @@ -3747,6 +3754,7 @@ virDomainVideoDef *virDomainVideoDefNew(virDomainXMLO= ption *xmlopt); void virDomainVideoDefFree(virDomainVideoDef *def); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virDomainVideoDef, virDomainVideoDefFree); void virDomainVideoDefClear(virDomainVideoDef *def); +void virDomainIommufdDefFree(virDomainIommufdDef *def); virDomainHostdevDef *virDomainHostdevDefNew(void); void virDomainHostdevDefFree(virDomainHostdevDef *def); void virDomainHubDefFree(virDomainHubDef *def); diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c index 4861b1c002..88649ba0b9 100644 --- a/src/conf/domain_validate.c +++ b/src/conf/domain_validate.c @@ -1838,9 +1838,9 @@ virDomainDefCputuneValidate(const virDomainDef *def) static int virDomainDefIOMMUValidate(const virDomainDef *def) { - size_t i; + size_t i, j; =20 - if (!def->iommu) + if (!def->iommu || def->niommus =3D=3D 0) return 0; =20 for (i =3D 0; i < def->niommus; i++) { @@ -1851,6 +1851,39 @@ virDomainDefIOMMUValidate(const virDomainDef *def) _("IOMMU model smmuv3Dev must be specified for = multiple IOMMU definitions")); } =20 + for (j =3D i + 1; j < def->niommus; j++) { + if (virDomainIOMMUDefEquals(iommu, + def->iommu[j])) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("IOMMU already exists in the domain confi= guration")); + return -1; + } + + if (iommu->iommufd && def->iommu[j]->iommufd) { + if (iommu->iommufd->id && def->iommu[j]->iommufd->id) { + if (STRNEQ(iommu->iommufd->id, def->iommu[j]->iommufd-= >id)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("iommufd ID must be the same for = multiple IOMMUs")); + return -1; + } + } else { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("iommufd ID must be specified")); + } + if (iommu->iommufd->fd && def->iommu[j]->iommufd->fd && + STRNEQ(iommu->iommufd->fd, def->iommu[j]->iommufd->fd)= ) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("iommufd FD must be the same for mult= iple IOMMUs")); + return -1; + } + } else if ((iommu->iommufd && !def->iommu[j]->iommufd) || + (!iommu->iommufd && def->iommu[j]->iommufd)) { + virReportError(VIR_ERR_XML_ERROR, "%s", + _("The same iommufd configuration must be s= pecified for multiple IOMMUs")); + return -1; + } + } + if (iommu->intremap =3D=3D VIR_TRISTATE_SWITCH_ON && def->features[VIR_DOMAIN_FEATURE_IOAPIC] !=3D VIR_DOMAIN_IOAPI= C_QEMU) { virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", @@ -3115,6 +3148,13 @@ virDomainIOMMUDefValidate(const virDomainIOMMUDef *i= ommu) break; } =20 + if (iommu->iommufd) { + if (!iommu->iommufd->id) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("iommufd must have an associated id")); + return -1; + } + } return 0; } =20 diff --git a/src/conf/schemas/domaincommon.rng b/src/conf/schemas/domaincom= mon.rng index 8d1768b24f..41db338c71 100644 --- a/src/conf/schemas/domaincommon.rng +++ b/src/conf/schemas/domaincommon.rng @@ -6231,6 +6231,20 @@ + + + + + + + + + + + + + + diff --git a/src/conf/virconftypes.h b/src/conf/virconftypes.h index c70437bc05..47392154a4 100644 --- a/src/conf/virconftypes.h +++ b/src/conf/virconftypes.h @@ -142,6 +142,8 @@ typedef struct _virDomainHubDef virDomainHubDef; =20 typedef struct _virDomainHugePage virDomainHugePage; =20 +typedef struct _virDomainIommufdDef virDomainIommufdDef; + typedef struct _virDomainIOMMUDef virDomainIOMMUDef; =20 typedef struct _virDomainIOThreadIDDef virDomainIOThreadIDDef; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 9deafefaad..d683d0eef7 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -6166,6 +6166,19 @@ qemuBuildIOMMUCommandLine(virCommand *cmd, if (!def->iommu || def->niommus <=3D 0) return 0; =20 + if (def->iommu[0]->iommufd) { + if (qemuMonitorCreateObjectProps(&props, "iommufd", + def->iommu[0]->iommufd->id, + "S:fd", def->iommu[0]->iommufd->f= d, + NULL) < 0) + return -1; + + if (qemuBuildObjectCommandlineFromJSON(cmd, props) < 0) + return -1; + } + + props =3D NULL; + for (i =3D 0; i < def->niommus; i++) { virDomainIOMMUDef *iommu =3D def->iommu[i]; switch (iommu->model) { --=20 2.43.0