aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJohn Keller <jpk@sgi.com>2007-05-11 01:42:44 -0400
committerTony Luck <tony.luck@intel.com>2007-05-11 12:35:38 -0400
commit25d61578daae697c4a0eb817f42a868af9824f82 (patch)
treeec4ac10132f0b12a822dba6a53d05bab78ec3760
parent3e3d32770204ea24cf71919a90d9ccfc2bd407dd (diff)
[IA64] SN: validate smp_affinity mask on intr redirect
On SN, only allow one bit to be set in the smp_affinty mask when redirecting an interrupt. Currently setting multiple bits is allowed, but only the first bit is used in determining the CPU to redirect to. This has caused confusion among some customers. [akpm@linux-foundation.org: fixes] Signed-off-by: John Keller <jpk@sgi.com> Signed-off-by: Andrew Morton <akpm@linux-foundation.org> Signed-off-by: Tony Luck <tony.luck@intel.com>
-rw-r--r--arch/ia64/kernel/irq.c11
-rw-r--r--include/asm-ia64/irq.h6
-rw-r--r--kernel/irq/proc.c7
3 files changed, 24 insertions, 0 deletions
diff --git a/arch/ia64/kernel/irq.c b/arch/ia64/kernel/irq.c
index ce49c85c928f..b4c239685d2e 100644
--- a/arch/ia64/kernel/irq.c
+++ b/arch/ia64/kernel/irq.c
@@ -104,6 +104,17 @@ void set_irq_affinity_info (unsigned int irq, int hwid, int redir)
104 irq_redir[irq] = (char) (redir & 0xff); 104 irq_redir[irq] = (char) (redir & 0xff);
105 } 105 }
106} 106}
107
108bool is_affinity_mask_valid(cpumask_t cpumask)
109{
110 if (ia64_platform_is("sn2")) {
111 /* Only allow one CPU to be specified in the smp_affinity mask */
112 if (cpus_weight(cpumask) != 1)
113 return false;
114 }
115 return true;
116}
117
107#endif /* CONFIG_SMP */ 118#endif /* CONFIG_SMP */
108 119
109#ifdef CONFIG_HOTPLUG_CPU 120#ifdef CONFIG_HOTPLUG_CPU
diff --git a/include/asm-ia64/irq.h b/include/asm-ia64/irq.h
index 79479e2c6966..67221615e317 100644
--- a/include/asm-ia64/irq.h
+++ b/include/asm-ia64/irq.h
@@ -11,6 +11,9 @@
11 * 02/29/00 D.Mosberger moved most things into hw_irq.h 11 * 02/29/00 D.Mosberger moved most things into hw_irq.h
12 */ 12 */
13 13
14#include <linux/types.h>
15#include <linux/cpumask.h>
16
14#define NR_IRQS 256 17#define NR_IRQS 256
15#define NR_IRQ_VECTORS NR_IRQS 18#define NR_IRQ_VECTORS NR_IRQS
16 19
@@ -29,5 +32,8 @@ extern void disable_irq (unsigned int);
29extern void disable_irq_nosync (unsigned int); 32extern void disable_irq_nosync (unsigned int);
30extern void enable_irq (unsigned int); 33extern void enable_irq (unsigned int);
31extern void set_irq_affinity_info (unsigned int irq, int dest, int redir); 34extern void set_irq_affinity_info (unsigned int irq, int dest, int redir);
35bool is_affinity_mask_valid(cpumask_t cpumask);
36
37#define is_affinity_mask_valid is_affinity_mask_valid
32 38
33#endif /* _ASM_IA64_IRQ_H */ 39#endif /* _ASM_IA64_IRQ_H */
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c
index ddde0ef9ccdc..b4f1674fca79 100644
--- a/kernel/irq/proc.c
+++ b/kernel/irq/proc.c
@@ -27,6 +27,10 @@ static int irq_affinity_read_proc(char *page, char **start, off_t off,
27 return len; 27 return len;
28} 28}
29 29
30#ifndef is_affinity_mask_valid
31#define is_affinity_mask_valid(val) 1
32#endif
33
30int no_irq_affinity; 34int no_irq_affinity;
31static int irq_affinity_write_proc(struct file *file, const char __user *buffer, 35static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
32 unsigned long count, void *data) 36 unsigned long count, void *data)
@@ -42,6 +46,9 @@ static int irq_affinity_write_proc(struct file *file, const char __user *buffer,
42 if (err) 46 if (err)
43 return err; 47 return err;
44 48
49 if (!is_affinity_mask_valid(new_value))
50 return -EINVAL;
51
45 /* 52 /*
46 * Do not allow disabling IRQs completely - it's a too easy 53 * Do not allow disabling IRQs completely - it's a too easy
47 * way to make the system unusable accidentally :-) At least 54 * way to make the system unusable accidentally :-) At least