From patchwork Thu Jun 17 19:16:36 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Ben Hutchings X-Patchwork-Id: 106731 Received: from vger.kernel.org (vger.kernel.org [209.132.180.67]) by demeter.kernel.org (8.14.3/8.14.3) with ESMTP id o5HJGpYG015559 for ; Thu, 17 Jun 2010 19:16:51 GMT Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand id S933168Ab0FQTQm (ORCPT ); Thu, 17 Jun 2010 15:16:42 -0400 Received: from exchange.solarflare.com ([216.237.3.220]:18680 "EHLO exchange.solarflare.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S933148Ab0FQTQl (ORCPT ); Thu, 17 Jun 2010 15:16:41 -0400 Received: from [10.17.20.50] ([10.17.20.50]) by exchange.solarflare.com over TLS secured channel with Microsoft SMTPSVC(6.0.3790.3959); Thu, 17 Jun 2010 12:17:02 -0700 Subject: [PATCH] PCI: MSI: Remove unsafe and unnecessary hardware access From: Ben Hutchings To: Jesse Barnes Cc: Michael Chan , Matthew Wilcox , linux-pci@vger.kernel.org, netdev@vger.kernel.org In-Reply-To: <1276564403.19104.28.camel@HP1> References: <1276564403.19104.28.camel@HP1> Organization: Solarflare Communications Date: Thu, 17 Jun 2010 20:16:36 +0100 Message-Id: <1276802196.2083.12.camel@achroite.uk.solarflarecom.com> Mime-Version: 1.0 X-Mailer: Evolution 2.26.1 (2.26.1-2.fc11) X-OriginalArrivalTime: 17 Jun 2010 19:17:03.0273 (UTC) FILETIME=[AAE90990:01CB0E51] X-TM-AS-Product-Ver: SMEX-8.0.0.1181-6.000.1038-17450.005 X-TM-AS-Result: No--42.105300-0.000000-31 X-TM-AS-User-Approved-Sender: Yes X-TM-AS-User-Blocked-Sender: No Sender: linux-pci-owner@vger.kernel.org Precedence: bulk List-ID: X-Mailing-List: linux-pci@vger.kernel.org X-Greylist: IP, sender and recipient auto-whitelisted, not delayed by milter-greylist-4.2.3 (demeter.kernel.org [140.211.167.41]); Thu, 17 Jun 2010 19:16:53 +0000 (UTC) diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c index 77b68ea..03f04dc 100644 --- a/drivers/pci/msi.c +++ b/drivers/pci/msi.c @@ -196,30 +196,15 @@ void unmask_msi_irq(unsigned int irq) void read_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - if (entry->msi_attrib.is_msix) { - void __iomem *base = entry->mask_base + - entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE; - msg->address_lo = readl(base + PCI_MSIX_ENTRY_LOWER_ADDR); - msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR); - msg->data = readl(base + PCI_MSIX_ENTRY_DATA); - } else { - struct pci_dev *dev = entry->dev; - int pos = entry->msi_attrib.pos; - u16 data; + /* We do not touch the hardware (which may not even be + * accessible at the moment) but return the last message + * written. Assert that this is valid, assuming that + * valid messages are not all-zeroes. */ + BUG_ON(!(entry->msg.address_hi | entry->msg.address_lo | + entry->msg.data)); - pci_read_config_dword(dev, msi_lower_address_reg(pos), - &msg->address_lo); - if (entry->msi_attrib.is_64) { - pci_read_config_dword(dev, msi_upper_address_reg(pos), - &msg->address_hi); - pci_read_config_word(dev, msi_data_reg(pos, 1), &data); - } else { - msg->address_hi = 0; - pci_read_config_word(dev, msi_data_reg(pos, 0), &data); - } - msg->data = data; - } + *msg = entry->msg; } void read_msi_msg(unsigned int irq, struct msi_msg *msg) @@ -232,7 +217,10 @@ void read_msi_msg(unsigned int irq, struct msi_msg *msg) void write_msi_msg_desc(struct irq_desc *desc, struct msi_msg *msg) { struct msi_desc *entry = get_irq_desc_msi(desc); - if (entry->msi_attrib.is_msix) { + + if (entry->dev->current_state != PCI_D0) { + /* Don't touch the hardware now */ + } else if (entry->msi_attrib.is_msix) { void __iomem *base; base = entry->mask_base + entry->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE;