From nobody Fri Nov 21 10:14:39 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 1762196022349336.66730840687444; Mon, 3 Nov 2025 10:53:42 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id 4EFC8440DF; Mon, 3 Nov 2025 13:53:41 -0500 (EST) Received: from [172.19.199.29] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 36B2A44235; Mon, 3 Nov 2025 13:48:17 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id BDF08440C8; Mon, 3 Nov 2025 13:48:05 -0500 (EST) Received: from MW6PR02CU001.outbound.protection.outlook.com (mail-westus2azon11012022.outbound.protection.outlook.com [52.101.48.22]) (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 8137C4412A for ; Mon, 3 Nov 2025 13:47:34 -0500 (EST) Received: from SJ0PR12MB6855.namprd12.prod.outlook.com (2603:10b6:a03:47e::6) by MN2PR12MB4205.namprd12.prod.outlook.com (2603:10b6:208:198::10) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9275.16; Mon, 3 Nov 2025 18:47:29 +0000 Received: from SJ0PR12MB6855.namprd12.prod.outlook.com ([fe80::1924:8e6f:c8f3:83c2]) by SJ0PR12MB6855.namprd12.prod.outlook.com ([fe80::1924:8e6f:c8f3:83c2%3]) with mapi id 15.20.9275.015; Mon, 3 Nov 2025 18:47:29 +0000 X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-26) on lists.libvirt.org X-Spam-Level: X-Spam-Status: No, score=-5.0 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, 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=f7GkfI9ypUxKE0JbUlUi0QkNApylrM8s2mVfFv1xFNsd2hIs5zgWDQ3/at/dSz5sK4xBK5BMLWglmFsitIin1/4070uRzjlbw7m20ou5JSBV3gu45oUFIDmXYjFK25GOzT1z65BxaMDi8WGp7NVxy7fzBLgvBGPTbLR828YHEW2UFwk8MWlLwpGgl8pGQNjiePp87KL1kPaPwESY8iUf5Z6Qa8/C/mOzGd7V4zLt3cUNC5yj1WG25LvXeiOrVNa1PxanpH76HdOGpe+nYnxGHsr6sVCcjMAXNDB8tZU8JrpG0lDVaaZFOjccCLQQWOeTOjkEzV2Ibts1/GdZjESNaA== 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=iWVnOzZmrgqYuf2vcWNaZsG0rLf8F6A3we4UwJ4UX3M=; b=UEkNDoCukBnmykC2tGACx6JfUu35Gh5j9IlnkJ8K10zGiNfIHKa3OyQMzm68/yythzd6f4JrujrOVXJ5mT9itE3qL/xkbBH2iKQLR3s+Ilg7QlKBecOflzHEZ5Z6TZNZA1e9pJMEswafD8t4mARgnX3lx+xRSSm6N5KBO4i2qiNAzUeGLgsh6uNr1v5UcJOp3K7BFiUOYIx2f9zMeFmMAhVd93bAmAw1TiPko6IU5mddPzv/WEjqACZ7Xv3bwTNsWkKWhqrkh2TcgTtxbVoue2iZwszsgppVT9P4FHg94y33xkYSj8x4F+aIWbjiJ3vpfZxIpxcXw8aomfLXmfrEuA== 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=iWVnOzZmrgqYuf2vcWNaZsG0rLf8F6A3we4UwJ4UX3M=; b=ccvjeEekM34sA3iNo/dP+GVENOm5NPOt0Zh1vJ3ts6uB0XNpHp8utjStk6Vt8r2msQ+9HoWDwOYlGigPB/lC9YFZ5Lq69rJFRvE+RMYbwU4Z5brkiySbEcOOyMZKm0dcVQbEawAOWCewnEnmGebhJ1X7a1iqwyAtWIhlHhFyLlxie19t6d69fAfxRw660sRZ+kDMFWG+OFUb6sXK4RV2qlGlf5C0cgerV2yVKVyHUC2uux+nxnk+BHwE3ZM7EOzSUoJ/qeXLk0ExsG7Zdp38AGrlZIz/zrPuv0Awt+tI52FLRwlMg9OlllAMffnaHJzlqzp/GfzopeMjuget8OAtdQ== Authentication-Results: dkim=none (message not signed) header.d=none;dmarc=none action=none header.from=nvidia.com; To: devel@lists.libvirt.org Subject: [PATCH 3/4] qemu: Update Cgroup, namespace, and seclabel for qemu to access iommufd paths Date: Mon, 3 Nov 2025 10:47:10 -0800 Message-ID: <20251103184711.4022833-4-nathanc@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251103184711.4022833-1-nathanc@nvidia.com> References: <20251103184711.4022833-1-nathanc@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: PH7P221CA0089.NAMP221.PROD.OUTLOOK.COM (2603:10b6:510:328::7) To SJ0PR12MB6855.namprd12.prod.outlook.com (2603:10b6:a03:47e::6) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SJ0PR12MB6855:EE_|MN2PR12MB4205:EE_ X-MS-Office365-Filtering-Correlation-Id: 3251c8fc-7d26-4fa0-6406-08de1b0970a6 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|1800799024|366016|376014; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?fbPq6vsf4wyls6yhM+csHyEo/BS2s1xWiHBy6DfvuyW8OIVXD5qKX47SkEn1?= =?us-ascii?Q?bJcH5mjnstjbhfbxY9PcQd5b5L5O51Bh4ydl4uRDiP3GDn0PuEraJVVPOABL?= =?us-ascii?Q?G+eMK+TSw6RkUBW5rcc8sZsW1f7VhN7lduN0G9KEMtGhxglAgzZM3LCQtOTE?= =?us-ascii?Q?mmbkUEgzTCpx02oKnknsnXdJPbAO2izMj7CbHvk6Tz9TFCIDD+oIbOidPenU?= =?us-ascii?Q?qyLVagke7oK55w78B86pAnSijo2qz/pJQJY2TeJKdMIKgLeuwxrqiYOcjEgq?= =?us-ascii?Q?7SPCaIcr/Fcg5MHYQf8tYtDAWylY2LG1syT+7++GUw2qLy0OBxWraRT8B7rg?= =?us-ascii?Q?pvtEDWOe5IZKXrp/YbScn5sY2qVq7xrUrR0xtB4vIQRq+Iat4z6wbZjoj2gG?= =?us-ascii?Q?/sF4DIuCUdEvw02nh6l1v2Oo7Q5LiDdQz0b+g1XWFYc5/jftbX8wXRZUpwqC?= =?us-ascii?Q?ViZatOmsA8oWy4eiRNLXgiZIYidd9Thor/USBkVicaWI5dg/U/K+ZyGSgE4n?= =?us-ascii?Q?Am3mFpwWxTjbpOIAhrwG5RDZcwNZs7ZhLHW30Xrz7KnFTZeWwCw1BfFu7rUp?= =?us-ascii?Q?F9jflQKJA7ZQHFyzY1WytzVBxFxPekmoB5wiPVobObQqt4iJcxMzjyU10nZK?= =?us-ascii?Q?qQkruTnIteveALF4n1pUsyytqTY6Ffgxr8oQ5DFAoN0DlsIMTWLQ5NffWI5k?= =?us-ascii?Q?Y9iPT0BzNeK+MBhAd7D1njw25jsygScTo1GhwPufJAAWiDFphjZxvgj/AB0G?= =?us-ascii?Q?VhRAdhqXSn0ZRTl8jlc817QxYqNE2iRqgcpuNXPNvOh8gKmCSeRrKt9H+i4a?= =?us-ascii?Q?AFQBymC8yx0cQ7r7GluFk6Q/54V4jdJJHa46Iu06vF3b8AVQKmc4evxBrFwy?= =?us-ascii?Q?5m1O3eKSMO88k+1Dnmt3chbyuV28r+uuZATyfZdPZtV8k8zubbE3nApB/cvX?= =?us-ascii?Q?CHC36rrVfYZnkRTGbaIUp8JZvTTnUpVWhfXcrSEk3hae/7gR78ojrL7p3CnU?= =?us-ascii?Q?e2JHdvfwHbFWPgCE+jnUcR040rEnICPbK5UYEtl0/mkit8e0iUW6P4RD4Nb8?= =?us-ascii?Q?pNmnYKGijhw/AUIMCT2IbqChQkcoeS8cZNWGm+HZdbDA0IZFpyKKdGfmHfeV?= =?us-ascii?Q?i/RlZpfK9RTaMVIeE/lAC3jqgIG1mBq7huTO7br+F1rOquaoApA2VxNStwi2?= =?us-ascii?Q?68YyxcTiE2MCu/YqxDVfyFazHMC13aI0dsThRLgOQ2WMAAJDl/6bouI+uJCP?= =?us-ascii?Q?zxbnWBaaFDNEYhO0F5NS5UCo/RexILsF4omHvP2xiEBV58cNqZKw80AHitty?= =?us-ascii?Q?c051SyDA2IG91pOugMUPwzc7ZLTBvodkSKkZ7/wRnh2/AGSZprSMGqZLOZ8P?= =?us-ascii?Q?7uqVzNLmPXrCQCz5d1G0Oa9wo13gzbGYBrsszhnMltb1dtCSFzfQTrhrG5Uk?= =?us-ascii?Q?BE8hFs5FyGrEwsiPsjmmU+/NocoY/CMF?= X-Forefront-Antispam-Report: CIP:255.255.255.255;CTRY:;LANG:en;SCL:1;SRV:;IPV:NLI;SFV:NSPM;H:SJ0PR12MB6855.namprd12.prod.outlook.com;PTR:;CAT:NONE;SFS:(13230040)(1800799024)(366016)(376014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?stP8bU+no09vwO9uUzLPSSgIJrlIcrznOYlwiEmaeR6tX4RKNof0tkFEa6f9?= =?us-ascii?Q?DNnqKFi1V0k6ixOo7YJm4HOIj96tHvKlN1AfF45iE3/SVNDK1lVLOqNNqX6p?= =?us-ascii?Q?Kz22939qvLhpbmffVWqXY+/3wUe5OnzgXdFIi/JFf04ohIpuRENLZa+Jt2KB?= =?us-ascii?Q?5OShr9+jRNhpjsWIICJMED8ltOUc2c4l3Ts+CP6H/xW6dOGETB5od3Hk/zVA?= =?us-ascii?Q?maUoBaMWCUjLkOXlWYX+k/mjNvVks40IS6SVfJyFIVBwz7g6+P7GZdk9+mrJ?= =?us-ascii?Q?/20KiiAw1bXJTlb9VAnvWtPE6ZUfgUBgc7xqLXhOURE4fSpzSTB6dzz9jpHJ?= =?us-ascii?Q?D+WCigkIL/zfje7lqbLqnh0jR5EY3gHs8Xcsv6BWXuIN37Eii10CMKP6WATC?= =?us-ascii?Q?HBndBXFsPxwFqD19sPfIT6EcZ2X8J2eEb6szdVWgc6q5w3eOImHMFT2KfKkv?= =?us-ascii?Q?L2vDu/Zc0NTNUgCYqJgau02Oy7XwyP5ktsfQvLmmUsp42xaGo6ueyQxUzI7d?= =?us-ascii?Q?Urcnrqo4ygtAw9Xtj7p8SU0sw1TzewXU1OJbN4Z2TIULe1OTkznPHfp4iWBT?= =?us-ascii?Q?0a8A5Uxc9890xNw0GHLF9gNgvNZSgtjWMOCrIQlg5YJF77Rn70N9xjQLBTrz?= =?us-ascii?Q?d2jgZtwDnpT9+nkS7cB27ZitLFPPiyYTikBWwicfDNUdDJUzUrGYSm3zvkbC?= =?us-ascii?Q?qNUL4LP36fZ5peh3iLyDD4Fk2jAaT7vbu8eAXN2LZZO25TT4AMUqr8Vb/4lr?= =?us-ascii?Q?kk4uZllAzSlwjEQpo2NvQZGFQjMLKJSEdsAEHfWNDLibVLc6ADj2Ct4eHFmg?= =?us-ascii?Q?JgCyrzeAtUfFnwuvHgISo/wkPUHsduEyTyL9STZIHfnjMc9NqG1HyT3O9WHV?= =?us-ascii?Q?Df9xgUbxKcgQigbh+uun4DQOpGEMqwvrnFuRYg/pYWWqA52JvCc2tlNXJorY?= =?us-ascii?Q?Okp+D3S2nidykrNAr6GGV0LIsZjzdg9ex1ye/R8QECosP1olja6Uc6Ty7D3L?= =?us-ascii?Q?K94rr41VaCKV99pbTk4jx/z5BLRB8isUDTwP69Xk5ssCIXMkXl8MEVkaTQfI?= =?us-ascii?Q?A4J6WvtT2ldvc+RQps6ydkSpGWtzfDomFrkPmnfeqls2wE4TuH0q1twmfn1Q?= =?us-ascii?Q?YD0sxgQwX4YVt2V2mJ9MvLYFG9V25ErfInA9RVcQjldMEP4ylR90A2EN3HYF?= =?us-ascii?Q?+H91SSAZXdGrGsi4gfHrXy9X27SrhYhEKOQmYUZLDjXqZLTE+PvAmBARgOlm?= =?us-ascii?Q?mI81BAlNfq4z6p7GhG97phuqTu88/I6agNGLJjRISHxJCveQZJhDNOS9aX/c?= =?us-ascii?Q?GO9HS9MgnaOZ4mfaddLuJKlCKIJtSIVJcCPA4igB3nlL+/Uu4o3K13W9hmTy?= =?us-ascii?Q?HnWsvuPVpNrMdXJ3QyQNsxVqN13UiXZmnSn9EKW6+vkt3D+unWgZStvZAjn+?= =?us-ascii?Q?CmYEd+fMvACsv0SMJJtw+jyR6q7L0dkDnt1KzsOR339jSMGvYX0w522qM/mK?= =?us-ascii?Q?Gf8MN9iHnITj75n0u9E7HqtD9z/mI6oTmMmDdRNJ39Cmn0gfX7mIykAEooVi?= =?us-ascii?Q?TU+fhAGlNl0IhPNk2oMnWTgBekrvue9BIxgK941O?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 3251c8fc-7d26-4fa0-6406-08de1b0970a6 X-MS-Exchange-CrossTenant-AuthSource: SJ0PR12MB6855.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 03 Nov 2025 18:47:29.3823 (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: IJUtyyKT6uAaAcpJp+Vzqa4Eoji7euTSNClfwjNjWF+hIg3fKf+xKEvroat/ciSmYa27mmIyROFETL+cxHV5WQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: MN2PR12MB4205 Message-ID-Hash: 7WPWN3N4QKJ7WCFYMSYHA7AKDRGXFDJD X-Message-ID-Hash: 7WPWN3N4QKJ7WCFYMSYHA7AKDRGXFDJD 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: skolothumtho@nvidia.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: 1762196026269158500 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 | 34 ++++++++++++++++ src/security/virt-aa-helper.c | 11 +++++- src/util/virpci.c | 68 ++++++++++++++++++++++++++++++++ src/util/virpci.h | 1 + 9 files changed, 268 insertions(+), 1 deletion(-) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index 46a7dc1d8b..e15ffd2007 100644 --- a/src/qemu/qemu_cgroup.c +++ b/src/qemu/qemu_cgroup.c @@ -461,6 +461,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 @@ -759,6 +807,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)) @@ -836,6 +885,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 932777505b..80496f2f0f 100644 --- a/src/qemu/qemu_namespace.c +++ b/src/qemu/qemu_namespace.c @@ -683,6 +683,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, @@ -706,6 +747,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..fbe8f63ab4 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,21 @@ 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); + const char *iommufdDir =3D "/dev/iommu"; + if (vfiofdDev) { + int ret2 =3D virSecuritySELinuxRestoreFileLabel(mgr, v= fiofdDev, false); + if (ret2 < 0) + ret =3D ret2; + ret2 =3D virSecuritySELinuxRestoreFileLabel(mgr, iommu= fdDir, false); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } } else { ret =3D virPCIDeviceFileIterate(pci, virSecuritySELinuxRestore= PCILabel, mgr); } diff --git a/src/security/virt-aa-helper.c b/src/security/virt-aa-helper.c index de0a826063..c9e6d9c6a9 100644 --- a/src/security/virt-aa-helper.c +++ b/src/security/virt-aa-helper.c @@ -878,7 +878,7 @@ get_files(vahControl * ctl) size_t i; g_autofree char *uuid =3D NULL; char uuidstr[VIR_UUID_STRING_BUFLEN]; - bool needsVfio =3D false, needsvhost =3D false, needsgl =3D false; + bool needsVfio =3D false, needsvhost =3D false, needsgl =3D false, nee= dsIommufd =3D false; =20 /* verify uuid is same as what we were given on the command line */ virUUIDFormat(ctl->def->uuid, uuidstr); @@ -1119,6 +1119,9 @@ get_files(vahControl * ctl) needsVfio =3D true; } =20 + if (dev->source.subsys.u.pci.driver.iommufd) + needsIommufd =3D true; + if (pci =3D=3D NULL) continue; =20 @@ -1348,6 +1351,12 @@ get_files(vahControl * ctl) virBufferAddLit(&buf, " \"/dev/vfio/vfio\" rw,\n"); virBufferAddLit(&buf, " \"/dev/vfio/[0-9]*\" rw,\n"); } + + if (needsIommufd) { + virBufferAddLit(&buf, " \"/dev/iommu\" rwm,\n"); + virBufferAddLit(&buf, " \"/dev/vfio/devices/vfio[0-9]*\" rwm,\n"); + } + if (needsgl) { /* if using gl all sorts of further dri related paths will be need= ed */ virBufferAddLit(&buf, " # DRI/Mesa/(e)GL config and driver paths\= n"); 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