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 1758591334141699.0162634436599; Mon, 22 Sep 2025 18:35:34 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 3A34E43E71; Mon, 22 Sep 2025 21:35:33 -0400 (EDT) Received: from [172.19.199.10] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 0003343FE2; Mon, 22 Sep 2025 21:19:55 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 993) id 5523D419E9; Mon, 22 Sep 2025 21:19:26 -0400 (EDT) Received: from SN4PR2101CU001.outbound.protection.outlook.com (mail-southcentralusazon11012013.outbound.protection.outlook.com [40.93.195.13]) (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 95EA343E1C for ; Mon, 22 Sep 2025 21:16:19 -0400 (EDT) Received: from PH7PR12MB6834.namprd12.prod.outlook.com (2603:10b6:510:1b4::18) by IA1PR12MB6090.namprd12.prod.outlook.com (2603:10b6:208:3ee::19) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9137.19; Tue, 23 Sep 2025 01:16:14 +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.9137.018; Tue, 23 Sep 2025 01:16:14 +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=hcbwhuehwul5Vrt+dPNTyjPjLpJwSMBg5PcpjYkgAVxZLi52lSm96RoeZpnMzpydGdsPcIsMwG7Owom3lrJU5RiHV/fSolUtgDJSoyEUjd+YmJ3QVn6U0j/spHB8IHSQ9NbjNayB+55vxyInv80kO5deVTxAzOh/Tt8IL7P2McqCQ1lq8ERagLhrabEd5LyUdZ2jfrVhUiZ/83mZvyXqSNBaJQ7kMVfXWx+bWOrW1gZ+MTmaTdK0PSLKTNj0A8ijT8SHRt7l7NJUQlrHSwomzrKNOfP/eyInQgGwHKwCAbT/5mkKdCulsC4zPmEKDGIWuSWd6nsP8CiKT2oMC8QvxA== 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=vA9JCtRJKMH27NZ9y1aI5FdaArw3LV1VCap5RMrbs156xcS0QmeSD8NJXv0IlZQLYxg+KoEPaDx0NldQOYEa9wwfunusdbR+pvKT7o1TPnWFoEZAXdZ6heZQCvuZeB3KHw+3W44RZLfGelYBafvUhRyyRz3VaMmA8RhBIjYGeX5z16jYMZM73W4cJHUFIMlnTdN6bcixpc2NsVLCSTV+PhRcZk5owRTTE+O+MLGcntlZGpSJSoV9N1OSIoFvu/9bNrK6Ui840d+HbrcO5JtNEurOZpS8+TwI2KUeY81txjON8dtZxdrgsAwjnHWdAHzNWP9k/umFW0sRXOmcNzub2g== 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=eGDc9LVzDgrsnSlGpQcOa3zpHJOoiQ7G3QZpJ7AuBd9cn+MRd5ZZcKkdvQKHyguvBCGcBHvnSBimox/ZHe2rwMqqUH+KhSWm6Ezr+U9ETQa19dtQZn6GVW9oKxtrPmpXYE+yCizRXvq7D7kB4Otc2UARuF3JgVLQCvqKnKvsZkAp8X8J66wlBQn1L4TNM51/LCjf19Cpl3xQ2pROKqM9J+65FVw612e6+odpiqwmbPlZwVFmKv5JtpJl7Q1MGQ2Ecw2wZPYik7FB7WrYuN76c0hQa8z9bDk35vxuF7zv8yaG35pFKsgpJAEqDKwYvO+NuvXi+uJu12fq0aXiIQj1QA== 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 6/7] qemu: Update Cgroup, namespace, and seclabel for qemu to access iommufd paths Date: Mon, 22 Sep 2025 18:15:59 -0700 Message-ID: <20250923011600.3229388-7-nathanc@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250923011600.3229388-1-nathanc@nvidia.com> References: <20250923011600.3229388-1-nathanc@nvidia.com> Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BY5PR20CA0016.namprd20.prod.outlook.com (2603:10b6:a03:1f4::29) To PH7PR12MB6834.namprd12.prod.outlook.com (2603:10b6:510:1b4::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH7PR12MB6834:EE_|IA1PR12MB6090:EE_ X-MS-Office365-Filtering-Correlation-Id: 5c48ef06-47fc-4276-c40c-08ddfa3ec9e1 X-MS-Exchange-SenderADCheck: 1 X-MS-Exchange-AntiSpam-Relay: 0 X-Microsoft-Antispam: BCL:0;ARA:13230040|366016|376014|1800799024; X-Microsoft-Antispam-Message-Info: =?us-ascii?Q?3p02clEe0hwb5JDSVpu6gR3t+Nzgr5sV4Eq8edviSLu9X38FWn/hKA/Q0rt1?= =?us-ascii?Q?unAT1SM40YzB6GZIDkosmeZL2oh3/Ab/67Eli0FUyBpkqfFZePanqLp94A0n?= =?us-ascii?Q?kZDKElHqF6crr6D9toRygxjxqWe0Q2zKtGbrDoU7QsJNf8b2ZDkBEAUQ9i7w?= =?us-ascii?Q?ZSa04aPiVuSGtG3Fy5H4IECyoxBtFTxV5c+g/aS8U425ePiRAfTNXEeB3Eqw?= =?us-ascii?Q?UP1fGn2Xm078DZPGuVQTghUWs6p+Ci+e+MSvY9vV0V+8bIdvP6Lt1pgdv3v/?= =?us-ascii?Q?NPreWx8jJ/lqbXXkC9zaqDBIdeeYiVPAJlJW21GPkVPNtAtYv+5ZZyh4L8/G?= =?us-ascii?Q?7U6/IzpdqtPg9GF1g7os/iTfIysqTW9K13fHqVw7E5/kOymdCsYfx+t5wKpj?= =?us-ascii?Q?GCMtnEYrPCr7Q2xLRxZDB2UvNImeFexQv8nzGzQpjVQ98OfdcOWTDeR1mMiA?= =?us-ascii?Q?8uyMeZxPa4qzWS8gH7oRano43xAdeuc/+/J2hqKNzJ0Fxfyfun4e+ftDo3dl?= =?us-ascii?Q?+qPo/NrD9kY5/ZbljL3czUP6KkThHyjTIYFCj92W5GnAgmOTQB/cX/pQ0EK+?= =?us-ascii?Q?JeIyuoiickzdSKCdemuvsLw+sHDs52uyrA+HNvdFSzP1HEVa1NX+NpA3fHm8?= =?us-ascii?Q?R7RiBDYQIGjiZG17SZca6jK4BBlsutfdxVBe3GtVvcXDeJI3NabuchhvprKX?= =?us-ascii?Q?NCajU7rmPufYnB36JOTRyFzPP6AekNdnnRPQZhkMNnwXGFok8jNfwPqWY7ij?= =?us-ascii?Q?haQx8+/yJUKJyqhERKaKJG5Hw6kBe5KGpjEGkgh7B6UjsEOPQhl65qDR3cjK?= =?us-ascii?Q?8Hxwuvqwje4SiFJyo1rLgrr/rCfrPQwX+DfErZcZEYjZyPT0dMpIQQxxh98V?= =?us-ascii?Q?RJlCHzZVXhku3MnrtBnFtEwZr8HBorj+UMc+wkZNekuxM0tGrDbq607TPLaW?= =?us-ascii?Q?AF69vcTkiFGVOrhbG3QoP1W4MbqQsUPStVFE6r0mBAHwbobTfm2ssrVvg9/r?= =?us-ascii?Q?3RyjV7n60wY1Dh/jmyzaLAzMGDtQnn9wyViNzFhNegW82G+wCX6FI4ynd/f7?= =?us-ascii?Q?GVrr4kTBv1wYYnenF8HiLfGr+ir4YKe6B4UxsDUJnCjCGSuUEjXcJFbqGVeH?= =?us-ascii?Q?+H3BK9NA33mphu1vVNvNC4c3af5dkxV2WuObcJgAzUJpCLEwlC6dcdlgLyrm?= =?us-ascii?Q?qnu6CTlJLZ1HQDgbDzi4XlGErDYcHPDcaqlYk3Fw+/kVS8eiVd7cpSOTenBA?= =?us-ascii?Q?b5sVcHUqxCUSGqiteqL5EqSSML4+DTrY96iYS7trqr1RzeD0eaJ6WH3pdIAE?= =?us-ascii?Q?nStXu4A0MC/TxoBN0KLJgA4J60wGUbWFvo3aThb/+19PTNLlmvswE4lCSUQi?= =?us-ascii?Q?CeduUs7KVjNLBH3dGTVETuB5K7XXRR89TuW44g58J6fFoNyFAcl6Ii3UslEc?= =?us-ascii?Q?ery6vP/RL4Y=3D?= 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)(366016)(376014)(1800799024);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?2FUN//Veo1KTfHTAxp1aW652oXoTbeMMbVpLhNg17bj0a87DQaMGXIivy2wy?= =?us-ascii?Q?Tbo6ydBhm040+R6QacDlJFYNNj6CYTrIHe4G6MDSBgP2IR/0ZiIFhf22dVkm?= =?us-ascii?Q?+mGt4wYa1xvXvkDUMSCfpilI1sAldJI2lWKqzRNB2tQJxl7aAwLGG5pUUFpW?= =?us-ascii?Q?6spCvGNgZ/9bHVa0fp+HxEyqKlNU+6E7sgVoarAh7GWvnAW3yfiPnYtbuJzQ?= =?us-ascii?Q?dJY1NsjpMZFpaQ/0kpBvdMKHoMiYiEqH0h8cJkxyaLxDh1jGdUKYSCtYgR9D?= =?us-ascii?Q?iPqPxfO19WHpPSz26y/FzYxQEl/+Lr3cXHYeNAcLCTunbK9yjjHFcFiLMM4u?= =?us-ascii?Q?XK35uMhvv8TXLdt1GxUz/CBChONIyiVbhPm1UWuzrftQIAPV2g/ejARI5WJg?= =?us-ascii?Q?NhxUoY6V0WG0lmk2taSd2y9IQW9ILTqIT9If2YdG8PWr9DhUPWoPNixtS6AU?= =?us-ascii?Q?9bWgdo+HON1rWifFGB0W8mGw9pOyJg4jIPTnR8CNj4bLZaOfDCUoi3vH89Kw?= =?us-ascii?Q?lOvDk33mVyPaIwLzxCc/tMqZshZ0Xa1N8WLO+f93JFw2A1ipQCf7o96yWJvz?= =?us-ascii?Q?bxiRSqFTlWm6hvt3KsM6NDfPr383u2yL09GSjhUXsGErUgWyyituodC4d7sZ?= =?us-ascii?Q?5t6BnX4zxLkU4VsgvKdeT17Hkgzz/3EZ9CwJl5akeq5vYA889kfzb/ewtZA5?= =?us-ascii?Q?KrF8bRMMIfX6zDa5qLv5WLn525ufm0V6nGjTWTka3AdMXPWMx8Y+cdC/fb9d?= =?us-ascii?Q?2kv7gl6B8S2RQsnM/X6fGUiMxUbL0eCwDvceGNGlVJmS+dKEeeSsm4yOQ8LW?= =?us-ascii?Q?/xo+hwkY5vjRIzVKwaF6GJ1P0Tg705FkxXkiH7bmtfuaBLHZAFsIGrqQLh8V?= =?us-ascii?Q?GRcaznf8xkN4zi+lOnGoBPvHd3G2wMorSkY9dkwdGVdY0JvmI08ybo9ZsQWK?= =?us-ascii?Q?5H/RRIdZNkAF5EGeJfH5PrXVhsExAV3nq5exwqPtLWO80ASrvRaYLg9hIIaR?= =?us-ascii?Q?SIsdsijRvMiyDa9qL0MB7oZEZBVdDkUOScN//hhDi73kln6XIEJgBExhrmkk?= =?us-ascii?Q?MlMAUYFF74qw3erjy4sZie0LcltESyiHeh2s3FItAFWEgCanbcWCA3zXvHf6?= =?us-ascii?Q?8oPq4Kmig0daBzYdkVydy7KrgWJEN9Le3lNRFpKpGNW0z0IqiezJ0TYmszqM?= =?us-ascii?Q?hVdMvYPp/QElk9oPzUeMhUUrS/C+lSeidlXp/rnerqGAsx6Xng4C2vXECRAT?= =?us-ascii?Q?Y4EfEFml2nD9VSKSI1g75WT/rc1CGes8nPqXClvAz3BFrUm8ZLHnm8Fx24nu?= =?us-ascii?Q?+/2MxNhD9V1fJv9BsMaam3SWft+yFY+ervw25+1rdT5070p4bgKVmJp8GuHU?= =?us-ascii?Q?4coCWOwDzXARYQZZT6vwbxV9VIDkygCcXRQJp/rECRov5KfhEXGoecx2XOBJ?= =?us-ascii?Q?p+KWQtYcjxsO/K2InJ3+5pKU81nzRpw/rgngnfdYbp7kVRLIwhl1rMKT2z/y?= =?us-ascii?Q?weDeBTQbVP+makrKhQIuOj3GFZDl7ugFqiNfk1zyU0x1mx5Gz1iC2cMjyqOO?= =?us-ascii?Q?nqk5nYIQfbsBdwaP5mWo21LOwhHMKAt3zexUkJm0?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 5c48ef06-47fc-4276-c40c-08ddfa3ec9e1 X-MS-Exchange-CrossTenant-AuthSource: PH7PR12MB6834.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 23 Sep 2025 01:16:13.9908 (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: B9DW9p7QMkmrAjEBFzCBQmxL3eOi/3g+NGffFKtkEvKZPsR4ScmBjX/SsQ7squr3KzJ06KpeVBb3oDj76fpqSg== X-MS-Exchange-Transport-CrossTenantHeadersStamped: IA1PR12MB6090 Message-ID-Hash: H3K22FGST3QFQ27NVQ5KX3VZR7JXDWC7 X-Message-ID-Hash: H3K22FGST3QFQ27NVQ5KX3VZR7JXDWC7 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: 1758591335405116600 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