Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f32e057c authored by Yijing Wang's avatar Yijing Wang Committed by Alex Shi
Browse files

PCI/MSI: Add pci_msi_ignore_mask to prevent writes to MSI/MSI-X Mask Bits



MSI-X vector Mask Bits are in MSI-X Tables in PCI memory space.  Xen PV
guests can't write to those tables.  MSI vector Mask Bits are in PCI
configuration space.  Xen PV guests can write to config space, but those
writes are ignored.

Commit 0e4ccb15 ("PCI: Add x86_msi.msi_mask_irq() and
msix_mask_irq()") added a way to override default_mask_msi_irqs() and
default_mask_msix_irqs() so they can be no-ops in Xen guests, but this is
more complicated than necessary.

Add "pci_msi_ignore_mask" in the core PCI MSI code.  If set,
default_mask_msi_irqs() and default_mask_msix_irqs() return without doing
anything.  This is less flexible, but much simpler.

[bhelgaas: changelog]
Signed-off-by: default avatarYijing Wang <wangyijing@huawei.com>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
Reviewed-by: default avatarDavid Vrabel <david.vrabel@citrix.com>
CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: xen-devel@lists.xenproject.org
(cherry picked from commit 38737d82f9f0168955f9944c3f8bd3bb262c7e88)

Signed-off-by: default avatarAlex Shi <alex.shi@linaro.org>
parent 2e9d8621
Loading
Loading
Loading
Loading
+2 −0
Original line number Original line Diff line number Diff line
@@ -427,6 +427,7 @@ int __init pci_xen_init(void)
	x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
	x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
	x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
	x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
	x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
	x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
	pci_msi_ignore_mask = 1;
#endif
#endif
	return 0;
	return 0;
}
}
@@ -462,6 +463,7 @@ int __init pci_xen_initial_domain(void)
	x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
	x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
	x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
	x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
	x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
	x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
	pci_msi_ignore_mask = 1;
#endif
#endif
	__acpi_register_gsi = acpi_register_gsi_xen;
	__acpi_register_gsi = acpi_register_gsi_xen;
	/* Pre-allocate legacy irqs */
	/* Pre-allocate legacy irqs */
+6 −1
Original line number Original line Diff line number Diff line
@@ -23,6 +23,7 @@
#include "pci.h"
#include "pci.h"


static int pci_msi_enable = 1;
static int pci_msi_enable = 1;
int pci_msi_ignore_mask;


#define msix_table_size(flags)	((flags & PCI_MSIX_FLAGS_QSIZE) + 1)
#define msix_table_size(flags)	((flags & PCI_MSIX_FLAGS_QSIZE) + 1)


@@ -176,7 +177,7 @@ u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
{
	u32 mask_bits = desc->masked;
	u32 mask_bits = desc->masked;


	if (!desc->msi_attrib.maskbit)
	if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
		return 0;
		return 0;


	mask_bits &= ~mask;
	mask_bits &= ~mask;
@@ -208,6 +209,10 @@ u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
	u32 mask_bits = desc->masked;
	u32 mask_bits = desc->masked;
	unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
	unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
						PCI_MSIX_ENTRY_VECTOR_CTRL;
						PCI_MSIX_ENTRY_VECTOR_CTRL;

	if (pci_msi_ignore_mask)
		return 0;

	mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
	mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
	if (flag)
	if (flag)
		mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
		mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
+1 −0
Original line number Original line Diff line number Diff line
@@ -10,6 +10,7 @@ struct msi_msg {
	u32	data;		/* 16 bits of msi message data */
	u32	data;		/* 16 bits of msi message data */
};
};


extern int pci_msi_ignore_mask;
/* Helper functions */
/* Helper functions */
struct irq_data;
struct irq_data;
struct msi_desc;
struct msi_desc;