Linux-HyperV List
 help / color / mirror / Atom feed
* [PATCH 11/16] PCI: xilinx-nwl: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:48 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Michal Simek <michal.simek@amd.com>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig           |  1 +
 drivers/pci/controller/pcie-xilinx-nwl.c | 45 ++++++++++++------------
 2 files changed, 24 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index c9b6180239732..118ff622fa69e 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -342,6 +342,7 @@ config PCIE_XILINX_NWL
 	bool "Xilinx NWL PCIe controller"
 	depends on ARCH_ZYNQMP || COMPILE_TEST
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	help
 	 Say 'Y' here if you want kernel support for Xilinx
 	 NWL PCIe controller. The controller can act as Root Port
diff --git a/drivers/pci/controller/pcie-xilinx-nwl.c b/drivers/pci/controller/pcie-xilinx-nwl.c
index c8b05477b7198..de76c836915f0 100644
--- a/drivers/pci/controller/pcie-xilinx-nwl.c
+++ b/drivers/pci/controller/pcie-xilinx-nwl.c
@@ -10,6 +10,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -145,7 +146,6 @@
 #define LINK_WAIT_USLEEP_MAX           100000
 
 struct nwl_msi {			/* MSI information */
-	struct irq_domain *msi_domain;
 	DECLARE_BITMAP(bitmap, INT_PCI_MSI_NR);
 	struct irq_domain *dev_domain;
 	struct mutex lock;		/* protect bitmap variable */
@@ -418,19 +418,22 @@ static const struct irq_domain_ops intx_domain_ops = {
 };
 
 #ifdef CONFIG_PCI_MSI
-static struct irq_chip nwl_msi_irq_chip = {
-	.name = "nwl_pcie:msi",
-	.irq_enable = pci_msi_unmask_irq,
-	.irq_disable = pci_msi_mask_irq,
-	.irq_mask = pci_msi_mask_irq,
-	.irq_unmask = pci_msi_unmask_irq,
-};
 
-static struct msi_domain_info nwl_msi_domain_info = {
-	.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		 MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI,
-	.chip = &nwl_msi_irq_chip,
+#define NWL_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				MSI_FLAG_NO_AFFINITY)
+
+#define NWL_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK		| \
+				 MSI_FLAG_MULTI_PCI_MSI)
+
+static const struct msi_parent_ops nwl_msi_parent_ops = {
+	.required_flags		= NWL_MSI_FLAGS_REQUIRED,
+	.supported_flags	= NWL_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.prefix			= "nwl-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
+
 #endif
 
 static void nwl_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
@@ -497,20 +500,18 @@ static int nwl_pcie_init_msi_irq_domain(struct nwl_pcie *pcie)
 	struct device *dev = pcie->dev;
 	struct fwnode_handle *fwnode = of_fwnode_handle(dev->of_node);
 	struct nwl_msi *msi = &pcie->msi;
-
-	msi->dev_domain = irq_domain_create_linear(NULL, INT_PCI_MSI_NR, &dev_msi_domain_ops, pcie);
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &dev_msi_domain_ops,
+		.host_data	= pcie,
+		.size		= INT_PCI_MSI_NR,
+	};
+
+	msi->dev_domain  = msi_create_parent_irq_domain(&info, &nwl_msi_parent_ops);
 	if (!msi->dev_domain) {
 		dev_err(dev, "failed to create dev IRQ domain\n");
 		return -ENOMEM;
 	}
-	msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-						    &nwl_msi_domain_info,
-						    msi->dev_domain);
-	if (!msi->msi_domain) {
-		dev_err(dev, "failed to create msi IRQ domain\n");
-		irq_domain_remove(msi->dev_domain);
-		return -ENOMEM;
-	}
 #endif
 	return 0;
 }
-- 
2.39.5


^ permalink raw reply related

* [PATCH 10/16] PCI: xilinx-xdma: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:48 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Michal Simek <michal.simek@amd.com>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig              |  1 +
 drivers/pci/controller/pcie-xilinx-dma-pl.c | 48 +++++++++------------
 2 files changed, 22 insertions(+), 27 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 8b9492e9ae693..c9b6180239732 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -331,6 +331,7 @@ config PCIE_XILINX_DMA_PL
 	depends on ARCH_ZYNQMP || COMPILE_TEST
 	depends on PCI_MSI
 	select PCI_HOST_COMMON
+	select IRQ_MSI_LIB
 	help
 	  Say 'Y' here if you want kernel support for the Xilinx PL DMA
 	  PCIe host bridge. The controller is a Soft IP which can act as
diff --git a/drivers/pci/controller/pcie-xilinx-dma-pl.c b/drivers/pci/controller/pcie-xilinx-dma-pl.c
index dc9690a535e16..fbc379fd118b4 100644
--- a/drivers/pci/controller/pcie-xilinx-dma-pl.c
+++ b/drivers/pci/controller/pcie-xilinx-dma-pl.c
@@ -7,6 +7,7 @@
 #include <linux/bitfield.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -90,7 +91,6 @@ struct xilinx_pl_dma_variant {
 };
 
 struct xilinx_msi {
-	struct irq_domain	*msi_domain;
 	unsigned long		*bitmap;
 	struct irq_domain	*dev_domain;
 	struct mutex		lock;		/* Protect bitmap variable */
@@ -373,20 +373,20 @@ static irqreturn_t xilinx_pl_dma_pcie_intr_handler(int irq, void *dev_id)
 	return IRQ_HANDLED;
 }
 
-static struct irq_chip xilinx_msi_irq_chip = {
-	.name = "pl_dma:PCIe MSI",
-	.irq_enable = pci_msi_unmask_irq,
-	.irq_disable = pci_msi_mask_irq,
-	.irq_mask = pci_msi_mask_irq,
-	.irq_unmask = pci_msi_unmask_irq,
-};
+#define XILINX_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				   MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				   MSI_FLAG_NO_AFFINITY)
 
-static struct msi_domain_info xilinx_msi_domain_info = {
-	.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		 MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI,
-	.chip = &xilinx_msi_irq_chip,
-};
+#define XILINX_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK	| \
+				    MSI_FLAG_MULTI_PCI_MSI)
 
+static const struct msi_parent_ops xilinx_msi_parent_ops = {
+	.required_flags		= XILINX_MSI_FLAGS_REQUIRED,
+	.supported_flags	= XILINX_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.prefix			= "pl_dma-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
+};
 static void xilinx_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	struct pl_dma_pcie *pcie = irq_data_get_irq_chip_data(data);
@@ -458,11 +458,6 @@ static void xilinx_pl_dma_pcie_free_irq_domains(struct pl_dma_pcie *port)
 		irq_domain_remove(msi->dev_domain);
 		msi->dev_domain = NULL;
 	}
-
-	if (msi->msi_domain) {
-		irq_domain_remove(msi->msi_domain);
-		msi->msi_domain = NULL;
-	}
 }
 
 static int xilinx_pl_dma_pcie_init_msi_irq_domain(struct pl_dma_pcie *port)
@@ -471,18 +466,17 @@ static int xilinx_pl_dma_pcie_init_msi_irq_domain(struct pl_dma_pcie *port)
 	struct xilinx_msi *msi = &port->msi;
 	int size = BITS_TO_LONGS(XILINX_NUM_MSI_IRQS) * sizeof(long);
 	struct fwnode_handle *fwnode = of_fwnode_handle(port->dev->of_node);
-
-	msi->dev_domain = irq_domain_create_linear(NULL, XILINX_NUM_MSI_IRQS,
-						   &dev_msi_domain_ops, port);
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &dev_msi_domain_ops,
+		.host_data	= port,
+		.size		= XILINX_NUM_MSI_IRQS,
+	};
+
+	msi->dev_domain  = msi_create_parent_irq_domain(&info, &xilinx_msi_parent_ops);
 	if (!msi->dev_domain)
 		goto out;
 
-	msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-						    &xilinx_msi_domain_info,
-						    msi->dev_domain);
-	if (!msi->msi_domain)
-		goto out;
-
 	mutex_init(&msi->lock);
 	msi->bitmap = kzalloc(size, GFP_KERNEL);
 	if (!msi->bitmap)
-- 
2.39.5


^ permalink raw reply related

* [PATCH 09/16] PCI: rcar-host: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao, Geert Uytterhoeven, Magnus Damm
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Marek Vasut <marek.vasut+renesas@gmail.com>
Cc: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Cc: Geert Uytterhoeven <geert+renesas@glider.be>
Cc: Magnus Damm <magnus.damm@gmail.com>
Cc: linux-renesas-soc@vger.kernel.org
---
 drivers/pci/controller/Kconfig          |  1 +
 drivers/pci/controller/pcie-rcar-host.c | 69 +++++++++----------------
 2 files changed, 26 insertions(+), 44 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 65289a171333c..8b9492e9ae693 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -243,6 +243,7 @@ config PCIE_RCAR_HOST
 	bool "Renesas R-Car PCIe controller (host mode)"
 	depends on ARCH_RENESAS || COMPILE_TEST
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	help
 	  Say Y here if you want PCIe controller support on R-Car SoCs in host
 	  mode.
diff --git a/drivers/pci/controller/pcie-rcar-host.c b/drivers/pci/controller/pcie-rcar-host.c
index c32b803a47c7c..ad2bda635d47f 100644
--- a/drivers/pci/controller/pcie-rcar-host.c
+++ b/drivers/pci/controller/pcie-rcar-host.c
@@ -17,6 +17,7 @@
 #include <linux/delay.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/init.h>
@@ -597,30 +598,6 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
 	return IRQ_HANDLED;
 }
 
