From: Bjorn Helgaas <helgaas@kernel.org>
To: Roger Pau Monne <roger.pau@citrix.com>
Cc: linux-kernel@vger.kernel.org, xen-devel@lists.xenproject.org,
linux-pci@vger.kernel.org, Thomas Gleixner <tglx@linutronix.de>,
Juergen Gross <jgross@suse.com>,
Bjorn Helgaas <bhelgaas@google.com>,
Ingo Molnar <mingo@redhat.com>, Borislav Petkov <bp@alien8.de>,
Dave Hansen <dave.hansen@linux.intel.com>,
x86@kernel.org, "H. Peter Anvin" <hpa@zytor.com>
Subject: Re: [PATCH v3 3/3] PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag
Date: Thu, 20 Mar 2025 16:07:41 -0500 [thread overview]
Message-ID: <20250320210741.GA1099701@bhelgaas> (raw)
In-Reply-To: <20250219092059.90850-4-roger.pau@citrix.com>
On Wed, Feb 19, 2025 at 10:20:57AM +0100, Roger Pau Monne wrote:
> Setting pci_msi_ignore_mask inhibits the toggling of the mask bit for both
> MSI and MSI-X entries globally, regardless of the IRQ chip they are using.
> Only Xen sets the pci_msi_ignore_mask when routing physical interrupts over
> event channels, to prevent PCI code from attempting to toggle the maskbit,
> as it's Xen that controls the bit.
>
> However, the pci_msi_ignore_mask being global will affect devices that use
> MSI interrupts but are not routing those interrupts over event channels
> (not using the Xen pIRQ chip). One example is devices behind a VMD PCI
> bridge. In that scenario the VMD bridge configures MSI(-X) using the
> normal IRQ chip (the pIRQ one in the Xen case), and devices behind the
> bridge configure the MSI entries using indexes into the VMD bridge MSI
> table. The VMD bridge then demultiplexes such interrupts and delivers to
> the destination device(s). Having pci_msi_ignore_mask set in that scenario
> prevents (un)masking of MSI entries for devices behind the VMD bridge.
>
> Move the signaling of no entry masking into the MSI domain flags, as that
> allows setting it on a per-domain basis. Set it for the Xen MSI domain
> that uses the pIRQ chip, while leaving it unset for the rest of the
> cases.
>
> Remove pci_msi_ignore_mask at once, since it was only used by Xen code, and
> with Xen dropping usage the variable is unneeded.
>
> This fixes using devices behind a VMD bridge on Xen PV hardware domains.
>
> Albeit Devices behind a VMD bridge are not known to Xen, that doesn't mean
> Linux cannot use them. By inhibiting the usage of
> VMD_FEAT_CAN_BYPASS_MSI_REMAP and the removal of the pci_msi_ignore_mask
> bodge devices behind a VMD bridge do work fine when use from a Linux Xen
> hardware domain. That's the whole point of the series.
>
> Signed-off-by: Roger Pau Monné <roger.pau@citrix.com>
> Reviewed-by: Thomas Gleixner <tglx@linutronix.de>
> Acked-by: Juergen Gross <jgross@suse.com>
Acked-by: Bjorn Helgaas <bhelgaas@google.com>
I assume you'll merge this series via the Xen tree. Let me know if
otherwise.
> ---
> Changes since v2:
> - Fix subject line.
>
> Changes since v1:
> - Fix build.
> - Expand commit message.
> ---
> arch/x86/pci/xen.c | 8 ++------
> drivers/pci/msi/msi.c | 37 +++++++++++++++++++++----------------
> include/linux/msi.h | 3 ++-
> kernel/irq/msi.c | 2 +-
> 4 files changed, 26 insertions(+), 24 deletions(-)
>
> diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
> index 0f2fe524f60d..b8755cde2419 100644
> --- a/arch/x86/pci/xen.c
> +++ b/arch/x86/pci/xen.c
> @@ -436,7 +436,8 @@ static struct msi_domain_ops xen_pci_msi_domain_ops = {
> };
>
> static struct msi_domain_info xen_pci_msi_domain_info = {
> - .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS | MSI_FLAG_DEV_SYSFS,
> + .flags = MSI_FLAG_PCI_MSIX | MSI_FLAG_FREE_MSI_DESCS |
> + MSI_FLAG_DEV_SYSFS | MSI_FLAG_NO_MASK,
> .ops = &xen_pci_msi_domain_ops,
> };
>
> @@ -484,11 +485,6 @@ static __init void xen_setup_pci_msi(void)
> * in allocating the native domain and never use it.
> */
> x86_init.irqs.create_pci_msi_domain = xen_create_pci_msi_domain;
> - /*
> - * With XEN PIRQ/Eventchannels in use PCI/MSI[-X] masking is solely
> - * controlled by the hypervisor.
> - */
> - pci_msi_ignore_mask = 1;
> }
>
> #else /* CONFIG_PCI_MSI */
> diff --git a/drivers/pci/msi/msi.c b/drivers/pci/msi/msi.c
> index 2f647cac4cae..4c8c2b57b5f6 100644
> --- a/drivers/pci/msi/msi.c
> +++ b/drivers/pci/msi/msi.c
> @@ -10,12 +10,12 @@
> #include <linux/err.h>
> #include <linux/export.h>
> #include <linux/irq.h>
> +#include <linux/irqdomain.h>
>
> #include "../pci.h"
> #include "msi.h"
>
> int pci_msi_enable = 1;
> -int pci_msi_ignore_mask;
>
> /**
> * pci_msi_supported - check whether MSI may be enabled on a device
> @@ -285,6 +285,8 @@ static void pci_msi_set_enable(struct pci_dev *dev, int enable)
> static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
> struct irq_affinity_desc *masks)
> {
> + const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
> + const struct msi_domain_info *info = d->host_data;
> struct msi_desc desc;
> u16 control;
>
> @@ -295,8 +297,7 @@ static int msi_setup_msi_desc(struct pci_dev *dev, int nvec,
> /* Lies, damned lies, and MSIs */
> if (dev->dev_flags & PCI_DEV_FLAGS_HAS_MSI_MASKING)
> control |= PCI_MSI_FLAGS_MASKBIT;
> - /* Respect XEN's mask disabling */
> - if (pci_msi_ignore_mask)
> + if (info->flags & MSI_FLAG_NO_MASK)
> control &= ~PCI_MSI_FLAGS_MASKBIT;
>
> desc.nvec_used = nvec;
> @@ -604,12 +605,15 @@ static void __iomem *msix_map_region(struct pci_dev *dev,
> */
> void msix_prepare_msi_desc(struct pci_dev *dev, struct msi_desc *desc)
> {
> + const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
> + const struct msi_domain_info *info = d->host_data;
> +
> desc->nvec_used = 1;
> desc->pci.msi_attrib.is_msix = 1;
> desc->pci.msi_attrib.is_64 = 1;
> desc->pci.msi_attrib.default_irq = dev->irq;
> desc->pci.mask_base = dev->msix_base;
> - desc->pci.msi_attrib.can_mask = !pci_msi_ignore_mask &&
> + desc->pci.msi_attrib.can_mask = !(info->flags & MSI_FLAG_NO_MASK) &&
> !desc->pci.msi_attrib.is_virtual;
>
> if (desc->pci.msi_attrib.can_mask) {
> @@ -659,9 +663,6 @@ static void msix_mask_all(void __iomem *base, int tsize)
> u32 ctrl = PCI_MSIX_ENTRY_CTRL_MASKBIT;
> int i;
>
> - if (pci_msi_ignore_mask)
> - return;
> -
> for (i = 0; i < tsize; i++, base += PCI_MSIX_ENTRY_SIZE)
> writel(ctrl, base + PCI_MSIX_ENTRY_VECTOR_CTRL);
> }
> @@ -714,6 +715,8 @@ static int msix_setup_interrupts(struct pci_dev *dev, struct msix_entry *entries
> static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
> int nvec, struct irq_affinity *affd)
> {
> + const struct irq_domain *d = dev_get_msi_domain(&dev->dev);
> + const struct msi_domain_info *info = d->host_data;
> int ret, tsize;
> u16 control;
>
> @@ -744,15 +747,17 @@ static int msix_capability_init(struct pci_dev *dev, struct msix_entry *entries,
> /* Disable INTX */
> pci_intx_for_msi(dev, 0);
>
> - /*
> - * Ensure that all table entries are masked to prevent
> - * stale entries from firing in a crash kernel.
> - *
> - * Done late to deal with a broken Marvell NVME device
> - * which takes the MSI-X mask bits into account even
> - * when MSI-X is disabled, which prevents MSI delivery.
> - */
> - msix_mask_all(dev->msix_base, tsize);
> + if (!(info->flags & MSI_FLAG_NO_MASK)) {
> + /*
> + * Ensure that all table entries are masked to prevent
> + * stale entries from firing in a crash kernel.
> + *
> + * Done late to deal with a broken Marvell NVME device
> + * which takes the MSI-X mask bits into account even
> + * when MSI-X is disabled, which prevents MSI delivery.
> + */
> + msix_mask_all(dev->msix_base, tsize);
> + }
> pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
>
> pcibios_free_irq(dev);
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index b10093c4d00e..59a421fc42bf 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -73,7 +73,6 @@ struct msi_msg {
> };
> };
>
> -extern int pci_msi_ignore_mask;
> /* Helper functions */
> struct msi_desc;
> struct pci_dev;
> @@ -556,6 +555,8 @@ enum {
> MSI_FLAG_PCI_MSIX_ALLOC_DYN = (1 << 20),
> /* PCI MSIs cannot be steered separately to CPU cores */
> MSI_FLAG_NO_AFFINITY = (1 << 21),
> + /* Inhibit usage of entry masking */
> + MSI_FLAG_NO_MASK = (1 << 22),
> };
>
> /**
> diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
> index 396a067a8a56..7682c36cbccc 100644
> --- a/kernel/irq/msi.c
> +++ b/kernel/irq/msi.c
> @@ -1143,7 +1143,7 @@ static bool msi_check_reservation_mode(struct irq_domain *domain,
> if (!(info->flags & MSI_FLAG_MUST_REACTIVATE))
> return false;
>
> - if (IS_ENABLED(CONFIG_PCI_MSI) && pci_msi_ignore_mask)
> + if (info->flags & MSI_FLAG_NO_MASK)
> return false;
>
> /*
> --
> 2.46.0
>
next prev parent reply other threads:[~2025-03-20 21:07 UTC|newest]
Thread overview: 28+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20250219092059.90850-1-roger.pau@citrix.com>
2025-02-19 9:20 ` [PATCH v3 2/3] PCI: vmd: Disable MSI remapping bypass under Xen Roger Pau Monne
2025-03-03 14:16 ` Roger Pau Monné
2025-03-20 21:06 ` Bjorn Helgaas
2025-02-19 9:20 ` [PATCH v3 3/3] PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag Roger Pau Monne
2025-03-20 21:07 ` Bjorn Helgaas [this message]
2025-03-21 8:00 ` Jürgen Groß
2025-03-24 14:29 ` Daniel Gomez
2025-03-24 17:51 ` Roger Pau Monné
2025-03-24 18:58 ` Daniel Gomez
2025-03-24 19:18 ` Roger Pau Monné
2025-03-24 20:45 ` Daniel Gomez
2025-03-25 8:11 ` Thomas Gleixner
2025-03-25 9:20 ` Thomas Gleixner
2025-03-25 9:47 ` Daniel Gomez
2025-03-25 10:22 ` Roger Pau Monné
2025-03-25 10:27 ` Thomas Gleixner
2025-03-25 10:55 ` Roger Pau Monné
2025-03-26 8:14 ` Thomas Gleixner
2025-03-26 8:10 ` Roger Pau Monné
2025-03-26 11:26 ` Marek Szyprowski
2025-03-26 12:05 ` [PATCH] PCI/MSI: Handle the NOMASK flag correctly for all PCI/MSI backends Thomas Gleixner
2025-03-26 12:09 ` Jürgen Groß
2025-03-26 12:46 ` Thomas Gleixner
2025-03-26 12:16 ` Juergen Gross
2025-03-30 14:57 ` Bert Karwatzki
2025-03-26 11:04 ` [PATCH v3 3/3] PCI/MSI: Convert pci_msi_ignore_mask to per MSI domain flag Borislav Petkov
2025-03-26 11:14 ` Roger Pau Monné
2025-03-26 11:21 ` Borislav Petkov
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=20250320210741.GA1099701@bhelgaas \
--to=helgaas@kernel.org \
--cc=bhelgaas@google.com \
--cc=bp@alien8.de \
--cc=dave.hansen@linux.intel.com \
--cc=hpa@zytor.com \
--cc=jgross@suse.com \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=mingo@redhat.com \
--cc=roger.pau@citrix.com \
--cc=tglx@linutronix.de \
--cc=x86@kernel.org \
--cc=xen-devel@lists.xenproject.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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox