All of lore.kernel.org
 help / color / mirror / Atom feed
From: Thomas Gleixner <tglx@linutronix.de>
To: LKML <linux-kernel@vger.kernel.org>
Cc: x86@kernel.org, Joerg Roedel <joro@8bytes.org>,
	Will Deacon <will@kernel.org>,
	linux-pci@vger.kernel.org, Bjorn Helgaas <bhelgaas@google.com>,
	Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>,
	Marc Zyngier <maz@kernel.org>,
	Greg Kroah-Hartman <gregkh@linuxfoundation.org>,
	Jason Gunthorpe <jgg@mellanox.com>,
	Dave Jiang <dave.jiang@intel.com>,
	Alex Williamson <alex.williamson@redhat.com>,
	Kevin Tian <kevin.tian@intel.com>,
	Dan Williams <dan.j.williams@intel.com>,
	Logan Gunthorpe <logang@deltatee.com>,
	Ashok Raj <ashok.raj@intel.com>, Jon Mason <jdmason@kudzu.us>,
	Allen Hubbe <allenbh@gmail.com>
Subject: [patch V2 33/33] irqchip: Add IDXD Interrupt Message Store driver
Date: Mon, 21 Nov 2022 15:38:27 +0100 (CET)	[thread overview]
Message-ID: <20221121091328.288703733@linutronix.de> (raw)
In-Reply-To: 20221121083657.157152924@linutronix.de

Provide a driver for the Intel IDXD IMS implementation. The implementation
uses a large message store array in device memory.

The IMS domain implementation is minimal and just provides the required
irq_chip callbacks and one domain callback which prepares the MSI
descriptor for easy usage in the irq_chip callbacks.

The necessary iobase is stored in the irqdomain and the PASID which is
required for operation is handed in via msi_instance_cookie in the
allocation function.

Not much to see here. A few lines of code and a filled in template is all
what's needed.

Signed-off-by: Thomas Gleixner <tglx@linutronix.de>
---
 drivers/irqchip/Kconfig                    |    7 +
 drivers/irqchip/Makefile                   |    1 
 drivers/irqchip/irq-pci-intel-idxd.c       |  143 +++++++++++++++++++++++++++++
 include/linux/irqchip/irq-pci-intel-idxd.h |   22 ++++
 4 files changed, 173 insertions(+)

--- a/drivers/irqchip/Kconfig
+++ b/drivers/irqchip/Kconfig
@@ -695,4 +695,11 @@ config SUNPLUS_SP7021_INTC
 	  chained controller, routing all interrupt source in P-Chip to
 	  the primary controller on C-Chip.
 
+config PCI_INTEL_IDXD_IMS
+	tristate "Intel IDXD Interrupt Message Store controller"
+	depends on PCI_MSI
+	help
+	  Support for Intel IDXD IMS Interrupt Message Store controller
+	  with IMS slot storage in a slot array in device memory
+
 endmenu
--- a/drivers/irqchip/Makefile
+++ b/drivers/irqchip/Makefile
@@ -121,3 +121,4 @@ obj-$(CONFIG_IRQ_IDT3243X)		+= irq-idt32
 obj-$(CONFIG_APPLE_AIC)			+= irq-apple-aic.o
 obj-$(CONFIG_MCHP_EIC)			+= irq-mchp-eic.o
 obj-$(CONFIG_SUNPLUS_SP7021_INTC)	+= irq-sp7021-intc.o
