From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444881; cv=none; d=zohomail.com; s=zohoarc; b=j4NIfQFGn46dwSQmgjSMHIiXvwi+EIXwxdj0lbSerycXrGTo/GFE/gcyFvt/nfuICReOizWmZejSLOcu6KtNSZQvq486J4T7CIQ50x7UYkTi+YHXxByodgdbIbKsTsMknRqLyZDi3O2e1wX+E29oxJXDOiJFgk2Xtf6pIh04N2o= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444881; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=AZvC+bc7Rv16uKzN3ihkV/oSvkk6tH0QJHksWVaFqwg=; b=WQj1daiWWOBzu4EkZbv3G6D+NKT7TqfneN1XZmoL1+S+LFmM1xTtvZdTUYBw/aVAzpccQ1BUufqTPdcBhbfJvUwbA2A08JAO+JrTBF7QRZGUnkfpE8fD5IDEm8teCaD4IqXtJnzLUG4k6Txyo2bsEAEr3RSYWnALsKN18PDMA5E= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444881786201.24593975758296; Thu, 3 Sep 2026 07:14:41 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407255.1640336 (Exim 4.92) (envelope-from ) id 1x28Cr-0005EJ-E0; Thu, 03 Sep 2026 14:14:21 +0000 Received: by outflank-mailman (output) from mailman id 1407255.1640336; Thu, 03 Sep 2026 14:14:21 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cr-0005EC-BC; Thu, 03 Sep 2026 14:14:21 +0000 Received: by outflank-mailman (input) for mailman id 1407255; Thu, 03 Sep 2026 14:14:20 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cq-0005E6-8q for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:20 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28Cp-007l5G-Fy for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:19 +0200 Received: from [10.42.69.2] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980bb-e002-0a2a0a5209dd-0a2a4502ed04-4 for ; Thu, 03 Sep 2026 16:14:19 +0200 Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net) by tlsNG-720697.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980bb-6ca4-0a2a45020019-b9ff1c22a33f-3 for ; Thu, 03 Sep 2026 16:14:19 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ecc95000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:15 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id CA78F83FF2; Thu, 3 Sep 2026 16:14:14 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=AZvC+bc7Rv16uKzN3ihkV/oSvkk6tH0QJHksWVaFqwg=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=nfBm8a2r+v8k2jTuP+btTUtJmr6JGra3XeGqzxYuVwWGZB2qDAwJzL3223h7XTzshP64V71DW o/KpL5QyBcCEeKeZ53Y1/DCV6mc/HL3ss3f0tKYH4qgKBSp0LE4PPSs1+Or7SBt02bzmNJSB8mL 0hgGNv1h8DruoKtIphBWe5IvmOwoaEF6UVItCA3AvgOn6FmLYFm/ZkPi54xpJM7pIR8DNo+fup7 cdrUCtt9yrMFDR4kHj5ldBEQhrZHVpr1Hau8lEXiBHtX4tz+7LsxIhbJobmT8XP8CWUgSMMTsp3 OU5toNukl9813kaYIEUYZiJ1I55xqGuYgGb4gdGlKuWQ== X-Zone-Loop: c7255c66a8cde000f0d3f03de70656fe9edd765119b3 x-campaign-type: default x-transaction-id: 299ef29c-5d39-4dd9-8576-84dec8e8c7a6 x-swg-uid: 01-699fc82e-4a5d-4ca2-a927-a03bfb769b8d X-Mailer: Sweego Message-ID: <1788444855.8631fc262581453bbf619ec5b2062170.1a0679ecc95000c4f3@vates.tech> x-swg-bid: 1788444855.8631fc262581453bbf619ec5b2062170.1a0679ecc95000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 01/11] x86/vioapic: Add ioapic_check() to validate IO-APIC state before restore Date: Thu, 3 Sep 2026 16:13:59 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35a4.21631d333167ec9d.1a0679ecb06.d028971a7c8c5bc6=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444855046 X-purgate-ID: tlsNG-720697/1788444859-319CB2AC-9CC873AE/0/0 X-purgate-type: clean X-purgate-size: 4379 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444884449158500 ---=Part.35a4.21631d333167ec9d.1a0679ecb06.d028971a7c8c5bc6=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Register a check callback for the IOAPIC HVM save/restore entry, following the pattern established by vpic_check() for the virtual PIC. The function first verifies the target domain actually has a virtual IO-APIC, returning -ENODEV otherwise. It then validates individual fields of the saved state: base_address must be non-zero, page-aligned, and leave room for the MMIO window below the domain's physical address limit. The APIC ID must fit the 4-bit field vioapic_write_indirect() stores and no redirection table entry may carry a delivery_status bit, which is read-only and always cleared on a guest write. Signed-off-by: Julian Vetter --- Changes in v5: - The check now verifies base_address is page-alignment and hap_paddr_bits and not just "!=3D 0". - The APIC ID is bounded by the IO_APIC_reg_02 field and not a hard-coded 0xf (added comment). - Replaced the ioregsel check with a loop rejecting any entry that has delivery_status set. - Commit message rewritten. Signed-off-by: Julian Vetter --- xen/arch/x86/hvm/vioapic.c | 44 +++++++++++++++++++++++++++++++++++++- 1 file changed, 43 insertions(+), 1 deletion(-) diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 222e59e2c2..80dc9148a9 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -323,6 +323,7 @@ static void vioapic_write_indirect( * Presumably because we emulate an Intel IOAPIC which only has a * 4 bit ID field (compared to 8 for AMD), using union IO_APIC_reg= _02 * for the ID register (union IO_APIC_reg_00's ID field is 8 bits). + * ioapic_check() validates the saved id field accordingly. */ vioapic->id =3D ((union IO_APIC_reg_02){ .raw =3D val }).bits.arbi= tration; break; @@ -595,6 +596,47 @@ int vioapic_get_trigger_mode(const struct domain *d, u= nsigned int gsi) return vioapic->redirtbl[pin].fields.trig_mode; } =20 +static int cf_check ioapic_check(const struct domain *d, hvm_domain_contex= t_t *h) +{ + const HVM_SAVE_TYPE(IOAPIC) *s; + + if ( !has_vioapic(d) ) + return -ENODEV; + + s =3D hvm_get_entry(IOAPIC, h); + if ( !s ) + return -ENODATA; + + /* + * base_address must be non-zero, page-aligned (hardware constraint), = and + * within the guest's physical address space (with room for the full M= MIO + * window). + */ + if ( !s->base_address || + !IS_ALIGNED(s->base_address, PAGE_SIZE) || + s->base_address > (1ULL << hap_paddr_bits) - VIOAPIC_MEM_LENGTH ) + return -EINVAL; + + /* + * vioapic_write_indirect() stores only the 4-bit arbitration field of + * IO_APIC_reg_02 as the APIC ID. See that function's comment for why + * IO_APIC_reg_02 is used rather than IO_APIC_reg_00. + */ + if ( s->id > ((union IO_APIC_reg_02){ .raw =3D ~0U }).bits.arbitration= ) + return -EINVAL; + + /* + * Reject redirection table entries carrying bits that + * vioapic_write_redirent() would never store: delivery_status is read= -only + * and always cleared on a guest write. + */ + for ( unsigned int i =3D 0; i < ARRAY_SIZE(s->redirtbl); i++ ) + if ( s->redirtbl[i].fields.delivery_status ) + return -EINVAL; + + return 0; +} + static int cf_check ioapic_save(struct vcpu *v, hvm_domain_context_t *h) { const struct domain *d =3D v->domain; @@ -631,7 +673,7 @@ static int cf_check ioapic_load(struct domain *d, hvm_d= omain_context_t *h) return 0; } =20 -HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, NULL, ioapic_load, 1, +HVM_REGISTER_SAVE_RESTORE(IOAPIC, ioapic_save, ioapic_check, ioapic_load, = 1, HVMSR_PER_DOM); =20 void vioapic_reset(struct domain *d) --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35a4.21631d333167ec9d.1a0679ecb06.d028971a7c8c5bc6=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444888; cv=none; d=zohomail.com; s=zohoarc; b=bATHwPqejDNSX6JtMTM6LQVc6GzAo1B6XjN0aUe94OJ/T8Rfrkx3s24KuGKBOwTecQEVFFEdZUM9F5928ZVtWcln8IMsrC1KQNe1wuhT4PHYlLobo/3bqhGfylJjzZPavJbUPZbKPqqH0FhPae19p9SOLnxrS6Lo+Nd652mBMZ0= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444888; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=r+KqnF8bmZ4P6mM47X2d2/6/TckhTEd5k85Fqf1f/Kw=; b=nLThImuv0J7npdxSa7p5MEDBF2ekUMcW2bV+6KQw7rRtvUrgCLzgke97JE+UQz8bkJOXmD8m69xc7Af0SdbqDROoNJHAWHeEwb4ChHXcoSkP7XKapejfzzB3xvaz5HIRil1N4+g1JzcR3N2eglD1W+jHHaUAZ0khQ2FJWh6UFZE= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444888451603.2259555653745; Thu, 3 Sep 2026 07:14:48 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407256.1640345 (Exim 4.92) (envelope-from ) id 1x28Cx-0005Uo-QC; Thu, 03 Sep 2026 14:14:27 +0000 Received: by outflank-mailman (output) from mailman id 1407256.1640345; Thu, 03 Sep 2026 14:14:27 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cx-0005Uf-LY; Thu, 03 Sep 2026 14:14:27 +0000 Received: by outflank-mailman (input) for mailman id 1407256; Thu, 03 Sep 2026 14:14:25 +0000 Received: from mx.expurgate.net ([195.190.135.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cv-0005Re-Qd for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:25 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28Cu-006VeY-UU for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:24 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980a0-bab6-0a2a0a5309dd-0a2a4506deb4-38 for ; Thu, 03 Sep 2026 16:14:24 +0200 Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980c0-195a-0a2a45060019-b9ff1c238775-3 for ; Thu, 03 Sep 2026 16:14:24 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed206000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:16 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 34BFC83FF2; Thu, 3 Sep 2026 16:14:16 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=r+KqnF8bmZ4P6mM47X2d2/6/TckhTEd5k85Fqf1f/Kw=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=KIKtkYRM4wkHG3Sp+annclTs9TFxeAUHROUaO+uybfcMNAfpc99qNwhwrTIFo0eGh3TFtJ+ao M3nfpBHA/bOWAvPuvFAcwigagCwYaZtmaFGSA4eJ9IdwwxU5gHFmuEtQsUmamTMnSlKjankguOC 16u+7EAURaQh04TUGf42k9gCZ2TIsIeOFsXbbiF9Ny8J7t+tJT6QxunSElDASB97UztOZ1sIYd6 kEgWWDQ2jTOBTKDGsG4q/xfxucE26XFXNwQg8D2JweVcjQSxUX4I77a7Rb59UZB83bQXNzEI87y 9NH+/PgX1kAd9uqaAe8CWBPnBth5VIGvyP1At24342/w== X-Zone-Loop: ba365be1de0d39ba773c754a122acf6dbd1f56c3b1a4 x-campaign-type: default x-transaction-id: c242f644-79e9-4583-b5e2-1a90ae0c0f8d x-swg-uid: 01-0e9fb388-982f-4dd0-bc14-bc6d134075c2 X-Mailer: Sweego Message-ID: <1788444856.8631fc262581453bbf619ec5b2062170.1a0679ed206000c4f3@vates.tech> x-swg-bid: 1788444856.8631fc262581453bbf619ec5b2062170.1a0679ed206000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 02/11] x86/passthrough: Wrap pt_irq_create_bind() restart block in braces Date: Thu, 3 Sep 2026 16:14:00 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35a5.d06bb82c97bcd973.1a0679ed066.5d48df588f90c8dd=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444856422 X-purgate-ID: tlsNG-16d1c6/1788444864-FC40377B-BB071CD8/0/0 X-purgate-type: clean X-purgate-size: 4918 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444890278158500 ---=Part.35a5.d06bb82c97bcd973.1a0679ed066.5d48df588f90c8dd=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Enclose the restart/retry block in pt_irq_create_bind() in an explicit compound statement to prepare for its extraction into a helper function ("x86/passthrough: Extract pt_irq_dpci_setup() from pt_irq_create_bind()"). Reflow the two comments inside the block that no longer fit in 80 columns at the increased indentation, and fix an unbalanced parenthesis in the second one. No functional change. Signed-off-by: Julian Vetter --- Changes in v5: - Fixed two comments to fit 80-columns (and fixed unbalanced-parenthesis in comment) - Commit message now names the follow-up patch correctly. Signed-off-by: Julian Vetter --- xen/drivers/passthrough/x86/hvm.c | 81 ++++++++++++++++--------------- 1 file changed, 42 insertions(+), 39 deletions(-) diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index b73bb55055..1d5b1fb0f8 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -229,52 +229,55 @@ int pt_irq_create_bind( return -EINVAL; =20 restart: - write_lock(&d->event_lock); - - hvm_irq_dpci =3D domain_get_irq_dpci(d); - if ( !hvm_irq_dpci && !is_hardware_domain(d) ) { - unsigned int i; + write_lock(&d->event_lock); =20 - /* - * NB: the hardware domain doesn't use a hvm_irq_dpci struct becau= se - * it's only allowed to identity map GSIs, and so the data contain= ed in - * that struct (used to map guest GSIs into machine GSIs and perfo= rm - * interrupt routing) is completely useless to it. - */ - hvm_irq_dpci =3D xzalloc(struct hvm_irq_dpci); - if ( hvm_irq_dpci =3D=3D NULL ) + hvm_irq_dpci =3D domain_get_irq_dpci(d); + if ( !hvm_irq_dpci && !is_hardware_domain(d) ) + { + unsigned int i; + + /* + * NB: the hardware domain doesn't use a hvm_irq_dpci struct + * because it's only allowed to identity map GSIs, and so the + * data contained in that struct (used to map guest GSIs into + * machine GSIs and perform interrupt routing) is completely + * useless to it. + */ + hvm_irq_dpci =3D xzalloc(struct hvm_irq_dpci); + if ( hvm_irq_dpci =3D=3D NULL ) + { + write_unlock(&d->event_lock); + return -ENOMEM; + } + for ( i =3D 0; i < NR_HVM_DOMU_IRQS; i++ ) + INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]); + + hvm_domain_irq(d)->dpci =3D hvm_irq_dpci; + } + + info =3D pirq_get_info(d, pirq); + if ( !info ) { write_unlock(&d->event_lock); return -ENOMEM; } - for ( i =3D 0; i < NR_HVM_DOMU_IRQS; i++ ) - INIT_LIST_HEAD(&hvm_irq_dpci->girq[i]); - - hvm_domain_irq(d)->dpci =3D hvm_irq_dpci; - } - - info =3D pirq_get_info(d, pirq); - if ( !info ) - { - write_unlock(&d->event_lock); - return -ENOMEM; - } - pirq_dpci =3D pirq_dpci(info); + pirq_dpci =3D pirq_dpci(info); =20 - /* - * A crude 'while' loop with us dropping the spinlock and giving - * the softirq_dpci a chance to run. - * We MUST check for this condition as the softirq could be scheduled - * and hasn't run yet. Note that this code replaced tasklet_kill which - * would have spun forever and would do the same thing (wait to flush = out - * outstanding hvm_dirq_assist calls. - */ - if ( pt_pirq_softirq_active(pirq_dpci) ) - { - write_unlock(&d->event_lock); - cpu_relax(); - goto restart; + /* + * A crude 'while' loop with us dropping the spinlock and giving + * the softirq_dpci a chance to run. + * We MUST check for this condition as the softirq could be schedu= led + * and hasn't run yet. Note that this code replaced tasklet_kill + * which would have spun forever and would do the same thing (wait + * to flush out outstanding hvm_dirq_assist calls). + */ + if ( pt_pirq_softirq_active(pirq_dpci) ) + { + write_unlock(&d->event_lock); + cpu_relax(); + goto restart; + } } =20 switch ( pt_irq_bind->irq_type ) --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35a5.d06bb82c97bcd973.1a0679ed066.5d48df588f90c8dd=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444884; cv=none; d=zohomail.com; s=zohoarc; b=JCwHOTly/unCLpo0OZ5G22FtndvHJLKZ/Pgvl/4IZq2VDzBwNa5D6GRP3q7wWPcYTxrSzHL92DEGtHZ+Fn0cAUrb2ePPBu/mTFJDX/w2PSWbpAXLHq/ldl+QuaMHsSjs0Iz0FfZZyozLY8Sa4BrXAnHhlKgl2/Rhngko6JbYDHs= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444884; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=h3ZP4W9g2bPX9SP7yYh6igBoYL0cy5yX8xSLc9mKgjs=; b=GSfVmMpChack7dAySy9gMkSONJopDGNqHkyg9TR/shWXQAXPEzdT7ueRoITTtPf4WY8ptdjwBGLYJMH4jrf40X7194mVsZKUHzB40vXHUmjS551VbFYmNCCg3h69vv6H4ZjoPkHIS1NQMHyY8sbuvCDbIpLzNpgwQYVIpUsvPzo= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 178844488426313.725996306344427; Thu, 3 Sep 2026 07:14:44 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407257.1640354 (Exim 4.92) (envelope-from ) id 1x28Cy-0005ik-VA; Thu, 03 Sep 2026 14:14:28 +0000 Received: by outflank-mailman (output) from mailman id 1407257.1640354; Thu, 03 Sep 2026 14:14:28 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cy-0005iZ-SB; Thu, 03 Sep 2026 14:14:28 +0000 Received: by outflank-mailman (input) for mailman id 1407257; Thu, 03 Sep 2026 14:14:27 +0000 Received: from mx.expurgate.net ([195.190.135.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cx-0005UD-JW for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:27 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28Cx-006VeY-05 for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:27 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980a0-bab6-0a2a0a5309dd-0a2a4506deb4-44 for ; Thu, 03 Sep 2026 16:14:26 +0200 Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980c0-195a-0a2a45060019-b9ff1c238775-4 for ; Thu, 03 Sep 2026 16:14:26 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed358000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:17 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 8310284007; Thu, 3 Sep 2026 16:14:16 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=h3ZP4W9g2bPX9SP7yYh6igBoYL0cy5yX8xSLc9mKgjs=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=pc3tqOqL+2ALS7GtUGitfMGPn+lgB2hMuVe0+XIbMQ0eQ+8xYp193La6bSgmV+qWDHt5GGsT8 rTqckfJXiYK1wdRdcK3488NORCO3E0og2JLHKmIEOGp++O/IAjw9fLUhfmgmGdukiT8fGi6zOYM Xxf0ONj8AVCKWstPgpzn5GuuqTUcQsUsZU3GvD5rfth6ZFsDCrz1Jb5E4HOPwCEzFSnH0VyONTO ewzMjyn4vyS5UgScTIfSpIcMAb1+DHhtz7swEQRfMiA7izC/zmCaOpPU4Od8zprkY4SjAPoDIM6 fzGLNTd0CkaHStc5fCiXFDhjXBHO7EUtKpu+gSL5MLcA== X-Zone-Loop: f15ddafbb473f4cd2d2f3b01ccba6975d4de71124084 x-campaign-type: default x-transaction-id: 306bf369-c149-4751-98d5-927e2ae20227 x-swg-uid: 01-f1e1b78d-ce97-44a8-9869-e35e8147fb31 X-Mailer: Sweego Message-ID: <1788444857.8631fc262581453bbf619ec5b2062170.1a0679ed358000c4f3@vates.tech> x-swg-bid: 1788444857.8631fc262581453bbf619ec5b2062170.1a0679ed358000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 03/11] x86/passthrough: Replace pt_irq_create_bind() goto restart with a loop Date: Thu, 3 Sep 2026 16:14:01 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35a6.f864c585202bbc2b.1a0679ed1a8.584221bc86a559c0=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444856744 X-purgate-ID: tlsNG-16d1c6/1788444866-F607177B-E1B4D181/0/0 X-purgate-type: clean X-purgate-size: 1883 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444886197158500 ---=Part.35a6.f864c585202bbc2b.1a0679ed1a8.584221bc86a559c0=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Change "goto restart" retry in pt_irq_create_bind() into a "for ( ; ;)" loop with continue/break, so that the following patch extracting the block into a helper is only a code move without a label crossing a function boundary. No functional change. Signed-off-by: Julian Vetter --- Changes in v5: - New patch, split out of v4's "Extract pt_irq_dpci_setup()". It only converts the "goto restart" retry into a "for ( ; ; )" loop, so the following commit's extraction is only a code move with no label crossing a function boundary. - Use "for ( ; ; )" rather than v4's "do { } while ( true )". Signed-off-by: Julian Vetter --- xen/drivers/passthrough/x86/hvm.c | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index 1d5b1fb0f8..a74521fb57 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -228,7 +228,7 @@ int pt_irq_create_bind( if ( pirq < 0 || pirq >=3D d->nr_pirqs ) return -EINVAL; =20 - restart: + for ( ; ; ) { write_lock(&d->event_lock); =20 @@ -276,8 +276,10 @@ int pt_irq_create_bind( { write_unlock(&d->event_lock); cpu_relax(); - goto restart; + continue; } + + break; } =20 switch ( pt_irq_bind->irq_type ) --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35a6.f864c585202bbc2b.1a0679ed1a8.584221bc86a559c0=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444891; cv=none; d=zohomail.com; s=zohoarc; b=ZcugA9zcvHTdKIC8DG3w5PaP1i5XtDsl1CTso53OQGCj5vegjyrqvt9x7ouQ1ED7fUPyf6v/Bc+kWMffCUzFcz81OoCUZFmsfqf2r7BP7lttsm6NbuVRftJDvv3ZHX64NPMDhXVXPl7l1NpVSYE0yNpLoOL4HQgH43bm+uYPJIQ= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444891; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=+6GkMIp/1eeu/JYU7MqSA0Jg0HqhrlFBR87a2YshFkM=; b=M3UUh4bx4NCG2KHeAfOriTrBI13PliAeVuvpsqRqgWo5kTtZzTPr3kx8u+jdh9buAL/L/HeTI+hlLS+qsOxE1VAC4VA9OIf5ji+3W7meT3waQKxWivsINvXZJqPeFF7ydHQM18NvGA9qiD5FQHn/zZrOQiN2gE+gX/fNfcxP75I= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444891705766.3736067006827; Thu, 3 Sep 2026 07:14:51 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407258.1640363 (Exim 4.92) (envelope-from ) id 1x28D0-0005we-6Z; Thu, 03 Sep 2026 14:14:30 +0000 Received: by outflank-mailman (output) from mailman id 1407258.1640363; Thu, 03 Sep 2026 14:14:30 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D0-0005wU-2Y; Thu, 03 Sep 2026 14:14:30 +0000 Received: by outflank-mailman (input) for mailman id 1407258; Thu, 03 Sep 2026 14:14:29 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28Cz-0005p7-Hg for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:29 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28Cy-001H4c-Uh for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:28 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980c3-2eae-0a2a0a5409dd-0a2a4506ae08-8 for ; Thu, 03 Sep 2026 16:14:28 +0200 Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980c0-195a-0a2a45060019-b9ff1c238775-5 for ; Thu, 03 Sep 2026 16:14:28 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed4c6000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:17 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id D21A384009; Thu, 3 Sep 2026 16:14:16 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=+6GkMIp/1eeu/JYU7MqSA0Jg0HqhrlFBR87a2YshFkM=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=iBocxmf2ySsOM/kuCSrJW50/IJxqr68w2FA1zILstYiuIRYahHRcntJXrekr6DDoIOn5foko0 2EoCpgNC+nES1mV09YIAhvyGybjHB3A+dvdsYq1pIi2QSKoCfOVVZ1EC2foi9SqM5vjQRJs19og yg1dLPKscntAh9uvzloVQUxJdX7jq0t2QZw+aSk0gytQW9MIvvxjUPQYJjQ5MKSzNHeX5PMPSc3 wY1KlZ2jLL16GUbySlI5Wcig9OyyKd7gZDbyqWmrdaD0XH0qfwLDWuNhGkgs1ed2i6YZPmAhT7D s0IIhwWfbAWRm8dHuqXtVTo7a/G1Dsmf1Fby+QD5JnQQ== X-Zone-Loop: 1ff00ec3e46e6bd6b9f1e9af5dbd4868d064be86c2ad x-campaign-type: default x-transaction-id: db0da7ba-05bb-42ec-9404-4b1c1434aef6 x-swg-uid: 01-14015135-ea07-494e-a639-aea863dc84cb X-Mailer: Sweego Message-ID: <1788444857.8631fc262581453bbf619ec5b2062170.1a0679ed4c6000c4f3@vates.tech> x-swg-bid: 1788444857.8631fc262581453bbf619ec5b2062170.1a0679ed4c6000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 04/11] x86/passthrough: Extract pt_irq_dpci_setup() from pt_irq_create_bind() Date: Thu, 3 Sep 2026 16:14:02 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35a7.ad47fc3b5f677688.1a0679ed2ed.de73df203679ce07=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444857069 X-purgate-ID: tlsNG-16d1c6/1788444868-F70C777B-49ABC3EE/0/0 X-purgate-type: clean X-purgate-size: 2904 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444892271158500 ---=Part.35a7.ad47fc3b5f677688.1a0679ed2ed.de73df203679ce07=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" The setup preamble in pt_irq_create_bind() (lazily allocating hvm_irq_dpci, looking up the struct pirq, and spinning until any pending hvm_dirq_assist softirq has drained) is needed by the MSI bind path as well. Move it into a static helper pt_irq_dpci_setup() that returns with d->event_lock write-locked on success and hands the three looked-up pointers back through out parameters. No functional change. Signed-off-by: Julian Vetter --- Changes in v5: - The goto-to-loop conversion is now in the preceding patch, so this one just moves code around. - Commit message reworded. Signed-off-by: Julian Vetter --- xen/drivers/passthrough/x86/hvm.c | 32 +++++++++++++++++++++++++------ 1 file changed, 26 insertions(+), 6 deletions(-) diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index a74521fb57..7fcd3cc046 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -217,16 +217,14 @@ static struct vcpu *vector_hashing_dest(const struct = domain *d, return dest; } =20 -int pt_irq_create_bind( - struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind) +static int pt_irq_dpci_setup(struct domain *d, unsigned int pirq, + struct hvm_irq_dpci **hvm_irq_dpci_out, + struct hvm_pirq_dpci **pirq_dpci_out, + struct pirq **info_out) { struct hvm_irq_dpci *hvm_irq_dpci; struct hvm_pirq_dpci *pirq_dpci; struct pirq *info; - int rc, pirq =3D pt_irq_bind->machine_irq; - - if ( pirq < 0 || pirq >=3D d->nr_pirqs ) - return -EINVAL; =20 for ( ; ; ) { @@ -282,6 +280,28 @@ int pt_irq_create_bind( break; } =20 + *hvm_irq_dpci_out =3D hvm_irq_dpci; + *pirq_dpci_out =3D pirq_dpci; + *info_out =3D info; + + return 0; +} + +int pt_irq_create_bind( + struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind) +{ + struct hvm_irq_dpci *hvm_irq_dpci; + struct hvm_pirq_dpci *pirq_dpci; + struct pirq *info; + int rc, pirq =3D pt_irq_bind->machine_irq; + + if ( pirq < 0 || pirq >=3D d->nr_pirqs ) + return -EINVAL; + + rc =3D pt_irq_dpci_setup(d, pirq, &hvm_irq_dpci, &pirq_dpci, &info); + if ( rc ) + return rc; + switch ( pt_irq_bind->irq_type ) { case PT_IRQ_TYPE_MSI: --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35a7.ad47fc3b5f677688.1a0679ed2ed.de73df203679ce07=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444891; cv=none; d=zohomail.com; s=zohoarc; b=dgG7ASuH6y2eMZ67tr+52LhShrR/gjH2ql12ZFgDXjZtcW/0TncpjuKByXh2laOC0A6qbPscPAacwuzyAR4QApOrIGXU67ipqEdfleKD1hdRHxZ40SYNGR7z+AdC8TOxJWdC025OkNMKwG0/I0Mj2ZxaG0Q773n9+LWWe1hiY3w= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444891; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=EMoj4d2wG+b14N1m0v4nZI3dq2ElOe1px6bJBfqEcts=; b=UdFyt6uuJtz99KVyEtoyYsumqq5mFzEsNGqrBc3vUFQ5nhOWvHO2bmOT6Nh8OQoLsNYG2ctG2I8uzhPitZ7UUZC5j9DsF0rN8Y9k/RKWYQwpQHxrB1fPFm0N9PWmCWV7u55rHCpTS4CSpraMleCAU/6MgiPRGuAVjBOtS+o4qhk= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444891000485.5353787457507; Thu, 3 Sep 2026 07:14:51 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407259.1640372 (Exim 4.92) (envelope-from ) id 1x28D2-0006C9-DU; Thu, 03 Sep 2026 14:14:32 +0000 Received: by outflank-mailman (output) from mailman id 1407259.1640372; Thu, 03 Sep 2026 14:14:32 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D2-0006C0-AI; Thu, 03 Sep 2026 14:14:32 +0000 Received: by outflank-mailman (input) for mailman id 1407259; Thu, 03 Sep 2026 14:14:30 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D0-00063Q-Pr for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:30 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28D0-001H4c-6J for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:30 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980c3-2eae-0a2a0a5409dd-0a2a4506ae08-12 for ; Thu, 03 Sep 2026 16:14:30 +0200 Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980c0-195a-0a2a45060019-b9ff1c238775-6 for ; Thu, 03 Sep 2026 16:14:30 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed5cb000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:17 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 2D2D48400B; Thu, 3 Sep 2026 16:14:17 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=EMoj4d2wG+b14N1m0v4nZI3dq2ElOe1px6bJBfqEcts=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=P10K10XmOLF2zVa2SU1jN2trI4UVwJKX2I8yxbmXoGIAsnBK0k1pcfMWQVCZ5KOYXbs5XAqKR vAQ5dbf2c2weugGRqy/zY8L29sWpfTCAa0dE7cC6GacDBzkEe4wwAF9bVO6FWlY24PHzWQnipEm Pgi7NhRUFR/x7baiMbaAoxWGox1GdeBJjEEB2gafJih7q3d3uFj7NedWSzNuBqNrmvG5UnampvU Nxxf+qApFtJ92AE1bUuEWHFY6C21n1iIcbZpH9RhVHNS2ODyuQGhlCicWNpFt21Yh1c/g7O2iqt GA7PA+qPAf6NvcMnJ2T4qGUFVtg4JvsZNnYxKi59iE1A== X-Zone-Loop: 805b0bc169318dc6ad4260f732d926418730b83fe513 x-campaign-type: default x-transaction-id: 17d51502-7c92-47e6-910f-5c7f0c7b0138 x-swg-uid: 01-d46563e3-3bd1-49f0-8f7c-35efecd22d89 X-Mailer: Sweego Message-ID: <1788444857.8631fc262581453bbf619ec5b2062170.1a0679ed5cb000c4f3@vates.tech> x-swg-bid: 1788444857.8631fc262581453bbf619ec5b2062170.1a0679ed5cb000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 05/11] x86/passthrough: Extract PT_IRQ_TYPE_MSI body into pt_irq_bind_msi() Date: Thu, 3 Sep 2026 16:14:03 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35a8.4b933214084d2238.1a0679ed436.e3f9f62c71b5f07a=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444857399 X-purgate-ID: tlsNG-16d1c6/1788444870-1EEC477B-A58899A3/0/0 X-purgate-type: clean X-purgate-size: 8979 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444892349158500 ---=Part.35a8.4b933214084d2238.1a0679ed436.e3f9f62c71b5f07a=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Move the PT_IRQ_TYPE_MSI case of pt_irq_create_bind() into a new static helper pt_irq_bind_msi(d, machine_irq, gvec, gflags, gtable, unmasked). The helper calls pt_irq_dpci_setup() itself, so pt_irq_create_bind() now invokes the setup helper separately in the PCI / MSI_TRANSLATE case and the 'default' case no longer needs to drop d->event_lock. To keep this step "just" a code move, the extracted body is left at its original (switch/case) indentation inside a compound block. The next commit re-indents it. References to pt_irq_bind->u.msi.* are replaced by the corresponding parameters, and the two pt_irq_destroy_bind() error paths build a local xen_domctl_bind_pt_irq instead. No functional change. Signed-off-by: Julian Vetter --- Changes in v5: - New patch: this is the first half of v4's single "Extract PT_IRQ_TYPE_MSI body" patch, now split into "extract as-is, keeping the switch/case indentation inside a bare block" plus a re-indent (next patch), so each step reviews cleanly. - machine_irq / gflags parameters are now unsigned int. - The redundant nr_pirqs bound check inside the helper was dropped. - The "!!" on the unmasked argument was removed. - pt_irq_dpci_setup() is now called per-case. - The "default" case no longer double-unlocks d->event_lock. - The two pt_irq_destroy_bind() error paths build a local xen_domctl_bind_pt_irq. - Comment capitalisation fixed. Signed-off-by: Julian Vetter --- xen/drivers/passthrough/x86/hvm.c | 81 +++++++++++++++++++++---------- 1 file changed, 55 insertions(+), 26 deletions(-) diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index 7fcd3cc046..ed368a7fdb 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -287,40 +287,33 @@ static int pt_irq_dpci_setup(struct domain *d, unsign= ed int pirq, return 0; } =20 -int pt_irq_create_bind( - struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind) +static int pt_irq_bind_msi(struct domain *d, unsigned int machine_irq, + uint8_t gvec, unsigned int gflags, uint64_t gta= ble, + bool unmasked) { struct hvm_irq_dpci *hvm_irq_dpci; struct hvm_pirq_dpci *pirq_dpci; struct pirq *info; - int rc, pirq =3D pt_irq_bind->machine_irq; - - if ( pirq < 0 || pirq >=3D d->nr_pirqs ) - return -EINVAL; + int rc; =20 - rc =3D pt_irq_dpci_setup(d, pirq, &hvm_irq_dpci, &pirq_dpci, &info); + rc =3D pt_irq_dpci_setup(d, machine_irq, &hvm_irq_dpci, &pirq_dpci, &i= nfo); if ( rc ) return rc; =20 - switch ( pt_irq_bind->irq_type ) - { - case PT_IRQ_TYPE_MSI: { uint8_t dest, delivery_mode; bool dest_mode; int dest_vcpu_id; const struct vcpu *vcpu; - uint32_t gflags =3D pt_irq_bind->u.msi.gflags & - ~XEN_DOMCTL_VMSI_X86_UNMASKED; =20 if ( !(pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) ) { pirq_dpci->flags =3D HVM_IRQ_DPCI_MAPPED | HVM_IRQ_DPCI_MACH_M= SI | HVM_IRQ_DPCI_GUEST_MSI; - pirq_dpci->gmsi.gvec =3D pt_irq_bind->u.msi.gvec; + pirq_dpci->gmsi.gvec =3D gvec; pirq_dpci->gmsi.gflags =3D gflags; /* - * 'pt_irq_create_bind' can be called after 'pt_irq_destroy_bi= nd'. + * 'pt_irq_bind_msi' can be called after 'pt_irq_destroy_bind'. * The 'pirq_cleanup_check' which would free the structure is = only * called if the event channel for the PIRQ is active. However * OS-es that use event channels usually bind PIRQs to eventds @@ -328,14 +321,14 @@ int pt_irq_create_bind( * result that we re-use the 'dpci' structure. This can be * reproduced with unloading and loading the driver for a devi= ce. * - * As such on every 'pt_irq_create_bind' call we MUST set it. + * As such on every 'pt_irq_bind_msi' call we MUST set it. */ pirq_dpci->dom =3D d; - /* bind after hvm_irq_dpci is setup to avoid race with irq han= dler*/ + /* Bind after hvm_irq_dpci is setup to avoid race with irq han= dler. */ rc =3D pirq_guest_bind(d->vcpu[0], info, 0); - if ( rc =3D=3D 0 && pt_irq_bind->u.msi.gtable ) + if ( rc =3D=3D 0 && gtable ) { - rc =3D msixtbl_pt_register(d, info, pt_irq_bind->u.msi.gta= ble); + rc =3D msixtbl_pt_register(d, info, gtable); if ( unlikely(rc) ) { pirq_guest_unbind(d, info); @@ -371,13 +364,13 @@ int pt_irq_create_bind( } =20 /* If pirq is already mapped as vmsi, update guest data/addr. = */ - if ( pirq_dpci->gmsi.gvec !=3D pt_irq_bind->u.msi.gvec || + if ( pirq_dpci->gmsi.gvec !=3D gvec || pirq_dpci->gmsi.gflags !=3D gflags ) { /* Directly clear pending EOIs before enabling new MSI inf= o. */ pirq_guest_eoi(info); =20 - pirq_dpci->gmsi.gvec =3D pt_irq_bind->u.msi.gvec; + pirq_dpci->gmsi.gvec =3D gvec; pirq_dpci->gmsi.gflags =3D gflags; } } @@ -408,23 +401,31 @@ int pt_irq_create_bind( /* Use interrupt posting if it is supported. */ if ( iommu_intpost ) { - rc =3D hvm_pi_update_irte(vcpu, info, pirq_dpci->gmsi.gvec); + struct xen_domctl_bind_pt_irq pt_irq_bind =3D { + .machine_irq =3D machine_irq, + .irq_type =3D PT_IRQ_TYPE_MSI, + }; =20 + rc =3D hvm_pi_update_irte(vcpu, info, pirq_dpci->gmsi.gvec); if ( rc ) { - pt_irq_destroy_bind(d, pt_irq_bind); + pt_irq_destroy_bind(d, &pt_irq_bind); return rc; } } =20 - if ( pt_irq_bind->u.msi.gflags & XEN_DOMCTL_VMSI_X86_UNMASKED ) + if ( unmasked ) { + struct xen_domctl_bind_pt_irq pt_irq_bind =3D { + .machine_irq =3D machine_irq, + .irq_type =3D PT_IRQ_TYPE_MSI, + }; unsigned long flags; struct irq_desc *desc =3D pirq_spin_lock_irq_desc(info, &flags= ); =20 if ( !desc ) { - pt_irq_destroy_bind(d, pt_irq_bind); + pt_irq_destroy_bind(d, &pt_irq_bind); return -EINVAL; } =20 @@ -432,15 +433,44 @@ int pt_irq_create_bind( spin_unlock_irqrestore(&desc->lock, flags); } =20 - break; + return 0; + } +} + +int pt_irq_create_bind( + struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind) +{ + int pirq =3D pt_irq_bind->machine_irq; + + if ( pirq < 0 || pirq >=3D d->nr_pirqs ) + return -EINVAL; + + switch ( pt_irq_bind->irq_type ) + { + case PT_IRQ_TYPE_MSI: + { + unsigned int gflags =3D pt_irq_bind->u.msi.gflags; + + return pt_irq_bind_msi(d, pirq, pt_irq_bind->u.msi.gvec, + gflags & ~XEN_DOMCTL_VMSI_X86_UNMASKED, + pt_irq_bind->u.msi.gtable, + gflags & XEN_DOMCTL_VMSI_X86_UNMASKED); } =20 case PT_IRQ_TYPE_PCI: case PT_IRQ_TYPE_MSI_TRANSLATE: { + struct hvm_irq_dpci *hvm_irq_dpci; + struct hvm_pirq_dpci *pirq_dpci; + struct pirq *info; struct dev_intx_gsi_link *digl =3D NULL; struct hvm_girq_dpci_mapping *girq =3D NULL; unsigned int guest_gsi; + int rc; + + rc =3D pt_irq_dpci_setup(d, pirq, &hvm_irq_dpci, &pirq_dpci, &info= ); + if ( rc ) + return rc; =20 /* * Mapping GSIs for the hardware domain is different than doing it= for @@ -589,7 +619,6 @@ int pt_irq_create_bind( } =20 default: - write_unlock(&d->event_lock); return -EOPNOTSUPP; } =20 --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35a8.4b933214084d2238.1a0679ed436.e3f9f62c71b5f07a=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444902; cv=none; d=zohomail.com; s=zohoarc; b=bS7xiOZGotpi/neWIeV+RIfhB4RaZTf56bTP4yCteH2+rqDb9I50SG/iUI7v9zAO435t/2L/daxsUXpkLtTh4ujeTeq/k/fF4doOxoG1Gohb/tBqAGJNXI2FO4Q66G3afW/Y6INWBCGptqxVTSdJnDnHOZj3i6STLl2f9x8gQsk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444902; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=XlXn7+U7AhcVnIuq8LehatGTdH1rv7CZg+DUPNdYgUU=; b=UgwO2k2iKk9yEe4M9+e6TzswJZ05bQ5fH3wrHKiyyW3sNrBZ66VEckxr1ySNggfpMRI9F6r2EoURfFRf2x3/u5YbfAJMeHDDhtdzYTru5pbfdBe7GaxPzp1iG2Gido3E4Oa0EEGVylOfLwFuYkNGA8UHqqZFIULxuo10CTTtGj8= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444902813936.5415053418118; Thu, 3 Sep 2026 07:15:02 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407260.1640381 (Exim 4.92) (envelope-from ) id 1x28D4-0006T4-Qv; Thu, 03 Sep 2026 14:14:34 +0000 Received: by outflank-mailman (output) from mailman id 1407260.1640381; Thu, 03 Sep 2026 14:14:34 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D4-0006St-N9; Thu, 03 Sep 2026 14:14:34 +0000 Received: by outflank-mailman (input) for mailman id 1407260; Thu, 03 Sep 2026 14:14:33 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D2-0006FP-Rm for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:32 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28D2-001H4c-7x for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:32 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980c3-2eae-0a2a0a5409dd-0a2a4506ae08-18 for ; Thu, 03 Sep 2026 16:14:32 +0200 Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980c0-195a-0a2a45060019-b9ff1c238775-7 for ; Thu, 03 Sep 2026 16:14:32 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed728000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:18 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 7D6AB8400D; Thu, 3 Sep 2026 16:14:17 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=XlXn7+U7AhcVnIuq8LehatGTdH1rv7CZg+DUPNdYgUU=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=Gkq0stmJhwqiGy80JiK+VixgmmbCoI+NQAlTG5W+JcewQXs3cQaJgQVRXgKAqAz1WmiWI8EqL 8NgoxORM4GPgGHyWesiwuQnPDi4oyd6MSKdRa4UwZQI3P1r2y/EE9umwfZy1Qa+3A7/alS3F6oJ om9Ytno/CdkMbDPVi/fH1w95VoVTu4l+qx1+JZjmXFlbVuIMIHoIZUR0HROkP3hvh/t+L5+V82T vzyt1TEpauRVWCoj3MlYq+Pqz7dxFXkaLuR9c57kjiyMpXsY+7kxLaNhSQuLtQ9oYzKHXUFHD3L 9+eNk6llGkn2ZWNT2jFkdpQU5IjKKSs95p0eKl2g0z2Q== X-Zone-Loop: 70ef9b24403594f9905bebe9f916eb79cba80da7c1eb x-campaign-type: default x-transaction-id: 11323503-91e7-43da-b618-24919b35d4cb x-swg-uid: 01-301f6409-08d7-4cbb-8e44-63148d780951 X-Mailer: Sweego Message-ID: <1788444858.8631fc262581453bbf619ec5b2062170.1a0679ed728000c4f3@vates.tech> x-swg-bid: 1788444858.8631fc262581453bbf619ec5b2062170.1a0679ed728000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 06/11] x86/passthrough: Re-indent pt_irq_bind_msi() body Date: Thu, 3 Sep 2026 16:14:04 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35a9.39c8d9bf421e1e25.1a0679ed57e.33cdc81cbace567b=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444857726 X-purgate-ID: tlsNG-16d1c6/1788444872-FD80D77B-5DB27F4F/0/0 X-purgate-type: clean X-purgate-size: 12064 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444904683158500 ---=Part.35a9.39c8d9bf421e1e25.1a0679ed57e.33cdc81cbace567b=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Purely mechanical follow-up to the previous patch: drop the compound block that preserved the original switch/case indentation, shift the body one level left, move the block-local declarations to the top of the function, and add the missing blank line before the dest_vcpu_id calculation. No functional change. 'git show --ignore-all-space' is empty apart from the declaration move and the removed brackets. Signed-off-by: Julian Vetter --- Changes in v5: - New patch: the re-indent half of the v4 extraction. Drops the compound block, shifts the body one level left, move the block-local declarations and adds the missing blank line. Signed-off-by: Julian Vetter --- xen/drivers/passthrough/x86/hvm.c | 224 +++++++++++++++--------------- 1 file changed, 111 insertions(+), 113 deletions(-) diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index ed368a7fdb..5fdb885311 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -295,146 +295,144 @@ static int pt_irq_bind_msi(struct domain *d, unsign= ed int machine_irq, struct hvm_pirq_dpci *pirq_dpci; struct pirq *info; int rc; + uint8_t dest, delivery_mode; + bool dest_mode; + int dest_vcpu_id; + const struct vcpu *vcpu; =20 rc =3D pt_irq_dpci_setup(d, machine_irq, &hvm_irq_dpci, &pirq_dpci, &i= nfo); if ( rc ) return rc; =20 + if ( !(pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) ) { - uint8_t dest, delivery_mode; - bool dest_mode; - int dest_vcpu_id; - const struct vcpu *vcpu; - - if ( !(pirq_dpci->flags & HVM_IRQ_DPCI_MAPPED) ) + pirq_dpci->flags =3D HVM_IRQ_DPCI_MAPPED | HVM_IRQ_DPCI_MACH_MSI | + HVM_IRQ_DPCI_GUEST_MSI; + pirq_dpci->gmsi.gvec =3D gvec; + pirq_dpci->gmsi.gflags =3D gflags; + /* + * 'pt_irq_bind_msi' can be called after 'pt_irq_destroy_bind'. + * The 'pirq_cleanup_check' which would free the structure is only + * called if the event channel for the PIRQ is active. However + * OS-es that use event channels usually bind PIRQs to eventds + * and unbind them before calling 'pt_irq_destroy_bind' - with the + * result that we re-use the 'dpci' structure. This can be + * reproduced with unloading and loading the driver for a device. + * + * As such on every 'pt_irq_bind_msi' call we MUST set it. + */ + pirq_dpci->dom =3D d; + /* Bind after hvm_irq_dpci is setup to avoid race with irq handler= . */ + rc =3D pirq_guest_bind(d->vcpu[0], info, 0); + if ( rc =3D=3D 0 && gtable ) { - pirq_dpci->flags =3D HVM_IRQ_DPCI_MAPPED | HVM_IRQ_DPCI_MACH_M= SI | - HVM_IRQ_DPCI_GUEST_MSI; - pirq_dpci->gmsi.gvec =3D gvec; - pirq_dpci->gmsi.gflags =3D gflags; - /* - * 'pt_irq_bind_msi' can be called after 'pt_irq_destroy_bind'. - * The 'pirq_cleanup_check' which would free the structure is = only - * called if the event channel for the PIRQ is active. However - * OS-es that use event channels usually bind PIRQs to eventds - * and unbind them before calling 'pt_irq_destroy_bind' - with= the - * result that we re-use the 'dpci' structure. This can be - * reproduced with unloading and loading the driver for a devi= ce. - * - * As such on every 'pt_irq_bind_msi' call we MUST set it. - */ - pirq_dpci->dom =3D d; - /* Bind after hvm_irq_dpci is setup to avoid race with irq han= dler. */ - rc =3D pirq_guest_bind(d->vcpu[0], info, 0); - if ( rc =3D=3D 0 && gtable ) - { - rc =3D msixtbl_pt_register(d, info, gtable); - if ( unlikely(rc) ) - { - pirq_guest_unbind(d, info); - /* - * Between 'pirq_guest_bind' and before 'pirq_guest_un= bind' - * an interrupt can be scheduled. No more of them are = going - * to be scheduled but we must deal with the one that = may be - * in the queue. - */ - pt_pirq_softirq_reset(pirq_dpci); - } - } + rc =3D msixtbl_pt_register(d, info, gtable); if ( unlikely(rc) ) { - pirq_dpci->gmsi.gflags =3D 0; - pirq_dpci->gmsi.gvec =3D 0; - pirq_dpci->dom =3D NULL; - pirq_dpci->flags =3D 0; - if ( !info->evtchn ) - pirq_cleanup_check(info, d); - write_unlock(&d->event_lock); - return rc; + pirq_guest_unbind(d, info); + /* + * Between 'pirq_guest_bind' and before 'pirq_guest_unbind' + * an interrupt can be scheduled. No more of them are going + * to be scheduled but we must deal with the one that may = be + * in the queue. + */ + pt_pirq_softirq_reset(pirq_dpci); } } - else + if ( unlikely(rc) ) { - uint32_t mask =3D HVM_IRQ_DPCI_MACH_MSI | HVM_IRQ_DPCI_GUEST_M= SI; - - if ( (pirq_dpci->flags & mask) !=3D mask ) - { - write_unlock(&d->event_lock); - return -EBUSY; - } - - /* If pirq is already mapped as vmsi, update guest data/addr. = */ - if ( pirq_dpci->gmsi.gvec !=3D gvec || - pirq_dpci->gmsi.gflags !=3D gflags ) - { - /* Directly clear pending EOIs before enabling new MSI inf= o. */ - pirq_guest_eoi(info); - - pirq_dpci->gmsi.gvec =3D gvec; - pirq_dpci->gmsi.gflags =3D gflags; - } + pirq_dpci->gmsi.gflags =3D 0; + pirq_dpci->gmsi.gvec =3D 0; + pirq_dpci->dom =3D NULL; + pirq_dpci->flags =3D 0; + if ( !info->evtchn ) + pirq_cleanup_check(info, d); + write_unlock(&d->event_lock); + return rc; } - /* Calculate dest_vcpu_id for MSI-type pirq migration. */ - dest =3D MASK_EXTR(pirq_dpci->gmsi.gflags, - XEN_DOMCTL_VMSI_X86_DEST_ID_MASK); - dest_mode =3D pirq_dpci->gmsi.gflags & XEN_DOMCTL_VMSI_X86_DM_MASK; - delivery_mode =3D MASK_EXTR(pirq_dpci->gmsi.gflags, - XEN_DOMCTL_VMSI_X86_DELIV_MASK); - - dest_vcpu_id =3D hvm_girq_dest_2_vcpu_id(d, dest, dest_mode); - pirq_dpci->gmsi.dest_vcpu_id =3D dest_vcpu_id; - write_unlock(&d->event_lock); + } + else + { + uint32_t mask =3D HVM_IRQ_DPCI_MACH_MSI | HVM_IRQ_DPCI_GUEST_MSI; =20 - pirq_dpci->gmsi.posted =3D false; - vcpu =3D (dest_vcpu_id >=3D 0) ? d->vcpu[dest_vcpu_id] : NULL; - if ( iommu_intpost ) + if ( (pirq_dpci->flags & mask) !=3D mask ) { - if ( delivery_mode =3D=3D dest_LowestPrio ) - vcpu =3D vector_hashing_dest(d, dest, dest_mode, - pirq_dpci->gmsi.gvec); - if ( vcpu ) - pirq_dpci->gmsi.posted =3D true; + write_unlock(&d->event_lock); + return -EBUSY; } - if ( vcpu && is_iommu_enabled(d) ) - hvm_migrate_pirq(pirq_dpci, vcpu); =20 - /* Use interrupt posting if it is supported. */ - if ( iommu_intpost ) + /* If pirq is already mapped as vmsi, update guest data/addr. */ + if ( pirq_dpci->gmsi.gvec !=3D gvec || + pirq_dpci->gmsi.gflags !=3D gflags ) { - struct xen_domctl_bind_pt_irq pt_irq_bind =3D { - .machine_irq =3D machine_irq, - .irq_type =3D PT_IRQ_TYPE_MSI, - }; + /* Directly clear pending EOIs before enabling new MSI info. */ + pirq_guest_eoi(info); =20 - rc =3D hvm_pi_update_irte(vcpu, info, pirq_dpci->gmsi.gvec); - if ( rc ) - { - pt_irq_destroy_bind(d, &pt_irq_bind); - return rc; - } + pirq_dpci->gmsi.gvec =3D gvec; + pirq_dpci->gmsi.gflags =3D gflags; } + } + + /* Calculate dest_vcpu_id for MSI-type pirq migration. */ + dest =3D MASK_EXTR(pirq_dpci->gmsi.gflags, + XEN_DOMCTL_VMSI_X86_DEST_ID_MASK); + dest_mode =3D pirq_dpci->gmsi.gflags & XEN_DOMCTL_VMSI_X86_DM_MASK; + delivery_mode =3D MASK_EXTR(pirq_dpci->gmsi.gflags, + XEN_DOMCTL_VMSI_X86_DELIV_MASK); + + dest_vcpu_id =3D hvm_girq_dest_2_vcpu_id(d, dest, dest_mode); + pirq_dpci->gmsi.dest_vcpu_id =3D dest_vcpu_id; + write_unlock(&d->event_lock); + + pirq_dpci->gmsi.posted =3D false; + vcpu =3D (dest_vcpu_id >=3D 0) ? d->vcpu[dest_vcpu_id] : NULL; + if ( iommu_intpost ) + { + if ( delivery_mode =3D=3D dest_LowestPrio ) + vcpu =3D vector_hashing_dest(d, dest, dest_mode, + pirq_dpci->gmsi.gvec); + if ( vcpu ) + pirq_dpci->gmsi.posted =3D true; + } + if ( vcpu && is_iommu_enabled(d) ) + hvm_migrate_pirq(pirq_dpci, vcpu); + + /* Use interrupt posting if it is supported. */ + if ( iommu_intpost ) + { + struct xen_domctl_bind_pt_irq pt_irq_bind =3D { + .machine_irq =3D machine_irq, + .irq_type =3D PT_IRQ_TYPE_MSI, + }; =20 - if ( unmasked ) + rc =3D hvm_pi_update_irte(vcpu, info, pirq_dpci->gmsi.gvec); + if ( rc ) { - struct xen_domctl_bind_pt_irq pt_irq_bind =3D { - .machine_irq =3D machine_irq, - .irq_type =3D PT_IRQ_TYPE_MSI, - }; - unsigned long flags; - struct irq_desc *desc =3D pirq_spin_lock_irq_desc(info, &flags= ); + pt_irq_destroy_bind(d, &pt_irq_bind); + return rc; + } + } =20 - if ( !desc ) - { - pt_irq_destroy_bind(d, &pt_irq_bind); - return -EINVAL; - } + if ( unmasked ) + { + struct xen_domctl_bind_pt_irq pt_irq_bind =3D { + .machine_irq =3D machine_irq, + .irq_type =3D PT_IRQ_TYPE_MSI, + }; + unsigned long flags; + struct irq_desc *desc =3D pirq_spin_lock_irq_desc(info, &flags); =20 - guest_mask_msi_irq(desc, false); - spin_unlock_irqrestore(&desc->lock, flags); + if ( !desc ) + { + pt_irq_destroy_bind(d, &pt_irq_bind); + return -EINVAL; } =20 - return 0; + guest_mask_msi_irq(desc, false); + spin_unlock_irqrestore(&desc->lock, flags); } + + return 0; } =20 int pt_irq_create_bind( --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35a9.39c8d9bf421e1e25.1a0679ed57e.33cdc81cbace567b=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444891; cv=none; d=zohomail.com; s=zohoarc; b=TOcevSfUJh81NTRCeHmYxqrRY5f2+f+jKsoWsA/R3ZZRMCUjQfTLiQ0H4CdnU6ZNMhp7HE8qJZSvtIb3R1YLcNg+/ej0/dzWz9qjfkudOfZEM8mC3KY2F+T+nTn3fFqKXqxD0Mx1aEtAMH6omxtY0O43RZ7UOcZ+Wg/EdgTuKXk= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444891; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=9x3EXxYPO7WpUDT21fZIhOifLMj2tjMarh2jBk7e3DU=; b=Kt+OQ6xiPcDf6CU8eiK4maLRrYjuPqz0ZI3QiedteGwiloVQtCaw00I5pnjLGJX15cnZ1k2phFrGr7x7dqjlFkg59qg8HBG7GgA03ruaKUtuqJj2NgYGU1p2PNqXjih9TVNagfFrTRzBY2Zo/JpCLqv5n+qEXVlR56qcW14++bc= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444891137134.12221506895742; Thu, 3 Sep 2026 07:14:51 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407261.1640390 (Exim 4.92) (envelope-from ) id 1x28D6-0006i3-5b; Thu, 03 Sep 2026 14:14:36 +0000 Received: by outflank-mailman (output) from mailman id 1407261.1640390; Thu, 03 Sep 2026 14:14:36 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D6-0006hK-0o; Thu, 03 Sep 2026 14:14:36 +0000 Received: by outflank-mailman (input) for mailman id 1407261; Thu, 03 Sep 2026 14:14:34 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D3-0006R8-Tz for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:34 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28D3-001H4c-AX for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:33 +0200 Received: from [10.42.69.6] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980c3-2eae-0a2a0a5409dd-0a2a4506ae08-20 for ; Thu, 03 Sep 2026 16:14:33 +0200 Received: from [185.255.28.35] (helo=prod-mta-13-02.swg-srv.net) by tlsNG-16d1c6.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980c0-195a-0a2a45060019-b9ff1c238775-8 for ; Thu, 03 Sep 2026 16:14:33 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-02.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed87d000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:18 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id CF48B8400F; Thu, 3 Sep 2026 16:14:17 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=9x3EXxYPO7WpUDT21fZIhOifLMj2tjMarh2jBk7e3DU=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=AeGq01d8R+kU3cs6YUzPsJKWAuirprXqvRt+LyGVvWjb4l6mvOPxQ9l6RXsRf8ML5WFtOhFiE k3F64rXkCqM52PeggiU8KCsuMIA4CVf5pbDLeGJOpOB7kJ5BFz7OjakikHFB4hdjMPLViecOXKn j8mFKQt6N2Mwrbu/pgcpkYqw0g47UzIIVG8RPKvERoFfbfvgij1k+8HvW9YyAnOFVr6Un4iA/1x pyFpzSDhggZDJmTqjkc0ja7Rp19HGFKwwPjd0Djd0DV9mApUFQK8Dn0WJDz1ULOsbXsL8KbXpCN Q/acgedcn5WbXGVzb3gTaOPABzJ4bj+Wkm5PFrQiKmjw== X-Zone-Loop: e2860f3bf6f5c88daf4c29b74384454ffc27abbcc75f x-campaign-type: default x-transaction-id: 87ba8cff-7c68-402f-8f6a-a1082e0cd86e x-swg-uid: 01-480ed2de-1b84-429f-93f3-a1548f6fd399 X-Mailer: Sweego Message-ID: <1788444858.8631fc262581453bbf619ec5b2062170.1a0679ed87d000c4f3@vates.tech> x-swg-bid: 1788444858.8631fc262581453bbf619ec5b2062170.1a0679ed87d000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 07/11] x86/passthrough: Switch pt_irq_bind_msi() to raw MSI address/data Date: Thu, 3 Sep 2026 16:14:05 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35aa.daf7bf3a43bd1d0b.1a0679ed6ce.2c4e65cada2122c3=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444858062 X-purgate-ID: tlsNG-16d1c6/1788444873-1ECC577B-49595DC8/0/0 X-purgate-type: clean X-purgate-size: 18045 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444892368158500 ---=Part.35aa.daf7bf3a43bd1d0b.1a0679ed6ce.2c4e65cada2122c3=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Some hypervisors let a guest use the "Extended Destination ID" field of the MSI address (and the IO-APIC RTE) to reach APIC IDs beyond the architectural 8-bit destination field, extending the range from 8 to 15 bits (as supported by Linux since commit ab0f59c6f135). This way an HVM guest with APIC IDs above 254 can target an MSI or IO-APIC interrupt. This series adds support for it, gated on the guest's device model opting in. Change pt_irq_bind_msi() (and struct hvm_gmsi_info) to store and operate on the raw MSI address and data words instead of the pre-decoded gvec/gflags pair. A new MSI_ADDR_DEST() helper extracts the combined destination ID from an address, including the extended bits (address 11:5). The extended part is always zero for the messages built here and is only acted upon once the guest opts in. pt_irq_bind_msi() now also rejects (-EINVAL) an address that isn't in MSI format (0xfeexxxxx), so that every path storing into gmsi.addr, in particular the raw-address device-model op, is guaranteed a well-formed message. The function vpci_msi_update() already performed this check. pt_irq_create_bind() keeps working for domctl callers by rebuilding a raw MSI message from the gflags it is handed. vpci_msi_update() now calls pt_irq_bind_msi() directly and msi_gflags() goes away. The "already mapped" fast path now compares the full stored address and data rather than just gvec/gflags. This is not a behavioural change: the previous gvec/gflags pair was a loss-free re-encoding of exactly the destination, delivery-mode, trigger-mode and vector bits that address/data carry, so any message that would have compared equal before still does, and messages differing only in bits that were previously dropped now correctly trigger a re-program. No functional change for existing (8-bit destination ID) guests. Signed-off-by: Julian Vetter --- Changes in v5: - Retitled: "Switch pt_irq_bind_msi() to raw MSI address/data" - struct hvm_gmsi_info stores addr/data, so msi_gflags() is gone and vpci_msi_update() calls pt_irq_bind_msi() directly. - MSI_ADDR_DEST() derives its shift from a new MSI_ADDR_DEST_ID_WIDTH. The original MSI_ADDR_DEST_ID_* lines are left untouched. - Removed the "Intel convention" wording in the comment. - pt_irq_bind_msi() rejects an address that isn't in MSI format (0xfeexxxxx) with -EINVAL, so every caller storing into gmsi.addr is guaranteed a well-formed message. Per Jan's comment: "cope with existing code passing rubbish there ... e.g. in vpci_msi_update()". - _hvm_dpci_msi_eoi() dest-mode bug fixed: it tested XEN_DOMCTL_VMSI_X86_DM_MASK against a raw address, now uses MSI_ADDR_DESTMODE_MASK. - vmsi_deliver_pirq() reads gmsi.addr/gmsi.data with the standard MSI masks (v4 kept XEN_DOMCTL_VMSI_X86_FULL_DEST()). - pt_irq_create_bind()'s PT_IRQ_TYPE_MSI case keeps working here by rebuilding a raw message from gflags (v4 rejected it with -EOPNOTSUPP). - Commit message explains why the "already mapped" comparison widened to full addr/data. - Use MASK_EXTR/MASK_INSR throughout. Signed-off-by: Julian Vetter --- xen/arch/x86/hvm/vmsi.c | 53 +++++++-------------- xen/arch/x86/include/asm/hvm/irq.h | 4 +- xen/arch/x86/include/asm/msi.h | 19 ++++++++ xen/drivers/passthrough/x86/hvm.c | 75 +++++++++++++++++++----------- xen/include/xen/iommu.h | 3 ++ 5 files changed, 91 insertions(+), 63 deletions(-) diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 27b1f089e2..6966cabfa7 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -43,6 +43,7 @@ #include #include #include +#include =20 static void vmsi_inj_irq( struct vlapic *target, @@ -107,12 +108,13 @@ int vmsi_deliver( =20 void vmsi_deliver_pirq(struct domain *d, const struct hvm_pirq_dpci *pirq_= dpci) { - uint32_t flags =3D pirq_dpci->gmsi.gflags; - int vector =3D pirq_dpci->gmsi.gvec; - uint8_t dest =3D (uint8_t)flags; - bool dest_mode =3D flags & XEN_DOMCTL_VMSI_X86_DM_MASK; - uint8_t delivery_mode =3D MASK_EXTR(flags, XEN_DOMCTL_VMSI_X86_DELIV_M= ASK); - bool trig_mode =3D flags & XEN_DOMCTL_VMSI_X86_TRIG_MASK; + uint64_t addr =3D pirq_dpci->gmsi.addr; + uint32_t data =3D pirq_dpci->gmsi.data; + unsigned int vector =3D MASK_EXTR(data, MSI_DATA_VECTOR_MASK); + uint32_t dest =3D MSI_ADDR_DEST(addr); + bool dest_mode =3D addr & MSI_ADDR_DESTMODE_MASK; + unsigned int delivery_mode =3D MASK_EXTR(data, MSI_DATA_DELIVERY_MODE_= MASK); + bool trig_mode =3D data & MSI_DATA_TRIGGER_MASK; =20 HVM_DBG_LOG(DBG_LEVEL_IOAPIC, "msi: dest=3D%x dest_mode=3D%x delivery_mode=3D%x " @@ -793,27 +795,6 @@ void msix_write_completion(struct vcpu *v) } =20 #ifdef CONFIG_HAS_VPCI -static unsigned int msi_gflags(uint16_t data, uint64_t addr, bool masked) -{ - /* - * We need to use the DOMCTL constants here because the output of this - * function is used as input to pt_irq_create_bind, which also takes t= he - * input from the DOMCTL itself. - */ - return MASK_INSR(MASK_EXTR(addr, MSI_ADDR_DEST_ID_MASK), - XEN_DOMCTL_VMSI_X86_DEST_ID_MASK) | - MASK_INSR(MASK_EXTR(addr, MSI_ADDR_REDIRECTION_MASK), - XEN_DOMCTL_VMSI_X86_RH_MASK) | - MASK_INSR(MASK_EXTR(addr, MSI_ADDR_DESTMODE_MASK), - XEN_DOMCTL_VMSI_X86_DM_MASK) | - MASK_INSR(MASK_EXTR(data, MSI_DATA_DELIVERY_MODE_MASK), - XEN_DOMCTL_VMSI_X86_DELIV_MASK) | - MASK_INSR(MASK_EXTR(data, MSI_DATA_TRIGGER_MASK), - XEN_DOMCTL_VMSI_X86_TRIG_MASK) | - /* NB: by default MSI vectors are bound masked. */ - (masked ? 0 : XEN_DOMCTL_VMSI_X86_UNMASKED); -} - static void vpci_mask_pirq(struct domain *d, int pirq, bool mask) { unsigned long flags; @@ -850,17 +831,19 @@ static int vpci_msi_update(const struct pci_dev *pdev= , uint32_t data, { uint8_t vector =3D MASK_EXTR(data, MSI_DATA_VECTOR_MASK); uint8_t vector_mask =3D 0xff >> (8 - fls(vectors) + 1); - struct xen_domctl_bind_pt_irq bind =3D { - .machine_irq =3D pirq + i, - .irq_type =3D PT_IRQ_TYPE_MSI, - .u.msi.gvec =3D (vector & ~vector_mask) | - ((vector + i) & vector_mask), - .u.msi.gflags =3D msi_gflags(data, address, (mask >> i) & 1), - }; - int rc =3D pt_irq_create_bind(pdev->domain, &bind); + uint8_t gvec =3D (vector & ~vector_mask) | ((vector + i) & vector_= mask); + uint32_t msi_data =3D (data & ~MSI_DATA_VECTOR_MASK) | + MASK_INSR(gvec, MSI_DATA_VECTOR_MASK); + int rc =3D pt_irq_bind_msi(pdev->domain, pirq + i, address, msi_da= ta, + 0 /* gtable */, !((mask >> i) & 1)); =20 if ( rc ) { + struct xen_domctl_bind_pt_irq bind =3D { + .irq_type =3D PT_IRQ_TYPE_MSI, + .machine_irq =3D pirq + i, + }; + gdprintk(XENLOG_ERR, "%pp: failed to bind PIRQ %u: %d\n", &pdev->sbdf, pirq + i, rc); while ( bind.machine_irq-- > pirq ) diff --git a/xen/arch/x86/include/asm/hvm/irq.h b/xen/arch/x86/include/asm/= hvm/irq.h index 77595fb3f4..e79e2e3fed 100644 --- a/xen/arch/x86/include/asm/hvm/irq.h +++ b/xen/arch/x86/include/asm/hvm/irq.h @@ -120,8 +120,8 @@ struct dev_intx_gsi_link { #define HVM_IRQ_DPCI_TRANSLATE (1u << _HVM_IRQ_DPCI_TRANSLATE_SHIFT) =20 struct hvm_gmsi_info { - uint32_t gvec; - uint32_t gflags; + uint64_t addr; /* raw MSI address (0xfeexxxxx) */ + uint32_t data; /* raw MSI data (vector, delivery mode, trigger mode) */ int dest_vcpu_id; /* -1 :multi-dest, non-negative: dest_vcpu_id */ bool posted; /* directly deliver to guest via VT-d PI? */ }; diff --git a/xen/arch/x86/include/asm/msi.h b/xen/arch/x86/include/asm/msi.h index 6fb663b2e7..a553922853 100644 --- a/xen/arch/x86/include/asm/msi.h +++ b/xen/arch/x86/include/asm/msi.h @@ -54,6 +54,25 @@ #define MSI_ADDR_DEST_ID_MASK 0x00ff000 #define MSI_ADDR_DEST_ID(dest) (((dest) << MSI_ADDR_DEST_ID_SHIFT) & MSI= _ADDR_DEST_ID_MASK) =20 +/* Width of the architectural destination ID field (MSI address bits 19:12= ). */ +#define MSI_ADDR_DEST_ID_WIDTH 8 + +/* + * "Extended Destination ID": MSI address bits 11:5 carry the top 7 bits o= f a + * 15-bit APIC ID, extending the reachable destination range from 8 to 15 = bits. + * A guest is told this is available via XEN_HVM_CPUID_EXT_DEST_ID. The Li= nux + * guest side is x86_msi_msg_get_destid() in arch/x86/kernel/apic/apic.c. + * + * Only interpret these bits this way for a guest that has opted in. Other= wise + * treat them as reserved and ignore them. + */ +#define MSI_ADDR_EXT_DEST_ID_MASK 0x0000fe0 + +/* Combine the architectural and extended destination bits of an MSI addre= ss. */ +#define MSI_ADDR_DEST(addr) \ + (MASK_EXTR(addr, MSI_ADDR_DEST_ID_MASK) | \ + (MASK_EXTR(addr, MSI_ADDR_EXT_DEST_ID_MASK) << MSI_ADDR_DEST_ID_WIDTH= )) + /* MAX fixed pages reserved for mapping MSIX tables. */ #define FIX_MSIX_MAX_PAGES 512 =20 diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index 5fdb885311..bdab065eb7 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -287,19 +287,24 @@ static int pt_irq_dpci_setup(struct domain *d, unsign= ed int pirq, return 0; } =20 -static int pt_irq_bind_msi(struct domain *d, unsigned int machine_irq, - uint8_t gvec, unsigned int gflags, uint64_t gta= ble, - bool unmasked) +int pt_irq_bind_msi(struct domain *d, unsigned int machine_irq, + uint64_t msi_addr, uint32_t msi_data, + uint64_t gtable, bool unmasked) { struct hvm_irq_dpci *hvm_irq_dpci; struct hvm_pirq_dpci *pirq_dpci; struct pirq *info; int rc; - uint8_t dest, delivery_mode; + uint8_t gvec; + uint32_t dest; bool dest_mode; int dest_vcpu_id; const struct vcpu *vcpu; =20 + /* A passthrough MSI must carry an MSI-format address (0xfeexxxxx). */ + if ( (msi_addr & MSI_ADDR_BASE_MASK) !=3D MSI_ADDR_HEADER ) + return -EINVAL; + rc =3D pt_irq_dpci_setup(d, machine_irq, &hvm_irq_dpci, &pirq_dpci, &i= nfo); if ( rc ) return rc; @@ -308,8 +313,8 @@ static int pt_irq_bind_msi(struct domain *d, unsigned i= nt machine_irq, { pirq_dpci->flags =3D HVM_IRQ_DPCI_MAPPED | HVM_IRQ_DPCI_MACH_MSI | HVM_IRQ_DPCI_GUEST_MSI; - pirq_dpci->gmsi.gvec =3D gvec; - pirq_dpci->gmsi.gflags =3D gflags; + pirq_dpci->gmsi.addr =3D msi_addr; + pirq_dpci->gmsi.data =3D msi_data; /* * 'pt_irq_bind_msi' can be called after 'pt_irq_destroy_bind'. * The 'pirq_cleanup_check' which would free the structure is only @@ -341,8 +346,8 @@ static int pt_irq_bind_msi(struct domain *d, unsigned i= nt machine_irq, } if ( unlikely(rc) ) { - pirq_dpci->gmsi.gflags =3D 0; - pirq_dpci->gmsi.gvec =3D 0; + pirq_dpci->gmsi.addr =3D 0; + pirq_dpci->gmsi.data =3D 0; pirq_dpci->dom =3D NULL; pirq_dpci->flags =3D 0; if ( !info->evtchn ) @@ -362,23 +367,22 @@ static int pt_irq_bind_msi(struct domain *d, unsigned= int machine_irq, } =20 /* If pirq is already mapped as vmsi, update guest data/addr. */ - if ( pirq_dpci->gmsi.gvec !=3D gvec || - pirq_dpci->gmsi.gflags !=3D gflags ) + if ( pirq_dpci->gmsi.addr !=3D msi_addr || + pirq_dpci->gmsi.data !=3D msi_data ) { /* Directly clear pending EOIs before enabling new MSI info. */ pirq_guest_eoi(info); =20 - pirq_dpci->gmsi.gvec =3D gvec; - pirq_dpci->gmsi.gflags =3D gflags; + pirq_dpci->gmsi.addr =3D msi_addr; + pirq_dpci->gmsi.data =3D msi_data; } } =20 /* Calculate dest_vcpu_id for MSI-type pirq migration. */ - dest =3D MASK_EXTR(pirq_dpci->gmsi.gflags, - XEN_DOMCTL_VMSI_X86_DEST_ID_MASK); - dest_mode =3D pirq_dpci->gmsi.gflags & XEN_DOMCTL_VMSI_X86_DM_MASK; - delivery_mode =3D MASK_EXTR(pirq_dpci->gmsi.gflags, - XEN_DOMCTL_VMSI_X86_DELIV_MASK); + gvec =3D MASK_EXTR(msi_data, MSI_DATA_VECTOR_MASK); + dest =3D MSI_ADDR_DEST(msi_addr); + dest_mode =3D msi_addr & MSI_ADDR_DESTMODE_MASK; + delivery_mode =3D MASK_EXTR(msi_data, MSI_DATA_DELIVERY_MODE_MASK); =20 dest_vcpu_id =3D hvm_girq_dest_2_vcpu_id(d, dest, dest_mode); pirq_dpci->gmsi.dest_vcpu_id =3D dest_vcpu_id; @@ -389,8 +393,7 @@ static int pt_irq_bind_msi(struct domain *d, unsigned i= nt machine_irq, if ( iommu_intpost ) { if ( delivery_mode =3D=3D dest_LowestPrio ) - vcpu =3D vector_hashing_dest(d, dest, dest_mode, - pirq_dpci->gmsi.gvec); + vcpu =3D vector_hashing_dest(d, dest, dest_mode, gvec); if ( vcpu ) pirq_dpci->gmsi.posted =3D true; } @@ -405,7 +408,7 @@ static int pt_irq_bind_msi(struct domain *d, unsigned i= nt machine_irq, .irq_type =3D PT_IRQ_TYPE_MSI, }; =20 - rc =3D hvm_pi_update_irte(vcpu, info, pirq_dpci->gmsi.gvec); + rc =3D hvm_pi_update_irte(vcpu, info, gvec); if ( rc ) { pt_irq_destroy_bind(d, &pt_irq_bind); @@ -448,9 +451,30 @@ int pt_irq_create_bind( case PT_IRQ_TYPE_MSI: { unsigned int gflags =3D pt_irq_bind->u.msi.gflags; + uint64_t msi_addr; + uint32_t msi_data; =20 - return pt_irq_bind_msi(d, pirq, pt_irq_bind->u.msi.gvec, - gflags & ~XEN_DOMCTL_VMSI_X86_UNMASKED, + /* + * Rebuild a raw MSI message from the pre-decoded domctl gflags so= the + * canonical bind path can decode it uniformly. This legacy path n= ever + * carries extended destination ID bits. + */ + msi_addr =3D MSI_ADDR_HEADER | + MASK_INSR(MASK_EXTR(gflags, XEN_DOMCTL_VMSI_X86_DEST_ID= _MASK), + MSI_ADDR_DEST_ID_MASK) | + (gflags & XEN_DOMCTL_VMSI_X86_RH_MASK + ? MSI_ADDR_REDIRECTION_LOWPRI + : MSI_ADDR_REDIRECTION_CPU) | + (gflags & XEN_DOMCTL_VMSI_X86_DM_MASK + ? MSI_ADDR_DESTMODE_LOGIC + : MSI_ADDR_DESTMODE_PHYS); + msi_data =3D MASK_INSR(pt_irq_bind->u.msi.gvec, MSI_DATA_VECTOR_MA= SK) | + MASK_INSR(MASK_EXTR(gflags, XEN_DOMCTL_VMSI_X86_DELIV_M= ASK), + MSI_DATA_DELIVERY_MODE_MASK) | + (gflags & XEN_DOMCTL_VMSI_X86_TRIG_MASK + ? MSI_DATA_TRIGGER_LEVEL : 0); + + return pt_irq_bind_msi(d, pt_irq_bind->machine_irq, msi_addr, msi_= data, pt_irq_bind->u.msi.gtable, gflags & XEN_DOMCTL_VMSI_X86_UNMASKED); } @@ -857,11 +881,10 @@ static int cf_check _hvm_dpci_msi_eoi( int vector =3D (long)arg; =20 if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) && - (pirq_dpci->gmsi.gvec =3D=3D vector) ) + MASK_EXTR(pirq_dpci->gmsi.data, MSI_DATA_VECTOR_MASK) =3D=3D vect= or ) { - unsigned int dest =3D MASK_EXTR(pirq_dpci->gmsi.gflags, - XEN_DOMCTL_VMSI_X86_DEST_ID_MASK); - bool dest_mode =3D pirq_dpci->gmsi.gflags & XEN_DOMCTL_VMSI_X86_DM= _MASK; + unsigned int dest =3D MSI_ADDR_DEST(pirq_dpci->gmsi.addr); + bool dest_mode =3D pirq_dpci->gmsi.addr & MSI_ADDR_DESTMODE_MASK; =20 if ( vlapic_match_dest(vcpu_vlapic(current), NULL, 0, dest, dest_mode) ) diff --git a/xen/include/xen/iommu.h b/xen/include/xen/iommu.h index 37c4a1dc82..d68d9ca6ec 100644 --- a/xen/include/xen/iommu.h +++ b/xen/include/xen/iommu.h @@ -222,6 +222,9 @@ int pt_irq_create_bind(struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind); int pt_irq_destroy_bind(struct domain *d, const struct xen_domctl_bind_pt_irq *pt_irq_bind); +int pt_irq_bind_msi(struct domain *d, unsigned int machine_irq, + uint64_t msi_addr, uint32_t msi_data, + uint64_t gtable, bool unmasked); =20 struct hvm_irq_dpci *domain_get_irq_dpci(const struct domain *d); void free_hvm_irq_dpci(struct hvm_irq_dpci *dpci); --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35aa.daf7bf3a43bd1d0b.1a0679ed6ce.2c4e65cada2122c3=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444906; cv=none; d=zohomail.com; s=zohoarc; b=kV5gtGZSaq3dFnNtUybDoikeXLQ0yurCTShLeXKzTC80PmLMkOBrzFPGtEt2O4z6WZ3uefNT4h26ffdD18Kn2rMs1YU2+0c7Y0X8qpzKbvNlLyBhrVZGfQnItWyKxdn7pGA3hEcVJ0cQReBqxgB4ykEHueMhgLToJMS9A8yhUDw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444906; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=TFc5nplCWpPWb6TL9VVLyQHid2vUkbZ6H31MHV3pWe0=; b=YAs4mxKa1TSu2UYs0hNxy5u8ypT61AM5n/jCttcbBMP/J2W83h0qTmJ8JltVUvov8v7w5mCn5dJsjHvmHBEeroPMa2Ufk7O9u7LgUwbkj4a8r3KLhF7mzfbSkcAIsB57EBOuBGtD4+yiq3YSWMWiBYhEQxvZTCpHIsEudScMsag= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444906321897.6971661738521; Thu, 3 Sep 2026 07:15:06 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407263.1640399 (Exim 4.92) (envelope-from ) id 1x28D7-0006yY-J4; Thu, 03 Sep 2026 14:14:37 +0000 Received: by outflank-mailman (output) from mailman id 1407263.1640399; Thu, 03 Sep 2026 14:14:37 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D7-0006xz-F5; Thu, 03 Sep 2026 14:14:37 +0000 Received: by outflank-mailman (input) for mailman id 1407263; Thu, 03 Sep 2026 14:14:36 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D6-0006kV-GH for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:36 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28D5-001H4c-SG for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:35 +0200 Received: from [10.42.69.5] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980bd-2eae-0a2a0a5409dd-0a2a4505c668-28 for ; Thu, 03 Sep 2026 16:14:35 +0200 Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net) by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980cb-4cb1-0a2a45050019-b9ff1c228579-3 for ; Thu, 03 Sep 2026 16:14:35 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ed9b9000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:18 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 2C59784011; Thu, 3 Sep 2026 16:14:18 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=TFc5nplCWpPWb6TL9VVLyQHid2vUkbZ6H31MHV3pWe0=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=Qp7WExPsUYQbCeHcj9T3b90YMy2Y1LVopsrlS0Fqk5ae8aJdDC5TZZn8NzqdpcMl6XM3YMdUC wqmM89twND3GP1h+LjbpIK/xQfq77SKbdvLWAbPMc3w0Se9yGIjzDcb0v0Yp58PPFuixq152qEn v73FMgK2G2oymjkIuMaak4H9c/OzgbnZ80NTfPW1+D2XdDJPPWSX2YX4JhM5nSdvYtQDihIdfrW n2K6kwe15kZ/usQtzoayZYaPS90lZz9jcfQPGznMzzyz20JPOOBN+o1GQqNaYHDLDve3R71pfmo hvZIy8cN3yHhdH0EoCD/tsMzPHI+Ol06eaTHt+eQkD9Q== X-Zone-Loop: f743ef71d49e150dfec641ea08342951af9fe89bf7a2 x-campaign-type: default x-transaction-id: 071547b2-5152-4e0e-b954-168722a7635b x-swg-uid: 01-2e75de1e-8a2a-4c83-9194-d44ac0952cc7 X-Mailer: Sweego Message-ID: <1788444858.8631fc262581453bbf619ec5b2062170.1a0679ed9b9000c4f3@vates.tech> x-swg-bid: 1788444858.8631fc262581453bbf619ec5b2062170.1a0679ed9b9000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 08/11] x86/hvm: Decode extended MSI / IO-APIC destination IDs when opted in Date: Thu, 3 Sep 2026 16:14:06 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35ab.e5d7a6729895094a.1a0679ed81d.65b008e6a50fbf51=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444858397 X-purgate-ID: tlsNG-c201ff/1788444875-F6CB02A1-8B16E8B3/0/0 X-purgate-type: clean X-purgate-size: 11092 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444908492158500 ---=Part.35ab.e5d7a6729895094a.1a0679ed81d.65b008e6a50fbf51=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add the plumbing to allow for 15-bit destination IDs: - struct hvm_domain gains a tri-state ext_dest_id (UNSET / DISABLED / ENABLED). hvm_ext_dest_id_active() is the single point to guard every extended decode. - The vIO-APIC RTE save record grows an ext_dest_id:7 field (the top 7 bits of a 15-bit APIC ID) and VIOAPIC_RTE_DEST() combines it with dest_id. - vmsi_deliver() / hvm_girq_dest_2_vcpu_id() take a uint32_t dest. - hvm_inject_msi(), vioapic_deliver(), vmsi_deliver_pirq(), pt_irq_bind_msi() and _hvm_dpci_msi_eoi() fold in the extended bits only when hvm_ext_dest_id_active(), otherwise an unaware guest that left non-zero values in those bits would have its interrupts misrouted. Since ext_dest_id is never ENABLED yet, there is no functional change. Signed-off-by: Julian Vetter --- Changes in v5: - Rewritten to use a tri-state d->arch.hvm.ext_dest_id (UNSET / DISABLED / ENABLED). - Addressed Jan's comment about "wrong way round": every decode site folds in the extended bits only when active and ignores them otherwise, rather than rejecting a guest that left values there. - VIOAPIC_RTE_DEST() takes a union vioapic_redir_entry and uses .dest_id / .ext_dest_id. - Replaced comments and added one central explanation. Signed-off-by: Julian Vetter --- xen/arch/x86/hvm/irq.c | 6 ++++-- xen/arch/x86/hvm/vioapic.c | 5 ++++- xen/arch/x86/hvm/vmsi.c | 8 +++++--- xen/arch/x86/include/asm/hvm/domain.h | 13 +++++++++++++ xen/arch/x86/include/asm/hvm/hvm.h | 12 ++++++++++-- xen/arch/x86/include/asm/hvm/vioapic.h | 10 ++++++++++ xen/drivers/passthrough/x86/hvm.c | 8 ++++++-- xen/include/public/arch-x86/hvm/save.h | 4 +++- 8 files changed, 55 insertions(+), 11 deletions(-) diff --git a/xen/arch/x86/hvm/irq.c b/xen/arch/x86/hvm/irq.c index 5f64361113..aa5926529a 100644 --- a/xen/arch/x86/hvm/irq.c +++ b/xen/arch/x86/hvm/irq.c @@ -374,7 +374,8 @@ int hvm_set_pci_link_route(struct domain *d, u8 link, u= 8 isa_irq) int hvm_inject_msi(struct domain *d, uint64_t addr, uint32_t data) { uint32_t tmp =3D (uint32_t) addr; - uint8_t dest =3D (tmp & MSI_ADDR_DEST_ID_MASK) >> MSI_ADDR_DEST_ID_SH= IFT; + uint8_t dest =3D MASK_EXTR(tmp, MSI_ADDR_DEST_ID_MASK); + uint32_t full_dest =3D hvm_ext_dest_id_active(d) ? MSI_ADDR_DEST(tmp) = : dest; uint8_t dest_mode =3D !!(tmp & MSI_ADDR_DESTMODE_MASK); uint8_t delivery_mode =3D (data & MSI_DATA_DELIVERY_MODE_MASK) >> MSI_DATA_DELIVERY_MODE_SHIFT; @@ -412,7 +413,8 @@ int hvm_inject_msi(struct domain *d, uint64_t addr, uin= t32_t data) return -ERANGE; } =20 - return vmsi_deliver(d, vector, dest, dest_mode, delivery_mode, trig_mo= de); + return vmsi_deliver(d, vector, full_dest, dest_mode, delivery_mode, + trig_mode); } =20 void hvm_set_callback_via(struct domain *d, uint64_t via) diff --git a/xen/arch/x86/hvm/vioapic.c b/xen/arch/x86/hvm/vioapic.c index 80dc9148a9..ca9b34d3ea 100644 --- a/xen/arch/x86/hvm/vioapic.c +++ b/xen/arch/x86/hvm/vioapic.c @@ -39,6 +39,7 @@ #include #include #include +#include =20 /* HACK: Route IRQ0 only to VCPU0 to prevent time jumps. */ #define IRQ0_SPECIAL_ROUTING 1 @@ -413,7 +414,9 @@ static void ioapic_inj_irq( =20 static void vioapic_deliver(struct hvm_vioapic *vioapic, unsigned int pin) { - uint16_t dest =3D vioapic->redirtbl[pin].fields.dest_id; + union vioapic_redir_entry rte =3D vioapic->redirtbl[pin]; + uint32_t dest =3D hvm_ext_dest_id_active(vioapic_domain(vioapic)) + ? VIOAPIC_RTE_DEST(rte) : rte.fields.dest_id; uint8_t dest_mode =3D vioapic->redirtbl[pin].fields.dest_mode; uint8_t delivery_mode =3D vioapic->redirtbl[pin].fields.delivery_mode; uint8_t vector =3D vioapic->redirtbl[pin].fields.vector; diff --git a/xen/arch/x86/hvm/vmsi.c b/xen/arch/x86/hvm/vmsi.c index 6966cabfa7..eede42a202 100644 --- a/xen/arch/x86/hvm/vmsi.c +++ b/xen/arch/x86/hvm/vmsi.c @@ -67,7 +67,7 @@ static void vmsi_inj_irq( =20 int vmsi_deliver( struct domain *d, int vector, - uint8_t dest, uint8_t dest_mode, + uint32_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t trig_mode) { struct vlapic *target; @@ -111,7 +111,9 @@ void vmsi_deliver_pirq(struct domain *d, const struct h= vm_pirq_dpci *pirq_dpci) uint64_t addr =3D pirq_dpci->gmsi.addr; uint32_t data =3D pirq_dpci->gmsi.data; unsigned int vector =3D MASK_EXTR(data, MSI_DATA_VECTOR_MASK); - uint32_t dest =3D MSI_ADDR_DEST(addr); + uint32_t dest =3D hvm_ext_dest_id_active(d) + ? MSI_ADDR_DEST(addr) + : MASK_EXTR(addr, MSI_ADDR_DEST_ID_MASK); bool dest_mode =3D addr & MSI_ADDR_DESTMODE_MASK; unsigned int delivery_mode =3D MASK_EXTR(data, MSI_DATA_DELIVERY_MODE_= MASK); bool trig_mode =3D data & MSI_DATA_TRIGGER_MASK; @@ -127,7 +129,7 @@ void vmsi_deliver_pirq(struct domain *d, const struct h= vm_pirq_dpci *pirq_dpci) } =20 /* Return value, -1 : multi-dests, non-negative value: dest_vcpu_id */ -int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_m= ode) +int hvm_girq_dest_2_vcpu_id(struct domain *d, uint32_t dest, uint8_t dest_= mode) { int dest_vcpu_id =3D -1, w =3D 0; struct vcpu *v; diff --git a/xen/arch/x86/include/asm/hvm/domain.h b/xen/arch/x86/include/a= sm/hvm/domain.h index dd7fa96aad..16f0586907 100644 --- a/xen/arch/x86/include/asm/hvm/domain.h +++ b/xen/arch/x86/include/asm/hvm/domain.h @@ -102,6 +102,19 @@ struct hvm_domain { =20 bool is_s3_suspended; =20 + /* + * Whether extended (15-bit) MSI / IO-APIC destination IDs are honoure= d for + * this domain. Tri-state: EXT_DEST_ID_UNSET until the value is locked= (at + * creation_finished, or restored from a migration stream). Afterwards= it + * is a stable, guest-visible property advertised through + * XEN_HVM_CPUID_EXT_DEST_ID. + */ + enum { + EXT_DEST_ID_UNSET =3D 0, + EXT_DEST_ID_DISABLED, + EXT_DEST_ID_ENABLED, + } ext_dest_id; + /* Compatibility setting for a bug in x2APIC LDR */ bool bug_x2apic_ldr_vcpu_id; =20 diff --git a/xen/arch/x86/include/asm/hvm/hvm.h b/xen/arch/x86/include/asm/= hvm/hvm.h index 16383e1084..cedaa28820 100644 --- a/xen/arch/x86/include/asm/hvm/hvm.h +++ b/xen/arch/x86/include/asm/hvm/hvm.h @@ -296,11 +296,19 @@ uint64_t hvm_get_guest_time_fixed(const struct vcpu *= v, uint64_t at_tsc); =20 int vmsi_deliver( struct domain *d, int vector, - uint8_t dest, uint8_t dest_mode, + uint32_t dest, uint8_t dest_mode, uint8_t delivery_mode, uint8_t trig_mode); struct hvm_pirq_dpci; void vmsi_deliver_pirq(struct domain *d, const struct hvm_pirq_dpci *pirq_= dpci); -int hvm_girq_dest_2_vcpu_id(struct domain *d, uint8_t dest, uint8_t dest_m= ode); +int hvm_girq_dest_2_vcpu_id(struct domain *d, uint32_t dest, uint8_t dest_= mode); + +/* + * True when this domain has extended (15-bit) MSI / IO-APIC destination I= Ds + * enabled. Only then may address[11:5] / RTE[55:49] be folded into the + * destination ID. + */ +#define hvm_ext_dest_id_active(d) \ + ((d)->arch.hvm.ext_dest_id =3D=3D EXT_DEST_ID_ENABLED) =20 enum hvm_intblk hvm_interrupt_blocked(struct vcpu *v, struct hvm_intack intack); diff --git a/xen/arch/x86/include/asm/hvm/vioapic.h b/xen/arch/x86/include/= asm/hvm/vioapic.h index 68af6dce79..3df2aa7fe5 100644 --- a/xen/arch/x86/include/asm/hvm/vioapic.h +++ b/xen/arch/x86/include/asm/hvm/vioapic.h @@ -32,6 +32,16 @@ #define VIOAPIC_EDGE_TRIG 0 #define VIOAPIC_LEVEL_TRIG 1 =20 +/* + * Combined 15-bit destination ID of an IO-APIC redirection table entry: t= he + * architectural dest_id byte plus the 7 "Extended Destination ID" bits. T= he + * caller is responsible for only using the extended part when the guest h= as + * opted in (hvm_ext_dest_id_active()). + */ +#define VIOAPIC_RTE_DEST(rte) \ + ((rte).fields.dest_id | \ + ((uint32_t)(rte).fields.ext_dest_id << MSI_ADDR_DEST_ID_WIDTH)) + #define VIOAPIC_DEFAULT_BASE_ADDRESS 0xfec00000U #define VIOAPIC_MEM_LENGTH 0x100 =20 diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index bdab065eb7..a13dd86610 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -380,7 +380,8 @@ int pt_irq_bind_msi(struct domain *d, unsigned int mach= ine_irq, =20 /* Calculate dest_vcpu_id for MSI-type pirq migration. */ gvec =3D MASK_EXTR(msi_data, MSI_DATA_VECTOR_MASK); - dest =3D MSI_ADDR_DEST(msi_addr); + dest =3D hvm_ext_dest_id_active(d) ? MSI_ADDR_DEST(msi_addr) + : MASK_EXTR(msi_addr, MSI_ADDR_DEST_I= D_MASK); dest_mode =3D msi_addr & MSI_ADDR_DESTMODE_MASK; delivery_mode =3D MASK_EXTR(msi_data, MSI_DATA_DELIVERY_MODE_MASK); =20 @@ -883,7 +884,10 @@ static int cf_check _hvm_dpci_msi_eoi( if ( (pirq_dpci->flags & HVM_IRQ_DPCI_MACH_MSI) && MASK_EXTR(pirq_dpci->gmsi.data, MSI_DATA_VECTOR_MASK) =3D=3D vect= or ) { - unsigned int dest =3D MSI_ADDR_DEST(pirq_dpci->gmsi.addr); + unsigned int dest =3D hvm_ext_dest_id_active(d) + ? MSI_ADDR_DEST(pirq_dpci->gmsi.addr) + : MASK_EXTR(pirq_dpci->gmsi.addr, + MSI_ADDR_DEST_ID_MASK); bool dest_mode =3D pirq_dpci->gmsi.addr & MSI_ADDR_DESTMODE_MASK; =20 if ( vlapic_match_dest(vcpu_vlapic(current), NULL, 0, dest, diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/ar= ch-x86/hvm/save.h index 44d7924777..ff73b83d65 100644 --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -359,7 +359,9 @@ union vioapic_redir_entry uint8_t trig_mode:1; uint8_t mask:1; uint8_t reserve:7; - uint8_t reserved[4]; + uint8_t reserved[3]; + uint8_t reserved2:1; + uint8_t ext_dest_id:7; uint8_t dest_id; } fields; }; --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35ab.e5d7a6729895094a.1a0679ed81d.65b008e6a50fbf51=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444903; cv=none; d=zohomail.com; s=zohoarc; b=Z5hDoKRqDIylvP4hwSLdesjgsHYbMgSs3UdJWq+Lb/4xzp/7bSI3eA6GSQO/lbaUTeHl+lCfFcT4euk4GK3i5ZDgFtuNR1Ot51hEVBGQT7cSzR8JeDlyNNYS/5JytIgnz2ZJ1zUAsFIx6ahI1q9RjRXvtbmy++eISZBuwn3VF9I= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444903; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=wLovsWfA/SxNUKrf8umHetWd6JDKT68QQwT/Ms2jeAk=; b=oHgJH/7MxQdyK3StVZquBRmFtW4PEQYxn3dpPQSTn91aLG0Zxz8FbR37G4m9q6WTtJ0pnahU46AUivTQvNjBlQbgrs+j9C4i8D1GyK/YhaAdGWYYdXOg2C4Pj6NcSNJM5guvXjWYNK6qcYYlUmFbhVu1qjYLwaRQgqBUXxyAKiw= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444903765690.2318169677633; Thu, 3 Sep 2026 07:15:03 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407264.1640408 (Exim 4.92) (envelope-from ) id 1x28D9-0007I9-Qf; Thu, 03 Sep 2026 14:14:39 +0000 Received: by outflank-mailman (output) from mailman id 1407264.1640408; Thu, 03 Sep 2026 14:14:39 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D9-0007Hp-MJ; Thu, 03 Sep 2026 14:14:39 +0000 Received: by outflank-mailman (input) for mailman id 1407264; Thu, 03 Sep 2026 14:14:38 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28D8-00078B-Dn for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:38 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28D7-001HAI-Qu for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:37 +0200 Received: from [10.42.69.5] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980bd-2eae-0a2a0a5409dd-0a2a4505c668-36 for ; Thu, 03 Sep 2026 16:14:37 +0200 Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net) by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980cb-4cb1-0a2a45050019-b9ff1c228579-4 for ; Thu, 03 Sep 2026 16:14:37 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679edb8f000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:19 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 7E94984012; Thu, 3 Sep 2026 16:14:18 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=wLovsWfA/SxNUKrf8umHetWd6JDKT68QQwT/Ms2jeAk=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=nP/sr+vGFFJkyZ1VAg1SeINQH707ziL54maQHXOn7GQMnHAqtoCFWamVjGWkxEOkPvj+TVt0R KRD7haz3aps6W8Cb2b7pSCTD47WerHMg1zja7TAedeDxKAM/nb6cFCNW672KW/PfFqZuzoZH5D+ ruI6L2h3485vn9z++x6LYq5V9FEMgaX+cZB1e5QxumEUuxAYWRfJyUDhk89+LlnXgE1ErgR1RyT 7rDBcJOkjXbQ/aJhab8N2BJgDJKlcp1xOIe2fX1AsS05iJ8O+rYmv7Fwec3Zcur7B41Vf4C4YSW yNwGmHK+VRDACtBNYmzxwaKjSR5M13AHdAneSFqROsHA== X-Zone-Loop: 7533775c6bc53995e4466ee2d95ddc3d244e45d80323 x-campaign-type: default x-transaction-id: 7c40deaf-f49d-44da-93ee-702d62ae6c1e x-swg-uid: 01-58aa0035-e02e-4b8b-aaaa-cff792b813e4 X-Mailer: Sweego Message-ID: <1788444859.8631fc262581453bbf619ec5b2062170.1a0679edb8f000c4f3@vates.tech> x-swg-bid: 1788444859.8631fc262581453bbf619ec5b2062170.1a0679edb8f000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 09/11] x86/dmop: Add XEN_DMOP_{,un}bind_pt_msi_irq Date: Thu, 3 Sep 2026 16:14:07 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35ac.4cbeb03216e9d1fc.1a0679ed967.91135d8424a5c29e=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444858727 X-purgate-ID: tlsNG-c201ff/1788444877-730B22A1-2246DCEF/0/0 X-purgate-type: clean X-purgate-size: 21254 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444904683158501 ---=Part.35ac.4cbeb03216e9d1fc.1a0679ed967.91135d8424a5c29e=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Add two device-model ops that bind / unbind a passthrough interrupt to a guest MSI from the raw MSI message (address + data) the guest programmed. Xen decodes the message itself via pt_irq_bind_msi(), so the emulator needs no knowledge of the MSI layout and, in particular, extended (15-bit) destination IDs are handled without emulator changes. The MSI-X table base is passed as a guest-physical address. Fields are named msg_addr / msg_data / pirq, and the flag is XEN_DMOP_MSI_BIND_UNMASKED. The unbind op only requires a valid pirq mapping, not current IRQ permission, so an emulator can remove a binding even after the device has been deassigned. With this in place, PT_IRQ_TYPE_MSI is removed from XEN_DOMCTL_{,un}bind_pt_irq (returns -EINVAL) and from pt_irq_create_bind(). libxc's xc_domain_{update,unbind}_msi_irq() and vPCI already funnel through pt_irq_bind_msi(). This is an incompatible change for device models still using the domctl sub-case (noted in CHANGELOG.md and public/domctl.h). libxendevicemodel gains xendevicemodel_{,un}bind_pt_msi_irq() (map version VERS_1.5). Signed-off-by: Julian Vetter --- Changes in v5: - Retitled to "{,un}bind_pt_msi_irq". - Struct/flag renamed: pirq (was machine_irq), msg_addr / msg_data (was addr / data), XEN_DMOP_MSI_BIND_UNMASKED (was XEN_DMOP_MSI_FLAG_UNMASKED). - Documented gtable as a guest-physical address. - Diagnostics shortened to "%pd: fn() failed: %ld". - The unbind op drops the current-domain IRQ-permission check, so an emulator can unbind after the device has been deassigned. - Comment added noting access is gated by xsm_dm_op(). - This patch now also removes PT_IRQ_TYPE_MSI: a hard -EINVAL from XEN_DOMCTL_{,un}bind_pt_irq (not -EOPNOTSUPP) and deletion of the now-dead case from pt_irq_create_bind() - Incompatible changes are recorded in CHANGELOG.md and public/domctl.h. - Added the missing libxendevicemodel.map VERS_1.5 entry and Makefile MINOR bump. v4 never exported the new symbols. - Stale XEN_DMOP_enable_ext_dest_id #define and a stray blank line before a typedef removed. Signed-off-by: Julian Vetter --- CHANGELOG.md | 6 ++ tools/include/xendevicemodel.h | 30 +++++++++ tools/libs/ctrl/xc_domain.c | 51 +++++++-------- tools/libs/devicemodel/Makefile | 2 +- tools/libs/devicemodel/core.c | 38 +++++++++++ tools/libs/devicemodel/libxendevicemodel.map | 6 ++ xen/arch/x86/domctl.c | 11 +++- xen/arch/x86/hvm/dm.c | 66 ++++++++++++++++++++ xen/drivers/passthrough/x86/hvm.c | 35 +---------- xen/include/public/hvm/dm_op.h | 38 +++++++++++ xen/include/xlat.lst | 2 + 11 files changed, 221 insertions(+), 64 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index aa1a777dd4..76f5d06c91 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -34,6 +34,9 @@ The format is based on [Keep a Changelog](https://keepach= angelog.com/en/1.0.0/) - On x86: - Enable pf-fixup option by default for PVH dom0. - The libxenguest bzImage loader now uses the system liblz4 library. + - XEN_DOMCTL_{,un}bind_pt_irq no longer accept PT_IRQ_TYPE_MSI, device + models must bind passthrough MSIs via the new + XEN_DMOP_{,un}bind_pt_msi_irq, which carry the raw MSI message. =20 ### Added - Support for per-domain Xenstore quota in C xenstored (includes @@ -47,6 +50,9 @@ The format is based on [Keep a Changelog](https://keepach= angelog.com/en/1.0.0/) - Support for CPIO microcode in discrete multiboot modules. - Introduce get-core-temp command to xenpm to query CPU temperatures on Intel platforms. + - XEN_DMOP_{,un}bind_pt_msi_irq for binding passthrough MSIs from the r= aw + guest MSI message, enabling extended (15-bit) destination IDs for HVM + guests whose device models opt in. =20 - On Arm: - Support for guest suspend and resume to/from RAM via vPSCI. diff --git a/tools/include/xendevicemodel.h b/tools/include/xendevicemodel.h index 227e7fd810..698d719119 100644 --- a/tools/include/xendevicemodel.h +++ b/tools/include/xendevicemodel.h @@ -375,6 +375,36 @@ int xendevicemodel_nr_vcpus( */ int xendevicemodel_restrict(xendevicemodel_handle *dmod, domid_t domid); =20 +/** + * This function binds a passthrough interrupt to a guest MSI, described b= y the + * raw MSI message (address and data) the guest programmed. Xen decodes the + * message itself, so the caller does not need to interpret it. + * + * @parm dmod a handle to an open devicemodel interface. + * @parm domid the domain id to be serviced. + * @parm pirq the pass-through IRQ (pirq). + * @parm msg_addr the MSI message address, as programmed by the guest. + * @parm msg_data the MSI message data, as programmed by the guest. + * @parm gtable the MSI-X table base guest-physical address, or 0 for plai= n MSI. + * @parm unmasked if non-zero, leave the IRQ unmasked after binding. + * @return 0 on success, -1 on failure. + */ +int xendevicemodel_bind_pt_msi_irq( + xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq, + uint64_t msg_addr, uint32_t msg_data, uint64_t gtable, int unmasked); + +/** + * This function unbinds a passthrough interrupt previously bound with + * xendevicemodel_bind_pt_msi_irq. + * + * @parm dmod a handle to an open devicemodel interface. + * @parm domid the domain id to be serviced. + * @parm pirq the pass-through IRQ (pirq). + * @return 0 on success, -1 on failure. + */ +int xendevicemodel_unbind_pt_msi_irq( + xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq); + #endif /* XENDEVICEMODEL_H */ =20 /* diff --git a/tools/libs/ctrl/xc_domain.c b/tools/libs/ctrl/xc_domain.c index 94cfab0fa1..b4eed42f97 100644 --- a/tools/libs/ctrl/xc_domain.c +++ b/tools/libs/ctrl/xc_domain.c @@ -1677,6 +1677,21 @@ int xc_deassign_dt_device( =20 =20 =20 +static void xc_msi_gflags_to_addr_data(uint32_t gvec, uint32_t gflags, + uint64_t *msi_addr, uint32_t *msi_= data) +{ + *msi_addr =3D 0xfee00000U | + ((uint64_t)((gflags & XEN_DOMCTL_VMSI_X86_DEST_ID_MASK) << 12)) | + (gflags & XEN_DOMCTL_VMSI_X86_RH_MASK ? (1U << 3) : 0) | + (gflags & XEN_DOMCTL_VMSI_X86_DM_MASK ? (1U << 2) : 0); + + *msi_data =3D (gvec & 0xff) | + (uint32_t)(((gflags & XEN_DOMCTL_VMSI_X86_DELIV_MASK) >> + (/* shift of XEN_DOMCTL_VMSI_X86_DELIV_MASK */ 12 - + /* MSI data delivery shift */ 8))) | + (gflags & XEN_DOMCTL_VMSI_X86_TRIG_MASK ? (1U << 15) : 0); +} + int xc_domain_update_msi_irq( xc_interface *xch, uint32_t domid, @@ -1685,22 +1700,14 @@ int xc_domain_update_msi_irq( uint32_t gflags, uint64_t gtable) { - int rc; - struct xen_domctl_bind_pt_irq *bind; - struct xen_domctl domctl =3D {}; - - domctl.cmd =3D XEN_DOMCTL_bind_pt_irq; - domctl.domain =3D domid; + uint64_t msi_addr; + uint32_t msi_data; =20 - bind =3D &(domctl.u.bind_pt_irq); - bind->irq_type =3D PT_IRQ_TYPE_MSI; - bind->machine_irq =3D pirq; - bind->u.msi.gvec =3D gvec; - bind->u.msi.gflags =3D gflags; - bind->u.msi.gtable =3D gtable; + xc_msi_gflags_to_addr_data(gvec, gflags, &msi_addr, &msi_data); =20 - rc =3D do_domctl(xch, &domctl); - return rc; + return xendevicemodel_bind_pt_msi_irq(xch->dmod, domid, pirq, + msi_addr, msi_data, gtable, + gflags & XEN_DOMCTL_VMSI_X86_UNM= ASKED); } =20 int xc_domain_unbind_msi_irq( @@ -1710,21 +1717,7 @@ int xc_domain_unbind_msi_irq( uint32_t pirq, uint32_t gflags) { - int rc; - struct xen_domctl_bind_pt_irq *bind; - struct xen_domctl domctl =3D {}; - - domctl.cmd =3D XEN_DOMCTL_unbind_pt_irq; - domctl.domain =3D domid; - - bind =3D &(domctl.u.bind_pt_irq); - bind->irq_type =3D PT_IRQ_TYPE_MSI; - bind->machine_irq =3D pirq; - bind->u.msi.gvec =3D gvec; - bind->u.msi.gflags =3D gflags; - - rc =3D do_domctl(xch, &domctl); - return rc; + return xendevicemodel_unbind_pt_msi_irq(xch->dmod, domid, pirq); } =20 /* Pass-through: binds machine irq to guests irq */ diff --git a/tools/libs/devicemodel/Makefile b/tools/libs/devicemodel/Makef= ile index 20d1d112e7..270bb6c89f 100644 --- a/tools/libs/devicemodel/Makefile +++ b/tools/libs/devicemodel/Makefile @@ -2,7 +2,7 @@ XEN_ROOT =3D $(CURDIR)/../../.. include $(XEN_ROOT)/tools/Rules.mk =20 MAJOR =3D 1 -MINOR =3D 4 +MINOR =3D 5 version-script :=3D libxendevicemodel.map =20 include Makefile.common diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c index 8e619eeb0a..274a8eb28b 100644 --- a/tools/libs/devicemodel/core.c +++ b/tools/libs/devicemodel/core.c @@ -645,6 +645,44 @@ int xendevicemodel_nr_vcpus( return 0; } =20 +int xendevicemodel_bind_pt_msi_irq( + xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq, + uint64_t msg_addr, uint32_t msg_data, uint64_t gtable, int unmasked) +{ + struct xen_dm_op op; + struct xen_dm_op_bind_pt_msi_irq *data; + + memset(&op, 0, sizeof(op)); + + op.op =3D XEN_DMOP_bind_pt_msi_irq; + data =3D &op.u.bind_pt_msi_irq; + + data->pirq =3D pirq; + data->msg_data =3D msg_data; + data->msg_addr =3D msg_addr; + data->gtable =3D gtable; + if ( unmasked ) + data->flags |=3D XEN_DMOP_MSI_BIND_UNMASKED; + + return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op)); +} + +int xendevicemodel_unbind_pt_msi_irq( + xendevicemodel_handle *dmod, domid_t domid, uint32_t pirq) +{ + struct xen_dm_op op; + struct xen_dm_op_unbind_pt_msi_irq *data; + + memset(&op, 0, sizeof(op)); + + op.op =3D XEN_DMOP_unbind_pt_msi_irq; + data =3D &op.u.unbind_pt_msi_irq; + + data->pirq =3D pirq; + + return xendevicemodel_op(dmod, domid, 1, &op, sizeof(op)); +} + int xendevicemodel_restrict(xendevicemodel_handle *dmod, domid_t domid) { return osdep_xendevicemodel_restrict(dmod, domid); diff --git a/tools/libs/devicemodel/libxendevicemodel.map b/tools/libs/devi= cemodel/libxendevicemodel.map index f7f9e3d932..c34b66004e 100644 --- a/tools/libs/devicemodel/libxendevicemodel.map +++ b/tools/libs/devicemodel/libxendevicemodel.map @@ -44,3 +44,9 @@ VERS_1.4 { xendevicemodel_set_irq_level; xendevicemodel_nr_vcpus; } VERS_1.3; + +VERS_1.5 { + global: + xendevicemodel_bind_pt_msi_irq; + xendevicemodel_unbind_pt_msi_irq; +} VERS_1.4; diff --git a/xen/arch/x86/domctl.c b/xen/arch/x86/domctl.c index 51d62617bb..9846df4f88 100644 --- a/xen/arch/x86/domctl.c +++ b/xen/arch/x86/domctl.c @@ -622,6 +622,15 @@ long arch_do_domctl( if ( !is_hvm_domain(d) ) break; =20 + /* + * PT_IRQ_TYPE_MSI is no longer supported here: it can only convey= an + * 8-bit destination ID. Emulators must use XEN_DMOP_bind_pt_msi_i= rq, + * which passes the raw MSI message so Xen can decode it (extended + * destination IDs included). + */ + if ( bind->irq_type =3D=3D PT_IRQ_TYPE_MSI ) + break; + ret =3D xsm_bind_pt_irq(XSM_DM_PRIV, d, bind); if ( ret ) break; @@ -657,7 +666,7 @@ long arch_do_domctl( int irq =3D domain_pirq_to_irq(d, bind->machine_irq); =20 ret =3D -EINVAL; - if ( !is_hvm_domain(d) ) + if ( !is_hvm_domain(d) || bind->irq_type =3D=3D PT_IRQ_TYPE_MSI ) break; =20 ret =3D xsm_unbind_pt_irq(XSM_DM_PRIV, d, bind); diff --git a/xen/arch/x86/hvm/dm.c b/xen/arch/x86/hvm/dm.c index 91f6ca669b..9a6347e873 100644 --- a/xen/arch/x86/hvm/dm.c +++ b/xen/arch/x86/hvm/dm.c @@ -7,6 +7,8 @@ #include #include #include +#include +#include #include #include #include @@ -350,6 +352,8 @@ int dm_op(const struct dmop_args *op_args) [XEN_DMOP_relocate_memory] =3D sizeof(struct xen_= dm_op_relocate_memory), [XEN_DMOP_pin_memory_cacheattr] =3D sizeof(struct xen_= dm_op_pin_memory_cacheattr), [XEN_DMOP_nr_vcpus] =3D sizeof(struct xen_= dm_op_nr_vcpus), + [XEN_DMOP_bind_pt_msi_irq] =3D sizeof(struct xen_= dm_op_bind_pt_msi_irq), + [XEN_DMOP_unbind_pt_msi_irq] =3D sizeof(struct xen_= dm_op_unbind_pt_msi_irq), }; =20 rc =3D rcu_lock_remote_domain_by_id(op_args->domid, &d); @@ -617,6 +621,66 @@ int dm_op(const struct dmop_args *op_args) break; } =20 + case XEN_DMOP_bind_pt_msi_irq: + { + const struct xen_dm_op_bind_pt_msi_irq *data =3D &op.u.bind_pt_msi= _irq; + int irq =3D domain_pirq_to_irq(d, data->pirq); + + rc =3D -EINVAL; + if ( data->pad || (data->flags & ~XEN_DMOP_MSI_BIND_UNMASKED) ) + break; + + /* Access is otherwise gated by xsm_dm_op() at the top of dm_op().= */ + rc =3D -EPERM; + if ( irq <=3D 0 || !irq_access_permitted(current->domain, irq) ) + break; + + rc =3D -ESRCH; + if ( is_iommu_enabled(d) ) + { + read_lock(&d->pci_lock); + rc =3D pt_irq_bind_msi(d, data->pirq, data->msg_addr, data->ms= g_data, + data->gtable, + data->flags & XEN_DMOP_MSI_BIND_UNMASKED); + read_unlock(&d->pci_lock); + } + if ( rc < 0 ) + printk(XENLOG_G_ERR "%pd: pt_irq_bind_msi() failed: %ld\n", d,= rc); + break; + } + + case XEN_DMOP_unbind_pt_msi_irq: + { + const struct xen_dm_op_unbind_pt_msi_irq *data =3D + &op.u.unbind_pt_msi_irq; + struct xen_domctl_bind_pt_irq bind =3D { + .machine_irq =3D data->pirq, + .irq_type =3D PT_IRQ_TYPE_MSI, + }; + int irq =3D domain_pirq_to_irq(d, data->pirq); + + /* + * Only require a valid pirq mapping, not current permission over = it: + * the emulator must be able to tear the binding down even after t= he + * device (and its IRQ) has been deassigned. + */ + rc =3D -EPERM; + if ( irq <=3D 0 ) + break; + + rc =3D -ESRCH; + if ( is_iommu_enabled(d) ) + { + read_lock(&d->pci_lock); + rc =3D pt_irq_destroy_bind(d, &bind); + read_unlock(&d->pci_lock); + } + if ( rc < 0 ) + printk(XENLOG_G_ERR "%pd: pt_irq_destroy_bind() failed: %ld\n", + d, rc); + break; + } + default: rc =3D ioreq_server_dm_op(&op, d, &const_op); break; @@ -653,6 +717,8 @@ CHECK_dm_op_remote_shutdown; CHECK_dm_op_relocate_memory; CHECK_dm_op_pin_memory_cacheattr; CHECK_dm_op_nr_vcpus; +CHECK_dm_op_bind_pt_msi_irq; +CHECK_dm_op_unbind_pt_msi_irq; =20 int compat_dm_op( domid_t domid, unsigned int nr_bufs, XEN_GUEST_HANDLE_PARAM(void) bufs) diff --git a/xen/drivers/passthrough/x86/hvm.c b/xen/drivers/passthrough/x8= 6/hvm.c index a13dd86610..c5d74fcebf 100644 --- a/xen/drivers/passthrough/x86/hvm.c +++ b/xen/drivers/passthrough/x86/hvm.c @@ -449,37 +449,6 @@ int pt_irq_create_bind( =20 switch ( pt_irq_bind->irq_type ) { - case PT_IRQ_TYPE_MSI: - { - unsigned int gflags =3D pt_irq_bind->u.msi.gflags; - uint64_t msi_addr; - uint32_t msi_data; - - /* - * Rebuild a raw MSI message from the pre-decoded domctl gflags so= the - * canonical bind path can decode it uniformly. This legacy path n= ever - * carries extended destination ID bits. - */ - msi_addr =3D MSI_ADDR_HEADER | - MASK_INSR(MASK_EXTR(gflags, XEN_DOMCTL_VMSI_X86_DEST_ID= _MASK), - MSI_ADDR_DEST_ID_MASK) | - (gflags & XEN_DOMCTL_VMSI_X86_RH_MASK - ? MSI_ADDR_REDIRECTION_LOWPRI - : MSI_ADDR_REDIRECTION_CPU) | - (gflags & XEN_DOMCTL_VMSI_X86_DM_MASK - ? MSI_ADDR_DESTMODE_LOGIC - : MSI_ADDR_DESTMODE_PHYS); - msi_data =3D MASK_INSR(pt_irq_bind->u.msi.gvec, MSI_DATA_VECTOR_MA= SK) | - MASK_INSR(MASK_EXTR(gflags, XEN_DOMCTL_VMSI_X86_DELIV_M= ASK), - MSI_DATA_DELIVERY_MODE_MASK) | - (gflags & XEN_DOMCTL_VMSI_X86_TRIG_MASK - ? MSI_DATA_TRIGGER_LEVEL : 0); - - return pt_irq_bind_msi(d, pt_irq_bind->machine_irq, msi_addr, msi_= data, - pt_irq_bind->u.msi.gtable, - gflags & XEN_DOMCTL_VMSI_X86_UNMASKED); - } - case PT_IRQ_TYPE_PCI: case PT_IRQ_TYPE_MSI_TRANSLATE: { @@ -767,8 +736,8 @@ int pt_irq_destroy_bind( msixtbl_pt_unregister(d, pirq); pirq_dpci->flags =3D 0; /* - * See comment in pt_irq_create_bind's PT_IRQ_TYPE_MSI before the - * call to pt_pirq_softirq_reset. + * See the comment in pt_irq_bind_msi() before its call to + * pt_pirq_softirq_reset. */ pt_pirq_softirq_reset(pirq_dpci); =20 diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h index 2bf0fdc1ae..d76777f71f 100644 --- a/xen/include/public/hvm/dm_op.h +++ b/xen/include/public/hvm/dm_op.h @@ -444,6 +444,42 @@ struct xen_dm_op_nr_vcpus { }; typedef struct xen_dm_op_nr_vcpus xen_dm_op_nr_vcpus_t; =20 +/* + * XEN_DMOP_bind_pt_msi_irq: bind a passthrough interrupt to a guest MSI, + * described by the raw MSI message (address and data) the guest programme= d. + * Xen decodes the message itself, so the emulator does not need to know t= he + * MSI layout and, in particular, extended destination IDs are handled + * transparently. + */ +#define XEN_DMOP_bind_pt_msi_irq 21 + +struct xen_dm_op_bind_pt_msi_irq { + /* IN - pirq */ + uint32_t pirq; + /* IN - MSI message data word */ + uint32_t msg_data; + /* IN - bind flags */ + uint32_t flags; +#define XEN_DMOP_MSI_BIND_UNMASKED (1u << 0) + uint32_t pad; + /* IN - MSI message address */ + uint64_aligned_t msg_addr; + /* IN - MSI-X table base address (guest physical), 0 for plain MSI */ + uint64_aligned_t gtable; +}; +typedef struct xen_dm_op_bind_pt_msi_irq xen_dm_op_bind_pt_msi_irq_t; + +/* + * XEN_DMOP_unbind_pt_msi_irq: undo a previous XEN_DMOP_bind_pt_msi_irq. + */ +#define XEN_DMOP_unbind_pt_msi_irq 22 + +struct xen_dm_op_unbind_pt_msi_irq { + /* IN - pirq */ + uint32_t pirq; +}; +typedef struct xen_dm_op_unbind_pt_msi_irq xen_dm_op_unbind_pt_msi_irq_t; + struct xen_dm_op { uint32_t op; uint32_t pad; @@ -468,6 +504,8 @@ struct xen_dm_op { xen_dm_op_relocate_memory_t relocate_memory; xen_dm_op_pin_memory_cacheattr_t pin_memory_cacheattr; xen_dm_op_nr_vcpus_t nr_vcpus; + xen_dm_op_bind_pt_msi_irq_t bind_pt_msi_irq; + xen_dm_op_unbind_pt_msi_irq_t unbind_pt_msi_irq; } u; }; =20 diff --git a/xen/include/xlat.lst b/xen/include/xlat.lst index 33dc8e2b2a..7255f4c65d 100644 --- a/xen/include/xlat.lst +++ b/xen/include/xlat.lst @@ -98,6 +98,7 @@ ? grant_entry_v2 grant_table.h =20 ! dm_op_buf hvm/dm_op.h +? dm_op_bind_pt_msi_irq hvm/dm_op.h ? dm_op_create_ioreq_server hvm/dm_op.h ? dm_op_destroy_ioreq_server hvm/dm_op.h ? dm_op_get_ioreq_server_info hvm/dm_op.h @@ -116,6 +117,7 @@ ? dm_op_set_pci_intx_level hvm/dm_op.h ? dm_op_set_pci_link_route hvm/dm_op.h ? dm_op_track_dirty_vram hvm/dm_op.h +? dm_op_unbind_pt_msi_irq hvm/dm_op.h =20 ! hvm_altp2m_set_mem_access_multi hvm/hvm_op.h =20 --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35ac.4cbeb03216e9d1fc.1a0679ed967.91135d8424a5c29e=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444907; cv=none; d=zohomail.com; s=zohoarc; b=fSnnd6pz0E4F42sEuRTf07Tfm3lQ82Z7nZ+BuKPovoCY1e5Xl+/6NdOfRmJ4Tt3WzzDahFQ3fI6SDWVdKXi3S8kzEKf1RFbBGlKkRDBXaJQGF7iENKYsdDOGcfDdsrXrqFz8xRy179Rf7dsraPmgWh7U588uzXi88PhjLAR4Pxw= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444907; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=X+GMiNwPDnM2Yn/cscWUSLUInDV4hAIUbO0QY9cSEz4=; b=QtxDD+h/TGUUHPq/5UrPrbkVqI3HGrBEO0SFuYmpU7sleHmB4Jc34Guq7IRuhiZxy0nJ1/FNU8Tw3C504yX9lKEqPraqNtkY/aFW/TY6wtVZp9q3YsqjfDuX3DzNPKyFaxYi9B+EryWB2VYJyZFTlT0WcZeI+vXnWGNj2asYqYY= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444907488114.17433871734181; Thu, 3 Sep 2026 07:15:07 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407267.1640417 (Exim 4.92) (envelope-from ) id 1x28DC-0007e6-Cu; Thu, 03 Sep 2026 14:14:42 +0000 Received: by outflank-mailman (output) from mailman id 1407267.1640417; Thu, 03 Sep 2026 14:14:42 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28DC-0007dj-7W; Thu, 03 Sep 2026 14:14:42 +0000 Received: by outflank-mailman (input) for mailman id 1407267; Thu, 03 Sep 2026 14:14:41 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28DA-0007Ru-PS for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:40 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28DA-001HAI-65 for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:40 +0200 Received: from [10.42.69.5] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980bd-2eae-0a2a0a5409dd-0a2a4505c668-38 for ; Thu, 03 Sep 2026 16:14:40 +0200 Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net) by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980cb-4cb1-0a2a45050019-b9ff1c228579-5 for ; Thu, 03 Sep 2026 16:14:40 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679edcb9000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:19 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id E7C2284011; Thu, 3 Sep 2026 16:14:18 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=X+GMiNwPDnM2Yn/cscWUSLUInDV4hAIUbO0QY9cSEz4=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=n6A6v6OJRPpxsRHL71sjEiq/CHSlVnz+nKDoDsIiz3MqZ/jhYsSQlnu6A5caPcT/OvpVeVDOu USNAnUvh6GH8PSJmeS7vOrBOfbJnuwk8kYwFj3or4ew6W/bX1g9EgXJ5XSvCOoYDj6/ece+Ywu9 2pYOVatCAxEn6lCBrwNEVuDjKYPf3XMfeZLG5kX00pmNA4avO0dzEfqxOFoUtDK2A9br4vhjudJ l//JdSFanSu2I3TFqz1v2pLKxws+Z4k/h4Z2vhSRGRgILYtJ/ePp9jurvsVNYPmaVvDTwI1cOnX YWjzGEPrs5sTx0eeu7Dh5kgAXM4XVtC8ntCNZbAEdgag== X-Zone-Loop: 88865dbdf5dde7b16d5315d2b90afe816912eb9d03fb x-campaign-type: default x-transaction-id: 8fb334c3-3549-45f1-89da-701e101f6a05 x-swg-uid: 01-c0bad502-9462-4659-a18c-743f20f32cb6 X-Mailer: Sweego Message-ID: <1788444859.8631fc262581453bbf619ec5b2062170.1a0679edcb9000c4f3@vates.tech> x-swg-bid: 1788444859.8631fc262581453bbf619ec5b2062170.1a0679edcb9000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 10/11] hvm/ioreq: Negotiate extended destination ID support per ioreq server Date: Thu, 3 Sep 2026 16:14:08 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35ad.88da934c2c0754a.1a0679edb1d.ec095fd8a6ac7414=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444859165 X-purgate-ID: tlsNG-c201ff/1788444880-F66B52A1-5C04D7D4/0/0 X-purgate-type: clean X-purgate-size: 16762 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444908605158500 ---=Part.35ad.88da934c2c0754a.1a0679edb1d.ec095fd8a6ac7414=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Extended (15-bit) MSI / IO-APIC destination IDs need Xen to decode the raw MSI message for every passthrough MSI, which in turn requires every device model to use XEN_DMOP_bind_pt_msi_irq. Let each ioreq server advertise that it does so: - XEN_DMOP_create_ioreq_server gains a flags byte (reusing pad[0]) with XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID. arch_ioreq_server_create_check() validates the flags (rejecting unknown bits, and the whole flag on non-x86) and, once the feature is locked, refuses a server that lacks it. - hvm_ext_dest_id_enabled() is true if at least one server exists and all of them opted in. arch_domain_creation_finished() latches the result into the tri-state d->arch.hvm.ext_dest_id, unless a migration stream already fixed it. - A new HVM_SAVE_TYPE(EXT_DEST_ID) record (with save/check/load) migrates the latched value, so the destination host behaves identically regardless of when its device model re-registers ioreq servers. A stream from a Xen predating the feature carries no such record. hvm_load() then resolves the still-UNSET state to DISABLED so arch_domain_creation_finished() does not mistake the restored domain for a fresh one and enable the feature behind an unaware guest. libxendevicemodel's xendevicemodel_create_ioreq_server() grows the flags argument (0 for existing callers). Signed-off-by: Julian Vetter --- Changes in v5: - Commit message rewritten as a bulleted summary. - As discussed with Jan: The creation_finished latch only fires while it is still UNSET, so a value restored from the migration stream wins. v4 OR-ed hvm_ext_dest_id_enabled() onto a bool, which flipped an unaware migrated guest to ENABLED. - hvm_ext_dest_id_enabled() moved out of the header into common/ioreq.c as a function with a locking note. It iterates via ARRAY_SIZE(d->ioreq_server.server), not MAX_NR_IOREQ_SERVERS. - Flags are unsigned int now. Flag-bit validation is arch-specific arch_ioreq_server_create_check() rejects unknown bits and the Arm stub rejects any non-zero flag. The is_hvm_domain() check is dropped from the x86 hook. The post-lock rejection tests EXT_DEST_ID_ENABLED explicitly. - The save record gains a check handler (ext_dest_id_check). Load validates the enum range and returns -ENODATA on a truncated record. - Save-record comment de-x86-ified. - A stream from a Xen predating the feature carries no EXT_DEST_ID record, so hvm_load() resolves the UNSET state to DISABLED at end-of-stream. - Removed the vIO-APIC ioapic_check() extended-bit rejection loop. - Added parentheses around the bitwise logic. Signed-off-by: Julian Vetter --- tools/include/xendevicemodel.h | 3 +- tools/libs/ctrl/xc_devicemodel_compat.c | 2 +- tools/libs/devicemodel/core.c | 3 +- xen/arch/arm/ioreq.c | 6 +++ xen/arch/x86/domain.c | 13 ++++++ xen/arch/x86/hvm/ioreq.c | 57 +++++++++++++++++++++++++ xen/arch/x86/hvm/save.c | 9 ++++ xen/common/ioreq.c | 31 ++++++++++++-- xen/include/public/arch-x86/hvm/save.h | 16 ++++++- xen/include/public/hvm/dm_op.h | 13 +++++- xen/include/xen/ioreq.h | 11 +++++ 11 files changed, 156 insertions(+), 8 deletions(-) diff --git a/tools/include/xendevicemodel.h b/tools/include/xendevicemodel.h index 698d719119..72994d1313 100644 --- a/tools/include/xendevicemodel.h +++ b/tools/include/xendevicemodel.h @@ -44,12 +44,13 @@ int xendevicemodel_close(xendevicemodel_handle *dmod); * @parm domid the domain id to be serviced * @parm handle_bufioreq how should the IOREQ Server handle buffered * requests (HVM_IOREQSRV_BUFIOREQ_*)? + * @parm flags bitmask of XEN_DMOP_IOREQ_SERVER_* capability flags (0 if n= one). * @parm id pointer to an ioservid_t to receive the IOREQ Server id. * @return 0 on success, -1 on failure. */ int xendevicemodel_create_ioreq_server( xendevicemodel_handle *dmod, domid_t domid, int handle_bufioreq, - ioservid_t *id); + uint8_t flags, ioservid_t *id); =20 /** * This function retrieves the necessary information to allow an diff --git a/tools/libs/ctrl/xc_devicemodel_compat.c b/tools/libs/ctrl/xc_d= evicemodel_compat.c index a46011cd17..91366e250c 100644 --- a/tools/libs/ctrl/xc_devicemodel_compat.c +++ b/tools/libs/ctrl/xc_devicemodel_compat.c @@ -11,7 +11,7 @@ int xc_hvm_create_ioreq_server( ioservid_t *id) { return xendevicemodel_create_ioreq_server(xch->dmod, domid, - handle_bufioreq, id); + handle_bufioreq, 0, id); } =20 int xc_hvm_get_ioreq_server_info( diff --git a/tools/libs/devicemodel/core.c b/tools/libs/devicemodel/core.c index 274a8eb28b..5b2acb1869 100644 --- a/tools/libs/devicemodel/core.c +++ b/tools/libs/devicemodel/core.c @@ -167,7 +167,7 @@ static int xendevicemodel_op( =20 int xendevicemodel_create_ioreq_server( xendevicemodel_handle *dmod, domid_t domid, int handle_bufioreq, - ioservid_t *id) + uint8_t flags, ioservid_t *id) { struct xen_dm_op op; struct xen_dm_op_create_ioreq_server *data; @@ -179,6 +179,7 @@ int xendevicemodel_create_ioreq_server( data =3D &op.u.create_ioreq_server; =20 data->handle_bufioreq =3D handle_bufioreq; + data->flags =3D flags; =20 rc =3D xendevicemodel_op(dmod, domid, 1, &op, sizeof(op)); if (rc) diff --git a/xen/arch/arm/ioreq.c b/xen/arch/arm/ioreq.c index b4211f0159..7d26180926 100644 --- a/xen/arch/arm/ioreq.c +++ b/xen/arch/arm/ioreq.c @@ -201,6 +201,12 @@ void arch_ioreq_domain_init(struct domain *d) { } =20 +int arch_ioreq_server_create_check(const struct domain *d, unsigned int fl= ags) +{ + /* No XEN_DMOP_IOREQ_SERVER_* capability flags are defined for Arm. */ + return flags ? -EINVAL : 0; +} + /* * Local variables: * mode: C diff --git a/xen/arch/x86/domain.c b/xen/arch/x86/domain.c index 996b50af7a..69c9093e06 100644 --- a/xen/arch/x86/domain.c +++ b/xen/arch/x86/domain.c @@ -25,6 +25,7 @@ #include #include #include +#include #include #include #include @@ -1106,7 +1107,19 @@ int arch_domain_soft_reset(struct domain *d) void arch_domain_creation_finished(struct domain *d) { if ( is_hvm_domain(d) ) + { + /* + * Latch the extended destination ID decision now that all boot-ti= me + * ioreq servers are registered. A value restored from a migration + * stream (EXT_DEST_ID save record) already fixes it and wins. + */ + if ( d->arch.hvm.ext_dest_id =3D=3D EXT_DEST_ID_UNSET ) + d->arch.hvm.ext_dest_id =3D hvm_ext_dest_id_enabled(d) + ? EXT_DEST_ID_ENABLED + : EXT_DEST_ID_DISABLED; + hvm_domain_creation_finished(d); + } } =20 #ifdef CONFIG_COMPAT diff --git a/xen/arch/x86/hvm/ioreq.c b/xen/arch/x86/hvm/ioreq.c index a5fa97e149..63d22f6738 100644 --- a/xen/arch/x86/hvm/ioreq.c +++ b/xen/arch/x86/hvm/ioreq.c @@ -19,6 +19,7 @@ =20 #include #include +#include #include #include =20 @@ -325,6 +326,62 @@ void arch_ioreq_domain_init(struct domain *d) register_portio_handler(d, 0xcf8, 4, hvm_access_cf8); } =20 +int arch_ioreq_server_create_check(const struct domain *d, unsigned int fl= ags) +{ + if ( flags & ~XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID ) + return -EINVAL; + + /* + * Once the domain is running with extended destination IDs advertised, + * every ioreq server it gains must be able to bind MSIs the new way. + * (Before that point d->arch.hvm.ext_dest_id is still UNSET and serve= rs + * are levelled at arch_domain_creation_finished().) + */ + if ( d->arch.hvm.ext_dest_id =3D=3D EXT_DEST_ID_ENABLED && + !(flags & XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID) ) + return -EPERM; + + return 0; +} + +static int cf_check ext_dest_id_save(struct vcpu *v, hvm_domain_context_t = *h) +{ + struct hvm_hw_ext_dest_id s =3D { + .enabled =3D v->domain->arch.hvm.ext_dest_id, + }; + + return hvm_save_entry(EXT_DEST_ID, 0, h, &s); +} + +static int cf_check ext_dest_id_check(const struct domain *d, + hvm_domain_context_t *h) +{ + const struct hvm_hw_ext_dest_id *s =3D hvm_get_entry(EXT_DEST_ID, h); + + if ( !s ) + return -ENODATA; + + return s->enabled > EXT_DEST_ID_ENABLED ? -EINVAL : 0; +} + +static int cf_check ext_dest_id_load(struct domain *d, hvm_domain_context_= t *h) +{ + struct hvm_hw_ext_dest_id s; + + if ( hvm_load_entry(EXT_DEST_ID, h, &s) ) + return -ENODATA; + + if ( s.enabled > EXT_DEST_ID_ENABLED ) + return -EINVAL; + + d->arch.hvm.ext_dest_id =3D s.enabled; + + return 0; +} + +HVM_REGISTER_SAVE_RESTORE(EXT_DEST_ID, ext_dest_id_save, ext_dest_id_check, + ext_dest_id_load, 1, HVMSR_PER_DOM); + /* * Local variables: * mode: C diff --git a/xen/arch/x86/hvm/save.c b/xen/arch/x86/hvm/save.c index 8ab6405706..aac8498049 100644 --- a/xen/arch/x86/hvm/save.c +++ b/xen/arch/x86/hvm/save.c @@ -341,6 +341,15 @@ int hvm_load(struct domain *d, bool real, hvm_domain_c= ontext_t *h) /* Reset cursor for hvm_load(, true, ). */ if ( !real ) h->cur =3D 0; + + /* + * A migration stream from a Xen predating extended destinatio= n IDs + * carries no EXT_DEST_ID record, leaving ext_dest_id UNSET he= re. + * Set it to DISABLED then, because the domain has no knowledge + * about EXT_DEST_IDs. + */ + else if ( d->arch.hvm.ext_dest_id =3D=3D EXT_DEST_ID_UNSET ) + d->arch.hvm.ext_dest_id =3D EXT_DEST_ID_DISABLED; return 0; } =20 diff --git a/xen/common/ioreq.c b/xen/common/ioreq.c index f5fd30ce12..53003286c4 100644 --- a/xen/common/ioreq.c +++ b/xen/common/ioreq.c @@ -79,6 +79,25 @@ static struct ioreq_server *get_ioreq_server(const struc= t domain *d, return GET_IOREQ_SERVER(d, id); } =20 +bool hvm_ext_dest_id_enabled(const struct domain *d) +{ + unsigned int id; + bool any =3D false; + + for ( id =3D 0; id < ARRAY_SIZE(d->ioreq_server.server); id++ ) + { + const struct ioreq_server *s =3D GET_IOREQ_SERVER(d, id); + + if ( !s ) + continue; + if ( !s->ext_dest_id ) + return false; + any =3D true; + } + + return any; +} + /* * Iterate over all possible ioreq servers. * @@ -641,7 +660,7 @@ static void ioreq_server_deinit(struct ioreq_server *s) } =20 static int ioreq_server_create(struct domain *d, int bufioreq_handling, - ioservid_t *id) + unsigned int flags, ioservid_t *id) { struct ioreq_server *s; unsigned int i; @@ -683,6 +702,8 @@ static int ioreq_server_create(struct domain *d, int bu= fioreq_handling, goto fail; } =20 + s->ext_dest_id =3D flags & XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID; + if ( id ) *id =3D i; =20 @@ -1350,10 +1371,14 @@ int ioreq_server_dm_op(struct xen_dm_op *op, struct= domain *d, bool *const_op) *const_op =3D false; =20 rc =3D -EINVAL; - if ( data->pad[0] || data->pad[1] || data->pad[2] ) + if ( data->pad[0] || data->pad[1] ) + break; + + rc =3D arch_ioreq_server_create_check(d, data->flags); + if ( rc ) break; =20 - rc =3D ioreq_server_create(d, data->handle_bufioreq, + rc =3D ioreq_server_create(d, data->handle_bufioreq, data->flags, &data->id); break; } diff --git a/xen/include/public/arch-x86/hvm/save.h b/xen/include/public/ar= ch-x86/hvm/save.h index ff73b83d65..58d301512e 100644 --- a/xen/include/public/arch-x86/hvm/save.h +++ b/xen/include/public/arch-x86/hvm/save.h @@ -629,12 +629,26 @@ struct hvm_msr { =20 #define CPU_MSR_CODE 20 =20 +/* + * Extended (15-bit) MSI / IO-APIC destination ID support, as negotiated w= ith + * the domain's ioreq servers and latched when the domain starts running. + * + * 'enabled' takes the values of enum in struct hvm_domain: 0 =3D undecide= d, + * 1 =3D off, 2 =3D on. + */ +struct hvm_hw_ext_dest_id { + uint8_t enabled; + uint8_t pad[7]; +}; + +DECLARE_HVM_SAVE_TYPE(EXT_DEST_ID, 21, struct hvm_hw_ext_dest_id); + /* Range 22 - 34 (inclusive) reserved for Amazon */ =20 /* * Largest type-code in use */ -#define HVM_SAVE_CODE_MAX 20 +#define HVM_SAVE_CODE_MAX 21 =20 #endif /* __XEN_PUBLIC_HVM_SAVE_X86_H__ */ =20 diff --git a/xen/include/public/hvm/dm_op.h b/xen/include/public/hvm/dm_op.h index d76777f71f..0e1774b1d3 100644 --- a/xen/include/public/hvm/dm_op.h +++ b/xen/include/public/hvm/dm_op.h @@ -44,13 +44,24 @@ typedef uint16_t ioservid_t; * hvm_op.h. If the value is HVM_IOREQSRV_BUFIOREQ_OFF then the buffered * ioreq ring will not be allocated and hence all emulation requests to * this server will be synchronous. + * + * x86 HVM only: a server that sets XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID in + * promises to bind every passthrough MSI via XEN_DMOP_bind_pt_msi= _irq + * (which carries the raw MSI message). Extended (15-bit) MSI / IO-APIC + * destination IDs are enabled for the domain, and advertised via + * XEN_HVM_CPUID_EXT_DEST_ID, only if *every* ioreq server registered befo= re + * the domain starts running sets this flag. Once the feature is locked in, + * later servers that lack the flag are rejected. */ #define XEN_DMOP_create_ioreq_server 1 =20 struct xen_dm_op_create_ioreq_server { /* IN - should server handle buffered ioreqs */ uint8_t handle_bufioreq; - uint8_t pad[3]; + /* IN - XEN_DMOP_IOREQ_SERVER_* */ + uint8_t flags; +#define XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID (1u << 0) + uint8_t pad[2]; /* OUT - server id */ ioservid_t id; }; diff --git a/xen/include/xen/ioreq.h b/xen/include/xen/ioreq.h index e86f0869fa..a75bd04b97 100644 --- a/xen/include/xen/ioreq.h +++ b/xen/include/xen/ioreq.h @@ -54,9 +54,19 @@ struct ioreq_server { evtchn_port_t bufioreq_evtchn; struct rangeset *range[NR_IO_RANGE_TYPES]; bool enabled; + bool ext_dest_id; uint8_t bufioreq_handling; }; =20 +/* + * True if at least one ioreq server is registered and every registered se= rver + * set XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID. Only meaningful before the domain + * starts running (called from arch_domain_creation_finished(), when no + * concurrent ioreq server (de)registration can occur). The result is latc= hed + * into d->arch.hvm.ext_dest_id there. + */ +bool hvm_ext_dest_id_enabled(const struct domain *d); + static inline paddr_t ioreq_mmio_first_byte(const ioreq_t *p) { return unlikely(p->df) ? @@ -137,6 +147,7 @@ bool arch_ioreq_server_destroy_all(struct domain *d); bool arch_ioreq_server_get_type_addr(const struct domain *d, const ioreq_t= *p, uint8_t *type, uint64_t *addr); void arch_ioreq_domain_init(struct domain *d); +int arch_ioreq_server_create_check(const struct domain *d, unsigned int fl= ags); =20 #endif /* __XEN_IOREQ_H__ */ =20 --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35ad.88da934c2c0754a.1a0679edb1d.ec095fd8a6ac7414=--- From nobody Thu Sep 24 20:24:25 2026 Delivered-To: importer@patchew.org Received-SPF: pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) client-ip=192.237.175.120; envelope-from=xen-devel-bounces@lists.xenproject.org; helo=lists.xenproject.org; Authentication-Results: mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass(p=none dis=none) header.from=vates.tech ARC-Seal: i=1; a=rsa-sha256; t=1788444902; cv=none; d=zohomail.com; s=zohoarc; b=WJyqLSbNgFUz2Nn+2aSzyPoOZY72wGKowU/QsJQduTVA19ehhGgkc8rxV5I4DkFCZSko7CmD9oU6lY2MOXu9pkIAtyO2hbNOXr9X+8qhOUSFkSzD9PkPy8BcTc7qHYxPhnbHuii8A08Bb6qjynDy4PlQ2WdYYKcks3wq6auyyx8= ARC-Message-Signature: i=1; a=rsa-sha256; c=relaxed/relaxed; d=zohomail.com; s=zohoarc; t=1788444902; h=Content-Type:Cc:Cc:Date:Date:From:From:In-Reply-To:List-Subscribe:List-Post:List-Id:List-Help:List-Unsubscribe:MIME-Version:Message-ID:References:Sender:Subject:Subject:To:To:Message-Id:Reply-To; bh=oWieLxc234k5uH169K+pisoqXQICUG6e/oesPGrXHLk=; b=bsLfhc9BYZaogAHAwiIhRm6igNmYoYbDbTEttW/TyuQcwZ8mMLJRqurQsKEH4fqs0k/M4NGqtVjsiMbi+EDD6nm1FEVoU8BEIU3V24GI0R04njV1masHYFC6PTXRT1WrfVJgGnuQosrfiyaiI83Napu78Lea5fjz74CCat1+eN0= ARC-Authentication-Results: i=1; mx.zohomail.com; dkim=pass; spf=pass (zohomail.com: domain of lists.xenproject.org designates 192.237.175.120 as permitted sender) smtp.mailfrom=xen-devel-bounces@lists.xenproject.org; dmarc=pass header.from= (p=none dis=none) Return-Path: Received: from lists.xenproject.org (lists.xenproject.org [192.237.175.120]) by mx.zohomail.com with SMTPS id 1788444902330810.1005236945426; Thu, 3 Sep 2026 07:15:02 -0700 (PDT) Received: from list by lists.xenproject.org with outflank-mailman.1407269.1640426 (Exim 4.92) (envelope-from ) id 1x28DE-0007yF-Ol; Thu, 03 Sep 2026 14:14:44 +0000 Received: by outflank-mailman (output) from mailman id 1407269.1640426; Thu, 03 Sep 2026 14:14:44 +0000 Received: from localhost ([127.0.0.1] helo=lists.xenproject.org) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28DE-0007y2-KH; Thu, 03 Sep 2026 14:14:44 +0000 Received: by outflank-mailman (input) for mailman id 1407269; Thu, 03 Sep 2026 14:14:44 +0000 Received: from mx.expurgate.net ([194.145.224.20]) by lists.xenproject.org with esmtp (Exim 4.92) (envelope-from ) id 1x28DE-0007wI-3d for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 14:14:44 +0000 Received: from mx.expurgate.net (helo=localhost) by mx.expurgate.net with esmtp id 1x28DD-001HAI-GD for xen-devel@lists.xenproject.org; Thu, 03 Sep 2026 16:14:43 +0200 Received: from [10.42.69.5] (helo=localhost) by localhost with ESMTP (eXpurgate MTA 0.9.1) (envelope-from ) id 6a9980bd-2eae-0a2a0a5409dd-0a2a4505c668-46 for ; Thu, 03 Sep 2026 16:14:43 +0200 Received: from [185.255.28.34] (helo=prod-mta-13-01.swg-srv.net) by tlsNG-c201ff.mxtls.expurgate.net with ESMTPS (eXpurgate 4.57.1) (envelope-from ) id 6a9980cb-4cb1-0a2a45050019-b9ff1c228579-6 for ; Thu, 03 Sep 2026 16:14:43 +0200 Received: from mail2.vates.fr ([37.26.189.201] mail2.vates.fr) (Authenticated sender: 8631fc262581453bbf619ec5b2062170/smtp/7773de5a-2839-4720-82ee-e06722ae1d3e) by prod-mta-13-01.swg-srv.net (ZoneMTA - prod-mta-13) with ESMTPSA id 1a0679ede0d000c4f3.006 for (version=TLSv1.3 cipher=TLS_AES_256_GCM_SHA384); Thu, 03 Sep 2026 14:14:19 +0000 Received: from julian.home (areims-651-1-80-194.w90-18.abo.wanadoo.fr [90.18.187.194]) (Authenticated sender: julian.vetter@vates.tech) by mail2.vates.fr (Postfix) with ESMTPSA id 462F684017; Thu, 3 Sep 2026 16:14:19 +0200 (CEST) X-Outflank-Mailman: Message body and most headers restored to incoming version X-BeenThere: xen-devel@lists.xenproject.org List-Id: Xen developer discussion List-Unsubscribe: , List-Post: List-Help: List-Subscribe: , Errors-To: xen-devel-bounces@lists.xenproject.org Precedence: list Sender: "Xen-devel" Authentication-Results: eu.smtp.expurgate.cloud; dkim=pass header.s=selector1 header.d=vates.tech header.i="@vates.tech" header.h="From:Subject:Date:Message-ID:To:Cc:MIME-Version:Content-Type:In-Reply-To:References:Feedback-ID" DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=vates.tech; q=dns/txt; s=selector1; bh=oWieLxc234k5uH169K+pisoqXQICUG6e/oesPGrXHLk=; h=from:subject:date:message-id:to:cc:mime-version:content-type:in-reply-to:references:feedback-id; b=DZ0uyy0jO63ngUNEYoK2Dh2QPQrjgBPyMLXupjtf2AITZcUkxhYdJ07dwrpvEIv2zOmPfW/3t 06O/Pz9U3J4YnwlFladbJhiF1sMONN9+XMPjTPhDmuEERa86wW4CMvsQ6MROo1yKcL1GYN14xUu 2eCIWYQ8+FItbHVxKMnVarw5BCJvfH82PPb96v+1kO8kEvGWrj2QGl1cU2TFzNCcKC+IkwybyWH AVGml618nrTTTcT+kxG9Vd9JeNPqPFfoMSyxOcZqs8Eu/arNmha0TD0hiH//xQARhJLL5PV9eRp fMSx7xqS5i8SVjOWi2GEgg8Uyh3SAKcn/O6Bg8Ya3tRQ== X-Zone-Loop: c9557038a1ecc87329f44ca244c39a867c93183a5dac x-campaign-type: default x-transaction-id: ae0a429b-35e3-4a3a-9c93-10ddf3fcd485 x-swg-uid: 01-855ebf8e-114e-4bcb-b2a7-08b977133bec X-Mailer: Sweego Message-ID: <1788444859.8631fc262581453bbf619ec5b2062170.1a0679ede0d000c4f3@vates.tech> x-swg-bid: 1788444859.8631fc262581453bbf619ec5b2062170.1a0679ede0d000c4f3 Feedback-ID: default:8631fc262581453bbf619ec5b2062170:Sweego x-campaign-id: default x-client-id: 8631fc262581453bbf619ec5b2062170 X-Originating-IP: [37.26.189.201] From: Julian Vetter To: xen-devel@lists.xenproject.org Cc: Oleksii Kurochko , Community Manager , Andrew Cooper , Anthony PERARD , Michal Orzel , Jan Beulich , Julien Grall , =?UTF-8?q?Roger=20Pau=20Monn=C3=A9?= , Stefano Stabellini , Juergen Gross , Teddy Astie , "Daniel P. Smith" , Julian Vetter Subject: [PATCH v5 11/11] x86/cpuid: Advertise XEN_HVM_CPUID_EXT_DEST_ID Date: Thu, 3 Sep 2026 16:14:09 +0200 In-Reply-To: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> References: <1788444605.8631fc262581453bbf619ec5b2062170.1a0679afc0d000c4f3@vates.tech> MIME-Version: 1.0 X-BM-Disclaimer: Yes Content-Type: multipart/alternative; boundary="-=Part.35ae.99efa79bcd8cdbfb.1a0679edc75.1550d244ce0da3c1=-" X-Bm-Milter-Handled: 4ffbd6c1-ee69-4e1b-aabd-f977039bd3e2 X-Bm-Transport-Timestamp: 1788444859509 X-purgate-ID: tlsNG-c201ff/1788444883-F70B22A1-C8EB1064/0/0 X-purgate-type: clean X-purgate-size: 2203 X-ZohoMail-DKIM: pass (identity @vates.tech) X-ZM-MESSAGEID: 1788444904609158500 ---=Part.35ae.99efa79bcd8cdbfb.1a0679edc75.1550d244ce0da3c1=- Content-Transfer-Encoding: quoted-printable MIME-Version: 1.0 Content-Type: text/plain; charset="utf-8" Expose the extended-destination-ID feature bit in the HVM hypervisor CPUID leaf when d->arch.hvm.ext_dest_id is EXT_DEST_ID_ENABLED, i.e. the domain's ioreq servers all opted in and the value was latched at creation_finished (or restored from migration). An older device model that never sets XEN_DMOP_IOREQ_SERVER_EXT_DEST_ID leaves the bit clear and the guest keeps 8-bit APIC destination IDs. Signed-off-by: Julian Vetter --- Changes in v5: - Retitled (dropped "when device model opts in"). - Removed the dynamic pre-creation_finished path: guest_cpuid() only ever runs for "current", so the value is always latched by the time the leaf is read. The check is now just hvm_ext_dest_id_active(d). - Commit message rewritten to match the new logic. Signed-off-by: Julian Vetter --- xen/arch/x86/cpuid.c | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/xen/arch/x86/cpuid.c b/xen/arch/x86/cpuid.c index a9aeb2d268..1e8dbf8a15 100644 --- a/xen/arch/x86/cpuid.c +++ b/xen/arch/x86/cpuid.c @@ -148,6 +148,14 @@ static void cpuid_hypervisor_leaves(const struct vcpu = *v, uint32_t leaf, res->a |=3D XEN_HVM_CPUID_DOMID_PRESENT; res->c =3D d->domain_id; =20 + /* + * Advertise extended (15-bit) MSI / IO-APIC destination IDs when = the + * feature was negotiated with the domain's device model(s) and la= tched + * at creation_finished (see hvm_ext_dest_id_enabled()). + */ + if ( hvm_ext_dest_id_active(d) ) + res->a |=3D XEN_HVM_CPUID_EXT_DEST_ID; + /* * Per-vCPU event channel upcalls are implemented and work * correctly with PIRQs routed over event channels. --=20 2.53.0 --=20 Julian Vetter | Vates Hypervisor & Kernel Developer XCP-ng & Xen Orchestra - Vates solutions web: https://vates.tech ---=Part.35ae.99efa79bcd8cdbfb.1a0679edc75.1550d244ce0da3c1=---