From nobody Fri Jan 9 08:53:56 2026 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; 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 1766111216638486.05496885598416; Thu, 18 Dec 2025 18:26:56 -0800 (PST) Received: by lists.libvirt.org (Postfix, from userid 993) id CDC244195C; Thu, 18 Dec 2025 21:26:54 -0500 (EST) Received: from [172.19.199.83] (lists.libvirt.org [8.43.85.245]) by lists.libvirt.org (Postfix) with ESMTP id 3A2A941ABC; Thu, 18 Dec 2025 21:20:00 -0500 (EST) Received: by lists.libvirt.org (Postfix, from userid 993) id 28867419A5; Thu, 18 Dec 2025 21:19:41 -0500 (EST) Received: from CH1PR05CU001.outbound.protection.outlook.com (mail-northcentralusazon11010067.outbound.protection.outlook.com [52.101.193.67]) (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 A7A474184D for ; Thu, 18 Dec 2025 21:19:35 -0500 (EST) Received: from SN7PR12MB6838.namprd12.prod.outlook.com (2603:10b6:806:266::18) by CH1PPFC908D89D1.namprd12.prod.outlook.com (2603:10b6:61f:fc00::623) with Microsoft SMTP Server (version=TLS1_2, cipher=TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384) id 15.20.9434.8; Fri, 19 Dec 2025 02:19:30 +0000 Received: from SN7PR12MB6838.namprd12.prod.outlook.com ([fe80::69ae:2df4:372b:6fbc]) by SN7PR12MB6838.namprd12.prod.outlook.com ([fe80::69ae:2df4:372b:6fbc%7]) with mapi id 15.20.9434.001; Fri, 19 Dec 2025 02:19:30 +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=rdcP7s9huVQEq8dpV82Kg1iXJXxs6e84O+bgbv3VJw6a6eQKzrKQQPhsB4NAx5jOVTtZOD2c77sxyQeUlQQuGInfj8JkaXraj1I6kNRDQ13FNh4+AiPlTJ0OiZweIrmbBMthpns/3eOCRAeUJAZku1V/qqZ3fRbZjukCApK5nQIsHtfq801gto2xPnBmvBpZGzbW9ZdYI5piuz3+NXAm0Ob0Fj93Yz3Z4pgqRUMZRspcsv5QgZKp+8fulBwPiy6dmsqWL4up0FvNDKUVL5sh4jIPgOZBwQ92zaVv6CVeO4eESUVP2nZt6K8ut4V+rbYJA5l6NnyIMzzT95zGZjQKyA== 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=kcbJgO+UTRtwzKp84gqqA/6UzdZm0uI8P6XuoWWvwMg=; b=sPdb8YCnw7czevbOue3M2ai/iZMB1gA4QRoNK6u9DdX4SKarL3SmLzzBiTX12/C/qILI50FOv99rWU0FhENTQu9b4iREfgHlOasfjesi/pLA65CHz2PYmpC/UIkE/W+zUlg7qKjehdZ+KpQZHgRJDDJmBzEQRLbagF2skLMayO+Bytshy+IKgbYvhv04MUq3r3YZdcBJ//nguqIvZcKGY9OT1lSJFATzFl6izofdnNWWN/i2GFQRkcmKnflg6p8ZudUfL9lMOPDtGDBhJuiB9/ByeBOlcSo+BjqyP6avH04SsBety7IMC/35oWE/sPdL/2nDS9Vp+hs3trcsqxbgIw== 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=kcbJgO+UTRtwzKp84gqqA/6UzdZm0uI8P6XuoWWvwMg=; b=YEIe0RCIPFl6QrVNGt8u8Et+r7FklDR4Og26NG1NHfjxKBuWNcXONXRH1u7VOk5fdwT2VbXd1/9MGA9bicisyqtzqnjwPWN7mz82YEfstEDY0xQziGtUk4hL2wu0gt7CmorCmmb3T5Ap8nkJK/MWzMqxRDnxkCWu0HE71SKp7WqEO1CASjnTc2BoAhbkVEP78L9priYzmdqDo7rOAyni+jfp2FSOMfDe1KJnHe6L6srvJWKHaLcOuB9cnaf3h5N4NWnO9dS06pbb3XM9jL6MuA3kKFrtlQmqm58T6Xf8yeRVl9gc0gIGCEJpLVeI1U1zjJRxIpsWJ1e16rsy5Lz1XA== 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 v3 3/7] qemu: open VFIO FDs from libvirt backend Date: Thu, 18 Dec 2025 18:19:21 -0800 Message-ID: <20251219021925.1864433-4-nathanc@nvidia.com> X-Mailer: git-send-email 2.43.0 In-Reply-To: <20251219021925.1864433-1-nathanc@nvidia.com> References: <20251219021925.1864433-1-nathanc@nvidia.com> Content-Type: text/plain; charset="utf-8" Content-Transfer-Encoding: quoted-printable X-ClientProxiedBy: BY3PR03CA0019.namprd03.prod.outlook.com (2603:10b6:a03:39a::24) To SN7PR12MB6838.namprd12.prod.outlook.com (2603:10b6:806:266::18) MIME-Version: 1.0 X-MS-PublicTrafficType: Email X-MS-TrafficTypeDiagnostic: SN7PR12MB6838:EE_|CH1PPFC908D89D1:EE_ X-MS-Office365-Filtering-Correlation-Id: 278b1b4d-d5ee-461f-95fe-08de3ea50a84 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: =?utf-8?B?R2Q1V3k0akxnblMrV1JtZE5Fek9ERFVxQkZveGVJQy8zVXl3eW1tdEtURTll?= =?utf-8?B?UFl3UXN4NFpjcmxPYkkxSnZqNDRGVFdoKzl5cmx4WFlBcHpBWENyY0RoVThP?= =?utf-8?B?NUEzVTdqQWVBaUE0NktzaVI3b2FUZlBQRWJsY0lGV04rSXc4ZjdnbG1qUjcv?= =?utf-8?B?VmlnVnV3UDRNRmVGaGs5aDJ5QTZhOHlvcDMxNXV5SmlWdWpGNUJPaEZ0SlFu?= =?utf-8?B?ZnZhWlRyTEp2a1pyTnk3eURqaW9reWxWVVN2SlZXb0VtM21XVjllTVBEcGZq?= =?utf-8?B?bFNnM2Q5U2lvTGtIUU5OVGlONFZhazk5YjdRNDlYNUgzWFhqVkJndEhjeW5p?= =?utf-8?B?QU1aNnA5ekRLei9Dc05oWko2NUdsZkxPcEtPTUVweXQ2OEUyRGdiZmE0TjYr?= =?utf-8?B?SFhVWXBSSFpVbTlQYTFUamdqVjhMQjl5dEptTXk5UW9UYlk4QzJ1RkhwcnBn?= =?utf-8?B?OFRPOWg3TC9Ja2tOVjN3bVhGcFN2MjM2S0c4bkVFRDZpa0MwTFk1NlNGazRT?= =?utf-8?B?d1ZDQU9iS053T2NLazkxdEF1aU4wamloQzdlbG1iSEQ5S0JCcTQvMk9JL0lK?= =?utf-8?B?MHJUeEtBcENKUUF3QzdMRkI5bWtpM2IwNjJzaWE0MHRVWHJVQnBKNytjM3k4?= =?utf-8?B?bGt2RTRFR0FlQ0syT2o4NkVRME1HakVJWVVrNjN2MlFRbitkTmlUTFRXVHZm?= =?utf-8?B?QlVnU0I0S0dWZFh0d1Y1TnJDNnYxS2Z4dFRwWkRibTdWR1QwQUFtKzVVRzZa?= =?utf-8?B?dWwzU1IvV0dIYm5OU3Z3b2VvTnhtc2hjL0RSR0pjV01KS3hRaUhYQ2ExMEtE?= =?utf-8?B?bXZReGE4c2lLSHBSQWU4SHIwMHdkSHEzWHVQc3Iydm9pejZaRkNIZzhneUlB?= =?utf-8?B?S1RNOTZKSThWb2U0MWpnNmdVWGNKQS9GcWQ1MDJocGhBMmNBV1VGcHJXUEgz?= =?utf-8?B?MTFYVE1haHgzb3VVY1hGQ0pFR3VoU0t2UlRxTFFUNzE0SzNSendCaS9FWlpH?= =?utf-8?B?ei8vRGZFdVRaY2xoeU95emMrYnczSmFzWnI4U0JXbG1lWE1NUkZpM1Jjd0ZD?= =?utf-8?B?NWZIYWZiVitjQ2JzSGovclhYd2UrcElhSVpESTVlRE5pbVd1citvWjdSWUdz?= =?utf-8?B?UUVLZ3F6L3JLYkVaR2RoOFJObzc1dzNTSnVVOGxMMFZUYkFHa1IzUDF0MXds?= =?utf-8?B?SmFFYmNDMUdnQmJEWS9NUk9LWVF6bU1DNHMzbUFpazZsSDV4bXpxRDNxdmVV?= =?utf-8?B?N21xWXdCTEgyYVFTZEwxZEVyR2V5cmRBSFpZRVEyQW85TDJZVXplMS9kU01E?= =?utf-8?B?Y0tZSXlLQ2RjTWVMZVpxbEtEQTRjZ0d0WFY2NTVMOFVYcDJtSHo5aXYvTE0r?= =?utf-8?B?VEJzZFZISEJyanFJT0RNVmNaUjB2V291S2VQdnhOMmJRQTFvSTVuYURhNUpK?= =?utf-8?B?KzhJNXhVS3dDbnhDQ2NwQ2RUQ0FsZWxGNEFsY2N1Y0NrbDBid0t0bkxPc21p?= =?utf-8?B?OHd0OGc3VUNwUWpIM29OVEpXYmFiRWVwLzFFYStsYkxhRTdvMm5tWEpOMGRX?= =?utf-8?B?RzkzSXVTeFBSMzFoVllWRW01cnZENG1oa29CdUVnZjJmNnZwaG9rUmErMlJS?= =?utf-8?B?V1pGWktUWmt5Y0t5ajlDaVg0ZmxlOWZaSGhCYnZuZ2krb1J1cmRWV0xKOVZK?= =?utf-8?B?aVNiVSt5OWlGMUxMWFFYMlRMV0xRU3pHaHd0M1pjVmUwQlRMaEcxNEwxU1ZM?= =?utf-8?B?MktJWTY0VzBFV294ajRwZkZpaCtVdXdLc21qODdCclhtY2VqRjVrV3ZhMGly?= =?utf-8?B?Y0o2OElGMi9sZi9oODA0d0VCTytURHZ4TGw1T3E3QzdtUWRxYWF2WFBRVXhp?= =?utf-8?B?ODN2bVo3OWdHbUFRTDRlK2VrM2ptdFloRmEzZ1o4a2ZyUVRLSDY0cWJ5NG5K?= =?utf-8?Q?0p0QVoraRlshqv8mx5y2zYgJIIqCHHBR?= 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)(1800799024)(366016)(376014);DIR:OUT;SFP:1101; X-MS-Exchange-AntiSpam-MessageData-ChunkCount: 1 X-MS-Exchange-AntiSpam-MessageData-0: =?utf-8?B?aWxXeFBFOFRoV2pqMTF5UjZjYXRQMmJXeWRjNFNOb1dkVFdNcVdpMTZ2dzBE?= =?utf-8?B?eXczKzZ6VnpySE85UGdrU3hYWXE3TjBWKzQ4RlpVMGUxK0dzU1J2U0puNmVB?= =?utf-8?B?dDNBSHpma0RFNy81aFBLZi9EM3MyS3BCOFlYUzRuN3cyb2lSZ2U2Z2ZtT3dT?= =?utf-8?B?TlVNS3FQZi82elVaSTNOMUg5Sk82ZkZ6R2VoZ1BXZDU1TUU1OHZyUWVjUFdL?= =?utf-8?B?N0EvVkJteFFuUmVtUld0OU1JN2Rkblc1Y01tK3dXcXZlNWQxSVh1ZU4xdEdE?= =?utf-8?B?ZitNdkhXOW8wZ05ScVJwZXBuZkRnUjkycHpmYUgwWWxBRU5lK3p2aWM5RWM4?= =?utf-8?B?Q013MkgwS0RJK2oxRks5U0pDa25uaVladVN2YTBKT2dRSCtuSlV2L3lFU3Jj?= =?utf-8?B?S1RjdUdnVnltdUtHdko4MW5LdTFxZ2lWYWZVV3kvQ0hqNHJQbmpvYmMrbXJ4?= =?utf-8?B?RHZsZ01BanVOaFJUMmw3VTZyVXh5Wk5Gb1lBUTUzWURWTUw4Njc2SElYNjhn?= =?utf-8?B?cnNKSDgzQXoyNWNDZnlqSDFnSmlncVlFRTZsaW9FeHpibFMva2lUQkJNVFZR?= =?utf-8?B?TWl2L1NmaVNLOEI0TkdwMzBuUS9BRHlFam9xc25iTzlZUjBjWFp0UTk3RCs0?= =?utf-8?B?UmpjbmQzR0xkYTIvNWJxc05hTVlDMjVRVTFxNU9sbHljbFBQbDUxY2grb25V?= =?utf-8?B?MzBFUUtZMStZMjdKejUzcTFiQTJ0eUd2dzNoVmtPeW1NRElIUkJTaDRpK3BR?= =?utf-8?B?TWZJT1g5VDVoTVlOTTF6ZVZpNDZnNmp2eEhWWmtNbWtuMG9Fam5uV3JhWGhS?= =?utf-8?B?ejdCWm9iUW1WNkQxSTVienE1ZXFzeWtKY09zMGNLdDdVcE1JOCtmYnFncURl?= =?utf-8?B?S0QrUGNmYnd0VFZNSXF5VTBxbVVYeWY1c0lUV240ek5uK2FZRzdmaVYveEl4?= =?utf-8?B?WUZHeWc4ZVJxVnk3d1VSZGdXaXpUbXJOalN2c1JJUDZPZkxRNjMvQ2gvcGJ6?= =?utf-8?B?bjVUSks5MmNERjQxSkp1MHZZTVhRNkdxbGFDYXJLU25aREZLUXFqRllJL2pJ?= =?utf-8?B?dDVlQk5ZL2pIWkRCN3lFUHFJTWNYdnEwb1pFTjRFMEMrSEZ2OTQwZ2RTZW1J?= =?utf-8?B?VTNxQUNYcExsZDZlbGNib2Q2cVNmQnRDY0RXVjJ0SDRqZTc3dHVpNzIzUlZM?= =?utf-8?B?SlRSbHZFRHFyNjlST0VxSVVBeG5sb21hdGFXR1Z1UkVUUXZocmJXbWc1UXQy?= =?utf-8?B?SGh5YWVaMUx2QXhNL3NZR3RsRythaGZ3bEwxWHFUTmlHMmJrcmR2UnEycnAy?= =?utf-8?B?UzQ4dHVsY0hWby9vT2ZNY0EzdWpCT1VFajhGMEVvdXdlYWpkdXFhRTFQWmpx?= =?utf-8?B?OWhHbnE1RlhBWjFka1I4cE52ZFdvWFN0VUFJUTd5V0IrVTd4WUZ4UUplbmFM?= =?utf-8?B?M1lwQ2NlUkUyazg1cU4vOGtpeDNTc2hXV0ZWRiticXlHUXd1anpyT0VuM0NL?= =?utf-8?B?QkpKcU5ydHprWXB1a2E5RmgyeGtmeWdqV0lUeFZ6amtPV244Q1BxcitMRTZF?= =?utf-8?B?ZWhUOFVuTDErWGZaNVFsRUZ2WHE1VFpXaVJPUWU4RTcvR2F2Tjg5emhJc1py?= =?utf-8?B?a1RqQlNnd3NqOU5UMGw1WFRzYTJiMlpzTDJnQU1ZTFB5U1NITDg4ckZVS09Y?= =?utf-8?B?aDR4cCsvbXlNTkc5UXp1RW9LVWNPTlA5R0p4MUcza2NUWHBhYXNxbTV1Yysw?= =?utf-8?B?UWlzeUMxcHhEWjc1TjZvUmFQdGszbVZhczg1NjFlMEFsbzAxbmp1K1AyRVFN?= =?utf-8?B?a1BWWUpIN0lEQnRjRXNPdFNFQzBNaDVLN3hheklhOW9NZEZOdDROQkRxRjUw?= =?utf-8?B?N0JiYVFhKzVaOWMzVGdvd2NUclROYTBLMlBQV3REMVJiR0E2NUpVaThsSmxw?= =?utf-8?B?V3Q0amRUdFdURjQ3R0M0c09vbjdCQUY4SUYyMFhTWDNCU09RWC9JOU9JV3Vr?= =?utf-8?B?cXNSZ3pUaTd5Nm4xZEhpamlYS3pkSCtNMnNnYTA4aFdXUmk1ZXZTb3VTRzU1?= =?utf-8?B?c2xhWW9FbW1iV2VMRmZZcUZDcFRKRWxMSkpWVTBXU3VQMW00Mjl3TFl6eXVp?= =?utf-8?Q?Qgwylu/xT99kJnRH7QP5LTyTR?= X-OriginatorOrg: Nvidia.com X-MS-Exchange-CrossTenant-Network-Message-Id: 278b1b4d-d5ee-461f-95fe-08de3ea50a84 X-MS-Exchange-CrossTenant-AuthSource: SN7PR12MB6838.namprd12.prod.outlook.com X-MS-Exchange-CrossTenant-AuthAs: Internal X-MS-Exchange-CrossTenant-OriginalArrivalTime: 19 Dec 2025 02:19:30.1202 (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: O02PClAfYn3IIholoKfrQOSB7VewIs6X7FsNC7d3rkAvNiTOfMc1NIA0vzq40VdhE6rivpvvSfK07yceiJ8B/Q== X-MS-Exchange-Transport-CrossTenantHeadersStamped: CH1PPFC908D89D1 Message-ID-Hash: NTEUSDOT4UBKB2YSIY43WLSKUV2OKVAZ X-Message-ID-Hash: NTEUSDOT4UBKB2YSIY43WLSKUV2OKVAZ 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: 1766111217581158500 From: Nathan Chen Open VFIO FDs from libvirt backend without exposing these FDs to XML users, i.e. one per iommufd hostdev for /dev/vfio/devices/vfioX, and pass the FD to qemu command line. Suggested-by: J=C3=A1n Tomko Signed-off-by: Nathan Chen --- src/libvirt_private.syms | 1 + src/qemu/qemu_command.c | 21 +++++++++++ src/qemu/qemu_process.c | 79 ++++++++++++++++++++++++++++++++++++++++ src/util/virpci.c | 69 +++++++++++++++++++++++++++++++++++ src/util/virpci.h | 2 + 5 files changed, 172 insertions(+) diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 4e57e4a8f6..ed2b0d381e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -3159,6 +3159,7 @@ virPCIDeviceGetStubDriverName; virPCIDeviceGetStubDriverType; virPCIDeviceGetUnbindFromStub; virPCIDeviceGetUsedBy; +virPCIDeviceGetVfioPath; virPCIDeviceGetVPD; virPCIDeviceHasPCIExpressLink; virPCIDeviceIsAssignable; diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c index 98e4469c25..2a16f9df63 100644 --- a/src/qemu/qemu_command.c +++ b/src/qemu/qemu_command.c @@ -4809,6 +4809,18 @@ qemuBuildPCIHostdevDevProps(const virDomainDef *def, NULL) < 0) return NULL; =20 + if (pcisrc->driver.name =3D=3D VIR_DEVICE_HOSTDEV_PCI_DRIVER_NAME_VFIO= && + pcisrc->driver.iommufd =3D=3D VIR_TRISTATE_BOOL_YES) { + qemuDomainHostdevPrivate *hostdevPriv =3D QEMU_DOMAIN_HOSTDEV_PRIV= ATE(dev); + + if (hostdevPriv->vfioDeviceFd !=3D -1) { + g_autofree char *fdstr =3D g_strdup_printf("%d", hostdevPriv->= vfioDeviceFd); + if (virJSONValueObjectAdd(&props, "S:fd", fdstr, NULL) < 0) + return NULL; + hostdevPriv->vfioDeviceFd =3D -1; + } + } + if (qemuBuildDeviceAddressProps(props, def, dev->info) < 0) return NULL; =20 @@ -5253,6 +5265,15 @@ qemuBuildHostdevCommandLine(virCommand *cmd, if (qemuCommandAddExtDevice(cmd, hostdev->info, def, qemuCaps)= < 0) return -1; =20 + if (subsys->u.pci.driver.iommufd =3D=3D VIR_TRISTATE_BOOL_YES)= { + qemuDomainHostdevPrivate *hostdevPriv =3D QEMU_DOMAIN_HOST= DEV_PRIVATE(hostdev); + + if (hostdevPriv->vfioDeviceFd !=3D -1) { + virCommandPassFD(cmd, hostdevPriv->vfioDeviceFd, + VIR_COMMAND_PASS_FD_CLOSE_PARENT); + } + } + if (!(devprops =3D qemuBuildPCIHostdevDevProps(def, hostdev))) return -1; =20 diff --git a/src/qemu/qemu_process.c b/src/qemu/qemu_process.c index 0e50cd1ccc..ab88a6bf62 100644 --- a/src/qemu/qemu_process.c +++ b/src/qemu/qemu_process.c @@ -103,6 +103,7 @@ #include "storage_source.h" #include "backup_conf.h" #include "storage_file_probe.h" +#include "virpci.h" =20 #include "logging/log_manager.h" #include "logging/log_protocol.h" @@ -8181,6 +8182,9 @@ qemuProcessLaunch(virConnectPtr conn, if (qemuExtDevicesStart(driver, vm, incomingMigrationExtDevices) < 0) goto cleanup; =20 + if (qemuProcessOpenVfioFds(vm) < 0) + goto cleanup; + if (!(cmd =3D qemuBuildCommandLine(vm, incoming ? "defer" : NULL, vmop, @@ -10360,3 +10364,78 @@ qemuProcessHandleNbdkitExit(qemuNbdkitProcess *nbd= kit, qemuProcessEventSubmit(vm, QEMU_PROCESS_EVENT_NBDKIT_EXITED, 0, 0, nbd= kit); virObjectUnlock(vm); } + +/** + * qemuProcessOpenVfioDeviceFd: + * @hostdev: host device definition + * @vfioFd: returned file descriptor + * + * Opens the VFIO device file descriptor for a hostdev. + * + * Returns: FD on success, -1 on failure + */ +static int +qemuProcessOpenVfioDeviceFd(virDomainHostdevDef *hostdev) +{ + g_autofree char *vfioPath =3D NULL; + int fd =3D -1; + + if (hostdev->mode !=3D VIR_DOMAIN_HOSTDEV_MODE_SUBSYS || + hostdev->source.subsys.type !=3D VIR_DOMAIN_HOSTDEV_SUBSYS_TYPE_PC= I) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("VFIO FD only supported for PCI hostdevs")); + return -1; + } + + if (virPCIDeviceGetVfioPath(&hostdev->source.subsys.u.pci.addr, &vfioP= ath) < 0) + return -1; + + VIR_DEBUG("Opening VFIO device %s", vfioPath); + + if ((fd =3D open(vfioPath, O_RDWR | O_CLOEXEC)) < 0) { + if (errno =3D=3D ENOENT) { + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, + _("VFIO device %1$s not found - ensure device i= s bound to vfio-pci driver"), + vfioPath); + } else { + virReportSystemError(errno, + _("cannot open VFIO device %1$s"), vfioPa= th); + } + return -1; + } + + VIR_DEBUG("Opened VFIO device FD %d for %s", fd, vfioPath); + return fd; +} + +/** + * qemuProcessOpenVfioFds: + * @vm: domain object + * + * Opens all necessary VFIO file descriptors for the domain. + * + * Returns: 0 on success, -1 on failure + */ +int +qemuProcessOpenVfioFds(virDomainObj *vm) +{ + size_t i; + + /* Check if we have any hostdevs that need VFIO FDs */ + for (i =3D 0; i < vm->def->nhostdevs; i++) { + virDomainHostdevDef *hostdev =3D vm->def->hostdevs[i]; + qemuDomainHostdevPrivate *hostdevPriv =3D QEMU_DOMAIN_HOSTDEV_PRIV= ATE(hostdev); + + if (hostdev->mode =3D=3D VIR_DOMAIN_HOSTDEV_MODE_SUBSYS && + hostdev->source.subsys.type =3D=3D VIR_DOMAIN_HOSTDEV_SUBSYS_T= YPE_PCI && + hostdev->source.subsys.u.pci.driver.name =3D=3D VIR_DEVICE_HOS= TDEV_PCI_DRIVER_NAME_VFIO && + hostdev->source.subsys.u.pci.driver.iommufd =3D=3D VIR_TRISTAT= E_BOOL_YES) { + /* Open VFIO device FD */ + hostdevPriv->vfioDeviceFd =3D qemuProcessOpenVfioDeviceFd(host= dev); + if (hostdevPriv->vfioDeviceFd =3D=3D -1) + return -1; + } + } + + return 0; +} diff --git a/src/util/virpci.c b/src/util/virpci.c index 90617e69c6..da62ece0f6 100644 --- a/src/util/virpci.c +++ b/src/util/virpci.c @@ -3320,3 +3320,72 @@ virPCIDeviceAddressFree(virPCIDeviceAddress *address) { g_free(address); } + +/** + * virPCIDeviceGetVfioPath: + * @addr: host device PCI address + * @vfioPath: returned VFIO device path + * + * Constructs the VFIO device path for a PCI hostdev. + * + * Returns: 0 on success, -1 on failure + */ +int +virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, + char **vfioPath) +{ + g_autofree char *addrStr =3D NULL; + + *vfioPath =3D NULL; + addrStr =3D virPCIDeviceAddressAsString(addr); + + /* First try: Direct lookup in device's vfio-dev subdirectory */ + { + g_autofree char *sysfsPath =3D NULL; + g_autoptr(DIR) dir =3D NULL; + struct dirent *entry =3D NULL; + + sysfsPath =3D g_strdup_printf("/sys/bus/pci/devices/%s/vfio-dev/",= addrStr); + + if (virDirOpen(&dir, sysfsPath) =3D=3D 1) { + while (virDirRead(dir, &entry, sysfsPath) > 0) { + if (STRPREFIX(entry->d_name, "vfio")) { + *vfioPath =3D g_strdup_printf("/dev/vfio/devices/%s", = entry->d_name); + return 0; + } + } + } + } + + /* Second try: Scan /sys/class/vfio-dev */ + { + g_autofree char *sysfsPath =3D g_strdup("/sys/class/vfio-dev"); + g_autoptr(DIR) dir =3D NULL; + struct dirent *entry =3D NULL; + + if (virDirOpen(&dir, sysfsPath) =3D=3D 1) { + while (virDirRead(dir, &entry, sysfsPath) > 0) { + g_autofree char *devLink =3D NULL; + g_autofree char *target =3D NULL; + + if (!STRPREFIX(entry->d_name, "vfio")) + continue; + + devLink =3D g_strdup_printf("/sys/class/vfio-dev/%s/device= ", entry->d_name); + + if (virFileResolveLink(devLink, &target) < 0) + continue; + + if (strstr(target, addrStr)) { + *vfioPath =3D g_strdup_printf("/dev/vfio/devices/%s", = entry->d_name); + return 0; + } + } + } + } + + virReportError(VIR_ERR_INTERNAL_ERROR, + _("cannot find VFIO device for PCI device %1$s"), + addrStr); + return -1; +} diff --git a/src/util/virpci.h b/src/util/virpci.h index fc538566e1..24ede10755 100644 --- a/src/util/virpci.h +++ b/src/util/virpci.h @@ -296,6 +296,8 @@ void virPCIEDeviceInfoFree(virPCIEDeviceInfo *dev); =20 void virPCIDeviceAddressFree(virPCIDeviceAddress *address); =20 +int virPCIDeviceGetVfioPath(virPCIDeviceAddress *addr, char **vfioPath); + G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDevice, virPCIDeviceFree); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIDeviceAddress, virPCIDeviceAddressFree= ); G_DEFINE_AUTOPTR_CLEANUP_FUNC(virPCIEDeviceInfo, virPCIEDeviceInfoFree); --=20 2.43.0