+obj-$(CONFIG_PCI_INTEL_IDXD_IMS)	+= irq-pci-intel-idxd.o
--- /dev/null
+++ b/drivers/irqchip/irq-pci-intel-idxd.c
@@ -0,0 +1,143 @@
+// SPDX-License-Identifier: GPL-2.0
+/*
+ * Interrupt chip and domain for Intel IDXD with hardware array based
+ * interrupt message store (IMS).
+ */
+#include <linux/device.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/msi.h>
+#include <linux/pci.h>
+
+#include <linux/irqchip/irq-pci-intel-idxd.h>
+
+MODULE_LICENSE("GPL");
+
+/**
+ * struct ims_slot - The hardware layout of a slot in the memory table
+ * @address_lo:	Lower 32bit address
+ * @address_hi:	Upper 32bit address
+ * @data:	Message data
+ * @ctrl:	Control word
+ */
+struct ims_slot {
+	u32	address_lo;
+	u32	address_hi;
+	u32	data;
+	u32	ctrl;
+} __packed;
+
+/* Bit to mask the interrupt in the control word */
+#define CTRL_VECTOR_MASKBIT	BIT(0)
+/* Bit to enable PASID in the control word */
+#define CTRL_PASID_ENABLE	BIT(3)
+/* Position of PASID.LSB in the control word */
+#define CTRL_PASID_SHIFT	12
+
+static inline void iowrite32_and_flush(u32 value, void __iomem *addr)
+{
+	iowrite32(value, addr);
+	ioread32(addr);
+}
+
+static void idxd_mask(struct irq_data *data)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(data);
+	struct ims_slot __iomem *slot = desc->data.dcookie.iobase;
+	u32 cval = (u32)desc->data.icookie.value;
+
+	iowrite32_and_flush(cval | CTRL_VECTOR_MASKBIT, &slot->ctrl);
+}
+
+static void idxd_unmask(struct irq_data *data)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(data);
+	struct ims_slot __iomem *slot = desc->data.dcookie.iobase;
+	u32 cval = (u32)desc->data.icookie.value;
+
+	iowrite32_and_flush(cval, &slot->ctrl);
+}
+
+static void idxd_write_msi_msg(struct irq_data *data, struct msi_msg *msg)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(data);
+	struct ims_slot __iomem *slot = desc->data.dcookie.iobase;
+
+	iowrite32(msg->address_lo, &slot->address_lo);
+	iowrite32(msg->address_hi, &slot->address_hi);
+	iowrite32_and_flush(msg->data, &slot->data);
+}
+
+static void idxd_shutdown(struct irq_data *data)
+{
+	struct msi_desc *desc = irq_data_get_msi_desc(data);
+	struct ims_slot __iomem *slot = desc->data.dcookie.iobase;
+
+	iowrite32(0, &slot->address_lo);
+	iowrite32(0, &slot->address_hi);
+	iowrite32(0, &slot->data);
+	iowrite32_and_flush(CTRL_VECTOR_MASKBIT, &slot->ctrl);
+}
+
+static void idxd_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *arg,
+			      struct msi_desc *desc)
+{
+	struct msi_domain_info *info = domain->host_data;
+	struct ims_slot __iomem *slot;
+
+	/* Set up the slot address for the irq_chip callbacks */
+	slot = (__force struct ims_slot __iomem *) info->data;
+	slot += desc->msi_index;
+	desc->data.dcookie.iobase = slot;
+
+	/* Mask the interrupt for paranoia sake */
+	iowrite32_and_flush(CTRL_VECTOR_MASKBIT, &slot->ctrl);
+
+	/*
+	 * The caller provided PASID. Shift it to the proper position
+	 * and set the PASID enable bit.
+	 */
+	desc->data.icookie.value <<= CTRL_PASID_SHIFT;
+	desc->data.icookie.value |= CTRL_PASID_ENABLE;
+
+	arg->hwirq = desc->msi_index;
+}
+
+static const struct msi_domain_template idxd_ims_template = {
+	.chip = {
+		.name			= "PCI-IDXD",
+		.irq_mask		= idxd_mask,
+		.irq_unmask		= idxd_unmask,
+		.irq_write_msi_msg	= idxd_write_msi_msg,
+		.irq_shutdown		= idxd_shutdown,
+		.flags			= IRQCHIP_ONESHOT_SAFE,
+	},
+
+	.ops = {
+		.prepare_desc		= idxd_prepare_desc,
+	},
+
+	.info = {
+		.flags			= MSI_FLAG_ALLOC_SIMPLE_MSI_DESCS |
+					  MSI_FLAG_FREE_MSI_DESCS |
+					  MSI_FLAG_PCI_IMS,
+		.bus_token		= DOMAIN_BUS_PCI_DEVICE_IMS,
+	},
+};
+
+/**
+ * pci_intel_idxd_create_ims_domain - Create a IDXD IMS domain
+ * @pdev:	IDXD PCI device to operate on
+ * @slots:	Pointer to the mapped slot memory arrray
+ * @nr_slots:	The number of slots in the array
+ *
+ * Returns: True on success, false otherwise
+ *
+ * The domain is automatically destroyed when the @pdev is destroyed
+ */
+bool pci_intel_idxd_create_ims_domain(struct pci_dev *pdev, void __iomem *slots,
+				      unsigned int nr_slots)
+{
+	return pci_create_ims_domain(pdev, &idxd_ims_template, nr_slots, (__force void *)slots);
+}
+EXPORT_SYMBOL_GPL(pci_intel_idxd_create_ims_domain);
--- /dev/null
+++ b/include/linux/irqchip/irq-pci-intel-idxd.h
@@ -0,0 +1,22 @@
+/* SPDX-License-Identifier: GPL-2.0 */
+/* (C) Copyright 2022 Thomas Gleixner <tglx@linutronix.de> */
+
+#ifndef _LINUX_IRQCHIP_IRQ_PCI_INTEL_IDXD_H
+#define _LINUX_IRQCHIP_IRQ_PCI_INTEL_IDXD_H
+
+#include <linux/msi_api.h>
+#include <linux/bits.h>
+#include <linux/types.h>
+
+/*
+ * Conveniance macro to wrap the PASID for interrupt allocation
+ * via pci_ims_alloc_irq(pdev, INTEL_IDXD_DEV_COOKIE(pasid))
+ */
+#define INTEL_IDXD_DEV_COOKIE(pasid)	(union msi_instance_cookie) { .value = (pasid), }
+
+struct pci_dev;
+
+bool pci_intel_idxd_create_ims_domain(struct pci_dev *pdev, void __iomem *slots,
+				      unsigned int nr_slots);
+
+#endif


  parent reply	other threads:[~2022-11-21 14:42 UTC|newest]

