diff options
Diffstat (limited to 'kernel/irq/proc.c')
| -rw-r--r-- | kernel/irq/proc.c | 35 |
1 files changed, 24 insertions, 11 deletions
diff --git a/kernel/irq/proc.c b/kernel/irq/proc.c index 4d161c70ba55..d2c0e5ee53c5 100644 --- a/kernel/irq/proc.c +++ b/kernel/irq/proc.c | |||
| @@ -40,33 +40,42 @@ static ssize_t irq_affinity_proc_write(struct file *file, | |||
| 40 | const char __user *buffer, size_t count, loff_t *pos) | 40 | const char __user *buffer, size_t count, loff_t *pos) |
| 41 | { | 41 | { |
| 42 | unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data; | 42 | unsigned int irq = (int)(long)PDE(file->f_path.dentry->d_inode)->data; |
| 43 | cpumask_t new_value; | 43 | cpumask_var_t new_value; |
| 44 | int err; | 44 | int err; |
| 45 | 45 | ||
| 46 | if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity || | 46 | if (!irq_to_desc(irq)->chip->set_affinity || no_irq_affinity || |
| 47 | irq_balancing_disabled(irq)) | 47 | irq_balancing_disabled(irq)) |
| 48 | return -EIO; | 48 | return -EIO; |
| 49 | 49 | ||
| 50 | if (!alloc_cpumask_var(&new_value, GFP_KERNEL)) | ||
| 51 | return -ENOMEM; | ||
| 52 | |||
| 50 | err = cpumask_parse_user(buffer, count, new_value); | 53 | err = cpumask_parse_user(buffer, count, new_value); |
| 51 | if (err) | 54 | if (err) |
| 52 | return err; | 55 | goto free_cpumask; |
| 53 | 56 | ||
| 54 | if (!is_affinity_mask_valid(new_value)) | 57 | if (!is_affinity_mask_valid(*new_value)) { |
| 55 | return -EINVAL; | 58 | err = -EINVAL; |
| 59 | goto free_cpumask; | ||
| 60 | } | ||
| 56 | 61 | ||
| 57 | /* | 62 | /* |
| 58 | * Do not allow disabling IRQs completely - it's a too easy | 63 | * Do not allow disabling IRQs completely - it's a too easy |
| 59 | * way to make the system unusable accidentally :-) At least | 64 | * way to make the system unusable accidentally :-) At least |
| 60 | * one online CPU still has to be targeted. | 65 | * one online CPU still has to be targeted. |
| 61 | */ | 66 | */ |
| 62 | if (!cpus_intersects(new_value, cpu_online_map)) | 67 | if (!cpumask_intersects(new_value, cpu_online_mask)) { |
| 63 | /* Special case for empty set - allow the architecture | 68 | /* Special case for empty set - allow the architecture |
| 64 | code to set default SMP affinity. */ | 69 | code to set default SMP affinity. */ |
| 65 | return irq_select_affinity(irq) ? -EINVAL : count; | 70 | err = irq_select_affinity_usr(irq) ? -EINVAL : count; |
| 66 | 71 | } else { | |
| 67 | irq_set_affinity(irq, new_value); | 72 | irq_set_affinity(irq, new_value); |
| 73 | err = count; | ||
| 74 | } | ||
| 68 | 75 | ||
| 69 | return count; | 76 | free_cpumask: |
| 77 | free_cpumask_var(new_value); | ||
| 78 | return err; | ||
| 70 | } | 79 | } |
| 71 | 80 | ||
| 72 | static int irq_affinity_proc_open(struct inode *inode, struct file *file) | 81 | static int irq_affinity_proc_open(struct inode *inode, struct file *file) |
| @@ -95,7 +104,7 @@ static ssize_t default_affinity_write(struct file *file, | |||
| 95 | cpumask_t new_value; | 104 | cpumask_t new_value; |
| 96 | int err; | 105 | int err; |
| 97 | 106 | ||
| 98 | err = cpumask_parse_user(buffer, count, new_value); | 107 | err = cpumask_parse_user(buffer, count, &new_value); |
| 99 | if (err) | 108 | if (err) |
| 100 | return err; | 109 | return err; |
| 101 | 110 | ||
| @@ -243,7 +252,11 @@ void init_irq_proc(void) | |||
| 243 | /* | 252 | /* |
| 244 | * Create entries for all existing IRQs. | 253 | * Create entries for all existing IRQs. |
| 245 | */ | 254 | */ |
| 246 | for_each_irq_desc(irq, desc) | 255 | for_each_irq_desc(irq, desc) { |
| 256 | if (!desc) | ||
| 257 | continue; | ||
| 258 | |||
| 247 | register_irq_proc(irq, desc); | 259 | register_irq_proc(irq, desc); |
| 260 | } | ||
| 248 | } | 261 | } |
| 249 | 262 | ||