-static void rcar_msi_top_irq_ack(struct irq_data *d)
-{
-	irq_chip_ack_parent(d);
-}
-
-static void rcar_msi_top_irq_mask(struct irq_data *d)
-{
-	pci_msi_mask_irq(d);
-	irq_chip_mask_parent(d);
-}
-
-static void rcar_msi_top_irq_unmask(struct irq_data *d)
-{
-	pci_msi_unmask_irq(d);
-	irq_chip_unmask_parent(d);
-}
-
-static struct irq_chip rcar_msi_top_chip = {
-	.name		= "PCIe MSI",
-	.irq_ack	= rcar_msi_top_irq_ack,
-	.irq_mask	= rcar_msi_top_irq_mask,
-	.irq_unmask	= rcar_msi_top_irq_unmask,
-};
-
 static void rcar_msi_irq_ack(struct irq_data *d)
 {
 	struct rcar_msi *msi = irq_data_get_irq_chip_data(d);
@@ -718,30 +695,37 @@ static const struct irq_domain_ops rcar_msi_domain_ops = {
 	.free	= rcar_msi_domain_free,
 };
 
-static struct msi_domain_info rcar_msi_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI,
-	.chip	= &rcar_msi_top_chip,
+#define RCAR_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				 MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				 MSI_FLAG_PCI_MSI_MASK_PARENT	| \
+				 MSI_FLAG_NO_AFFINITY)
+
+#define RCAR_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK	| \
+				  MSI_FLAG_MULTI_PCI_MSI)
+
+static const struct msi_parent_ops rcar_msi_parent_ops = {
+	.required_flags		= RCAR_MSI_FLAGS_REQUIRED,
+	.supported_flags	= RCAR_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "RCAR-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 static int rcar_allocate_domains(struct rcar_msi *msi)
 {
 	struct rcar_pcie *pcie = &msi_to_host(msi)->pcie;
 	struct fwnode_handle *fwnode = dev_fwnode(pcie->dev);
-	struct irq_domain *parent;
-
-	parent = irq_domain_create_linear(fwnode, INT_PCI_MSI_NR,
-					  &rcar_msi_domain_ops, msi);
-	if (!parent) {
-		dev_err(pcie->dev, "failed to create IRQ domain\n");
-		return -ENOMEM;
-	}
-	irq_domain_update_bus_token(parent, DOMAIN_BUS_NEXUS);
-
-	msi->domain = pci_msi_create_irq_domain(fwnode, &rcar_msi_info, parent);
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &rcar_msi_domain_ops,
+		.host_data	= msi,
+		.size		= INT_PCI_MSI_NR,
+	};
+
+	msi->domain = msi_create_parent_irq_domain(&info, &rcar_msi_parent_ops);
 	if (!msi->domain) {
-		dev_err(pcie->dev, "failed to create MSI domain\n");
-		irq_domain_remove(parent);
+		dev_err(pcie->dev, "failed to create IRQ domain\n");
 		return -ENOMEM;
 	}
 
@@ -750,10 +734,7 @@ static int rcar_allocate_domains(struct rcar_msi *msi)
 
 static void rcar_free_domains(struct rcar_msi *msi)
 {
-	struct irq_domain *parent = msi->domain->parent;
-
 	irq_domain_remove(msi->domain);
-	irq_domain_remove(parent);
 }
 
 static int rcar_pcie_enable_msi(struct rcar_pcie_host *host)
-- 
2.39.5


^ permalink raw reply related

* [PATCH 08/16] PCI: mediatek: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Ryder Lee <ryder.lee@mediatek.com>
Cc: Jianjun Wang <jianjun.wang@mediatek.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: linux-mediatek@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig         |  1 +
 drivers/pci/controller/pcie-mediatek.c | 46 ++++++++++++--------------
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index ec32c343a751d..65289a171333c 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -195,6 +195,7 @@ config PCIE_MEDIATEK
 	depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST
 	depends on OF
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	help
 	  Say Y here if you want to enable PCIe controller support on
 	  MediaTek SoCs.
diff --git a/drivers/pci/controller/pcie-mediatek.c b/drivers/pci/controller/pcie-mediatek.c
index e1934aa06c8d5..3ac5d14dd543e 100644
--- a/drivers/pci/controller/pcie-mediatek.c
+++ b/drivers/pci/controller/pcie-mediatek.c
@@ -12,6 +12,7 @@
 #include <linux/iopoll.h>
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/mfd/syscon.h>
@@ -180,7 +181,6 @@ struct mtk_pcie_soc {
  * @irq: GIC irq
  * @irq_domain: legacy INTx IRQ domain
  * @inner_domain: inner IRQ domain
- * @msi_domain: MSI IRQ domain
  * @lock: protect the msi_irq_in_use bitmap
  * @msi_irq_in_use: bit map for assigned MSI IRQ
  */
@@ -200,7 +200,6 @@ struct mtk_pcie_port {
 	int irq;
 	struct irq_domain *irq_domain;
 	struct irq_domain *inner_domain;
-	struct irq_domain *msi_domain;
 	struct mutex lock;
 	DECLARE_BITMAP(msi_irq_in_use, MTK_MSI_IRQS_NUM);
 };
@@ -470,17 +469,20 @@ static const struct irq_domain_ops msi_domain_ops = {
 	.free	= mtk_pcie_irq_domain_free,
 };
 
-static struct irq_chip mtk_msi_irq_chip = {
-	.name		= "MTK PCIe MSI",
-	.irq_ack	= irq_chip_ack_parent,
-	.irq_mask	= pci_msi_mask_irq,
-	.irq_unmask	= pci_msi_unmask_irq,
-};
+#define MTK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				MSI_FLAG_NO_AFFINITY)
+
+#define MTK_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK		| \
+				 MSI_FLAG_PCI_MSIX)
 
-static struct msi_domain_info mtk_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX,
-	.chip	= &mtk_msi_irq_chip,
+static const struct msi_parent_ops mtk_msi_parent_ops = {
+	.required_flags		= MTK_MSI_FLAGS_REQUIRED,
+	.supported_flags	= MTK_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "MTK-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port)
@@ -489,21 +491,19 @@ static int mtk_pcie_allocate_msi_domains(struct mtk_pcie_port *port)
 
 	mutex_init(&port->lock);
 
-	port->inner_domain = irq_domain_create_linear(fwnode, MTK_MSI_IRQS_NUM,
-						      &msi_domain_ops, port);
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &msi_domain_ops,
+		.host_data	= port,
+		.size		= MTK_MSI_IRQS_NUM,
+	};
+
+	port->inner_domain = msi_create_parent_irq_domain(&info, &mtk_msi_parent_ops);
 	if (!port->inner_domain) {
 		dev_err(port->pcie->dev, "failed to create IRQ domain\n");
 		return -ENOMEM;
 	}
 
-	port->msi_domain = pci_msi_create_irq_domain(fwnode, &mtk_msi_domain_info,
-						     port->inner_domain);
-	if (!port->msi_domain) {
-		dev_err(port->pcie->dev, "failed to create MSI domain\n");
-		irq_domain_remove(port->inner_domain);
-		return -ENOMEM;
-	}
-
 	return 0;
 }
 
@@ -532,8 +532,6 @@ static void mtk_pcie_irq_teardown(struct mtk_pcie *pcie)
 			irq_domain_remove(port->irq_domain);
 
 		if (IS_ENABLED(CONFIG_PCI_MSI)) {
-			if (port->msi_domain)
-				irq_domain_remove(port->msi_domain);
 			if (port->inner_domain)
 				irq_domain_remove(port->inner_domain);
 		}
-- 
2.39.5


^ permalink raw reply related

* [PATCH 07/16] PCI: mediatek-gen3: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Ryder Lee <ryder.lee@mediatek.com>
Cc: Jianjun Wang <jianjun.wang@mediatek.com>
Cc: Matthias Brugger <matthias.bgg@gmail.com>
Cc: AngeloGioacchino Del Regno <angelogioacchino.delregno@collabora.com>
Cc: linux-mediatek@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig              |  1 +
 drivers/pci/controller/pcie-mediatek-gen3.c | 67 ++++++++-------------
 2 files changed, 26 insertions(+), 42 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 375a019f35bd9..ec32c343a751d 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -203,6 +203,7 @@ config PCIE_MEDIATEK_GEN3
 	tristate "MediaTek Gen3 PCIe controller"
 	depends on ARCH_AIROHA || ARCH_MEDIATEK || COMPILE_TEST
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	help
 	  Adds support for PCIe Gen3 MAC controller for MediaTek SoCs.
 	  This PCIe controller is compatible with Gen3, Gen2 and Gen1 speed,
diff --git a/drivers/pci/controller/pcie-mediatek-gen3.c b/drivers/pci/controller/pcie-mediatek-gen3.c
index 5464b4ae5c20c..97147f43e41c5 100644
--- a/drivers/pci/controller/pcie-mediatek-gen3.c
+++ b/drivers/pci/controller/pcie-mediatek-gen3.c
@@ -12,6 +12,7 @@
 #include <linux/delay.h>
 #include <linux/iopoll.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -187,7 +188,6 @@ struct mtk_msi_set {
  * @saved_irq_state: IRQ enable state saved at suspend time
  * @irq_lock: lock protecting IRQ register access
  * @intx_domain: legacy INTx IRQ domain
- * @msi_domain: MSI IRQ domain
  * @msi_bottom_domain: MSI IRQ bottom domain
  * @msi_sets: MSI sets information
  * @lock: lock protecting IRQ bit map
@@ -210,7 +210,6 @@ struct mtk_gen3_pcie {
 	u32 saved_irq_state;
 	raw_spinlock_t irq_lock;
 	struct irq_domain *intx_domain;
-	struct irq_domain *msi_domain;
 	struct irq_domain *msi_bottom_domain;
 	struct mtk_msi_set msi_sets[PCIE_MSI_SET_NUM];
 	struct mutex lock;
@@ -526,30 +525,22 @@ static int mtk_pcie_startup_port(struct mtk_gen3_pcie *pcie)
 	return 0;
 }
 
