linux-kernel.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* [PATCH] x86/ioapic: Fix the vector_irq[] is corrupted randomly
@ 2012-10-29 16:15 Chuansheng Liu
  2012-10-29 20:24 ` Suresh Siddha
  0 siblings, 1 reply; 3+ messages in thread
From: Chuansheng Liu @ 2012-10-29 16:15 UTC (permalink / raw)
  To: mingo, hpa, tglx, yinghai, suresh.b.siddha
  Cc: x86, linux-kernel, chuansheng.liu


Not all irq chips are IO-APIC chip.

In our system, there are many demux GPIO interrupts except for the
io-apic chip interrupts, and these GPIO interrupts are belonged
to other irq chips, the chip data is not type of struct irq_cfg
either.

But in function __setup_vector_irq(), it listed all allocated irqs,
and presume all irq chip is ioapic_chip and the chip data is type
of struct irq_cfg, it possibly causes the vector_irq is corrupted
randomly.

For example, one irq 258 is not io-apic chip irq, in __setup_vector_irq(),
the chip data is forced to be used as struct irq_cfg, then the value
cfg->domain and cfg->vector are wrong to be used to write vector_irq:
		vector = cfg->vector;
		per_cpu(vector_irq, cpu)[vector] = irq;

This patch use the .flags to identify if the irq chip is io-apic.

Signed-off-by: liu chuansheng <chuansheng.liu@intel.com>
---
 arch/x86/kernel/apic/io_apic.c |   24 ++++++++++++++++++++++++
 1 files changed, 24 insertions(+), 0 deletions(-)

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 1817fa9..f9cac47 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -68,6 +68,18 @@
 #define for_each_irq_pin(entry, head) \
 	for (entry = head; entry; entry = entry->next)
 
+/* need more thoughts ... */
+#define CHIP_FLAG_IOAPIC	0x1000
+static inline bool is_ioapic_irq(int irq)
+{
+	struct irq_chip *chip;
+	chip = irq_get_chip(irq);
+	if ((chip) && (chip->flags == CHIP_FLAG_IOAPIC))
+		return true;
+
+	return false;
+}
+
 #ifdef CONFIG_IRQ_REMAP
 static void irq_remap_modify_chip_defaults(struct irq_chip *chip);
 static inline bool irq_remapped(struct irq_cfg *cfg)
@@ -1238,6 +1250,9 @@ void __setup_vector_irq(int cpu)
 	raw_spin_lock(&vector_lock);
 	/* Mark the inuse vectors */
 	for_each_active_irq(irq) {
+		if (!is_ioapic_irq(irq))
+			continue;
+
 		cfg = irq_get_chip_data(irq);
 		if (!cfg)
 			continue;
@@ -1259,6 +1274,9 @@ void __setup_vector_irq(int cpu)
 		if (irq < 0)
 			continue;
 
+		if (!is_ioapic_irq(irq))
+			continue;
+
 		cfg = irq_cfg(irq);
 		if (!cpumask_test_cpu(cpu, cfg->domain))
 			per_cpu(vector_irq, cpu)[vector] = -1;
@@ -2596,6 +2614,7 @@ static struct irq_chip ioapic_chip __read_mostly = {
 	.irq_eoi		= ack_apic_level,
 	.irq_set_affinity	= ioapic_set_affinity,
 	.irq_retrigger		= ioapic_retrigger_irq,
+	.flags			= CHIP_FLAG_IOAPIC,
 };
 
 static inline void init_IO_APIC_traps(void)
@@ -2661,6 +2680,7 @@ static struct irq_chip lapic_chip __read_mostly = {
 	.irq_mask	= mask_lapic_irq,
 	.irq_unmask	= unmask_lapic_irq,
 	.irq_ack	= ack_lapic_irq,
+	.flags			= CHIP_FLAG_IOAPIC,
 };
 
 static void lapic_register_intr(int irq)
@@ -3146,6 +3166,7 @@ static struct irq_chip msi_chip = {
 	.irq_ack		= ack_apic_edge,
 	.irq_set_affinity	= msi_set_affinity,
 	.irq_retrigger		= ioapic_retrigger_irq,
+	.flags			= CHIP_FLAG_IOAPIC,
 };
 
 static int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc, int irq)
@@ -3260,6 +3281,7 @@ static struct irq_chip dmar_msi_type = {
 	.irq_ack		= ack_apic_edge,
 	.irq_set_affinity	= dmar_msi_set_affinity,
 	.irq_retrigger		= ioapic_retrigger_irq,
+	.flags			= CHIP_FLAG_IOAPIC,
 };
 
 int arch_setup_dmar_msi(unsigned int irq)
@@ -3308,6 +3330,7 @@ static struct irq_chip hpet_msi_type = {
 	.irq_ack = ack_apic_edge,
 	.irq_set_affinity = hpet_msi_set_affinity,
 	.irq_retrigger = ioapic_retrigger_irq,
+	.flags			= CHIP_FLAG_IOAPIC,
 };
 
 int arch_setup_hpet_msi(unsigned int irq, unsigned int id)
@@ -3375,6 +3398,7 @@ static struct irq_chip ht_irq_chip = {
 	.irq_ack		= ack_apic_edge,
 	.irq_set_affinity	= ht_set_affinity,
 	.irq_retrigger		= ioapic_retrigger_irq,
+	.flags			= CHIP_FLAG_IOAPIC,
 };
 
 int arch_setup_ht_irq(unsigned int irq, struct pci_dev *dev)
-- 
1.7.0.4




^ permalink raw reply related	[flat|nested] 3+ messages in thread

* Re: [PATCH] x86/ioapic: Fix the vector_irq[] is corrupted randomly
  2012-10-29 16:15 [PATCH] x86/ioapic: Fix the vector_irq[] is corrupted randomly Chuansheng Liu
@ 2012-10-29 20:24 ` Suresh Siddha
  2012-10-30  1:11   ` Liu, Chuansheng
  0 siblings, 1 reply; 3+ messages in thread
From: Suresh Siddha @ 2012-10-29 20:24 UTC (permalink / raw)
  To: Chuansheng Liu; +Cc: mingo, hpa, tglx, yinghai, x86, linux-kernel

On Tue, 2012-10-30 at 00:15 +0800, Chuansheng Liu wrote:
> Not all irq chips are IO-APIC chip.
> 
> In our system, there are many demux GPIO interrupts except for the
> io-apic chip interrupts, and these GPIO interrupts are belonged
> to other irq chips, the chip data is not type of struct irq_cfg
> either.
> 
> But in function __setup_vector_irq(), it listed all allocated irqs,
> and presume all irq chip is ioapic_chip and the chip data is type
> of struct irq_cfg, it possibly causes the vector_irq is corrupted
> randomly.
> 
> For example, one irq 258 is not io-apic chip irq, in __setup_vector_irq(),
> the chip data is forced to be used as struct irq_cfg, then the value
> cfg->domain and cfg->vector are wrong to be used to write vector_irq:
> 		vector = cfg->vector;
> 		per_cpu(vector_irq, cpu)[vector] = irq;
> 
> This patch use the .flags to identify if the irq chip is io-apic.

I have a feeling that your gpio driver is abusing the 'chip_data' in the
struct irq_data. Shouldn't the driver be using 'handler_data' instead?

>From include/linux/irq.h:
 * @handler_data:       per-IRQ data for the irq_chip methods
 * @chip_data:          platform-specific per-chip private data for the chip
 *                      methods, to allow shared chip implementations

Also, how are these routed to the processors and the mechanism of the
vector assignment for these irq's? I presume irq_cfg is needed for the
setup and the interrupt migration from one cpu to another.

What am I missing?

thanks,
suresh


^ permalink raw reply	[flat|nested] 3+ messages in thread

* RE: [PATCH] x86/ioapic: Fix the vector_irq[] is corrupted randomly
  2012-10-29 20:24 ` Suresh Siddha
