From nobody Mon Sep 8 02:37:18 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 1755227005179129.03097699979367; Thu, 14 Aug 2025 20:03:25 -0700 (PDT) Received: by lists.libvirt.org (Postfix, from userid 996) id A4FF1980; Thu, 14 Aug 2025 23:03:24 -0400 (EDT) Received: from lists.libvirt.org (localhost [IPv6:::1]) by lists.libvirt.org (Postfix) with ESMTP id D8ADCC5F; Thu, 14 Aug 2025 22:55:46 -0400 (EDT) Received: by lists.libvirt.org (Postfix, from userid 996) id E73A1B92; Thu, 14 Aug 2025 22:55:42 -0400 (EDT) Received: from NAM11-BN8-obe.outbound.protection.outlook.com (mail-bn8nam11on2064.outbound.protection.outlook.com [40.107.236.64]) (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 776CAB26 for ; Thu, 14 Aug 2025 22:54:46 -0400 (EDT) Received: from PH7PR12MB6834.namprd12.prod.outlook.com (2603:10b6:510:1b4::18) by PH7PR12MB5685.namprd12.prod.outlook.com (2603:10b6:510:13c::22) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9031.15; Fri, 15 Aug 2025 02:54:42 +0000 Received: from PH7PR12MB6834.namprd12.prod.outlook.com ([fe80::f432:162b:b94e:d2cb]) by PH7PR12MB6834.namprd12.prod.outlook.com ([fe80::f432:162b:b94e:d2cb%4]) with mapi id 15.20.9009.017; Fri, 15 Aug 2025 02:54:42 +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=sTCdQ1te0rI6c031e86pLZHS27mtQjelly43Hgzs4yBrbG/LXFn2t207LomJVZRYmMEiNfe0rjsNV0i+Jw6T4ZVECiSux996Hzyxo5QuqocVe8VLrl6IlWfrh+31/afjEOT8LKIxiHUJcAMLeuGN2T8zf28RqoB4H4EZjZCooKjeR9xrZnRAtV0EpapjwuVQCwbFghE2NE6NphkmWbazUCJCMF8xi9rjiVD+MF21ISjv3YdBwBQ2KPB7kKDSiB9/sZQiiRaoezK7mBach+aI/naY5Ce4spc3lQGtixh/Z3VByVzRVXcyq8buyrV08joC7eioFuwwbwh11AAPaDkY4g== 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=OjABdEgSYDbdWboCInNRjGjHX4sOnmDNCN311GwFpA4=; b=vvJk3jdDaFFPh3IF2Jna1uw7F/STfmoV30cZ8ShsMHXZcas2gGvAJDANFLkBarcy1/NbblYiDc7Rj01iqZ8WAEj9qyGNhmOZpkaoqDHxVZTzWLf8Pli5z4VEjZR/g5IHfWunwtvFLm+yoFG7I3yuTjYsQiE2c3RG6NrbvjbqfUUlrfllmCqV5L/dDk4PR53OdfN8wGE+lbl8aUTd8J+Zn0zC0kBHPBlVIdYyz7wIbV9aFpcpxkbrAH2R/eRtsUgDp5YyrP/ShyItxsBt0ul5U96kzZgli1lcFOySef0QNcnPKgQWvH6hxqj1XqUSRgAs3dqTV+JzCXYV4IOWxb7xLg== 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=OjABdEgSYDbdWboCInNRjGjHX4sOnmDNCN311GwFpA4=; b=duwoITeVHKOiBiYfnrGL16saWkWMIcXEZAj2mj+7MxiZnhjXqB6hLKXyioqB/7gwity27RTDxSDKkccYUAzUnSDpKL1EF+gEJomqyzTRyK7erVLpjMToe3dskOk3jmnn6/9baDgrnpPFLlG3TutKtHNtb1HuD8PtmjBW3MtOFnJhH/7RuDk4tGTp7RaLpb6q1J+1AiyBszKwVWBN0WwLoPYBOLhLzDR8Bq33gceUmK/FgPu4J5HPyi+1SA4OvDD4u32L9TqzPimp7Al/PqKUouK6hlvR/EgbeiaouLfeY9kZoT8aisZhUgFIdmIqad5F65doQbKE4vOysRE4lDta9Q== 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 5/5] qemu: Update Cgroup, namespace, and seclabel for qemu to access iommufd paths Date: Thu, 14 Aug 2025 19:54:14 -0700 Message-ID: <20250815025415.2805374-6-nathanc@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20250815025415.2805374-1-nathanc@nvidia.com> References: <20250815025415.2805374-1-nathanc@nvidia.com> X-ClientProxiedBy: BYAPR05CA0087.namprd05.prod.outlook.com (2603:10b6:a03:e0::28) To PH7PR12MB6834.namprd12.prod.outlook.com (2603:10b6:510:1b4::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: PH7PR12MB6834:EE_|PH7PR12MB5685:EE_ X-MS-Office365-Filtering-Correlation-Id: 7c1c5fc0-36b9-4c0b-f28c-08dddba7154e 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?u4D2T40bQG2m715MSzahniOkxAh07mUpSy1DUDwnvL6CGJRmg5vMA0JgdiZu?= =?us-ascii?Q?DO25rn7qwPFkdxM/aqC37B3wPL1apNQLyEGQojOhSFNdCEy81ReutvEf+8GN?= =?us-ascii?Q?ZDz/D4KeJSlXY2IgkEeavnhzFDXxVWuOTK26nfL54pLVu/FBGdGhl/BA0INI?= =?us-ascii?Q?zJc8z+KCcno/U1ARF332+Exx+LMFaE1a8mIkqAMsERl/ZtwOku1oEw9RNF3z?= =?us-ascii?Q?Y+/ezNUGIs8VYxypEOzOfYVOggF5bAWYAxTuc5bHAGCptg+EQgUKScTxnnPP?= =?us-ascii?Q?5bncwhJmM7cdZEMdF836K0F9XmI0xjcoZpY0psleHpwAiMPCacqd/XEoB9FV?= =?us-ascii?Q?aJVhuokltPNjBdgadB+wfD50tx8AXrDf2ZauXp+zXzrSbKgb+U022QGz2ch4?= =?us-ascii?Q?/tWCq1f5aApFccucMwgeqq+5e2ZK+qJfS+RVmVQRfIevZNK6F/b16I92ECnL?= =?us-ascii?Q?IL9Pqv+NOR50HoQUPo5TrOY5+BPeQ6nVc/g/dtQCiUdBhi9ZJt1Te4KMGq02?= =?us-ascii?Q?+ShQ8OqhHH+rQQhJ1U3P8GApCV1q/mOOOeQ4e3oELHJP65Qa3d7vcyfuws14?= =?us-ascii?Q?/Pf+bf9mKe8Go3uTO5GcrZvocSVkci3rkviJdR5H+hbFtrHeGyUkIltvZGDe?= =?us-ascii?Q?FWxImGDsz4oUoU6GRFn+iwLQu+MOihBshifj0BKJKHhPeut2VgJvhQ736xq6?= =?us-ascii?Q?lJE+G6SNujI5SRWbgf9fD9X/RqMge6DFa9C3bHz8v4CNi3dJYrCOUwfS5F4Q?= =?us-ascii?Q?QqJ6nBed/OvFmNppj3Huf5QpA1hJMZrLL/0IrroBm4WP6FQTwkf93mhIN3pS?= =?us-ascii?Q?oYNVuErpwGyTz71fGsrwxj+7zUAD9V3xDEbgP2uNjM6SBn7sxlOxcTubrk1r?= =?us-ascii?Q?swkljNIpSS5CLtDD9osqOUiXy+NkDUIV0lxGuDANIab8hYrmkKdKWDGL6mCc?= =?us-ascii?Q?LdHNI/cxWnWy/loTAcov0R+VWbqLvYFmhhQVORKcH95Q0HDxvL64Zw6gvhYP?= =?us-ascii?Q?CtosTFxEW2wLEg9tRMC4dqNEenhvkgrTy/AEnOrhuSm65qWV8J18HWou+V36?= =?us-ascii?Q?SX5uPlGIHDCmKTx97HLDZIyUBzNOd2lfUrxkq7/+QU/cc4VM2G/132j01W4r?= =?us-ascii?Q?IoWEo1Mv+DNQsGVYIdQcgO3T8ihnWx8/DVdFQmvuKIMoTS1sSdVd0/F3yCNr?= =?us-ascii?Q?ivo9CJtFRPIN4UgUxSf5ffpC2/8T7mLxEJWBHXcGJEcRcseuTVePdhtILmUH?= =?us-ascii?Q?CHIP444MVWM9uGAQMymZiNBYV4MNY7g+OpZBdKJQH8403CHvSembh2zTsGDl?= =?us-ascii?Q?sT/BfOwd3rsYZjlqWCAAM/Ci2HbSKWeuIje4AV7aMbBOla8QMVKpyAmGajbB?= =?us-ascii?Q?RcZOWAMqYJSBV7oBrwK9FYOTohnskl0wk3Dd92S4tMl7rX16kQ=3D=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)(1800799024)(366016)(376014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?us-ascii?Q?QZqTIJR6v8p+v7R8tfDQy4sbTb1wsqpTwkl8Nco62AKgtxBUtVuTcxxpOkue?= =?us-ascii?Q?LHYS1LlyOhznWMtGEO1WYBgKLtm4rCwIMmY/yFiILu/mU4ixs2fRdPtEX0Pz?= =?us-ascii?Q?9pJnUfWIyvDHRPEc/DHSphNcwm4A2dNbpTzcmG+bPjaUzWoBj2vIbgPM2yAu?= =?us-ascii?Q?ziRqpQjs8j+VZCUTVdBxJEkC+Hu1G7/g1mOv36GRda2V8wPATWL3velpCPJC?= =?us-ascii?Q?Ka37iKCdNL1btN5CKYgX66kUOqTisysrpCHhZoVMG0b64UrdB3WJ2lVVpI2F?= =?us-ascii?Q?M+YK3FApjquYd6JuiPrHMM25kG5NcBZfct6Co9U8pf9M+sKjfkmbo3qacaGX?= =?us-ascii?Q?vi5pqPS0SXtNRQU7MM1V5ZI3NgjoO+6dsjyJIz+6PdRyIbIHfdtKa4yvcLOX?= =?us-ascii?Q?ZUTNJQxz+SPBeNN9PMtAoN6ptzP66pOW6rxOsGrlbZHnmSd5QsaBY48RYG8b?= =?us-ascii?Q?yBNEazvm+2a0UTjM2M8R8SfxhVvuh+pqjrZPZs9P+cHNRryYAIEOr+A5++1T?= =?us-ascii?Q?3vjXVjjp3DbpnNzMJeqaixYIyRLwi8fE+rrOf0P6CSK6qYEyYjDcyTS2FISp?= =?us-ascii?Q?yiYZvE1Tke27WXbzJs9r0iyzWKXKg38LjEL6teMYKTy/SyZHc5A8h3rx9uR+?= =?us-ascii?Q?ccthBVIOOAS0ePAluHR7dskHUGaOUWQfmqCsheA22+vUYjS4qgNw5+aD4vbK?= =?us-ascii?Q?QVQptDMWhP0D06pQg52tmDATU6ioLIuFiDPEFKIvX+kBuCbdOr51eeyJCf4h?= =?us-ascii?Q?ynVASKZ5P/fVi7m8F3UeloWtLIBvFW2/t3ZqLMFVmZeXwpWwIdrVimLqiSFc?= =?us-ascii?Q?LNlM6S5Bf54AloQMIExzt7X5oY08q80kQkUdXEDlqPrOCeOlJqcoqpf/Rc9J?= =?us-ascii?Q?0BeGux0Y1JCioDTy/uOPWDePoy+medlMIoPgGhNpLktONutwgOAt4n7o/M6N?= =?us-ascii?Q?289yo3+aeIrLqjnPmEEUYtvsyr+3YqC+3aVAAwVR1eufbjaoWY2RqQy9xoZH?= =?us-ascii?Q?8u+tUFaPShh9T44F1NAwqwD/JRnhpoejUE/Az/hLTIKZEHq2JVRJdPOmTmt0?= =?us-ascii?Q?61/IId+/qrJ1oKczBoZjtqbMFlhhSrCCyEb4M26jz73G9BXz9HQEp7hleus8?= =?us-ascii?Q?YEu9rcqEj2QXJ+kD7g5ItvDbbh+iRXa7AjGX0W/lRcTp/pLh0ixlyHUA5sgS?= =?us-ascii?Q?mQBlS3xFoc6fdaGV/54+HA/deg1bI0wJqjl+ux12WejJlrzYfPo7jm31Icay?= =?us-ascii?Q?Q/hvKGumY9x9B1nui1f9EWqABmTXkrNanrunEKiRUYDzce3jnvlqX0imZpGT?= =?us-ascii?Q?hCfpalQn6e5ocmxSbZ7VaOFeW5WJAgZJx8PgKXwfMRPIJF3yu8v2FurWzHGC?= =?us-ascii?Q?3JubzfVFnOea5GlQIBM1vMOMfJwW/9yltXyFz1oks/RPvJZRORE1iX31raXC?= =?us-ascii?Q?UbJPeikmgPGCwHlFegP/ynDbriC5G5LCszRvYpGj3rll6wZkolsKlUyo0Y8O?= =?us-ascii?Q?WKUyLFHQ7Wt1fb2IVtJ0psgwrGzQ9RXGXMc2M+EP7yuLfyyn2cNf3ORZRcB3?= =?us-ascii?Q?cN/HK83eSj+q52QW51sYDjFWme5NeTlBlxeD5/EV?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 7c1c5fc0-36b9-4c0b-f28c-08dddba7154e X-MS-Exchange-CrossTenant-AuthSource: PH7PR12MB6834.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 15 Aug 2025 02:54:42.1146 (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: IEfMKfN1oanX/6LqL/3kdGlb2tinuRdVzoadwG72WEsyW8nl0/Dn+IwzWMAl4+Rr+szhoOLF4HPl7lqAUIe4LQ== X-MS-Exchange-Transport-CrossTenantHeadersStamped: PH7PR12MB5685 Content-Transfer-Encoding: quoted-printable Message-ID-Hash: O4AVJXJTT254ZXAMUHPYUZLT2BANRSV5 X-Message-ID-Hash: O4AVJXJTT254ZXAMUHPYUZLT2BANRSV5 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, nathanc@nvidia.com 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: 1755227011022124100 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 | 11 ++++++ src/security/security_dac.c | 23 +++++++++++ src/security/security_selinux.c | 24 +++++++++++ src/util/virpci.c | 68 ++++++++++++++++++++++++++++++++ src/util/virpci.h | 1 + 8 files changed, 233 insertions(+) diff --git a/src/qemu/qemu_cgroup.c b/src/qemu/qemu_cgroup.c index f10976c2b0..73d0cb3a7a 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]->iommufdId) { + 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]->iommufdId) { + 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..965a304f7f 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]->iommufdId) { + 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..73dc750c94 100644 --- a/src/security/security_apparmor.c +++ b/src/security/security_apparmor.c @@ -856,6 +856,17 @@ AppArmorSetSecurityHostdevLabel(virSecurityManager *mg= r, } ret =3D AppArmorSetSecurityPCILabel(pci, vfioGroupDev, ptr); VIR_FREE(vfioGroupDev); + + if (dev->iommufdId) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + if (vfiofdDev) { + int ret2 =3D AppArmorSetSecurityPCILabel(pci, vfiofdDe= v, 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..327e36466d 100644 --- a/src/security/security_dac.c +++ b/src/security/security_dac.c @@ -1290,6 +1290,18 @@ virSecurityDACSetHostdevLabel(virSecurityManager *mg= r, ret =3D virSecurityDACSetHostdevLabelHelper(vfioGroupDev, false, &cbdata); + if (dev->iommufdId) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + if (vfiofdDev) { + int ret2 =3D virSecurityDACSetHostdevLabelHelper(vfiof= dDev, + false, + &cbdata= ); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } } else { ret =3D virPCIDeviceFileIterate(pci, virSecurityDACSetPCILabel, @@ -1450,6 +1462,17 @@ virSecurityDACRestoreHostdevLabel(virSecurityManager= *mgr, =20 ret =3D virSecurityDACRestoreFileLabelInternal(mgr, NULL, vfioGroupDev, fal= se); + if (dev->iommufdId) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + if (vfiofdDev) { + int ret2 =3D virSecurityDACRestoreFileLabelInternal(mg= r, NULL, + vfio= fdDev, 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..60dcadd839 100644 --- a/src/security/security_selinux.c +++ b/src/security/security_selinux.c @@ -2248,6 +2248,19 @@ virSecuritySELinuxSetHostdevSubsysLabel(virSecurityM= anager *mgr, ret =3D virSecuritySELinuxSetHostdevLabelHelper(vfioGroupDev, false, &data); + if (dev->iommufdId) { + g_autofree char *vfiofdDev =3D virPCIDeviceGetIOMMUFDDev(p= ci); + if (vfiofdDev) { + int ret2 =3D virSecuritySELinuxSetHostdevLabelHelper(v= fiofdDev, + fal= se, + &da= ta); + if (ret2 < 0) + ret =3D ret2; + } else { + return -1; + } + } + } else { ret =3D virPCIDeviceFileIterate(pci, virSecuritySELinuxSetPCIL= abel, &data); } @@ -2481,6 +2494,17 @@ virSecuritySELinuxRestoreHostdevSubsysLabel(virSecur= ityManager *mgr, return -1; =20 ret =3D virSecuritySELinuxRestoreFileLabel(mgr, vfioGroupDev, = false); + + if (dev->iommufdId) { + 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