From nobody Sun Oct 5 01:49:26 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 (Bad Signature); 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 175936627596911.452823666030895; Wed, 1 Oct 2025 17:51:15 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id A32E543F5D; Wed, 1 Oct 2025 20:51:14 -0400 (EDT) Received: from [172.19.199.14] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id EC7DE44397; Wed, 1 Oct 2025 20:39:36 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id C3E0644276; Wed, 1 Oct 2025 20:39:15 -0400 (EDT) Received: from CH5PR02CU005.outbound.protection.outlook.com (mail-northcentralusazon11012038.outbound.protection.outlook.com [40.107.200.38]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange ECDHE (prime256v1) server-signature RSA-PSS (3072 bits) server-digest SHA256) (No client certificate requested) by lists.libvirt.org (Postfix) with ESMTPS id 04EFB440DD for ; Wed, 1 Oct 2025 20:38:59 -0400 (EDT) Received: from PH7PR12MB6834.namprd12.prod.outlook.com (2603:10b6:510:1b4::18) by SN7PR12MB7299.namprd12.prod.outlook.com (2603:10b6:806:2af::15) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9160.18; Thu, 2 Oct 2025 00:38:51 +0000 Received: from PH7PR12MB6834.namprd12.prod.outlook.com ([fe80::f432:162b:b94e:d2cb]) by PH7PR12MB6834.namprd12.prod.outlook.com ([fe80::f432:162b:b94e:d2cb%6]) with mapi id 15.20.9160.015; Thu, 2 Oct 2025 00:38:51 +0000 X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-3.1 required=5.0 tests=ARC_SIGNED,ARC_VALID, DKIM_INVALID,DKIM_SIGNED,MAILING_LIST_MULTI,RCVD_IN_DNSWL_MED, RCVD_IN_VALIDITY_CERTIFIED_BLOCKED,RCVD_IN_VALIDITY_RPBL_BLOCKED, RCVD_IN_VALIDITY_SAFE_BLOCKED,SPF_PASS autolearn=unavailable autolearn_force=no version=4.0.1 ARC-Seal: i=1; a=rsa-sha256; s=arcselector10001; d=microsoft.com; cv=none; b=Tl5q7pxB3UpKsE3ceOUVYwsNMT6T1geTU5fjkj1iT2deZlxj0jXziy4eX4xaDtpZBTFhzWgEBB+P/2WsC2CaNetKgXJDzIWmlxmibDsEqhorJKo9lVI5QDckZwnS2w9VKfeC26ilp7cozFdaYHLxFTFwRUxdln9uv2w/P8jEpRxRzRszt5Fgjh1ZyW7bD/yD55WWgQmG9phLVUxEk1LXDmbIZqcOV7HysycE3DMvCJMiHvpVHWyMLcpiEhbAFXMg4XWxakcU9dsOqnH8TPAA7HvhvMiX5kbKP+Re7J4qTmvtkUKZkXv5g3qucgkTlRYIQMj9/+z/UYNNfMojDpVCig== 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=FT8UQU5Bd141K/gIh6l+t0GrgWy+0W6UX1l4dvL3ETc=; b=AYA1H4qqC7gxs0OxssBiP5c071x3g/nIekdXmtFQqazOCc0zFPB29V6BgmbYU3A5wD5yJ4egppU9E/Bth8YaXklxpaEpPr83SGGRAfVg4qXNWSY/ON4GM7/d7gnKeN9i+c1s8td/YMj8wnIOsJY7ST2+0Np7vOQ4al1lDK+x2/kIobKS/LiqIaF+UBXRawS8SV7Vt6GYsGa/JlnKVjL3d/2pUgY+BxvWXmMHRI8puBWS1xrohnr0jUm+wyg5+4mHXNssgPolQenibyamiWRYi5UQu+bAQXGb/NnMyq3i1oieZLa5b+0ka8SvyszxKgS9JFybS/GLOPhcHsTAJqpB8g== 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=FT8UQU5Bd141K/gIh6l+t0GrgWy+0W6UX1l4dvL3ETc=; b=jCWHU15YO7txmfOLq1wjprbwP1qseKv5tDP4JgKvif6+dHrrJpxdnTuHRqAVmR7R4shA6WJN4OcfVdD7zsNoy4b7mYVaO67sf3TK/GgT4+ZKRqBlYtZMwg3fOcy5/lArmOEifQgKYXgoE857ccBhRpDtZHso+auc8tnwRRmY31ivW+Yhezr5XYKc2hxhHkWHGKEKTYxOYcsD2XaB7SCcT9lqyWTUDpOmNGIdt8dbON2jXQY5YNEjVAScXWRQDSdVY4qzXsMxWrVTVajWvqPdBgCEc986SXGdiVoRjaZ+SQzaLbgJ7X3angHxyAnYX136/QqG2ceLYTduZuouISYmdQ== 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 v5 6/7] qemu: Update Cgroup, namespace, and seclabel for qemu to access iommufd paths Date: Wed, 1 Oct 2025 17:38:36 -0700 Message-ID: <20251002003837.1546646-7-nathanc@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251002003837.1546646-1-nathanc@nvidia.com> References: <20251002003837.1546646-1-nathanc@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BYAPR01CA0007.prod.exchangelabs.com (2603:10b6:a02:80::20) To PH7PR12MB6834.namprd12.prod.outlook.com (2603:10b6:510:1b4::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH7PR12MB6834:EE_|SN7PR12MB7299:EE_ X-MS-Office365-Filtering-Correlation-Id: 27ce1699-f7cd-45fb-200d-08de014c0f10 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|376014|366016|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?foa0Dx8AER6uZNWmRaX+ytX1BtsDLwlfjDicjBpTPDkOdwzfdbTXPh8+BHEW?= =?us-ascii?Q?GNt3A8ckN1arHbZdsiUcDBisVB5zqyu5nyr5KBAx1Wp9UDbqnZ7RzeJp+xbA?= =?us-ascii?Q?0VNCxf+SgTZWsA7qgxJHxqxciqP4DtVLNt6C1wX4UhgJU7ipnFQEdmsSbpbq?= =?us-ascii?Q?Q1iIRj0qQfwMgKXxGBsdJ6D5pvY9SAgJth/mje9RfmIEj3k/yxCD79FnzMMt?= =?us-ascii?Q?WgitGlDp5CtQDcee6geOxm3yU+ARBeKOlCXpe32HSzLdKK86VTSxEvGb+ma5?= =?us-ascii?Q?CDYQK4y0hDmOuGVkDfev4tGlfwP1RAEE1e7L7q/F2wIgdUiVdZmjwg2PayPu?= =?us-ascii?Q?awmR2AshWUBeumw6AQ2ovXkiODbiQx4x/+sx5thf8F0wW4Fp9H0JiFv4ywLk?= =?us-ascii?Q?F2ep+tNxiLaqd2cxl2fbdbg0/tXGzkvMbcmpW11cRq6URcUq9lekLLAsJVty?= =?us-ascii?Q?rMWoRhkUOBWxizUUV2w18+QQaZRv0m4xCVJZbN0oPKPObkM2NgvXXf98JvAk?= =?us-ascii?Q?C9Dh5spFScM6nhYpt/JtKoev4/An9urWpOd0uh490g3GWNHhJydt23MoWHf5?= =?us-ascii?Q?EKcmmp+I58/xe2Usb2hLURIEZsrmJq/zp46CgcbWfLDKb76wK21QcFRQP6Ig?= =?us-ascii?Q?YN29XxQFRsyKUA3GZTHpGr77i/zyJcQ/XntO4J2FiYMVgYK1lu6mmpNymQLM?= =?us-ascii?Q?GpVKmJWnF/LqPrvx49qA7rsR7NhDk7wF1/GUcXjR1HTXuSA6LeL04Ubt0TWZ?= =?us-ascii?Q?XEzfajhO9C3vTz/LrJ16p/4B+D0Z09jBtBsTSfXHMMHrD0y76vqF1/PTee1/?= =?us-ascii?Q?mbY0ZkCQBtrsnsMu7LMV/gmIuRSYoaJXEgBIKgbbio6kniDZRQCrn9RIv9A7?= =?us-ascii?Q?VgSSdazxlrvqr9VpSz0fTw3g8J1P1AIANoSHphcrBuqBRObhj2f3hXXwyVH8?= =?us-ascii?Q?stF9BrtSA5mgSnalWiqHQRtRNKbHVMLjmdU5UO4DEn6BhzrtsP7b2j+FXd7C?= =?us-ascii?Q?wWWJ6RkQ6ZUbqipt2cm8tDQmE29Q16sZGjjCwwPUfw4LKrS/vFu5N7uIYrjJ?= =?us-ascii?Q?RXnllr4Am9OM7VkVewms7O5hCXrvbND44SBVOVsM63hs9AkbO2y3+xcfomyA?= =?us-ascii?Q?CWi9Be4DjzQh9APZ29JxKq6vQhBn6M7L3fRK6IoKe2JHRiVRjsZAleyvYCau?= =?us-ascii?Q?Zt85J5DV5o0Qr1XvN+J/tAH7dkopJFI+57lBfMMQTQ9NnpcgWnBVkVPK68vK?= =?us-ascii?Q?sqLDQbLieAlvNsbc4mjOEBmIIl6UF79+6CubXmrOXZzcX2sXWV/ZoX469tST?= =?us-ascii?Q?pENqMjCUtg7wpPNRwPBpPK+r2UIKvbZS5nP1GUkjNUK7QFjdz8mTwelI2P6d?= =?us-ascii?Q?qGLjcmDvnh3jEEXHhywsOwSE7mgVupkxvhttXpp1aIWCD/VadMHMt04jJxwy?= =?us-ascii?Q?zq/C/fIgBzgU7cMpaOkGS8I81GTh6IHS?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:PH7PR12MB6834.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(376014)(366016)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?BQRLhUoac0Beyi5d5Xy409qBnvS21R3vKdaOPzJ2y+h+it4rVX5e6/SZBxY8?= =?us-ascii?Q?IhandpJ625VgUpEZVVlL4364+NEVOpeMmbXvFzn/sXMnIHRGR9fC6OLKIRPt?= =?us-ascii?Q?OrUDKb62rXh/xXOJsVENecxQgx6maYtXHKhKRw9OrhgkKYhbpvJP0Q+uPQ+w?= =?us-ascii?Q?QAVyeqrHQ1MJIj4otq6QLiHGQco56mwQWmUp6RLZmHWaGb3BsZAiijalEane?= =?us-ascii?Q?rB1+WBjyfJVOAkDYMvgSCI2TpFdeRlaob+DBFA2hzUoIYFBGWcWYcsEIrt8q?= =?us-ascii?Q?SNYWRJOd3b2rWWPNTLor10jS1BuL24YOMPkV47IF6EedzAoP4O8/UVylqL+7?= =?us-ascii?Q?z47ttzQm9ppa+mlU6NTDpdK+rN+niTsFzAMfN2ituwVy8jnCFRFnU7Oye4J7?= =?us-ascii?Q?wZjgwT2cK11nO/PreMQ0p/uix90q54xNkaA9JpwBhI0DhfcR4KhxSx9azf1Q?= =?us-ascii?Q?rPzGpXFidIyQwF/MhRGN+n6Tqg8jDS7zw/US+67W6hWaxbYxcjEvgkHyOfA/?= =?us-ascii?Q?Z6cop5f/ARDMSiZpCH++MJaj/OCECHpQRQRnev86N1+8ilBvsn7t625OVB/H?= =?us-ascii?Q?hOuww2Ro3Rr2fWJ9DWC79dvG5bG0LMmQj8ztNNqrUN6yPqcKaJaNrxHXGgko?= =?us-ascii?Q?4/sWx2+VKBSOAHcsWVfKQmP08//mKRSokcgDKgCfvSNfIYWH/i3LjkH6Xq2M?= =?us-ascii?Q?Kgllbr5QPmawebg1rlPabETkJvr5GoNxVMa6XW5My8tp3Y7C93ITMHx1ZmG4?= =?us-ascii?Q?ImcD5TzPXn51tA8RmeABGkRV0tCqQB+19YLL3l6cS0ga0XYEAcRisI8fbc/W?= =?us-ascii?Q?SNMt5cU9v7QnBf2Du4rD+Qy6fpozX67aH/Mp4yk4e+K9uUJy4Shu5cC7nKjy?= =?us-ascii?Q?arxuOyaEGyrZJ1H0KRr1ANtsM+pJnNjs3PLZf/OCfsrV0CRGl5MiWz24IFYt?= =?us-ascii?Q?g/u7x7gDAXpNtPWxliYIE2Yygiyq3Av5vKvz1eCIkkoya9PUZs/7j642Af6W?= =?us-ascii?Q?N1rcL3TfqlO6IRFEdR5NFZh3PsPOQfeKQhHO/vSxNrUHKcc8Ofi/QtQNEz5h?= =?us-ascii?Q?UprZ5qV/WVIoC2+EP7Zdb1NewXBfGAW9Q5tRsN2o+kwZMlSrK6DqKmz/6Btu?= =?us-ascii?Q?YvflNCO8+fZWY6r3MAPDyNGOWxJJORPbZc13n6A8kxvVcjAsjB/no/m4vuiM?= =?us-ascii?Q?0s+o2s+ogMpRtFc1SaS5Y70TcVDZs597bCflmIXIRUOZlHJywaOqNcY0IPV3?= =?us-ascii?Q?6Kci692JBz5LWL2cQBoEScNW9L8U9mjK6NB8sCCNBHtDyWkwfQj9fVe3TMhH?= =?us-ascii?Q?PHTP28gDQIXOxGK03aZltulqVTwfMJIY3Fs6EykIglf1n7WNMRiLpjYHa/mO?= =?us-ascii?Q?eIXxgV8sUW1dH9eK4hsdFZ7/IXeVxWSJWUySFtyedYHoEyrBauCZOy6ZlfEh?= =?us-ascii?Q?TU5GNGMHu3DdNSM/qgzCDtaP/mpa9qU53TwMABlzB9fLBe+Ly+nSraDji7DS?= =?us-ascii?Q?qYHoQv8YB/MHol6dDKYx5H7Cn7eDgKYwPkSBeDCsEsLWTERzTIW4n1hgGCSf?= =?us-ascii?Q?x2JFti3AJ2lkH4NrAZQtcOOtrgXerJS0svIzKZl3?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 27ce1699-f7cd-45fb-200d-08de014c0f10 X-MS-Exchange-CrossTenant-AuthSource: PH7PR12MB6834.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 02 Oct 2025 00:38:51.6585 (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: NiMgXNjujHDTL9ehIniBY/rby7MgMGjD1TjC3HcZ/zkiS/qsIFWL3U3r9OrPetYcsn6XE4Up6GehJgBNH8LHqw== X-MS-Exchange-Transport-CrossTenantHeadersStamped: SN7PR12MB7299 Message-ID-Hash: EDFKU3F3D5PFSEUQSZWJOSMMYEG2R6WV X-Message-ID-Hash: EDFKU3F3D5PFSEUQSZWJOSMMYEG2R6WV X-MailFrom: nathanc@nvidia.com X-Mailman-Rule-Misses: dmarc-mitigation; no-senders; approved; loop; banned-address; header-match-devel.lists.libvirt.org-0; emergency; member-moderation; nonmember-moderation; administrivia; implicit-dest; max-recipients; max-size; news-moderation; no-subject; digests; suspicious-header CC: shameerali.kolothum.thodi@huawei.com, nicolinc@nvidia.com, nathanc@nvidia.com, mochs@nvidia.com X-Mailman-Version: 3.3.10 Precedence: list List-Id: Development discussions about the libvirt library & tools Archived-At: List-Archive: List-Help: List-Owner: 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: 1759366277104116600 Content-Type: text/plain; charset="utf-8" Allow access to /dev/iommu and /dev/vfio/devices/vfio* when launching a qemu VM with iommufd feature enabled. Signed-off-by: Nathan Chen --- src/qemu/qemu_cgroup.c | 61 ++++++++++++++++++++++++++++ src/qemu/qemu_cgroup.h | 1 + src/qemu/qemu_namespace.c | 44 +++++++++++++++++++++ src/security/security_apparmor.c | 15 +++++++ src/security/security_dac.c | 34 ++++++++++++++++ src/security/security_selinux.c | 30 ++++++++++++++ src/util/virpci.c | 68 ++++++++++++++++++++++++++++++++ src/util/virpci.h | 1 + 8 files changed, 254 insertions(+) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index f10976c2b0..5f4315051a 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -462,6 +462,54 @@ qemuTeardownInputCgroup(virDomainObj *vm, } =20 =20 +int +qemuSetupIommufdCgroup(virDomainObj *vm) +{ + qemuDomainObjPrivate *priv =3D vm->privateData; + g_autoptr(DIR) dir =3D NULL; + struct dirent *dent; + g_autofree char *path =3D NULL; + int iommufd =3D 0; + size_t i; + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + if (vm->def->hostdevs[i]->source.subsys.u.pci.driver.iommufd) { + iommufd =3D 1; + break; + } + } + + if (iommufd =3D=3D 1) { + if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DE= VICES)) + return 0; + if (virDirOpen(&dir, "/dev/vfio/devices") < 0) { + if (errno =3D=3D ENOENT) + return 0; + return -1; + } + while (virDirRead(dir, &dent, "/dev/vfio/devices") > 0) { + if (STRPREFIX(dent->d_name, "vfio")) { + path =3D g_strdup_printf("/dev/vfio/devices/%s", dent->d_n= ame); + } + if (path && + qemuCgroupAllowDevicePath(vm, path, + VIR_CGROUP_DEVICE_RW, false) < 0= ) { + return -1; + } + path =3D NULL; + } + if (virFileExists("/dev/iommu")) + path =3D g_strdup("/dev/iommu"); + if (path && + qemuCgroupAllowDevicePath(vm, path, + VIR_CGROUP_DEVICE_RW, false) < 0) { + return -1; + } + } + return 0; +} + + /** * qemuSetupHostdevCgroup: * vm: domain object @@ -760,6 +808,7 @@ qemuSetupDevicesCgroup(virDomainObj *vm) g_autoptr(virQEMUDriverConfig) cfg =3D virQEMUDriverGetConfig(priv->dr= iver); const char *const *deviceACL =3D (const char *const *) cfg->cgroupDevi= ceACL; int rv =3D -1; + int iommufd =3D 0; size_t i; =20 if (!virCgroupHasController(priv->cgroup, VIR_CGROUP_CONTROLLER_DEVICE= S)) @@ -830,6 +879,18 @@ qemuSetupDevicesCgroup(virDomainObj *vm) return -1; } =20 + for (i =3D 0; i < vm->def->nhostdevs; i++) { + if (vm->def->hostdevs[i]->source.subsys.u.pci.driver.iommufd) { + iommufd =3D 1; + break; + } + } + + if (iommufd =3D=3D 1) { + if (qemuSetupIommufdCgroup(vm) < 0) + return -1; + } + for (i =3D 0; i < vm->def->nmems; i++) { if (qemuSetupMemoryDevicesCgroup(vm, vm->def->mems[i]) < 0) return -1; diff --git a/src/qemu/qemu_cgroup.h b/src/qemu/qemu_cgroup.h index 3668034cde..bea677ba3c 100644 --- a/src/qemu/qemu_cgroup.h +++ b/src/qemu/qemu_cgroup.h @@ -42,6 +42,7 @@ int qemuSetupHostdevCgroup(virDomainObj *vm, int qemuTeardownHostdevCgroup(virDomainObj *vm, virDomainHostdevDef *dev) G_GNUC_WARN_UNUSED_RESULT; +int qemuSetupIommufdCgroup(virDomainObj *vm); int qemuSetupMemoryDevicesCgroup(virDomainObj *vm, virDomainMemoryDef *mem); int qemuTeardownMemoryDevicesCgroup(virDomainObj *vm, diff --git a/src/qemu/qemu_namespace.c b/src/qemu/qemu_namespace.c index f72da83929..1928a84e26 100644 --- a/src/qemu/qemu_namespace.c +++ b/src/qemu/qemu_namespace.c @@ -677,6 +677,47 @@ qemuDomainSetupLaunchSecurity(virDomainObj *vm, } =20 =20 +static int +qemuDomainSetupIommufd(virDomainObj *vm, + GSList **paths) +{ + g_autoptr(DIR) dir =3D NULL; + struct dirent *dent; + g_autofree char *path =3D NULL; + int iommufd =3D 0; + size_t i; + + for (i =3D 0; i < vm->def->nhostdevs; i++) { + if (vm->def->hostdevs[i]->source.subsys.u.pci.driver.iommufd) { + iommufd =3D 1; + break; + } + } + + /* Check if iommufd is enabled */ + if (iommufd =3D=3D 1) { + if (virDirOpen(&dir, "/dev/vfio/devices") < 0) { + if (errno =3D=3D ENOENT) + return 0; + return -1; + } + while (virDirRead(dir, &dent, "/dev/vfio/devices") > 0) { + if (STRPREFIX(dent->d_name, "vfio")) { + path =3D g_strdup_printf("/dev/vfio/devices/%s", dent->d_n= ame); + *paths =3D g_slist_prepend(*paths, g_steal_pointer(&path)); + } + } + path =3D NULL; + if (virFileExists("/dev/iommu")) + path =3D g_strdup("/dev/iommu"); + if (path) + *paths =3D g_slist_prepend(*paths, g_steal_pointer(&path)); + } + + return 0; +} + + static int qemuNamespaceMknodPaths(virDomainObj *vm, GSList *paths, @@ -700,6 +741,9 @@ qemuDomainBuildNamespace(virQEMUDriverConfig *cfg, if (qemuDomainSetupAllDisks(vm, &paths) < 0) return -1; =20 + if (qemuDomainSetupIommufd(vm, &paths) < 0) + return -1; + if (qemuDomainSetupAllHostdevs(vm, &paths) < 0) return -1; =20 diff --git a/src/security/security_apparmor.c b/src/security/security_appar= mor.c index 68ac39611f..0a878fd205 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -856,6 +856,21 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mg= r, } ret =3D AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr); VIR_FREE(vfioGroupDev); + + if (dev->source.subsys.u.pci.driver.iommufd) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + const char *iommufdDir =3D "/dev/iommu"; + if (vfiofdDev) { + int ret2 =3D AppArmorSetSecurityPCILabel(pci, vfiofdDe= v, ptr); + if (ret2 < 0) + ret =3D ret2; + ret2 =3D AppArmorSetSecurityPCILabel(pci, iommufdDir, = ptr); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } } else { ret =3D virPCIDeviceFileIterate(pci, AppArmorSetSecurityPCILab= el, ptr); } diff --git a/src/security/security_dac.c b/src/security/security_dac.c index 2f788b872a..361106222d 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1290,6 +1290,24 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mg= r, ret =3D virSecurityDACSetHostdevLabelHelper(vfioGroupDev, false, &cbdata); + if (dev->source.subsys.u.pci.driver.iommufd) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + const char *iommufdDir =3D "/dev/iommu"; + if (vfiofdDev) { + int ret2 =3D virSecurityDACSetHostdevLabelHelper(vfiof= dDev, + false, + &cbdata= ); + if (ret2 < 0) + ret =3D ret2; + ret2 =3D virSecurityDACSetHostdevLabelHelper(iommufdDi= r, + false, + &cbdata); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } } else { ret =3D virPCIDeviceFileIterate(pci, virSecurityDACSetPCILabel, @@ -1450,6 +1468,22 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager= *mgr, =20 ret =3D virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfioGroupDev, fal= se); + if (dev->source.subsys.u.pci.driver.iommufd) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + const char *iommufdDir =3D "/dev/iommu"; + if (vfiofdDev) { + int ret2 =3D virSecurityDACRestoreFileLabelInternal(mg= r, NULL, + vfio= fdDev, false); + if (ret2 < 0) + ret =3D ret2; + ret2 =3D virSecurityDACRestoreFileLabelInternal(mgr, N= ULL, + iommufdD= ir, false); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } } else { ret =3D virPCIDeviceFileIterate(pci, virSecurityDACRestorePCIL= abel, mgr); } diff --git a/src/security/security_selinux.c b/src/security/security_selinu= x.c index fa5d1568eb..8f6b23846b 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2248,6 +2248,25 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityM= anager *mgr, ret =3D virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev, false, &data); + if (dev->source.subsys.u.pci.driver.iommufd) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + const char *iommufdDir =3D "/dev/iommu"; + if (vfiofdDev) { + int ret2 =3D virSecuritySELinuxSetHostdevLabelHelper(v= fiofdDev, + fal= se, + &da= ta); + if (ret2 < 0) + ret =3D ret2; + ret2 =3D virSecuritySELinuxSetHostdevLabelHelper(iommu= fdDir, + false, + &data); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } + } else { ret =3D virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCIL= abel, &data); } @@ -2481,6 +2500,17 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecur= ityManager *mgr, return -1; =20 ret =3D virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, = false); + + if (dev->source.subsys.u.pci.driver.iommufd) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + if (vfiofdDev) { + int ret2 =3D virSecuritySELinuxRestoreFileLabel(mgr, v= fiofdDev, false); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } } else { ret =3D virPCIDeviceFileIterate(pci, virSecuritySELinuxRestore= PCILabel, mgr); } diff --git a/src/util/virpci.c b/src/util/virpci.c index 90617e69c6..6e6e5e47c0 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -2478,6 +2478,74 @@ virPCIDeviceGetIOMMUGroupDev(virPCIDevice *dev) return g_strdup_printf("/dev/vfio/%s", groupFile); } =20 +/* virPCIDeviceGetIOMMUFDDev - return the name of the device used + * to control this PCI device's group (e.g. "/dev/vfio/devices/vfio15") + */ +char * +virPCIDeviceGetIOMMUFDDev(virPCIDevice *dev) +{ + g_autofree char *path =3D NULL; + const char *pci_addr =3D NULL; + g_autoptr(DIR) dir =3D NULL; + struct dirent *entry; + char *vfiodev =3D NULL; + + /* Get PCI device address */ + pci_addr =3D virPCIDeviceGetName(dev); + if (!pci_addr) + return NULL; + + /* First try: look in PCI device's vfio-dev subdirectory */ + path =3D g_strdup_printf("/sys/bus/pci/devices/%s/vfio-dev", pci_addr); + + if (virDirOpen(&dir, path) =3D=3D 1) { + while (virDirRead(dir, &entry, path) > 0) { + if (!g_str_has_prefix(entry->d_name, "vfio")) + continue; + + vfiodev =3D g_strdup_printf("/dev/vfio/devices/%s", entry->d_n= ame); + break; + } + /* g_autoptr will automatically close dir when it goes out of scop= e */ + dir =3D NULL; + } + + /* Second try: scan /sys/class/vfio-dev for matching device */ + if (!vfiodev) { + g_free(path); + path =3D g_strdup("/sys/class/vfio-dev"); + + if (virDirOpen(&dir, path) =3D=3D 1) { + while (virDirRead(dir, &entry, path) > 0) { + g_autofree char *dev_link =3D NULL; + g_autofree char *target =3D NULL; + + if (!g_str_has_prefix(entry->d_name, "vfio")) + continue; + + dev_link =3D g_strdup_printf("/sys/class/vfio-dev/%s/devic= e", entry->d_name); + + if (virFileResolveLink(dev_link, &target) < 0) + continue; + + if (strstr(target, pci_addr)) { + vfiodev =3D g_strdup_printf("/dev/vfio/devices/%s", en= try->d_name); + break; + } + } + /* g_autoptr will automatically close dir */ + } + } + + /* Verify the device path exists and is accessible */ + if (vfiodev && !virFileExists(vfiodev)) { + VIR_FREE(vfiodev); + return NULL; + } + + return vfiodev; +} + static int virPCIDeviceDownstreamLacksACS(virPCIDevice *dev) { diff --git a/src/util/virpci.h b/src/util/virpci.h index fc538566e1..996ffab2f9 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -203,6 +203,7 @@ int virPCIDeviceAddressGetIOMMUGroupNum(virPCIDeviceAdd= ress *addr); char *virPCIDeviceAddressGetIOMMUGroupDev(const virPCIDeviceAddress *devAd= dr); bool virPCIDeviceExists(const virPCIDeviceAddress *addr); char *virPCIDeviceGetIOMMUGroupDev(virPCIDevice *dev); +char *virPCIDeviceGetIOMMUFDDev(virPCIDevice *dev); =20 int virPCIDeviceIsAssignable(virPCIDevice *dev, int strict_acs_check); --=20 2.43.0