@ 2012-10-30  1:11   ` Liu, Chuansheng
  0 siblings, 0 replies; 3+ messages in thread
From: Liu, Chuansheng @ 2012-10-30  1:11 UTC (permalink / raw)
  To: Siddha, Suresh B; +Cc: mingo, hpa, tglx, yinghai, x86, linux-kernel

[-- Warning: decoded text below may be mangled, UTF-8 assumed --]
[-- Attachment #1: Type: text/plain; charset="utf-8", Size: 2759 bytes --]



> -----Original Message-----
> From: Siddha, Suresh B
> Sent: Tuesday, October 30, 2012 4:24 AM
> To: Liu, Chuansheng
> Cc: mingo@redhat.com; hpa@zytor.com; tglx@linutronix.de;
> yinghai@kernel.org; x86@kernel.org; linux-kernel@vger.kernel.org
> Subject: Re: [PATCH] x86/ioapic: Fix the vector_irq[] is corrupted randomly
> 
> On Tue, 2012-10-30 at 00:15 +0800, Chuansheng Liu wrote:
> > Not all irq chips are IO-APIC chip.
> >
> > In our system, there are many demux GPIO interrupts except for the
> > io-apic chip interrupts, and these GPIO interrupts are belonged
> > to other irq chips, the chip data is not type of struct irq_cfg
> > either.
> >
> > But in function __setup_vector_irq(), it listed all allocated irqs,
> > and presume all irq chip is ioapic_chip and the chip data is type
> > of struct irq_cfg, it possibly causes the vector_irq is corrupted
> > randomly.
> >
> > For example, one irq 258 is not io-apic chip irq, in __setup_vector_irq(),
> > the chip data is forced to be used as struct irq_cfg, then the value
> > cfg->domain and cfg->vector are wrong to be used to write vector_irq:
> > 		vector = cfg->vector;
> > 		per_cpu(vector_irq, cpu)[vector] = irq;
> >
> > This patch use the .flags to identify if the irq chip is io-apic.
> 
> I have a feeling that your gpio driver is abusing the 'chip_data' in the
> struct irq_data. Shouldn't the driver be using 'handler_data' instead?
Not abusing.

There are many driver codes which has their own chip and chip_data.
For example,
langwell_gpio.c, the chip_data type is struct lnw_gpio;
gpio_omap.c, the chip_data type is struct gpio_bank;

In these cases, if we abused the gpio chip_data type with struct irq_cfg,
we will get very wrong cfg->vector, the value maybe 1 or 1000, anyway,
it is a random value.
> 
> From include/linux/irq.h:
>  * @handler_data:       per-IRQ data for the irq_chip methods
>  * @chip_data:          platform-specific per-chip private data for the chip
>  *                      methods, to allow shared chip implementations
> 
> Also, how are these routed to the processors and the mechanism of the
> vector assignment for these irq's? I presume irq_cfg is needed for the
> setup and the interrupt migration from one cpu to another.
Normally gpio chip just has only one base irq is related with io-apic interrupt,
other allocated *VIRTUAL* irqs are based on this base irq, so no vector assign to them.

But in code __setup_vector_irq(), it list all allocated irqs which include the *VIRTUAL* irqs,
It causes this case that chip_data type is abused.

> 
> What am I missing?
> 
> thanks,
> suresh

ÿôèº{.nÇ+‰·Ÿ®‰­†+%ŠËÿ±éݶ\x17¥Šwÿº{.nÇ+‰·¥Š{±þG«éÿŠ{ayº\x1dʇڙë,j\a­¢f£¢·hšïêÿ‘êçz_è®\x03(­éšŽŠÝ¢j"ú\x1a¶^[m§ÿÿ¾\a«þG«éÿ¢¸?™¨è­Ú&£ø§~á¶iO•æ¬z·švØ^\x14\x04\x1a¶^[m§ÿÿÃ\fÿ¶ìÿ¢¸?–I¥

^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2012-10-30  1:11 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-10-29 16:15 [PATCH] x86/ioapic: Fix the vector_irq[] is corrupted randomly Chuansheng Liu
2012-10-29 20:24 ` Suresh Siddha
2012-10-30  1:11   ` Liu, Chuansheng

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).