diff options
author | Mike Travis <travis@sgi.com> | 2009-01-11 00:58:09 -0500 |
---|---|---|
committer | Ingo Molnar <mingo@elte.hu> | 2009-01-11 13:13:02 -0500 |
commit | 802bf931f2688ad125b73db597ce63cc842fb27a (patch) | |
tree | e3715fce62ffeaac7f06f352dc538dccac215216 /include | |
parent | 651f8118cf0a5724f23fe1de4a3d9d36b2e01c2e (diff) |
cpumask: fix bug in use cpumask_var_t in irq_desc
Impact: fix bug where new irq_desc uses old cpumask pointers which are freed.
As Yinghai pointed out, init_copy_one_irq_desc() copies the old desc to
the new desc overwriting the cpumask pointers. Since the old_desc and
the cpumask pointers are freed, then memory corruption will occur if
these old pointers are used.
Move the allocation of these pointers to after the copy.
Signed-off-by: Mike Travis <travis@sgi.com>
Cc: Yinghai Lu <yinghai@kernel.org>
Diffstat (limited to 'include')
-rw-r--r-- | include/linux/irq.h | 9 |
1 files changed, 7 insertions, 2 deletions
diff --git a/include/linux/irq.h b/include/linux/irq.h index fa27210f1dfd..27a67536511e 100644 --- a/include/linux/irq.h +++ b/include/linux/irq.h | |||
@@ -426,15 +426,18 @@ extern int set_irq_msi(unsigned int irq, struct msi_desc *entry); | |||
426 | /** | 426 | /** |
427 | * init_alloc_desc_masks - allocate cpumasks for irq_desc | 427 | * init_alloc_desc_masks - allocate cpumasks for irq_desc |
428 | * @desc: pointer to irq_desc struct | 428 | * @desc: pointer to irq_desc struct |
429 | * @cpu: cpu which will be handling the cpumasks | ||
429 | * @boot: true if need bootmem | 430 | * @boot: true if need bootmem |
430 | * | 431 | * |
431 | * Allocates affinity and pending_mask cpumask if required. | 432 | * Allocates affinity and pending_mask cpumask if required. |
432 | * Returns true if successful (or not required). | 433 | * Returns true if successful (or not required). |
433 | * Side effect: affinity has all bits set, pending_mask has all bits clear. | 434 | * Side effect: affinity has all bits set, pending_mask has all bits clear. |
434 | */ | 435 | */ |
435 | static inline bool init_alloc_desc_masks(struct irq_desc *desc, int node, | 436 | static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu, |
436 | bool boot) | 437 | bool boot) |
437 | { | 438 | { |
439 | int node; | ||
440 | |||
438 | if (boot) { | 441 | if (boot) { |
439 | alloc_bootmem_cpumask_var(&desc->affinity); | 442 | alloc_bootmem_cpumask_var(&desc->affinity); |
440 | cpumask_setall(desc->affinity); | 443 | cpumask_setall(desc->affinity); |
@@ -446,6 +449,8 @@ static inline bool init_alloc_desc_masks(struct irq_desc *desc, int node, | |||
446 | return true; | 449 | return true; |
447 | } | 450 | } |
448 | 451 | ||
452 | node = cpu_to_node(cpu); | ||
453 | |||
449 | if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node)) | 454 | if (!alloc_cpumask_var_node(&desc->affinity, GFP_ATOMIC, node)) |
450 | return false; | 455 | return false; |
451 | cpumask_setall(desc->affinity); | 456 | cpumask_setall(desc->affinity); |
@@ -484,7 +489,7 @@ static inline void init_copy_desc_masks(struct irq_desc *old_desc, | |||
484 | 489 | ||
485 | #else /* !CONFIG_SMP */ | 490 | #else /* !CONFIG_SMP */ |
486 | 491 | ||
487 | static inline bool init_alloc_desc_masks(struct irq_desc *desc, int node, | 492 | static inline bool init_alloc_desc_masks(struct irq_desc *desc, int cpu, |
488 | bool boot) | 493 | bool boot) |
489 | { | 494 | { |
490 | return true; | 495 | return true; |