-static void mtk_pcie_msi_irq_mask(struct irq_data *data)
-{
-	pci_msi_mask_irq(data);
-	irq_chip_mask_parent(data);
-}
-
-static void mtk_pcie_msi_irq_unmask(struct irq_data *data)
-{
-	pci_msi_unmask_irq(data);
-	irq_chip_unmask_parent(data);
-}
-
-static struct irq_chip mtk_msi_irq_chip = {
-	.irq_ack = irq_chip_ack_parent,
-	.irq_mask = mtk_pcie_msi_irq_mask,
-	.irq_unmask = mtk_pcie_msi_irq_unmask,
-	.name = "MSI",
-};
-
-static struct msi_domain_info mtk_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX |
-		  MSI_FLAG_MULTI_PCI_MSI,
-	.chip	= &mtk_msi_irq_chip,
+#define MTK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				MSI_FLAG_NO_AFFINITY		| \
+				MSI_FLAG_PCI_MSI_MASK_PARENT)
+
+#define MTK_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK		| \
+				 MSI_FLAG_PCI_MSIX		| \
+				 MSI_FLAG_MULTI_PCI_MSI)
+
+static const struct msi_parent_ops mtk_msi_parent_ops = {
+	.required_flags		= MTK_MSI_FLAGS_REQUIRED,
+	.supported_flags	= MTK_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "MTK3-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 static void mtk_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
@@ -756,28 +747,23 @@ static int mtk_pcie_init_irq_domains(struct mtk_gen3_pcie *pcie)
 	/* Setup MSI */
 	mutex_init(&pcie->lock);
 
-	pcie->msi_bottom_domain = irq_domain_create_linear(dev_fwnode(dev), PCIE_MSI_IRQS_NUM,
-							   &mtk_msi_bottom_domain_ops, pcie);
+	struct irq_domain_info info = {
+		.fwnode		= dev_fwnode(dev),
+		.ops		= &mtk_msi_bottom_domain_ops,
+		.host_data	= pcie,
+		.size		= PCIE_MSI_IRQS_NUM,
+	};
+
+	pcie->msi_bottom_domain = msi_create_parent_irq_domain(&info, &mtk_msi_parent_ops);
 	if (!pcie->msi_bottom_domain) {
 		dev_err(dev, "failed to create MSI bottom domain\n");
 		ret = -ENODEV;
 		goto err_msi_bottom_domain;
 	}
 
-	pcie->msi_domain = pci_msi_create_irq_domain(dev->fwnode,
-						     &mtk_msi_domain_info,
-						     pcie->msi_bottom_domain);
-	if (!pcie->msi_domain) {
-		dev_err(dev, "failed to create MSI domain\n");
-		ret = -ENODEV;
-		goto err_msi_domain;
-	}
-
 	of_node_put(intc_node);
 	return 0;
 
-err_msi_domain:
-	irq_domain_remove(pcie->msi_bottom_domain);
 err_msi_bottom_domain:
 	irq_domain_remove(pcie->intx_domain);
 out_put_node:
@@ -792,9 +778,6 @@ static void mtk_pcie_irq_teardown(struct mtk_gen3_pcie *pcie)
 	if (pcie->intx_domain)
 		irq_domain_remove(pcie->intx_domain);
 
-	if (pcie->msi_domain)
-		irq_domain_remove(pcie->msi_domain);
-
 	if (pcie->msi_bottom_domain)
 		irq_domain_remove(pcie->msi_bottom_domain);
 
-- 
2.39.5


^ permalink raw reply related

* [PATCH 06/16] PCI: iproc: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Ray Jui <rjui@broadcom.com>
Cc: Scott Branden <sbranden@broadcom.com>
Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig          |  1 +
 drivers/pci/controller/pcie-iproc-msi.c | 45 ++++++++++++-------------
 2 files changed, 22 insertions(+), 24 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 0f6cec244d4fa..375a019f35bd9 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -101,6 +101,7 @@ config PCIE_IPROC_MSI
 	bool "Broadcom iProc PCIe MSI support"
 	depends on PCIE_IPROC_PLATFORM || PCIE_IPROC_BCMA
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	default ARCH_BCM_IPROC
 	help
 	  Say Y here if you want to enable MSI support for Broadcom's iProc
diff --git a/drivers/pci/controller/pcie-iproc-msi.c b/drivers/pci/controller/pcie-iproc-msi.c
index d2cb4c4f821af..d0c7f004217fb 100644
--- a/drivers/pci/controller/pcie-iproc-msi.c
+++ b/drivers/pci/controller/pcie-iproc-msi.c
@@ -5,6 +5,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
 #include <linux/of_irq.h>
@@ -101,7 +102,6 @@ struct iproc_msi {
 	struct mutex bitmap_lock;
 	unsigned int nr_msi_vecs;
 	struct irq_domain *inner_domain;
-	struct irq_domain *msi_domain;
 	unsigned int nr_eq_region;
 	unsigned int nr_msi_region;
 	void *eq_cpu;
@@ -165,16 +165,18 @@ static inline unsigned int iproc_msi_eq_offset(struct iproc_msi *msi, u32 eq)
 		return eq * EQ_LEN * sizeof(u32);
 }
 
-static struct irq_chip iproc_msi_irq_chip = {
-	.name = "iProc-MSI",
+#define IPROC_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				  MSI_FLAG_USE_DEF_CHIP_OPS)
+#define IPROC_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK	| \
+				   MSI_FLAG_PCI_MSIX)
+
+static struct msi_parent_ops iproc_msi_parent_ops = {
+	.required_flags		= IPROC_MSI_FLAGS_REQUIRED,
+	.supported_flags	= IPROC_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.prefix			= "iProc-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
-
-static struct msi_domain_info iproc_msi_domain_info = {
-	.flags = MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		MSI_FLAG_PCI_MSIX,
-	.chip = &iproc_msi_irq_chip,
-};
-
 /*
  * In iProc PCIe core, each MSI group is serviced by a GIC interrupt and a
  * dedicated event queue.  Each MSI group can support up to 64 MSI vectors.
@@ -446,27 +448,22 @@ static void iproc_msi_disable(struct iproc_msi *msi)
 static int iproc_msi_alloc_domains(struct device_node *node,
 				   struct iproc_msi *msi)
 {
-	msi->inner_domain = irq_domain_create_linear(NULL, msi->nr_msi_vecs,
-						     &msi_domain_ops, msi);
+	struct irq_domain_info info = {
+		.fwnode		= of_fwnode_handle(node),
+		.ops		= &msi_domain_ops,
+		.host_data	= msi,
+		.size		= msi->nr_msi_vecs,
+	};
+
+	msi->inner_domain = msi_create_parent_irq_domain(&info, &iproc_msi_parent_ops);
 	if (!msi->inner_domain)
 		return -ENOMEM;
 
-	msi->msi_domain = pci_msi_create_irq_domain(of_fwnode_handle(node),
-						    &iproc_msi_domain_info,
-						    msi->inner_domain);
-	if (!msi->msi_domain) {
-		irq_domain_remove(msi->inner_domain);
-		return -ENOMEM;
-	}
-
 	return 0;
 }
 
 static void iproc_msi_free_domains(struct iproc_msi *msi)
 {
-	if (msi->msi_domain)
-		irq_domain_remove(msi->msi_domain);
-
 	if (msi->inner_domain)
 		irq_domain_remove(msi->inner_domain);
 }
@@ -542,7 +539,7 @@ int iproc_msi_init(struct iproc_pcie *pcie, struct device_node *node)
 	msi->nr_cpus = num_possible_cpus();
 
 	if (msi->nr_cpus == 1)
-		iproc_msi_domain_info.flags |=  MSI_FLAG_MULTI_PCI_MSI;
+		iproc_msi_parent_ops.supported_flags |= MSI_FLAG_MULTI_PCI_MSI;
 
 	msi->nr_irqs = of_irq_count(node);
 	if (!msi->nr_irqs) {
-- 
2.39.5


^ permalink raw reply related

* [PATCH 05/16] PCI: brcmstb: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Florian Fainelli <florian.fainelli@broadcom.com>
Cc: Broadcom internal kernel review list <bcm-kernel-feedback-list@broadcom.com>
Cc: Jim Quinlan <jim2101024@gmail.com>
Cc: Nicolas Saenz Julienne <nsaenz@kernel.org>
Cc: linux-rpi-kernel@lists.infradead.org
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig        |  1 +
 drivers/pci/controller/pcie-brcmstb.c | 44 +++++++++++++--------------
 2 files changed, 23 insertions(+), 22 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 012c18c67d9c6..0f6cec244d4fa 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -64,6 +64,7 @@ config PCIE_BRCMSTB
 		   BMIPS_GENERIC || COMPILE_TEST
 	depends on OF
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	default ARCH_BRCMSTB || BMIPS_GENERIC
 	help
 	  Say Y here to enable PCIe host controller support for
diff --git a/drivers/pci/controller/pcie-brcmstb.c b/drivers/pci/controller/pcie-brcmstb.c
index 744df5bd39aea..8ea75aa13130e 100644
--- a/drivers/pci/controller/pcie-brcmstb.c
+++ b/drivers/pci/controller/pcie-brcmstb.c
@@ -12,6 +12,7 @@
 #include <linux/iopoll.h>
 #include <linux/ioport.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/list.h>
@@ -269,7 +270,6 @@ struct brcm_msi {
 	struct device		*dev;
 	void __iomem		*base;
 	struct device_node	*np;
-	struct irq_domain	*msi_domain;
 	struct irq_domain	*inner_domain;
 	struct mutex		lock; /* guards the alloc/free operations */
 	u64			target_addr;
@@ -469,17 +469,20 @@ static void brcm_pcie_set_outbound_win(struct brcm_pcie *pcie,
 	writel(tmp, pcie->base + PCIE_MEM_WIN0_LIMIT_HI(win));
 }
 
-static struct irq_chip brcm_msi_irq_chip = {
-	.name            = "BRCM STB PCIe MSI",
-	.irq_ack         = irq_chip_ack_parent,
-	.irq_mask        = pci_msi_mask_irq,
-	.irq_unmask      = pci_msi_unmask_irq,
-};
+#define BRCM_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				 MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				 MSI_FLAG_NO_AFFINITY)
+
+#define BRCM_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK	| \
+				  MSI_FLAG_MULTI_PCI_MSI)
 
-static struct msi_domain_info brcm_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI,
-	.chip	= &brcm_msi_irq_chip,
+static const struct msi_parent_ops brcm_msi_parent_ops = {
+	.required_flags		= BRCM_MSI_FLAGS_REQUIRED,
+	.supported_flags	= BRCM_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "BRCM-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 static void brcm_pcie_msi_isr(struct irq_desc *desc)
@@ -588,18 +591,16 @@ static int brcm_allocate_domains(struct brcm_msi *msi)
 	struct fwnode_handle *fwnode = of_fwnode_handle(msi->np);
 	struct device *dev = msi->dev;
 
-	msi->inner_domain = irq_domain_create_linear(NULL, msi->nr, &msi_domain_ops, msi);
-	if (!msi->inner_domain) {
-		dev_err(dev, "failed to create IRQ domain\n");
-		return -ENOMEM;
-	}
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &msi_domain_ops,
+		.host_data	= msi,
+		.size		= msi->nr,
+	};
 
-	msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-						    &brcm_msi_domain_info,
-						    msi->inner_domain);
-	if (!msi->msi_domain) {
+	msi->inner_domain = msi_create_parent_irq_domain(&info, &brcm_msi_parent_ops);
+	if (!msi->inner_domain) {
 		dev_err(dev, "failed to create MSI domain\n");
-		irq_domain_remove(msi->inner_domain);
 		return -ENOMEM;
 	}
 
@@ -608,7 +609,6 @@ static int brcm_allocate_domains(struct brcm_msi *msi)
 
 static void brcm_free_domains(struct brcm_msi *msi)
 {
-	irq_domain_remove(msi->msi_domain);
 	irq_domain_remove(msi->inner_domain);
 }
 
-- 
2.39.5


^ permalink raw reply related

* [PATCH 04/16] PCI: altera-msi: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Joyce Ooi <joyce.ooi@intel.com>
---
 drivers/pci/controller/Kconfig           |  1 +
 drivers/pci/controller/pcie-altera-msi.c | 44 +++++++++++-------------
 2 files changed, 22 insertions(+), 23 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 91a2d4ffc3ac4..012c18c67d9c6 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -30,6 +30,7 @@ config PCIE_ALTERA_MSI
 	tristate "Altera PCIe MSI feature"
 	depends on PCIE_ALTERA
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	help
 	  Say Y here if you want PCIe MSI support for the Altera FPGA.
 	  This MSI driver supports Altera MSI to GIC controller IP.
diff --git a/drivers/pci/controller/pcie-altera-msi.c b/drivers/pci/controller/pcie-altera-msi.c
index a43f21eb8fbb9..2e48acd632c57 100644
--- a/drivers/pci/controller/pcie-altera-msi.c
+++ b/drivers/pci/controller/pcie-altera-msi.c
@@ -9,6 +9,7 @@
 
 #include <linux/interrupt.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/init.h>
 #include <linux/module.h>
@@ -29,7 +30,6 @@ struct altera_msi {
 	DECLARE_BITMAP(used, MAX_MSI_VECTORS);
 	struct mutex		lock;	/* protect "used" bitmap */
 	struct platform_device	*pdev;
-	struct irq_domain	*msi_domain;
 	struct irq_domain	*inner_domain;
 	void __iomem		*csr_base;
 	void __iomem		*vector_base;
@@ -74,18 +74,20 @@ static void altera_msi_isr(struct irq_desc *desc)
 	chained_irq_exit(chip, desc);
 }
 
-static struct irq_chip altera_msi_irq_chip = {
-	.name = "Altera PCIe MSI",
-	.irq_mask = pci_msi_mask_irq,
-	.irq_unmask = pci_msi_unmask_irq,
-};
+#define ALTERA_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS		| \
+				   MSI_FLAG_USE_DEF_CHIP_OPS		| \
+				   MSI_FLAG_NO_AFFINITY)
 
-static struct msi_domain_info altera_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX,
-	.chip	= &altera_msi_irq_chip,
-};
+#define ALTERA_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK		| \
+				    MSI_FLAG_PCI_MSIX)
 
