From mboxrd@z Thu Jan 1 00:00:00 1970 From: Kenji Kaneshige Date: Wed, 21 Jul 2004 08:52:14 +0000 Subject: [PATCH] bug in irq_affinity_write_proc Message-Id: <40FE2EBE.4070007@jp.fujitsu.com> List-Id: MIME-Version: 1.0 Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit To: linux-ia64@vger.kernel.org Hi, Writing a value with 'R' or 'r' character to /proc/irq//smp_affinity causes a kernel Oops. The following patch fixes this issue. Signed-off-by: Kenji Kaneshige --- linux-2.6.8-rc2-kanesige/arch/ia64/kernel/irq.c | 8 ++++++-- 1 files changed, 6 insertions(+), 2 deletions(-) diff -puN arch/ia64/kernel/irq.c~fix_irq_affinity_write_proc arch/ia64/kernel/irq.c --- linux-2.6.8-rc2/arch/ia64/kernel/irq.c~fix_irq_affinity_write_proc 2004-07-21 15:32:10.000000000 +0900 +++ linux-2.6.8-rc2-kanesige/arch/ia64/kernel/irq.c 2004-07-21 17:14:18.865086983 +0900 @@ -88,6 +88,7 @@ irq_desc_t _irq_desc[NR_IRQS] __cachelin * This is updated when the user sets irq affinity via /proc */ cpumask_t __cacheline_aligned pending_irq_cpumask[NR_IRQS]; +static int pending_irq_redir[NR_IRQS]; #ifdef CONFIG_IA64_GENERIC irq_desc_t * __ia64_irq_desc (unsigned int irq) @@ -973,6 +974,7 @@ static int irq_affinity_write_proc (stru int prelen; irq_desc_t *desc = irq_descp(irq); unsigned long flags; + int redir = 0; if (!desc->handler->set_affinity) return -EIO; @@ -995,7 +997,7 @@ static int irq_affinity_write_proc (stru prelen = 0; if (tolower(*rbuf) = 'r') { prelen = strspn(rbuf, "Rr "); - irq |= IA64_IRQ_REDIRECTED; + redir++; } err = cpumask_parse(buffer+prelen, count-prelen, new_value); @@ -1012,6 +1014,7 @@ static int irq_affinity_write_proc (stru return -EINVAL; spin_lock_irqsave(&desc->lock, flags); + pending_irq_redir[irq] = redir; pending_irq_cpumask[irq] = new_value; spin_unlock_irqrestore(&desc->lock, flags); @@ -1023,11 +1026,12 @@ void move_irq(int irq) /* note - we hold desc->lock */ cpumask_t tmp; irq_desc_t *desc = irq_descp(irq); + int irq_with_redir = pending_irq_redir[irq] ? (irq | IA64_IRQ_REDIRECTED) : irq; if (!cpus_empty(pending_irq_cpumask[irq])) { cpus_and(tmp, pending_irq_cpumask[irq], cpu_online_map); if (unlikely(!cpus_empty(tmp))) { - desc->handler->set_affinity(irq, pending_irq_cpumask[irq]); + desc->handler->set_affinity(irq_with_redir, pending_irq_cpumask[irq]); } cpus_clear(pending_irq_cpumask[irq]); } _