diff options
| -rw-r--r-- | drivers/pci/msi.c | 15 | 
1 files changed, 15 insertions, 0 deletions
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 57c9ec9b976b..7ee1ac47caa7 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -289,13 +289,28 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)  		/* Don't touch the hardware now */  	} else if (entry->msi_attrib.is_msix) {  		void __iomem *base = pci_msix_desc_addr(entry); +		bool unmasked = !(entry->masked & PCI_MSIX_ENTRY_CTRL_MASKBIT);  		if (!base)  			goto skip; +		/* +		 * The specification mandates that the entry is masked +		 * when the message is modified: +		 * +		 * "If software changes the Address or Data value of an +		 * entry while the entry is unmasked, the result is +		 * undefined." +		 */ +		if (unmasked) +			__pci_msix_desc_mask_irq(entry, PCI_MSIX_ENTRY_CTRL_MASKBIT); +  		writel(msg->address_lo, base + PCI_MSIX_ENTRY_LOWER_ADDR);  		writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);  		writel(msg->data, base + PCI_MSIX_ENTRY_DATA); + +		if (unmasked) +			__pci_msix_desc_mask_irq(entry, 0);  	} else {  		int pos = dev->msi_cap;  		u16 msgctl;  | 
