Hi Thomas, On 11/11/2022 5:59 AM, Thomas Gleixner wrote: > 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 which is allocated by the core 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_dev_cookie in the allocation > function. The use of PASID is optional for dedicated workqueues. Could this be supported to let the irqchip support all scenarios? Since the cookie is always provided I was wondering if an invalid PASID can be used to let the driver disable PASID? Please see the delta snippet below in which I primarily made such a change, but added a few more changes for consideration. Summary of changes: * Use provided invalid PASID to disable PASID for the interrupt. * Use bitmask to ensure that the cookie only contains a valid PASID. * Modify header comment to fix typo. * Modify header comment to reflect driver usage of macro. With the first change I am able to test IMS on the host using devmsi-v2-part3 of the development branch. I did try to update to the most recent development to confirm all is well but version devmsi-v3.1-part3 behaves differently in that pci_ims_alloc_irq() returns successfully but the returned virq is 0. This triggers a problem when request_threaded_irq() runs and reports: genirq: Flags mismatch irq 0. 00000000 (idxd-portal) vs. 00015a00 (timer) Thank you very much Reinette --- drivers/irqchip/irq-pci-intel-idxd.c | 20 ++++++++++++++------ include/linux/irqchip/irq-pci-intel-idxd.h | 4 ++-- 2 files changed, 16 insertions(+), 8 deletions(-) diff --git a/drivers/irqchip/irq-pci-intel-idxd.c b/drivers/irqchip/irq-pci-intel-idxd.c index d33c32787ad5..1b49c884bd85 100644 --- a/drivers/irqchip/irq-pci-intel-idxd.c +++ b/drivers/irqchip/irq-pci-intel-idxd.c @@ -4,6 +4,7 @@ * interrupt message store (IMS). */ #include <linux/device.h> +#include <linux/ioasid.h> #include <linux/irq.h> #include <linux/irqdomain.h> #include <linux/msi.h> @@ -33,6 +34,8 @@ struct ims_slot { #define CTRL_PASID_ENABLE BIT(3) /* Position of PASID.LSB in the control word */ #define CTRL_PASID_SHIFT 12 +/* Valid PASID is 20 bits */ +#define CTRL_PASID_VALID GENMASK(19, 0) static inline void iowrite32_and_flush(u32 value, void __iomem *addr) { @@ -93,12 +96,17 @@ static void idxd_prepare_desc(struct irq_domain *domain, msi_alloc_info_t *arg, /* 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; + if (pasid_valid((ioasid_t)desc->data.icookie.value)) { + /* + * The caller provided PASID. Shift it to the proper position + * and set the PASID enable bit. + */ + desc->data.icookie.value &= CTRL_PASID_VALID; + desc->data.icookie.value <<= CTRL_PASID_SHIFT; + desc->data.icookie.value |= CTRL_PASID_ENABLE; + } else { + desc->data.icookie.value = 0; + } arg->hwirq = desc->msi_index; } diff --git a/include/linux/irqchip/irq-pci-intel-idxd.h b/include/linux/irqchip/irq-pci-intel-idxd.h index d62ef5b3285c..48c73bffbb5d 100644 --- a/include/linux/irqchip/irq-pci-intel-idxd.h +++ b/include/linux/irqchip/irq-pci-intel-idxd.h @@ -9,8 +9,8 @@ #include <linux/types.h> /* - * Conveniance macro to wrap the PASID for interrupt allocation - * via pci_ims_alloc_irq(pdev, INTEL_IDXD_DEV_COOKIE(pasid)) + * Convenience 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), } ---