+static const struct msi_parent_ops altera_msi_parent_ops = {
+	.required_flags		= ALTERA_MSI_FLAGS_REQUIRED,
+	.supported_flags	= ALTERA_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.prefix			= "Altera-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
+};
 static void altera_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
 {
 	struct altera_msi *msi = irq_data_get_irq_chip_data(data);
@@ -165,19 +167,16 @@ static const struct irq_domain_ops msi_domain_ops = {
 static int altera_allocate_domains(struct altera_msi *msi)
 {
 	struct fwnode_handle *fwnode = of_fwnode_handle(msi->pdev->dev.of_node);
-
-	msi->inner_domain = irq_domain_create_linear(NULL, msi->num_of_vectors,
-					     &msi_domain_ops, msi);
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &msi_domain_ops,
+		.host_data	= msi,
+		.size		= msi->num_of_vectors,
+	};
+
+	msi->inner_domain = msi_create_parent_irq_domain(&info, &altera_msi_parent_ops);
 	if (!msi->inner_domain) {
-		dev_err(&msi->pdev->dev, "failed to create IRQ domain\n");
-		return -ENOMEM;
-	}
-
-	msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-				&altera_msi_domain_info, msi->inner_domain);
-	if (!msi->msi_domain) {
 		dev_err(&msi->pdev->dev, "failed to create MSI domain\n");
-		irq_domain_remove(msi->inner_domain);
 		return -ENOMEM;
 	}
 
@@ -186,7 +185,6 @@ static int altera_allocate_domains(struct altera_msi *msi)
 
 static void altera_free_domains(struct altera_msi *msi)
 {
-	irq_domain_remove(msi->msi_domain);
 	irq_domain_remove(msi->inner_domain);
 }
 
-- 
2.39.5


^ permalink raw reply related

* [PATCH 03/16] PCI: aardvark: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Thomas Petazzoni <thomas.petazzoni@bootlin.com>
Cc: "Pali Rohár" <pali@kernel.org>
Cc: linux-arm-kernel@lists.infradead.org
---
 drivers/pci/controller/Kconfig        |  1 +
 drivers/pci/controller/pci-aardvark.c | 59 +++++++++++----------------
 2 files changed, 24 insertions(+), 36 deletions(-)

diff --git a/drivers/pci/controller/Kconfig b/drivers/pci/controller/Kconfig
index 886f6f43a895f..91a2d4ffc3ac4 100644
--- a/drivers/pci/controller/Kconfig
+++ b/drivers/pci/controller/Kconfig
@@ -13,6 +13,7 @@ config PCI_AARDVARK
 	depends on OF
 	depends on PCI_MSI
 	select PCI_BRIDGE_EMUL
+	select IRQ_MSI_LIB
 	help
 	 Add support for Aardvark 64bit PCIe Host Controller. This
 	 controller is part of the South Bridge of the Marvel Armada
diff --git a/drivers/pci/controller/pci-aardvark.c b/drivers/pci/controller/pci-aardvark.c
index 7bac64533b143..e34bea1ff0ac6 100644
--- a/drivers/pci/controller/pci-aardvark.c
+++ b/drivers/pci/controller/pci-aardvark.c
@@ -13,6 +13,7 @@
 #include <linux/gpio/consumer.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
 #include <linux/module.h>
@@ -278,7 +279,6 @@ struct advk_pcie {
 	struct irq_domain *irq_domain;
 	struct irq_chip irq_chip;
 	raw_spinlock_t irq_lock;
-	struct irq_domain *msi_domain;
 	struct irq_domain *msi_inner_domain;
 	raw_spinlock_t msi_irq_lock;
 	DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
@@ -1332,18 +1332,6 @@ static void advk_msi_irq_unmask(struct irq_data *d)
 	raw_spin_unlock_irqrestore(&pcie->msi_irq_lock, flags);
 }
 
-static void advk_msi_top_irq_mask(struct irq_data *d)
-{
-	pci_msi_mask_irq(d);
-	irq_chip_mask_parent(d);
-}
-
-static void advk_msi_top_irq_unmask(struct irq_data *d)
-{
-	pci_msi_unmask_irq(d);
-	irq_chip_unmask_parent(d);
-}
-
 static struct irq_chip advk_msi_bottom_irq_chip = {
 	.name			= "MSI",
 	.irq_compose_msi_msg	= advk_msi_irq_compose_msi_msg,
@@ -1436,17 +1424,20 @@ static const struct irq_domain_ops advk_pcie_irq_domain_ops = {
 	.xlate = irq_domain_xlate_onecell,
 };
 
-static struct irq_chip advk_msi_irq_chip = {
-	.name		= "advk-MSI",
-	.irq_mask	= advk_msi_top_irq_mask,
-	.irq_unmask	= advk_msi_top_irq_unmask,
-};
-
-static struct msi_domain_info advk_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_MULTI_PCI_MSI |
-		  MSI_FLAG_PCI_MSIX,
-	.chip	= &advk_msi_irq_chip,
+#define ADVK_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS	| \
+				 MSI_FLAG_USE_DEF_CHIP_OPS	| \
+				 MSI_FLAG_PCI_MSI_MASK_PARENT	| \
+				 MSI_FLAG_NO_AFFINITY)
+#define ADVK_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK	| \
+				  MSI_FLAG_PCI_MSIX		| \
+				  MSI_FLAG_MULTI_PCI_MSI)
+
+static const struct msi_parent_ops advk_msi_parent_ops = {
+	.required_flags		= ADVK_MSI_FLAGS_REQUIRED,
+	.supported_flags	= ADVK_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.prefix			= "advk-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
@@ -1456,26 +1447,22 @@ static int advk_pcie_init_msi_irq_domain(struct advk_pcie *pcie)
 	raw_spin_lock_init(&pcie->msi_irq_lock);
 	mutex_init(&pcie->msi_used_lock);
 
-	pcie->msi_inner_domain = irq_domain_create_linear(NULL, MSI_IRQ_NUM,
-							  &advk_msi_domain_ops, pcie);
-	if (!pcie->msi_inner_domain)
-		return -ENOMEM;
+	struct irq_domain_info info = {
+		.fwnode		= dev_fwnode(dev),
+		.ops		= &advk_msi_domain_ops,
+		.host_data	= pcie,
+		.size		= MSI_IRQ_NUM,
+	};
 
-	pcie->msi_domain =
-		pci_msi_create_irq_domain(dev_fwnode(dev),
-					  &advk_msi_domain_info,
-					  pcie->msi_inner_domain);
-	if (!pcie->msi_domain) {
-		irq_domain_remove(pcie->msi_inner_domain);
+	pcie->msi_inner_domain = msi_create_parent_irq_domain(&info, &advk_msi_parent_ops);
+	if (!pcie->msi_inner_domain)
 		return -ENOMEM;
-	}
 
 	return 0;
 }
 
 static void advk_pcie_remove_msi_irq_domain(struct advk_pcie *pcie)
 {
-	irq_domain_remove(pcie->msi_domain);
 	irq_domain_remove(pcie->msi_inner_domain);
 }
 
-- 
2.39.5


^ permalink raw reply related

* [PATCH 02/16] PCI: mobiveil: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Karthikeyan Mitran <m.karthikeyan@mobiveil.co.in>
Cc: Hou Zhiqiang <Zhiqiang.Hou@nxp.com>
---
 drivers/pci/controller/mobiveil/Kconfig       |  1 +
 .../controller/mobiveil/pcie-mobiveil-host.c  | 42 ++++++++++---------
 .../pci/controller/mobiveil/pcie-mobiveil.h   |  1 -
 3 files changed, 23 insertions(+), 21 deletions(-)

diff --git a/drivers/pci/controller/mobiveil/Kconfig b/drivers/pci/controller/mobiveil/Kconfig
index 58ce034f701ab..c50c4625937f8 100644
--- a/drivers/pci/controller/mobiveil/Kconfig
+++ b/drivers/pci/controller/mobiveil/Kconfig
@@ -9,6 +9,7 @@ config PCIE_MOBIVEIL
 config PCIE_MOBIVEIL_HOST
 	bool
 	depends on PCI_MSI
+	select IRQ_MSI_LIB
 	select PCIE_MOBIVEIL
 
 config PCIE_LAYERSCAPE_GEN4
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
index cd44ddb698ea2..d17e887b6b61d 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil-host.c
@@ -12,6 +12,7 @@
 #include <linux/init.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -353,16 +354,19 @@ static const struct irq_domain_ops intx_domain_ops = {
 	.map = mobiveil_pcie_intx_map,
 };
 
-static struct irq_chip mobiveil_msi_irq_chip = {
-	.name = "Mobiveil PCIe MSI",
-	.irq_mask = pci_msi_mask_irq,
-	.irq_unmask = pci_msi_unmask_irq,
-};
+#define MOBIVEIL_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS		| \
+				     MSI_FLAG_USE_DEF_CHIP_OPS		| \
+				     MSI_FLAG_NO_AFFINITY)
+
+#define MOBIVEIL_MSI_FLAGS_SUPPORTED (MSI_GENERIC_FLAGS_MASK		| \
+				      MSI_FLAG_PCI_MSIX)
 
-static struct msi_domain_info mobiveil_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX,
-	.chip	= &mobiveil_msi_irq_chip,
+static const struct msi_parent_ops mobiveil_msi_parent_ops = {
+	.required_flags		= MOBIVEIL_MSI_FLAGS_REQUIRED,
+	.supported_flags	= MOBIVEIL_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.prefix			= "Mobiveil-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 static void mobiveil_compose_msi_msg(struct irq_data *data, struct msi_msg *msg)
@@ -439,19 +443,17 @@ static int mobiveil_allocate_msi_domains(struct mobiveil_pcie *pcie)
 	struct mobiveil_msi *msi = &pcie->rp.msi;
 
 	mutex_init(&msi->lock);
-	msi->dev_domain = irq_domain_create_linear(NULL, msi->num_of_vectors,
-						   &msi_domain_ops, pcie);
-	if (!msi->dev_domain) {
-		dev_err(dev, "failed to create IRQ domain\n");
-		return -ENOMEM;
-	}
 
-	msi->msi_domain = pci_msi_create_irq_domain(fwnode,
-						    &mobiveil_msi_domain_info,
-						    msi->dev_domain);
-	if (!msi->msi_domain) {
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &msi_domain_ops,
+		.host_data	= pcie,
+		.size		= msi->num_of_vectors,
+	};
+
+	msi->dev_domain = msi_create_parent_irq_domain(&info, &mobiveil_msi_parent_ops);
+	if (!msi->dev_domain) {
 		dev_err(dev, "failed to create MSI domain\n");
-		irq_domain_remove(msi->dev_domain);
 		return -ENOMEM;
 	}
 
diff --git a/drivers/pci/controller/mobiveil/pcie-mobiveil.h b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
index 662f17f9bf65c..7246de6a71768 100644
--- a/drivers/pci/controller/mobiveil/pcie-mobiveil.h
+++ b/drivers/pci/controller/mobiveil/pcie-mobiveil.h
@@ -135,7 +135,6 @@
 
 struct mobiveil_msi {			/* MSI information */
 	struct mutex lock;		/* protect bitmap variable */
-	struct irq_domain *msi_domain;
 	struct irq_domain *dev_domain;
 	phys_addr_t msi_pages_phys;
 	int num_of_vectors;
-- 
2.39.5


^ permalink raw reply related

* [PATCH 01/16] PCI: dwc: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao, Jingoo Han
In-Reply-To: <cover.1750858083.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
Cc: Jingoo Han <jingoohan1@gmail.com>
---
 drivers/pci/controller/dwc/Kconfig            |  1 +
 .../pci/controller/dwc/pcie-designware-host.c | 68 +++++++------------
 drivers/pci/controller/dwc/pcie-designware.h  |  1 -
 3 files changed, 25 insertions(+), 45 deletions(-)

diff --git a/drivers/pci/controller/dwc/Kconfig b/drivers/pci/controller/dwc/Kconfig
index bb95877b2c6c4..8a63e9bc0c039 100644
--- a/drivers/pci/controller/dwc/Kconfig
+++ b/drivers/pci/controller/dwc/Kconfig
@@ -19,6 +19,7 @@ config PCIE_DW_DEBUGFS
 config PCIE_DW_HOST
 	bool
 	select PCIE_DW
+	select IRQ_MSI_LIB
 
 config PCIE_DW_EP
 	bool
diff --git a/drivers/pci/controller/dwc/pcie-designware-host.c b/drivers/pci/controller/dwc/pcie-designware-host.c
index 906277f9ffaf7..a953e07a68aff 100644
--- a/drivers/pci/controller/dwc/pcie-designware-host.c
+++ b/drivers/pci/controller/dwc/pcie-designware-host.c
@@ -10,6 +10,7 @@
 
 #include <linux/iopoll.h>
 #include <linux/irqchip/chained_irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <linux/irqdomain.h>
 #include <linux/msi.h>
 #include <linux/of_address.h>
@@ -23,35 +24,21 @@
 static struct pci_ops dw_pcie_ops;
 static struct pci_ops dw_child_pcie_ops;
 
-static void dw_msi_ack_irq(struct irq_data *d)
-{
-	irq_chip_ack_parent(d);
-}
-
-static void dw_msi_mask_irq(struct irq_data *d)
-{
-	pci_msi_mask_irq(d);
-	irq_chip_mask_parent(d);
-}
-
-static void dw_msi_unmask_irq(struct irq_data *d)
-{
-	pci_msi_unmask_irq(d);
-	irq_chip_unmask_parent(d);
-}
-
-static struct irq_chip dw_pcie_msi_irq_chip = {
-	.name = "PCI-MSI",
-	.irq_ack = dw_msi_ack_irq,
-	.irq_mask = dw_msi_mask_irq,
-	.irq_unmask = dw_msi_unmask_irq,
-};
-
-static struct msi_domain_info dw_pcie_msi_domain_info = {
-	.flags	= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-		  MSI_FLAG_NO_AFFINITY | MSI_FLAG_PCI_MSIX |
-		  MSI_FLAG_MULTI_PCI_MSI,
-	.chip	= &dw_pcie_msi_irq_chip,
+#define DW_PCIE_MSI_FLAGS_REQUIRED (MSI_FLAG_USE_DEF_DOM_OPS		| \
+				    MSI_FLAG_USE_DEF_CHIP_OPS		| \
+				    MSI_FLAG_NO_AFFINITY		| \
+				    MSI_FLAG_PCI_MSI_MASK_PARENT)
+#define DW_PCIE_MSI_FLAGS_SUPPORTED (MSI_FLAG_MULTI_PCI_MSI		| \
+				     MSI_FLAG_PCI_MSIX			| \
+				     MSI_GENERIC_FLAGS_MASK)
+
+static const struct msi_parent_ops dw_pcie_msi_parent_ops = {
+	.required_flags		= DW_PCIE_MSI_FLAGS_REQUIRED,
+	.supported_flags	= DW_PCIE_MSI_FLAGS_SUPPORTED,
+	.bus_select_token	= DOMAIN_BUS_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "DW-",
+	.init_dev_msi_info	= msi_lib_init_dev_msi_info,
 };
 
 /* MSI int handler */
@@ -228,25 +215,19 @@ int dw_pcie_allocate_domains(struct dw_pcie_rp *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct fwnode_handle *fwnode = of_fwnode_handle(pci->dev->of_node);
-
-	pp->irq_domain = irq_domain_create_linear(fwnode, pp->num_vectors,
-					       &dw_pcie_msi_domain_ops, pp);
+	struct irq_domain_info info = {
+		.fwnode		= fwnode,
+		.ops		= &dw_pcie_msi_domain_ops,
+		.size		= pp->num_vectors,
+		.host_data	= pp,
+	};
+
+	pp->irq_domain = msi_create_parent_irq_domain(&info, &dw_pcie_msi_parent_ops);
 	if (!pp->irq_domain) {
 		dev_err(pci->dev, "Failed to create IRQ domain\n");
 		return -ENOMEM;
 	}
 
-	irq_domain_update_bus_token(pp->irq_domain, DOMAIN_BUS_NEXUS);
-
-	pp->msi_domain = pci_msi_create_irq_domain(fwnode,
-						   &dw_pcie_msi_domain_info,
-						   pp->irq_domain);
-	if (!pp->msi_domain) {
-		dev_err(pci->dev, "Failed to create MSI domain\n");
-		irq_domain_remove(pp->irq_domain);
-		return -ENOMEM;
-	}
-
 	return 0;
 }
 
@@ -260,7 +241,6 @@ static void dw_pcie_free_msi(struct dw_pcie_rp *pp)
 							 NULL, NULL);
 	}
 