Thread overview: 72+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2022-11-21 14:37 [patch V2 00/33] genirq, PCI/MSI: Support for per device MSI and PCI/IMS - Part 3 implementation Thomas Gleixner
2022-11-21 14:37 ` [patch V2 01/33] genirq/msi: Rearrange MSI domain flags Thomas Gleixner
2022-11-21 14:37 ` [patch V2 02/33] genirq/msi: Provide struct msi_parent_ops Thomas Gleixner
2022-11-23  7:57   ` Tian, Kevin
2022-11-23 11:28     ` Thomas Gleixner
2022-11-24  0:53       ` Tian, Kevin
2022-11-21 14:37 ` [patch V2 03/33] genirq/msi: Provide data structs for per device domains Thomas Gleixner
2022-11-23  7:57   ` Tian, Kevin
2022-11-23 11:29     ` Thomas Gleixner
2022-11-21 14:37 ` [patch V2 04/33] genirq/msi: Add size info to struct msi_domain_info Thomas Gleixner
2022-11-21 14:37 ` [patch V2 05/33] genirq/msi: Split msi_create_irq_domain() Thomas Gleixner
2022-11-21 14:37 ` [patch V2 06/33] genirq/irqdomain: Add irq_domain::dev for per device MSI domains Thomas Gleixner
2022-11-21 14:37 ` [patch V2 07/33] genirq/msi: Provide msi_create/free_device_irq_domain() Thomas Gleixner
2022-11-23  8:02   ` Tian, Kevin
2022-11-23 11:38     ` Thomas Gleixner
2022-11-23 21:01       ` Thomas Gleixner
2022-11-24  1:07       ` Tian, Kevin
2022-11-24  8:36         ` Thomas Gleixner
2022-11-28  1:47           ` Tian, Kevin
2022-11-21 14:37 ` [patch V2 08/33] genirq/msi: Provide msi_match_device_domain() Thomas Gleixner
2022-11-21 14:37 ` [patch V2 09/33] genirq/msi: Add range checking to msi_insert_desc() Thomas Gleixner
2022-11-21 14:37 ` [patch V2 10/33] PCI/MSI: Split __pci_write_msi_msg() Thomas Gleixner
2022-11-21 14:37 ` [patch V2 11/33] genirq/msi: Provide BUS_DEVICE_PCI_MSI[X] Thomas Gleixner
2022-11-21 14:38 ` [patch V2 12/33] PCI/MSI: Add support for per device MSI[X] domains Thomas Gleixner
2022-11-23  8:08   ` Tian, Kevin
2022-11-23 11:41     ` Thomas Gleixner
2022-11-23 21:50       ` Thomas Gleixner
2022-11-24  1:08         ` Tian, Kevin
2022-11-21 14:38 ` [patch V2 13/33] x86/apic/vector: Provide MSI parent domain Thomas Gleixner
2022-11-23  8:16   ` Tian, Kevin
2022-11-23 13:42     ` Thomas Gleixner
2022-11-24  1:10       ` Tian, Kevin
2022-11-21 14:38 ` [patch V2 14/33] PCI/MSI: Remove unused pci_dev_has_special_msi_domain() Thomas Gleixner
2022-11-21 14:38 ` [patch V2 15/33] iommu/vt-d: Switch to MSI parent domains Thomas Gleixner
2022-11-21 14:38 ` [patch V2 16/33] iommu/amd: Switch to MSI base domains Thomas Gleixner
2022-11-21 14:38 ` [patch V2 17/33] x86/apic/msi: Remove arch_create_remap_msi_irq_domain() Thomas Gleixner
2022-11-21 14:38 ` [patch V2 18/33] genirq/msi: Provide struct msi_map Thomas Gleixner
2022-11-21 14:38 ` [patch V2 19/33] genirq/msi: Provide msi_desc::msi_data Thomas Gleixner
2022-11-23  8:27   ` Tian, Kevin
2022-11-23 11:41     ` Thomas Gleixner
2022-11-21 14:38 ` [patch V2 20/33] genirq/msi: Provide msi_domain_ops::prepare_desc() Thomas Gleixner
2022-11-21 14:38 ` [patch V2 21/33] genirq/msi: Provide msi_domain_alloc_irq_at() Thomas Gleixner
2022-11-24  2:54   ` Tian, Kevin
2022-11-21 14:38 ` [patch V2 22/33] genirq/msi: Provide MSI_FLAG_MSIX_ALLOC_DYN Thomas Gleixner
2022-11-21 14:38 ` [patch V2 23/33] PCI/MSI: Split MSI-X descriptor setup Thomas Gleixner
2022-11-21 14:38 ` [patch V2 24/33] PCI/MSI: Provide prepare_desc() MSI domain op Thomas Gleixner
2022-11-21 14:38 ` [patch V2 25/33] PCI/MSI: Provide post-enable dynamic allocation interfaces for MSI-X Thomas Gleixner
2022-11-24  2:58   ` Tian, Kevin
2022-11-24  9:08     ` Thomas Gleixner
2022-11-28  1:49       ` Tian, Kevin
2023-02-21  7:32       ` [tip: irq/urgent] PCI/MSI: Clarify usage of pci_msix_free_irq() tip-bot2 for Reinette Chatre
2022-11-21 14:38 ` [patch V2 26/33] x86/apic/msi: Enable MSI_FLAG_PCI_MSIX_ALLOC_DYN Thomas Gleixner
2022-11-21 14:38 ` [patch V2 27/33] genirq/msi: Provide constants for PCI/IMS support Thomas Gleixner
2022-11-24  3:01   ` Tian, Kevin
2022-11-24  9:10     ` Thomas Gleixner
2022-11-24 13:09       ` Jason Gunthorpe
2022-11-24 13:28         ` Thomas Gleixner
2022-11-21 14:38 ` [patch V2 28/33] PCI/MSI: Provide IMS (Interrupt Message Store) support Thomas Gleixner
2022-11-24  3:10   ` Tian, Kevin
2022-11-24  9:10     ` Thomas Gleixner
2022-11-21 14:38 ` [patch V2 29/33] PCI/MSI: Provide pci_ims_alloc/free_irq() Thomas Gleixner
2022-11-24  3:11   ` Tian, Kevin
2022-11-21 14:38 ` [patch V2 30/33] x86/apic/msi: Enable PCI/IMS Thomas Gleixner
2022-11-21 14:38 ` [patch V2 31/33] iommu/vt-d: " Thomas Gleixner
2022-11-24  3:17   ` Tian, Kevin
2022-11-24  9:37     ` Thomas Gleixner
2022-11-24 13:14       ` Jason Gunthorpe
2022-11-24 13:21         ` Thomas Gleixner
2022-11-28  1:54           ` Tian, Kevin
2022-11-21 14:38 ` [patch V2 32/33] iommu/amd: " Thomas Gleixner
2022-11-21 14:38 ` Thomas Gleixner [this message]
2022-11-24  3:19   ` [patch V2 33/33] irqchip: Add IDXD Interrupt Message Store driver Tian, Kevin

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20221121091328.288703733@linutronix.de \
    --to=tglx@linutronix.de \
    --cc=alex.williamson@redhat.com \
    --cc=allenbh@gmail.com \
    --cc=ashok.raj@intel.com \
    --cc=bhelgaas@google.com \
    --cc=dan.j.williams@intel.com \
    --cc=dave.jiang@intel.com \
    --cc=gregkh@linuxfoundation.org \
    --cc=jdmason@kudzu.us \
    --cc=jgg@mellanox.com \
    --cc=joro@8bytes.org \
    --cc=kevin.tian@intel.com \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=logang@deltatee.com \
    --cc=lorenzo.pieralisi@arm.com \
    --cc=maz@kernel.org \
    --cc=will@kernel.org \
    --cc=x86@kernel.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.