diff options
author | Russell King <rmk@dyn-67.arm.linux.org.uk> | 2005-06-28 08:49:16 -0400 |
---|---|---|
committer | Russell King <rmk+kernel@arm.linux.org.uk> | 2005-06-28 08:49:16 -0400 |
commit | 4b0ef3b1127776d4a2787d7530ac0c4da82c2331 (patch) | |
tree | be7e11c8d325e757f1f4c0caf825966eb4d9c7b8 /arch/arm/kernel | |
parent | 564c90aa07cd43dc434d46cef8a15773a23d49a2 (diff) |
[PATCH] ARM SMP: Add IPI support code for SMP TLB flushing
Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/kernel')
-rw-r--r-- | arch/arm/kernel/smp.c | 123 |
1 files changed, 123 insertions, 0 deletions
diff --git a/arch/arm/kernel/smp.c b/arch/arm/kernel/smp.c index 34892758f098..a931409c8fe4 100644 --- a/arch/arm/kernel/smp.c +++ b/arch/arm/kernel/smp.c | |||
@@ -502,3 +502,126 @@ int __init setup_profiling_timer(unsigned int multiplier) | |||
502 | { | 502 | { |
503 | return -EINVAL; | 503 | return -EINVAL; |
504 | } | 504 | } |
505 | |||
506 | static int | ||
507 | on_each_cpu_mask(void (*func)(void *), void *info, int retry, int wait, | ||
508 | cpumask_t mask) | ||
509 | { | ||
510 | int ret = 0; | ||
511 | |||
512 | preempt_disable(); | ||
513 | |||
514 | ret = smp_call_function_on_cpu(func, info, retry, wait, mask); | ||
515 | if (cpu_isset(smp_processor_id(), mask)) | ||
516 | func(info); | ||
517 | |||
518 | preempt_enable(); | ||
519 | |||
520 | return ret; | ||
521 | } | ||
522 | |||
523 | /**********************************************************************/ | ||
524 | |||
525 | /* | ||
526 | * TLB operations | ||
527 | */ | ||
528 | struct tlb_args { | ||
529 | struct vm_area_struct *ta_vma; | ||
530 | unsigned long ta_start; | ||
531 | unsigned long ta_end; | ||
532 | }; | ||
533 | |||
534 | static inline void ipi_flush_tlb_all(void *ignored) | ||
535 | { | ||
536 | local_flush_tlb_all(); | ||
537 | } | ||
538 | |||
539 | static inline void ipi_flush_tlb_mm(void *arg) | ||
540 | { | ||
541 | struct mm_struct *mm = (struct mm_struct *)arg; | ||
542 | |||
543 | local_flush_tlb_mm(mm); | ||
544 | } | ||
545 | |||
546 | static inline void ipi_flush_tlb_page(void *arg) | ||
547 | { | ||
548 | struct tlb_args *ta = (struct tlb_args *)arg; | ||
549 | |||
550 | local_flush_tlb_page(ta->ta_vma, ta->ta_start); | ||
551 | } | ||
552 | |||
553 | static inline void ipi_flush_tlb_kernel_page(void *arg) | ||
554 | { | ||
555 | struct tlb_args *ta = (struct tlb_args *)arg; | ||
556 | |||
557 | local_flush_tlb_kernel_page(ta->ta_start); | ||
558 | } | ||
559 | |||
560 | static inline void ipi_flush_tlb_range(void *arg) | ||
561 | { | ||
562 | struct tlb_args *ta = (struct tlb_args *)arg; | ||
563 | |||
564 | local_flush_tlb_range(ta->ta_vma, ta->ta_start, ta->ta_end); | ||
565 | } | ||
566 | |||
567 | static inline void ipi_flush_tlb_kernel_range(void *arg) | ||
568 | { | ||
569 | struct tlb_args *ta = (struct tlb_args *)arg; | ||
570 | |||
571 | local_flush_tlb_kernel_range(ta->ta_start, ta->ta_end); | ||
572 | } | ||
573 | |||
574 | void flush_tlb_all(void) | ||
575 | { | ||
576 | on_each_cpu(ipi_flush_tlb_all, NULL, 1, 1); | ||
577 | } | ||
578 | |||
579 | void flush_tlb_mm(struct mm_struct *mm) | ||
580 | { | ||
581 | cpumask_t mask = mm->cpu_vm_mask; | ||
582 | |||
583 | on_each_cpu_mask(ipi_flush_tlb_mm, mm, 1, 1, mask); | ||
584 | } | ||
585 | |||
586 | void flush_tlb_page(struct vm_area_struct *vma, unsigned long uaddr) | ||
587 | { | ||
588 | cpumask_t mask = vma->vm_mm->cpu_vm_mask; | ||
589 | struct tlb_args ta; | ||
590 | |||
591 | ta.ta_vma = vma; | ||
592 | ta.ta_start = uaddr; | ||
593 | |||
594 | on_each_cpu_mask(ipi_flush_tlb_page, &ta, 1, 1, mask); | ||
595 | } | ||
596 | |||
597 | void flush_tlb_kernel_page(unsigned long kaddr) | ||
598 | { | ||
599 | struct tlb_args ta; | ||
600 | |||
601 | ta.ta_start = kaddr; | ||
602 | |||
603 | on_each_cpu(ipi_flush_tlb_kernel_page, &ta, 1, 1); | ||
604 | } | ||
605 | |||
606 | void flush_tlb_range(struct vm_area_struct *vma, | ||
607 | unsigned long start, unsigned long end) | ||
608 | { | ||
609 | cpumask_t mask = vma->vm_mm->cpu_vm_mask; | ||
610 | struct tlb_args ta; | ||
611 | |||
612 | ta.ta_vma = vma; | ||
613 | ta.ta_start = start; | ||
614 | ta.ta_end = end; | ||
615 | |||
616 | on_each_cpu_mask(ipi_flush_tlb_range, &ta, 1, 1, mask); | ||
617 | } | ||
618 | |||
619 | void flush_tlb_kernel_range(unsigned long start, unsigned long end) | ||
620 | { | ||
621 | struct tlb_args ta; | ||
622 | |||
623 | ta.ta_start = start; | ||
624 | ta.ta_end = end; | ||
625 | |||
626 | on_each_cpu(ipi_flush_tlb_kernel_range, &ta, 1, 1); | ||
627 | } | ||