-	irq_domain_remove(pp->msi_domain);
 	irq_domain_remove(pp->irq_domain);
 }
 
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index ce9e18554e426..d9daee4ce220d 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -417,7 +417,6 @@ struct dw_pcie_rp {
 	const struct dw_pcie_host_ops *ops;
 	int			msi_irq[MAX_MSI_CTRLS];
 	struct irq_domain	*irq_domain;
-	struct irq_domain	*msi_domain;
 	dma_addr_t		msi_data;
 	struct irq_chip		*msi_irq_chip;
 	u32			num_vectors;
-- 
2.39.5


^ permalink raw reply related

* [PATCH 00/16] PCI: MSI parent domain conversion
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: Marc Zyngier, Thomas Gleixner, Lorenzo Pieralisi,
	Krzysztof Wilczyński, Manivannan Sadhasivam, Rob Herring,
	Bjorn Helgaas, linux-pci, linux-kernel, Karthikeyan Mitran,
	Hou Zhiqiang, Thomas Petazzoni, Pali Rohár,
	K . Y . Srinivasan, Haiyang Zhang, Wei Liu, Dexuan Cui, Joyce Ooi,
	Jim Quinlan, Nicolas Saenz Julienne, Florian Fainelli,
	Broadcom internal kernel review list, Ray Jui, Scott Branden,
	Ryder Lee, Jianjun Wang, Marek Vasut, Yoshihiro Shimoda,
	Michal Simek, Daire McNamara, Nirmal Patel, Jonathan Derrick,
	Matthias Brugger, AngeloGioacchino Del Regno, linux-arm-kernel,
	linux-hyperv, linux-rpi-kernel, linux-mediatek, linux-renesas-soc
  Cc: Nam Cao

The initial implementation of PCI/MSI interrupt domains in the hierarchical
interrupt domain model used a shortcut by providing a global PCI/MSI
domain.

This works because the PCI/MSI[X] hardware is standardized and uniform, but
it violates the basic design principle of hierarchical interrupt domains:
Each hardware block involved in the interrupt delivery chain should have a
separate interrupt domain.

For PCI/MSI[X], the interrupt controller is per PCI device and not a global
made-up entity.

Unsurprisingly, the shortcut turned out to have downsides as it does not
allow dynamic allocation of interrupt vectors after initialization and it
prevents supporting IMS on PCI. For further details, see:

https://lore.kernel.org/lkml/20221111120501.026511281@linutronix.de/

The solution is implementing per device MSI domains, this means the
entities which provide global PCI/MSI domain so far have to implement MSI
parent domain functionality instead.

This series converts the PCI controller drivers to implement MSI parent
domain.

 drivers/pci/Kconfig                           |   1 +
 drivers/pci/controller/Kconfig                |  11 +
 drivers/pci/controller/dwc/Kconfig            |   1 +
 .../pci/controller/dwc/pcie-designware-host.c |  68 ++----
 drivers/pci/controller/dwc/pcie-designware.h  |   1 -
 drivers/pci/controller/mobiveil/Kconfig       |   1 +
 .../controller/mobiveil/pcie-mobiveil-host.c  |  42 ++--
 .../pci/controller/mobiveil/pcie-mobiveil.h   |   1 -
 drivers/pci/controller/pci-aardvark.c         |  59 ++---
 drivers/pci/controller/pci-hyperv.c           |  98 ++++++--
 drivers/pci/controller/pcie-altera-msi.c      |  44 ++--
 drivers/pci/controller/pcie-brcmstb.c         |  44 ++--
 drivers/pci/controller/pcie-iproc-msi.c       |  45 ++--
 drivers/pci/controller/pcie-mediatek-gen3.c   |  67 ++---
 drivers/pci/controller/pcie-mediatek.c        |  46 ++--
 drivers/pci/controller/pcie-rcar-host.c       |  69 ++----
 drivers/pci/controller/pcie-xilinx-dma-pl.c   |  48 ++--
 drivers/pci/controller/pcie-xilinx-nwl.c      |  45 ++--
 drivers/pci/controller/pcie-xilinx.c          |  55 +++--
 drivers/pci/controller/plda/Kconfig           |   1 +
 drivers/pci/controller/plda/pcie-plda-host.c  |  44 ++--
 drivers/pci/controller/plda/pcie-plda.h       |   1 -
 drivers/pci/controller/vmd.c                  | 229 +++++++++---------
 23 files changed, 504 insertions(+), 517 deletions(-)

-- 
2.39.5


^ permalink raw reply

* [PATCH 1/1] x86/hyperv: Switch to msi_create_parent_irq_domain()
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: K . Y . Srinivasan, Marc Zyngier, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, linux-hyperv, linux-kernel
  Cc: Nam Cao
In-Reply-To: <cover.1750947640.git.namcao@linutronix.de>

Move away from the legacy MSI domain setup, switch to use
msi_create_parent_irq_domain().

Signed-off-by: Nam Cao <namcao@linutronix.de>
---
 arch/x86/hyperv/irqdomain.c | 107 ++++++++++++++++++++++++------------
 drivers/hv/Kconfig          |   1 +
 2 files changed, 73 insertions(+), 35 deletions(-)

diff --git a/arch/x86/hyperv/irqdomain.c b/arch/x86/hyperv/irqdomain.c
index 31f0d29cbc5e3..924400c31d368 100644
--- a/arch/x86/hyperv/irqdomain.c
+++ b/arch/x86/hyperv/irqdomain.c
@@ -10,6 +10,7 @@
 
 #include <linux/pci.h>
 #include <linux/irq.h>
+#include <linux/irqchip/irq-msi-lib.h>
 #include <asm/mshyperv.h>
 
 static int hv_map_interrupt(union hv_device_id device_id, bool level,
@@ -276,59 +277,95 @@ static void hv_teardown_msi_irq(struct pci_dev *dev, struct irq_data *irqd)
 		hv_status_err(status, "\n");
 }
 
-static void hv_msi_free_irq(struct irq_domain *domain,
-			    struct msi_domain_info *info, unsigned int virq)
-{
-	struct irq_data *irqd = irq_get_irq_data(virq);
-	struct msi_desc *desc;
-
-	if (!irqd)
-		return;
-
-	desc = irq_data_get_msi_desc(irqd);
-	if (!desc || !desc->irq || WARN_ON_ONCE(!dev_is_pci(desc->dev)))
-		return;
-
-	hv_teardown_msi_irq(to_pci_dev(desc->dev), irqd);
-}
-
 /*
  * IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
  * which implement the MSI or MSI-X Capability Structure.
  */
 static struct irq_chip hv_pci_msi_controller = {
 	.name			= "HV-PCI-MSI",
-	.irq_unmask		= pci_msi_unmask_irq,
-	.irq_mask		= pci_msi_mask_irq,
 	.irq_ack		= irq_chip_ack_parent,
-	.irq_retrigger		= irq_chip_retrigger_hierarchy,
 	.irq_compose_msi_msg	= hv_irq_compose_msi_msg,
-	.irq_set_affinity	= msi_domain_set_affinity,
-	.flags			= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED,
+	.irq_set_affinity	= irq_chip_set_affinity_parent,
 };
 
-static struct msi_domain_ops pci_msi_domain_ops = {
-	.msi_free		= hv_msi_free_irq,
-	.msi_prepare		= pci_msi_prepare,
+static bool hv_init_dev_msi_info(struct device *dev, struct irq_domain *domain,
+				 struct irq_domain *real_parent, struct msi_domain_info *info)
+{
+	struct irq_chip *chip = info->chip;
+
+	if (!msi_lib_init_dev_msi_info(dev, domain, real_parent, info))
+		return false;
+
+	chip->flags |= IRQCHIP_SKIP_SET_WAKE | IRQCHIP_MOVE_DEFERRED;
+
+	info->ops->msi_prepare = pci_msi_prepare;
+
+	return true;
+}
+
+#define HV_MSI_FLAGS_SUPPORTED	(MSI_GENERIC_FLAGS_MASK | MSI_FLAG_PCI_MSIX)
+#define HV_MSI_FLAGS_REQUIRED	(MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS)
+
+static struct msi_parent_ops hv_msi_parent_ops = {
+	.supported_flags	= HV_MSI_FLAGS_SUPPORTED,
+	.required_flags		= HV_MSI_FLAGS_REQUIRED,
+	.bus_select_token	= DOMAIN_BUS_NEXUS,
+	.bus_select_mask	= MATCH_PCI_MSI,
+	.chip_flags		= MSI_CHIP_FLAG_SET_ACK,
+	.prefix			= "HV-",
+	.init_dev_msi_info	= hv_init_dev_msi_info,
 };
 
-static struct msi_domain_info hv_pci_msi_domain_info = {
-	.flags		= MSI_FLAG_USE_DEF_DOM_OPS | MSI_FLAG_USE_DEF_CHIP_OPS |
-			  MSI_FLAG_PCI_MSIX,
-	.ops		= &pci_msi_domain_ops,
-	.chip		= &hv_pci_msi_controller,
-	.handler	= handle_edge_irq,
-	.handler_name	= "edge",
+static int hv_msi_domain_alloc(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs,
+			       void *arg)
+{
+	/* TODO: move the content of hv_irq_compose_msi_msg() in here */
+	int ret;
+
+	ret = irq_domain_alloc_irqs_parent(d, virq, nr_irqs, arg);
+	if (ret)
+		return ret;
+
+	for (int i = 0; i < nr_irqs; ++i) {
+		irq_domain_set_info(d, virq + i, 0, &hv_pci_msi_controller, NULL,
+				    handle_edge_irq, NULL, "edge");
+	}
+	return 0;
+}
+
+static void hv_msi_domain_free(struct irq_domain *d, unsigned int virq, unsigned int nr_irqs)
+{
+	for (int i = 0; i < nr_irqs; ++i) {
+		struct irq_data *irqd = irq_domain_get_irq_data(d, virq);
+		struct msi_desc *desc;
+
+		desc = irq_data_get_msi_desc(irqd);
+		if (!desc || !desc->irq || WARN_ON_ONCE(!dev_is_pci(desc->dev)))
+			continue;
+
+		hv_teardown_msi_irq(to_pci_dev(desc->dev), irqd);
+	}
+	irq_domain_free_irqs_top(d, virq, nr_irqs);
+}
+
+static const struct irq_domain_ops hv_msi_domain_ops = {
+	.select	= msi_lib_irq_domain_select,
+	.alloc	= hv_msi_domain_alloc,
+	.free	= hv_msi_domain_free,
 };
 
 struct irq_domain * __init hv_create_pci_msi_domain(void)
 {
 	struct irq_domain *d = NULL;
-	struct fwnode_handle *fn;
 
-	fn = irq_domain_alloc_named_fwnode("HV-PCI-MSI");
-	if (fn)
-		d = pci_msi_create_irq_domain(fn, &hv_pci_msi_domain_info, x86_vector_domain);
+	struct irq_domain_info info = {
+		.fwnode		= irq_domain_alloc_named_fwnode("HV-PCI-MSI"),
+		.ops		= &hv_msi_domain_ops,
+		.parent		= x86_vector_domain,
+	};
+
+	if (info.fwnode)
+		d = msi_create_parent_irq_domain(&info, &hv_msi_parent_ops);
 
 	/* No point in going further if we can't get an irq domain */
 	BUG_ON(!d);
diff --git a/drivers/hv/Kconfig b/drivers/hv/Kconfig
index 1cd188b73b743..e62a0f8b34198 100644
--- a/drivers/hv/Kconfig
+++ b/drivers/hv/Kconfig
@@ -10,6 +10,7 @@ config HYPERV
 	select X86_HV_CALLBACK_VECTOR if X86
 	select OF_EARLY_FLATTREE if OF
 	select SYSFB if !HYPERV_VTL_MODE
+	select IRQ_MSI_LIB if X86
 	help
 	  Select this option to run Linux as a Hyper-V client operating
 	  system.
-- 
2.39.5


^ permalink raw reply related

* [PATCH 0/1] x86/hyperv: MSI parent domain conversion
From: Nam Cao @ 2025-06-26 14:47 UTC (permalink / raw)
  To: K . Y . Srinivasan, Marc Zyngier, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Thomas Gleixner, Ingo Molnar, Borislav Petkov,
	Dave Hansen, x86, H . Peter Anvin, linux-hyperv, linux-kernel
  Cc: Nam Cao

The initial implementation of PCI/MSI interrupt domains in the hierarchical
interrupt domain model used a shortcut by providing a global PCI/MSI
domain.

This works because the PCI/MSI[X] hardware is standardized and uniform, but
it violates the basic design principle of hierarchical interrupt domains:
Each hardware block involved in the interrupt delivery chain should have a
separate interrupt domain.

For PCI/MSI[X], the interrupt controller is per PCI device and not a global
made-up entity.

Unsurprisingly, the shortcut turned out to have downsides as it does not
allow dynamic allocation of interrupt vectors after initialization and it
prevents supporting IMS on PCI. For further details, see:

https://lore.kernel.org/lkml/20221111120501.026511281@linutronix.de/

The solution is implementing per device MSI domains, this means the
entities which provide global PCI/MSI domain so far have to implement MSI
parent domain functionality instead.

This series converts the x86 hyperv driver to implement MSI parent domain.

 arch/x86/hyperv/irqdomain.c | 107 ++++++++++++++++++++++++------------
 drivers/hv/Kconfig          |   1 +
 2 files changed, 73 insertions(+), 35 deletions(-)

-- 
2.39.5


^ permalink raw reply

* Re: [PATCH net-next v3 1/3] vsock: Add support for SIOCINQ ioctl
From: Xuewei Niu @ 2025-06-26  5:02 UTC (permalink / raw)
  To: sgarzare
  Cc: davem, decui, fupan.lfp, haiyangz, jasowang, kvm, kys, leonardi,
	linux-hyperv, linux-kernel, mst, netdev, niuxuewei.nxw,
	niuxuewei97, pabeni, stefanha, virtualization, wei.liu, xuanzhuo
In-Reply-To: <wgyxcpcsnpsta65q4n7pekw2hbedrbzqgtevkzqaqkjrqfjlyo@6jod5pw75lyf>

> On Wed, Jun 25, 2025 at 08:03:00AM +0000, Dexuan Cui wrote:
> >> From: Stefano Garzarella <sgarzare@redhat.com>
> >> Sent: Tuesday, June 17, 2025 7:39 AM
> >>  ...
> >> Now looks better to me, I just checked transports: vmci and virtio/vhost
> >> returns what we want, but for hyperv we have:
> >>
> >> 	static s64 hvs_stream_has_data(struct vsock_sock *vsk)
> >> 	{
> >> 		struct hvsock *hvs = vsk->trans;
> >> 		s64 ret;
> >>
> >> 		if (hvs->recv_data_len > 0)
> >> 			return 1;
> >>
> >> @Hyper-v maintainers: do you know why we don't return `recv_data_len`?
> >
> >Sorry for the late response!  This is the complete code of the function:
> >
> >static s64 hvs_stream_has_data(struct vsock_sock *vsk)
> >{
> >        struct hvsock *hvs = vsk->trans;
> >        s64 ret;
> >
> >        if (hvs->recv_data_len > 0)
> >                return 1;
> >
> >        switch (hvs_channel_readable_payload(hvs->chan)) {
> >        case 1:
> >                ret = 1;
> >                break;
> >        case 0:
> >                vsk->peer_shutdown |= SEND_SHUTDOWN;
> >                ret = 0;
> >                break;
> >        default: /* -1 */
> >                ret = 0;
> >                break;
> >        }
> >
> >        return ret;
> >}
> >
> >If (hvs->recv_data_len > 0), I think we can return hvs->recv_data_len here.
> >
> >If hvs->recv_data_len is 0, and hvs_channel_readable_payload(hvs->chan)
> >returns 1, we should not return hvs->recv_data_len (which is 0 here), 
> >and it's
> >not very easy to find how many bytes of payload in total is available right now:
> >each host-to-guest "packet" in the VMBus channel ringbuffer has a header
> >(which is not part of the payload data) and a trailing padding field, and we
> >would have to iterate on all the "packets" (or at least the next
> >"packet"?) to find the exact bytes of pending payload. Please see
> >hvs_stream_dequeue() for details.
> >
> >Ideally hvs_stream_has_data() should return the exact length of pending
> >readable payload, but when the hv_sock code was written in 2017,
> >vsock_stream_has_data() -> ... -> hvs_stream_has_data() basically only needs
> >to know whether there is any data or not, i.e. it's kind of a boolean variable, so
> >hvs_stream_has_data() was written to return 1 or 0 for simplicity. :-)
> 
> Yeah, I see, thanks for the details! :-)
> 
> >
> >I can post the patch below (not tested yet) to fix hvs_stream_has_data() by
> >returning the payload length of the next single "packet".  Does it look good
> >to you?
> 
> Yep, LGTM! Can be a best effort IMO.
> 
> Maybe when you have it tested, post it here as proper patch, and Xuewei 
> can include it in the next version of this series (of course with you as 
> author, etc.). In this way will be easy to test/merge, since they are 
> related.
> 
> @Xuewei @Dexuan Is it okay for you?

Yeah, sounds good to me!

Thanks,
Xuewei

> Thanks,
> Stefano
> 
> >
> >--- a/net/vmw_vsock/hyperv_transport.c
> >+++ b/net/vmw_vsock/hyperv_transport.c
> >@@ -694,15 +694,25 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
> > static s64 hvs_stream_has_data(struct vsock_sock *vsk)
> > {
> >        struct hvsock *hvs = vsk->trans;
> >+       bool need_refill = !hvs->recv_desc;
> >        s64 ret;
> >
> >        if (hvs->recv_data_len > 0)
> >-               return 1;
> >+               return hvs->recv_data_len;
> >
> >        switch (hvs_channel_readable_payload(hvs->chan)) {
> >        case 1:
> >-               ret = 1;
> >-               break;
> >+               if (!need_refill)
> >+                       return -EIO;
> >+
> >+               hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
> >+               if (!hvs->recv_desc)
> >+                       return -ENOBUFS;
> >+
> >+               ret = hvs_update_recv_data(hvs);
> >+               if (ret)
> >+                       return ret;
> >+               return hvs->recv_data_len;
> >        case 0:
> >                vsk->peer_shutdown |= SEND_SHUTDOWN;
> >                ret = 0;
> >
> >Thanks,
> >Dexuan

^ permalink raw reply

* Re: [PATCH net-next v2] net: mana: Fix build errors when CONFIG_NET_SHAPER is disabled
From: Simon Horman @ 2025-06-25 19:05 UTC (permalink / raw)
  To: Erni Sri Satya Vennela
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, linux-hyperv, netdev, linux-kernel
In-Reply-To: <1750851355-8067-1-git-send-email-ernis@linux.microsoft.com>

On Wed, Jun 25, 2025 at 04:35:55AM -0700, Erni Sri Satya Vennela wrote:
> Fix build errors when CONFIG_NET_SHAPER is disabled, including:
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:804:10: error:
> 'const struct net_device_ops' has no member named 'net_shaper_ops'
> 
>      804 |         .net_shaper_ops         = &mana_shaper_ops,
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:804:35: error:
> initialization of 'int (*)(struct net_device *, struct neigh_parms *)'
> from incompatible pointer type 'const struct net_shaper_ops *'
> [-Werror=incompatible-pointer-types]
> 
>      804 |         .net_shaper_ops         = &mana_shaper_ops,
> 
> Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> Fixes: 75cabb46935b ("net: mana: Add support for net_shaper_ops")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202506230625.bfUlqb8o-lkp@intel.com/
> ---
> Changes in v2:
> * Use "select NET_SHAPER" in Kconfig instead of adding multiple checks for
>   CONFIG_NET_SHAPER.

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply

* RE: [EXTERNAL] Re: [PATCH net-next v3 1/3] vsock: Add support for SIOCINQ ioctl
From: Dexuan Cui @ 2025-06-25 16:41 UTC (permalink / raw)
  To: Stefano Garzarella
  Cc: Xuewei Niu, KY Srinivasan, Haiyang Zhang, Wei Liu,
	linux-hyperv@vger.kernel.org, mst@redhat.com, pabeni@redhat.com,
	jasowang@redhat.com, xuanzhuo@linux.alibaba.com,
	davem@davemloft.net, netdev@vger.kernel.org, stefanha@redhat.com,
	leonardi@redhat.com, virtualization@lists.linux.dev,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	fupan.lfp@antgroup.com, Xuewei Niu
In-Reply-To: <wgyxcpcsnpsta65q4n7pekw2hbedrbzqgtevkzqaqkjrqfjlyo@6jod5pw75lyf>

> From: Stefano Garzarella <sgarzare@redhat.com>
> Sent: Wednesday, June 25, 2025 6:32 AM
> ...
> >I can post the patch below (not tested yet) to fix hvs_stream_has_data() by
> >returning the payload length of the next single "packet".  Does it look good
> >to you?
> 
> Yep, LGTM! Can be a best effort IMO.
Thanks! I'll test and post it later today.
 
> Maybe when you have it tested, post it here as proper patch, and Xuewei
> can include it in the next version of this series (of course with you as
> author, etc.). In this way will be easy to test/merge, since they are
> related.
> 
> @Xuewei @Dexuan Is it okay for you?
> 
> Thanks,
> Stefano

This is a good idea to me. I'll post a patch later today.

Thanks,
Dexuan

^ permalink raw reply

* Re: [EXTERNAL] Re: [PATCH net-next v3 1/3] vsock: Add support for SIOCINQ ioctl
From: Stefano Garzarella @ 2025-06-25 13:32 UTC (permalink / raw)
  To: Dexuan Cui
  Cc: Xuewei Niu, KY Srinivasan, Haiyang Zhang, Wei Liu,
	linux-hyperv@vger.kernel.org, mst@redhat.com, pabeni@redhat.com,
	jasowang@redhat.com, xuanzhuo@linux.alibaba.com,
	davem@davemloft.net, netdev@vger.kernel.org, stefanha@redhat.com,
	leonardi@redhat.com, virtualization@lists.linux.dev,
	kvm@vger.kernel.org, linux-kernel@vger.kernel.org,
	fupan.lfp@antgroup.com, Xuewei Niu
In-Reply-To: <BL1PR21MB31158AE6980AF18E769A4E65BF7BA@BL1PR21MB3115.namprd21.prod.outlook.com>

On Wed, Jun 25, 2025 at 08:03:00AM +0000, Dexuan Cui wrote:
>> From: Stefano Garzarella <sgarzare@redhat.com>
>> Sent: Tuesday, June 17, 2025 7:39 AM
>>  ...
>> Now looks better to me, I just checked transports: vmci and virtio/vhost
>> returns what we want, but for hyperv we have:
>>
>> 	static s64 hvs_stream_has_data(struct vsock_sock *vsk)
>> 	{
>> 		struct hvsock *hvs = vsk->trans;
>> 		s64 ret;
>>
>> 		if (hvs->recv_data_len > 0)
>> 			return 1;
>>
>> @Hyper-v maintainers: do you know why we don't return `recv_data_len`?
>
>Sorry for the late response!  This is the complete code of the function:
>
>static s64 hvs_stream_has_data(struct vsock_sock *vsk)
>{
>        struct hvsock *hvs = vsk->trans;
>        s64 ret;
>
>        if (hvs->recv_data_len > 0)
>                return 1;
>
>        switch (hvs_channel_readable_payload(hvs->chan)) {
>        case 1:
>                ret = 1;
>                break;
>        case 0:
>                vsk->peer_shutdown |= SEND_SHUTDOWN;
>                ret = 0;
>                break;
>        default: /* -1 */
>                ret = 0;
>                break;
>        }
>
>        return ret;
>}
>
>If (hvs->recv_data_len > 0), I think we can return hvs->recv_data_len here.
>
>If hvs->recv_data_len is 0, and hvs_channel_readable_payload(hvs->chan)
>returns 1, we should not return hvs->recv_data_len (which is 0 here), 
>and it's
>not very easy to find how many bytes of payload in total is available right now:
>each host-to-guest "packet" in the VMBus channel ringbuffer has a header
>(which is not part of the payload data) and a trailing padding field, and we
>would have to iterate on all the "packets" (or at least the next
>"packet"?) to find the exact bytes of pending payload. Please see
>hvs_stream_dequeue() for details.
>
>Ideally hvs_stream_has_data() should return the exact length of pending
>readable payload, but when the hv_sock code was written in 2017,
>vsock_stream_has_data() -> ... -> hvs_stream_has_data() basically only needs
>to know whether there is any data or not, i.e. it's kind of a boolean variable, so
>hvs_stream_has_data() was written to return 1 or 0 for simplicity. :-)

Yeah, I see, thanks for the details! :-)

>
>I can post the patch below (not tested yet) to fix hvs_stream_has_data() by
>returning the payload length of the next single "packet".  Does it look good
>to you?

Yep, LGTM! Can be a best effort IMO.

Maybe when you have it tested, post it here as proper patch, and Xuewei 
can include it in the next version of this series (of course with you as 
author, etc.). In this way will be easy to test/merge, since they are 
related.

@Xuewei @Dexuan Is it okay for you?

Thanks,
Stefano

>
>--- a/net/vmw_vsock/hyperv_transport.c
>+++ b/net/vmw_vsock/hyperv_transport.c
>@@ -694,15 +694,25 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
> static s64 hvs_stream_has_data(struct vsock_sock *vsk)
> {
>        struct hvsock *hvs = vsk->trans;
>+       bool need_refill = !hvs->recv_desc;
>        s64 ret;
>
>        if (hvs->recv_data_len > 0)
>-               return 1;
>+               return hvs->recv_data_len;
>
>        switch (hvs_channel_readable_payload(hvs->chan)) {
>        case 1:
>-               ret = 1;
>-               break;
>+               if (!need_refill)
>+                       return -EIO;
>+
>+               hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
>+               if (!hvs->recv_desc)
>+                       return -ENOBUFS;
>+
>+               ret = hvs_update_recv_data(hvs);
>+               if (ret)
>+                       return ret;
>+               return hvs->recv_data_len;
>        case 0:
>                vsk->peer_shutdown |= SEND_SHUTDOWN;
>                ret = 0;
>
>Thanks,
>Dexuan
>


^ permalink raw reply

* [PATCH net-next v2] net: mana: Fix build errors when CONFIG_NET_SHAPER is disabled
From: Erni Sri Satya Vennela @ 2025-06-25 11:35 UTC (permalink / raw)
  To: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, linux-hyperv, netdev, linux-kernel
  Cc: Erni Sri Satya Vennela

Fix build errors when CONFIG_NET_SHAPER is disabled, including:

drivers/net/ethernet/microsoft/mana/mana_en.c:804:10: error:
'const struct net_device_ops' has no member named 'net_shaper_ops'

     804 |         .net_shaper_ops         = &mana_shaper_ops,

drivers/net/ethernet/microsoft/mana/mana_en.c:804:35: error:
initialization of 'int (*)(struct net_device *, struct neigh_parms *)'
from incompatible pointer type 'const struct net_shaper_ops *'
[-Werror=incompatible-pointer-types]

     804 |         .net_shaper_ops         = &mana_shaper_ops,

Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
Fixes: 75cabb46935b ("net: mana: Add support for net_shaper_ops")
Reported-by: kernel test robot <lkp@intel.com>
Closes: https://lore.kernel.org/oe-kbuild-all/202506230625.bfUlqb8o-lkp@intel.com/
---
Changes in v2:
* Use "select NET_SHAPER" in Kconfig instead of adding multiple checks for
  CONFIG_NET_SHAPER.
---
 drivers/net/ethernet/microsoft/Kconfig | 1 +
 1 file changed, 1 insertion(+)

diff --git a/drivers/net/ethernet/microsoft/Kconfig b/drivers/net/ethernet/microsoft/Kconfig
index 901fbffbf718..3f36ee6a8ece 100644
--- a/drivers/net/ethernet/microsoft/Kconfig
+++ b/drivers/net/ethernet/microsoft/Kconfig
@@ -22,6 +22,7 @@ config MICROSOFT_MANA
 	depends on PCI_HYPERV
 	select AUXILIARY_BUS
 	select PAGE_POOL
+	select NET_SHAPER
 	help
 	  This driver supports Microsoft Azure Network Adapter (MANA).
 	  So far, the driver is only supported on X86_64.
-- 
2.34.1


^ permalink raw reply related

* Re: [PATCH net-next] net: mana: Fix build errors when CONFIG_NET_SHAPER is disabled
From: Erni Sri Satya Vennela @ 2025-06-25 10:58 UTC (permalink / raw)
  To: Jakub Kicinski
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	pabeni, shradhagupta, longli, kotaranov, lorenzo, shirazsaleem,
	schakrabarti, linux-hyperv, netdev, linux-kernel
In-Reply-To: <20250624163342.754f5b64@kernel.org>

On Tue, Jun 24, 2025 at 04:33:42PM -0700, Jakub Kicinski wrote:
> On Mon, 23 Jun 2025 04:14:01 -0700 Erni Sri Satya Vennela wrote:
> > Fix build errors when CONFIG_NET_SHAPER is disabled, including:
> > 
> > drivers/net/ethernet/microsoft/mana/mana_en.c:804:10: error:
> > 'const struct net_device_ops' has no member named 'net_shaper_ops'
> > 
> >      804 |         .net_shaper_ops         = &mana_shaper_ops,
> > 
> > drivers/net/ethernet/microsoft/mana/mana_en.c:804:35: error:
> > initialization of 'int (*)(struct net_device *, struct neigh_parms *)'
> > from incompatible pointer type 'const struct net_shaper_ops *'
> > [-Werror=incompatible-pointer-types]
> > 
> >      804 |         .net_shaper_ops         = &mana_shaper_ops,
> 
> You have to add
> 
> 	select NET_SHAPER
> 
> to kconfig dependencies for the driver. This symbol cannot be selected
> by the user, its hidden from the menus.
Thankyou for pointing it out Jakub.
I'll make this change in the next version of this patch.

- Vennela
> -- 
> pw-bot: cr

^ permalink raw reply

* RE: [EXTERNAL] Re: [PATCH net-next v3 1/3] vsock: Add support for SIOCINQ ioctl
From: Dexuan Cui @ 2025-06-25  8:03 UTC (permalink / raw)
  To: Stefano Garzarella, Xuewei Niu, KY Srinivasan, Haiyang Zhang,
	Wei Liu, linux-hyperv@vger.kernel.org
  Cc: mst@redhat.com, pabeni@redhat.com, jasowang@redhat.com,
	xuanzhuo@linux.alibaba.com, davem@davemloft.net,
	netdev@vger.kernel.org, stefanha@redhat.com, leonardi@redhat.com,
	virtualization@lists.linux.dev, kvm@vger.kernel.org,
	linux-kernel@vger.kernel.org, fupan.lfp@antgroup.com, Xuewei Niu
In-Reply-To: <y465uw5phymt3gbgdxsxlopeyhcbbherjri6b6etl64qhsc4ud@vc2c45mo5zxw>

> From: Stefano Garzarella <sgarzare@redhat.com>
> Sent: Tuesday, June 17, 2025 7:39 AM
>  ...
> Now looks better to me, I just checked transports: vmci and virtio/vhost
> returns what we want, but for hyperv we have:
> 
> 	static s64 hvs_stream_has_data(struct vsock_sock *vsk)
> 	{
> 		struct hvsock *hvs = vsk->trans;
> 		s64 ret;
> 
> 		if (hvs->recv_data_len > 0)
> 			return 1;
> 
> @Hyper-v maintainers: do you know why we don't return `recv_data_len`?

Sorry for the late response!  This is the complete code of the function:

static s64 hvs_stream_has_data(struct vsock_sock *vsk)
{
        struct hvsock *hvs = vsk->trans;
        s64 ret;

        if (hvs->recv_data_len > 0)
                return 1;

        switch (hvs_channel_readable_payload(hvs->chan)) {
        case 1:
                ret = 1;
                break;
        case 0:
                vsk->peer_shutdown |= SEND_SHUTDOWN;
                ret = 0;
                break;
        default: /* -1 */
                ret = 0;
                break;
        }

        return ret;
}

If (hvs->recv_data_len > 0), I think we can return hvs->recv_data_len here.

If hvs->recv_data_len is 0, and hvs_channel_readable_payload(hvs->chan)
returns 1, we should not return hvs->recv_data_len (which is 0 here), and it's
not very easy to find how many bytes of payload in total is available right now:
each host-to-guest "packet" in the VMBus channel ringbuffer has a header
(which is not part of the payload data) and a trailing padding field, and we
would have to iterate on all the "packets" (or at least the next
"packet"?) to find the exact bytes of pending payload. Please see
hvs_stream_dequeue() for details.

Ideally hvs_stream_has_data() should return the exact length of pending
readable payload, but when the hv_sock code was written in 2017, 
vsock_stream_has_data() -> ... -> hvs_stream_has_data() basically only needs
to know whether there is any data or not, i.e. it's kind of a boolean variable, so
hvs_stream_has_data() was written to return 1 or 0 for simplicity. :-)

I can post the patch below (not tested yet) to fix hvs_stream_has_data() by
returning the payload length of the next single "packet".  Does it look good
to you?

--- a/net/vmw_vsock/hyperv_transport.c
+++ b/net/vmw_vsock/hyperv_transport.c
@@ -694,15 +694,25 @@ static ssize_t hvs_stream_enqueue(struct vsock_sock *vsk, struct msghdr *msg,
 static s64 hvs_stream_has_data(struct vsock_sock *vsk)
 {
        struct hvsock *hvs = vsk->trans;
+       bool need_refill = !hvs->recv_desc;
        s64 ret;

        if (hvs->recv_data_len > 0)
-               return 1;
+               return hvs->recv_data_len;

        switch (hvs_channel_readable_payload(hvs->chan)) {
        case 1:
-               ret = 1;
-               break;
+               if (!need_refill)
+                       return -EIO;
+
+               hvs->recv_desc = hv_pkt_iter_first(hvs->chan);
+               if (!hvs->recv_desc)
+                       return -ENOBUFS;
+
+               ret = hvs_update_recv_data(hvs);
+               if (ret)
+                       return ret;
+               return hvs->recv_data_len;
        case 0:
                vsk->peer_shutdown |= SEND_SHUTDOWN;
                ret = 0;

Thanks,
Dexuan


^ permalink raw reply

* Re: [PATCH net-next] net: mana: Fix build errors when CONFIG_NET_SHAPER is disabled
From: Jakub Kicinski @ 2025-06-24 23:33 UTC (permalink / raw)
  To: Erni Sri Satya Vennela
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	pabeni, shradhagupta, longli, kotaranov, lorenzo, shirazsaleem,
	schakrabarti, linux-hyperv, netdev, linux-kernel
In-Reply-To: <1750677241-1504-1-git-send-email-ernis@linux.microsoft.com>

On Mon, 23 Jun 2025 04:14:01 -0700 Erni Sri Satya Vennela wrote:
> Fix build errors when CONFIG_NET_SHAPER is disabled, including:
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:804:10: error:
> 'const struct net_device_ops' has no member named 'net_shaper_ops'
> 
>      804 |         .net_shaper_ops         = &mana_shaper_ops,
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:804:35: error:
> initialization of 'int (*)(struct net_device *, struct neigh_parms *)'
> from incompatible pointer type 'const struct net_shaper_ops *'
> [-Werror=incompatible-pointer-types]
> 
>      804 |         .net_shaper_ops         = &mana_shaper_ops,

You have to add

	select NET_SHAPER

to kconfig dependencies for the driver. This symbol cannot be selected
by the user, its hidden from the menus.
-- 
pw-bot: cr

^ permalink raw reply

* Re: [PATCH v3 00/13] KVM: Make irqfd registration globally unique
From: Sean Christopherson @ 2025-06-24 19:38 UTC (permalink / raw)
  To: Sean Christopherson, K. Y. Srinivasan, Haiyang Zhang, Wei Liu,
	Dexuan Cui, Juergen Gross, Stefano Stabellini, Paolo Bonzini,
	Ingo Molnar, Peter Zijlstra, Juri Lelli, Vincent Guittot,
	Shuah Khan, Marc Zyngier, Oliver Upton
  Cc: linux-kernel, linux-hyperv, xen-devel, kvm, linux-kselftest,
	linux-arm-kernel, kvmarm, K Prateek Nayak, David Matlack
In-Reply-To: <20250522235223.3178519-1-seanjc@google.com>

On Thu, 22 May 2025 16:52:10 -0700, Sean Christopherson wrote:
> Non-KVM folks,
> 
> I am hoping to route this through the KVM tree (6.17 or later), as the non-KVM
> changes should be glorified nops.  Please holler if you object to that idea.
> 
> Hyper-V folks in particular, let me know if you want a stable topic branch/tag,
> e.g. on the off chance you want to make similar changes to the Hyper-V code,
> and I'll make sure that happens.
> 
> [...]

Applied to kvm-x86 irqs, thanks!

[01/13] KVM: Use a local struct to do the initial vfs_poll() on an irqfd
        https://github.com/kvm-x86/linux/commit/283ed5001d68
[02/13] KVM: Acquire SCRU lock outside of irqfds.lock during assignment
        https://github.com/kvm-x86/linux/commit/140768a7bf03
[03/13] KVM: Initialize irqfd waitqueue callback when adding to the queue
        https://github.com/kvm-x86/linux/commit/b5c543518ae9
[04/13] KVM: Add irqfd to KVM's list via the vfs_poll() callback
        https://github.com/kvm-x86/linux/commit/5f8ca05ea991
[05/13] KVM: Add irqfd to eventfd's waitqueue while holding irqfds.lock
        https://github.com/kvm-x86/linux/commit/86e00cd162a7
[06/13] sched/wait: Drop WQ_FLAG_EXCLUSIVE from add_wait_queue_priority()
        https://github.com/kvm-x86/linux/commit/867347bb21e1
[07/13] xen: privcmd: Don't mark eventfd waiter as EXCLUSIVE
        https://github.com/kvm-x86/linux/commit/a52664134a24
[08/13] sched/wait: Add a waitqueue helper for fully exclusive priority waiters
        https://github.com/kvm-x86/linux/commit/0d09582b3a60
[09/13] KVM: Disallow binding multiple irqfds to an eventfd with a priority waiter
        https://github.com/kvm-x86/linux/commit/2cdd64cbf990
[10/13] KVM: Drop sanity check that per-VM list of irqfds is unique
        https://github.com/kvm-x86/linux/commit/b599d44a71f1
[11/13] KVM: selftests: Assert that eventfd() succeeds in Xen shinfo test
        https://github.com/kvm-x86/linux/commit/033b76bc7f06
[12/13] KVM: selftests: Add utilities to create eventfds and do KVM_IRQFD
        https://github.com/kvm-x86/linux/commit/74e5e3fb0dd7
[13/13] KVM: selftests: Add a KVM_IRQFD test to verify uniqueness requirements
        https://github.com/kvm-x86/linux/commit/7e9b231c402a

--
https://github.com/kvm-x86/kvm-unit-tests/tree/next

^ permalink raw reply

* Re: [PATCH net-next] net: mana: Fix build errors when CONFIG_NET_SHAPER is disabled
From: Simon Horman @ 2025-06-24 10:02 UTC (permalink / raw)
  To: Erni Sri Satya Vennela
  Cc: kys, haiyangz, wei.liu, decui, andrew+netdev, davem, edumazet,
	kuba, pabeni, shradhagupta, longli, kotaranov, lorenzo,
	shirazsaleem, schakrabarti, linux-hyperv, netdev, linux-kernel
In-Reply-To: <1750677241-1504-1-git-send-email-ernis@linux.microsoft.com>

On Mon, Jun 23, 2025 at 04:14:01AM -0700, Erni Sri Satya Vennela wrote:
> Fix build errors when CONFIG_NET_SHAPER is disabled, including:
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:804:10: error:
> 'const struct net_device_ops' has no member named 'net_shaper_ops'
> 
>      804 |         .net_shaper_ops         = &mana_shaper_ops,
> 
> drivers/net/ethernet/microsoft/mana/mana_en.c:804:35: error:
> initialization of 'int (*)(struct net_device *, struct neigh_parms *)'
> from incompatible pointer type 'const struct net_shaper_ops *'
> [-Werror=incompatible-pointer-types]
> 
>      804 |         .net_shaper_ops         = &mana_shaper_ops,
> 
> Signed-off-by: Erni Sri Satya Vennela <ernis@linux.microsoft.com>
> Reviewed-by: Shradha Gupta <shradhagupta@linux.microsoft.com>
> Fixes: 75cabb46935b ("net: mana: Add support for net_shaper_ops")
> Reported-by: kernel test robot <lkp@intel.com>
> Closes: https://lore.kernel.org/oe-kbuild-all/202506230625.bfUlqb8o-lkp@intel.com/

Reviewed-by: Simon Horman <horms@kernel.org>


^ permalink raw reply

* Re: [PATCH 3/4] x86: hyperv: Expose hv_map_msi_interrupt function
From: Nuno Das Neves @ 2025-06-23 22:13 UTC (permalink / raw)
  To: Thomas Gleixner, Michael Kelley, linux-hyperv@vger.kernel.org,
	linux-arm-kernel@lists.infradead.org,
	linux-kernel@vger.kernel.org, linux-pci@vger.kernel.org
  Cc: kys@microsoft.com, haiyangz@microsoft.com, wei.liu@kernel.org,
	decui@microsoft.com, catalin.marinas@arm.com, will@kernel.org,
	mingo@redhat.com, bp@alien8.de, dave.hansen@linux.intel.com,
	hpa@zytor.com, lpieralisi@kernel.org, kw@linux.com,
	robh@kernel.org, bhelgaas@google.com,
	jinankjain@linux.microsoft.com, skinsburskii@linux.microsoft.com,
	mrathor@linux.microsoft.com, x86@kernel.org
In-Reply-To: <878qlmqtbn.ffs@tglx>

On 6/20/2025 9:19 AM, Thomas Gleixner wrote:
> On Wed, Jun 18 2025 at 14:08, Nuno Das Neves wrote:
>> On 6/11/2025 4:07 PM, Michael Kelley wrote:
>>> From: Nuno Das Neves <nunodasneves@linux.microsoft.com> Sent: Tuesday, June 10, 2025 4:52 PM
>>>> +/**
>>>> + * hv_map_msi_interrupt() - "Map" the MSI IRQ in the hypervisor.
>>>> + * @data:      Describes the IRQ
>>>> + * @out_entry: Hypervisor (MSI) interrupt entry (can be NULL)
>>>> + *
>>>> + * Map the IRQ in the hypervisor by issuing a MAP_DEVICE_INTERRUPT hypercall.
>>>> + */
>>>> +int hv_map_msi_interrupt(struct irq_data *data,
>>>> +			 struct hv_interrupt_entry *out_entry)
>>>>  {
>>>> -	union hv_device_id device_id = hv_build_pci_dev_id(dev);
>>>> +	struct msi_desc *msidesc;
>>>> +	struct pci_dev *dev;
>>>> +	union hv_device_id device_id;
>>>> +	struct hv_interrupt_entry dummy;
>>>> +	struct irq_cfg *cfg = irqd_cfg(data);
>>>> +	const cpumask_t *affinity;
>>>> +	int cpu;
>>>> +	u64 res;
> 
> https://www.kernel.org/doc/html/latest/process/maintainer-tip.html#variable-declarations
> 
>>>>
>>>> -	return hv_map_interrupt(device_id, false, cpu, vector, entry);
>>>> +	msidesc = irq_data_get_msi_desc(data);
>>>> +	dev = msi_desc_to_pci_dev(msidesc);
>>>> +	device_id = hv_build_pci_dev_id(dev);
>>>> +	affinity = irq_data_get_effective_affinity_mask(data);
>>>> +	cpu = cpumask_first_and(affinity, cpu_online_mask);
>>>
>>> Is the cpus_read_lock held at this point? I'm not sure what the
>>> overall calling sequence looks like. If it is not held, the CPU that
>>> is selected could go offline before hv_map_interrupt() is called.
>>> This computation of the target CPU is the same as in the code
>>> before this patch, but that existing code looks like it has the
>>> same problem.
>>>
>>
>> Thanks for pointing it out - It *looks* like the read lock is not held
>> everywhere this could be called, so it could indeed be a problem.
>>
>> I've been thinking about different ways around this but I lack the
>> knowledge to have an informed opinion about it:
>>
>> - We could take the cpu read lock in this function, would that work?
> 
> Obviously not.
> 
>> - I'm not actually sure why the code is getting the first cpu off the effective
>>   affinity mask in the first place. It is possible to get the apic id (and hence
>>   the cpu) already associated with the irq, as per e.g. x86_vector_msi_compose_msg()
>>   Maybe we could get the cpu that way, assuming that doesn't have a
>>   similar issue.
> 
> There is no reason to fiddle in the underlying low level data. The
> effective affinity mask is there for a reason.
> 
>> - We could just let this race happen, maybe the outcome isn't too catastrophic?
> 
> Let's terminate guesswork mode and look at the facts.
> 
> The point is that hv_map_msi_interrupt() is called from:
> 
>     1) hv_irq_compose_msi_msg()
> 
>     2) hv_arch_irq_unmask() (in patch 4/4)
> 
> Both functions are interrupt chip callbacks and invoked with the
> interrupt descriptor lock held.
> 
> At the point where they are called, the effective affinity mask is valid
> and immutable. Nothing can modify it as any modification requires the
> interrupt descriptor lock to be held. This applies to the CPU hotplug
> machinery too. So this AND cpu_online_mask is a complete pointless
> voodoo exercise.
> 

Thanks for explaining.

> Just use:
> 
>      cpu = cpumask_first(irq_data_get_effective_affinity_mask(data));
> 
> and be done with it.
> 
> Please fix that first with a seperate patch before moving this code
> around.

Will do!

Nuno

> 
> Thanks,
> 
>         tglx


^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox