From: Yinghai Lu <yhlu.kernel.send@gmail.com>
To: Thomas Gleixner <tglx@linutronix.de>,
Andrew Morton <akpm@linux-foundation.org>,
Ingo Molnar <mingo@elte.hu>,
"Eric W. Biederman" <ebiederm@xmission.com>
Cc: Jeff Garzik <jeff@garzik.org>, Ayaz Abdulla <aabdulla@nvidia.com>,
kernel list <linux-kernel@vger.kernel.org>
Subject: [PATCH] x86_64: restore mask_bits in msi shutdown
Date: Fri, 11 Apr 2008 16:26:11 -0700 [thread overview]
Message-ID: <200804111626.11232.yhlu.kernel@gmail.com> (raw)
I can not kexec RHEL 5.1 from 2.6.25-rc3 later
caused by:
commit 89d694b9dbe769ca1004e01db0ca43964806a611
Author: Thomas Gleixner <tglx@linutronix.de>
Date: Mon Feb 18 18:25:17 2008 +0100
genirq: do not leave interupts enabled on free_irq
The default_disable() function was changed in commit:
76d2160147f43f982dfe881404cfde9fd0a9da21
genirq: do not mask interrupts by default
It removed the mask function in favour of the default delayed
interrupt disabling. Unfortunately this also broke the shutdown in
free_irq() when the last handler is removed from the interrupt for
those architectures which rely on the default implementations. Now we
can end up with a enabled interrupt line after the last handler was
removed, which can result in spurious interrupts.
Fix this by adding a default_shutdown function, which is only
installed, when the irqchip implementation does provide neither a
shutdown nor a disable function.
[@stable: affected versions: .21 - .24 ]
for MSI, default_shutdown will call mask_bit for msi device. so all mask bits will
left disabled after free_irq.
then if kexec next kernel that only can use msi_enable bit.
all device's MSI can not be used.
So try to restore MSI mask bits that is saved before using msi in first kernel.
Signed-off-by: Yinghai Lu <yhlu.kernel@gmail.com>
Index: linux-2.6/arch/x86/kernel/io_apic_64.c
===================================================================
--- linux-2.6.orig/arch/x86/kernel/io_apic_64.c
+++ linux-2.6/arch/x86/kernel/io_apic_64.c
@@ -2003,6 +2003,14 @@ static void set_msi_irq_affinity(unsigne
}
#endif /* CONFIG_SMP */
+static void msi_shutdown(unsigned int irq)
+{
+ struct irq_desc *desc = irq_desc + irq;
+
+ msi_restore_mask_bits(irq);
+ desc->status |= IRQ_MASKED;
+}
+
/*
* IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
* which implement the MSI or MSI-X Capability Structure.
@@ -2012,6 +2020,7 @@ static struct irq_chip msi_chip = {
.unmask = unmask_msi_irq,
.mask = mask_msi_irq,
.ack = ack_apic_edge,
+ .shutdown = msi_shutdown,
#ifdef CONFIG_SMP
.set_affinity = set_msi_irq_affinity,
#endif
Index: linux-2.6/drivers/pci/msi.c
===================================================================
--- linux-2.6.orig/drivers/pci/msi.c
+++ linux-2.6/drivers/pci/msi.c
@@ -123,6 +123,31 @@ static void msix_flush_writes(unsigned i
}
}
+void msi_restore_mask_bits(unsigned int irq)
+{
+ struct msi_desc *entry;
+
+ entry = get_irq_msi(irq);
+ BUG_ON(!entry || !entry->dev);
+ switch (entry->msi_attrib.type) {
+ case PCI_CAP_ID_MSI:
+ if (entry->msi_attrib.maskbit) {
+ int pos;
+ u32 mask_bits;
+
+ pos = (long)entry->mask_base;
+ mask_bits = entry->orig_mask_bits;
+ pci_write_config_dword(entry->dev, pos, mask_bits);
+ }
+ break;
+ case PCI_CAP_ID_MSIX:
+ break;
+ default:
+ BUG();
+ break;
+ }
+}
+
static void msi_set_mask_bit(unsigned int irq, int flag)
{
struct msi_desc *entry;
@@ -376,6 +401,7 @@ static int msi_capability_init(struct pc
pci_read_config_dword(dev,
msi_mask_bits_reg(pos, is_64bit_address(control)),
&maskbits);
+ entry->orig_mask_bits = maskbits;
temp = (1 << multi_msi_capable(control));
temp = ((temp - 1) & ~temp);
maskbits |= temp;
Index: linux-2.6/include/linux/msi.h
===================================================================
--- linux-2.6.orig/include/linux/msi.h
+++ linux-2.6/include/linux/msi.h
@@ -14,6 +14,7 @@ extern void mask_msi_irq(unsigned int ir
extern void unmask_msi_irq(unsigned int irq);
extern void read_msi_msg(unsigned int irq, struct msi_msg *msg);
extern void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+extern void msi_restore_mask_bits(unsigned int irq);
struct msi_desc {
struct {
@@ -30,6 +31,7 @@ struct msi_desc {
struct list_head list;
void __iomem *mask_base;
+ u32 orig_mask_bits; /* restoring it for freeing */
struct pci_dev *dev;
/* Last set MSI message */
next reply other threads:[~2008-04-11 23:22 UTC|newest]
Thread overview: 8+ messages / expand[flat|nested] mbox.gz Atom feed top
2008-04-11 23:26 Yinghai Lu [this message]
2008-04-15 8:12 ` [PATCH] x86_64: restore mask_bits in msi shutdown Andrew Morton
2008-04-15 8:17 ` Yinghai Lu
2008-04-17 9:19 ` Eric W. Biederman
2008-04-17 9:44 ` Yinghai Lu
2008-04-17 9:51 ` Yinghai Lu
2008-04-17 10:15 ` Eric W. Biederman
2008-04-17 19:38 ` Yinghai Lu
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=200804111626.11232.yhlu.kernel@gmail.com \
--to=yhlu.kernel.send@gmail.com \
--cc=aabdulla@nvidia.com \
--cc=akpm@linux-foundation.org \
--cc=ebiederm@xmission.com \
--cc=jeff@garzik.org \
--cc=linux-kernel@vger.kernel.org \
--cc=mingo@elte.hu \
--cc=tglx@linutronix.de \
--cc=yhlu.kernel@gmail.com \
/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 an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.